Tables Programming - Discussion

Hi @thecil Carlos,

I have no problem building the contract when I use “helloworld”_n in the .cpp file
But if I replace with get_self() instead, the red box pops up and says get_self() is not defined, do you know why is that?

#include <helloworld.hpp>

void helloworld::hi(eosio::name const & nm)
{
  eosio::print("Hello", nm);
}

void addpet(uint64_t const id, eosio::name const & owner, eosio::name const & pet_name, uint64_t const age, eosio::name const & type)
{
  pets_table pets(get_self(), get_self().value); 
  pets.emplace(get_self(), [&](auto & entry){
    entry = pet_t(id, owner, pet_name, age, type);
  });

}
1 Like

It doesn’t know what get_self() is because it isn’t part of the helloworld class.

You need to change addpet to helloworld::addpet

1 Like

Thank you!
I have some probably very silly questions:
Why do we need to maintain two files .cpp and .hpp for EOS smart contract? while in Ethereum, only one .sol file is needed.

Do we always need to put table in a separate file? Can pet.hpp and helloworld.hpp be combined into one file?

1 Like

Ethereum solidity files can be sharded into many files, is not only for EOS to have a compiler file and headers files, it’s c++ structure, you can have all the logic in the cpp file if you want to, but for complex contracts, you would like to divided it into many headers files, until is easy for you or the team to update or modified a module of the contract.

No need to, just is better way to order all your code modules, it’s easy to modify and maintain functions in different files than look for a specific function and all his logic in a very large and complex file.

Hope this gives you a clear picture of the subject.
If you have any more questions, please let us know so we can help you! :slight_smile:

Carlos Z.

1 Like

Hi Carlos, thank you very much for your reply!

@Phillip_Hamnett I have another question regarding to the “Check and Authorization” lesson:
even before I add any authorization, I was only able to add, delete and modify pet table when I leave the Authorization field as “default: helloworld”
If I enter any name in that field, the message says that there is no signature for it:

transaction declares authority '{"actor":"lisa","permission":"active"}', but does not have signatures for it.
{
  "code": 401,
  "message": "UnAuthorized",
  "error": {
    "code": 3090003,
    "name": "unsatisfied_authorization",
    "what": "Provided keys, permissions, and delays do not satisfy declared authorizations",
    "details": [
      {
        "message": "transaction declares authority '{\"actor\":\"lisa\",\"permission\":\"active\"}', but does not have signatures for it.",
        "file": "authorization_manager.cpp",
        "line_number": 600,
        "method": "get_required_keys"
1 Like

Are you trying to add a pet of mike with lisa permissions?

Read carefuly, owner: mike so the only one authorized to add, delete or modify mike’s pets is himself (the owner), but you have actor: lisa, meaning you are trying to create a dog for mike in name of lisa (?)

Meaning, owner of the pet is the only one authorized to create pets for his own.

Hope this gives you a clear picture of the subject.
If you have any more questions, please let us know so we can help you! :slight_smile:

Carlos Z.

Hi Carlos,

I have some questions:

I have deployed and successfully inserted an entry in the table dogs with ‘bob’ scope

cleos set contract dognotoken $PWD dognotoken.wasm --abi dognotoken.abi -p dognotoken@active
Q1 : who is account code and receiver for that line ?
R1 :code = receiver = dognotoken

cleos push action dognotoken insert ‘[“bob”, “MIA”, 13]’ -p bob@active
Q2 : who is account code and receiver for that line ?
R2 : code = dognotoken ( authorizing the contract ) and receiver = bob ( executing the action )

#successful output
cleos get table bob bob dogs

The reason I have those questions are related to the code :
require_auth(owner);
“owner” is also the payer for the storage ( RAM ) ; I get it
In my case “owner” is “bob”

my concern is with that line:
dog_index dogs(get_self(), get_self().value);
//in pseudo code dog_index dogs( code , scope );
Q3 : who is accounr code ?
is it “bob” here ? i an getting confused :wink:
I thought it was “dognotoken”

thanks.

JJ.

Hi Carlos, thank you for your reply.

I meant that even before I add the require_auth(owner); I was unable to put other actor there to authorize the transaction. The code is as follows:

#include <helloworld.hpp>

void helloworld::hi(eosio::name const & nm)
{
  eosio::print("Hello ", nm);
}

void helloworld::addpet(uint64_t const id, eosio::name const & owner, eosio::name const & pet_name, uint64_t const age, eosio::name const & type)
{
 pets_table pets(get_self(), get_self().value); 
 pets.emplace(get_self(), [&](auto & entry){
    entry = pet_t(id, owner, pet_name, age, type);
  });
}

void helloworld::modifypet(uint64_t const id, eosio::name const & owner, eosio::name const & pet_name, uint64_t const age, eosio::name const & type)
{
  pets_table pets(get_self(), get_self().value);
  auto pet_itr = pets.find(id);
  pets.modify(pet_itr, get_self(), [&](auto & entry){
    entry = pet_t(id, owner, pet_name, age, type);
  });
}

void helloworld::removepet(uint64_t const id)
{
  pets_table pets(get_self(), get_self().value);
  auto pet_itr = pets.find(id);
  pets.erase(pet_itr);
}

This morning I was trying again, there was no problem when building the contract, but I was unable to deploy, which is strange, because I could deploy without problems last night:
image

If you try to authorize the transaction with an account that doesn’t exist, then that won’t work. I assume that that is the problem you had.

Ad for the “Unknown action setcode in contract eosio” error. I mention that in the videos. It is a bug with the EOS Studio IDE. Close and open the IDE and the error will go away

1 Like

Thank you for your reply Phillip!
So if I want to use lisa as the actor, I need to create an account named lisa?

I have tried several times to close it and open it again. I even uninstalled it from control panel and then installed again, it still does not work…
I installed EOS Studio 0.13.2 for Windows.

Update for people who have the same problems:
uninstall EOS Studio from control panel is not enough, you also need to delete all the folders created by EOS Studio on your C drive, then install it all over again. But remember to save your contracts separately somewhere before you delete everything.

dog_index dogs(get_self(), get_self().value);
SEARCH table(scope, value)
dog_index to search in the dogs table, get_self() point to the account owner of get_self().value.

Basically, “search in this table, if this account owns any element on the table (dogs)”.

If you have any more questions, please let us know so we can help you! :slight_smile:

Carlos Z.

1 Like

Thank you Carlos.

I think I get it now.

dog_index dogs( get_self() , get_self().value ) means that the owner of this table is the account who has deployed the contract and NOT “bob”
This is where lied my confusion…

It became clearer after looking at this :

The first parameter “code”, which specifies the owner of this table. As the owner, the account will be charged for storage costs. Also, only that account can modify or delete the data in this table unless another payer is specified. Here we use the get_self() function which will pass the name of this contract

1 Like

hello everybody

when I try to built the example for the multi-index table I get the following message. Does anybody has an idea what went wrong?
Thank you for your help.

Henning

1 Like

Hello @henmeh, I’ll be glad to help you, could you please share your code so i can take a look on it?

Remember you can use the “Preformatted Text” Button to encapsulate any kind of code you want to show.


function formatText(){

let words = “I’m a preformatted Text box, Please use me wisely!”

}

prefromatted_text-animated

Carlos Z.

#ifndef PET
#define PET

using namespace eosio;


class [[eosio::table, eosio::contract("helloworld")]] pet_t
{
    private:
        uint64_t id;
        name owner;
        name pet_name;
        uint64_t age;
        name type;

    public:
        pet_t(){}
        pet_t(uint64_t _id, name & _owner, name & _pet_name, uint64_t _age, name & _type)
        {
            id = _id;
            owner = _owner;
            pet_name = _pet_name;
            age = _age;
            type = _type;
        } //: id(_id), owner(_owner), pet_name(_pet_name), age(_age), type(_type) {}

    uint64_t get_id() const { return id; }
    name get_owner() const { return owner; }
    uint64_t get_owner_value() { return owner.value; }
    name get_pet_name() const { return pet_name; }
    uint64_t get_age() const { return age; }
    name get_type() const { return type; }

    uint64_t primary_key() const { return get_id(); };

    EOSLIB_SERIALIZE( pet_t, (id)(owner)(pet_name)(age)(type) )
};

typedef multi_index< "pets"_n, pet_t, eosio::indexed_by< "byowner"_n, eosio::const_mem_fun< pet_t, uint64_t, &pet_t::get_owner_value > > > pets_table;

#endif

Hello Carlos,

thank you for your help. Here you can find my code that gives me this error.

Henning

Hello @henmeh, hope you are OK.

Now, a few comments on your code:
1st, which video lessons did you watch to get this code?

There are a bunch of error on this contract, you are not using a table, you need one to get a multi-index of it.

You should always put the public functions on top of the privates (privates should go below).
You are not designing a table, you have a bunch of variables, but they are not inside of a table.
(id, owner, pet_name…)

In your public variables, pet_t(){} this one does not do anything, if you are trying to run the function below (should be a void function or an action) this is not the way, you first should declare the function and its body, then you can invoke it. not backward, also you dont need {} when you want to invoke the function.

You are also lacking of the namespaces for std and eosio properly.

#include <eosio/eosio.hpp>

using namespace std;
using namespace eosio;

This is not the way you define this “return” variable, there are used inside of a table.

    uint64_t get_id() const { return id; }
    name get_owner() const { return owner; }
    uint64_t get_owner_value() { return owner.value; }
    name get_pet_name() const { return pet_name; }
    uint64_t get_age() const { return age; }
    name get_type() const { return type; }

    uint64_t primary_key() const { return get_id(); };

This is the basic structure of a table, example:

      //table struct dog data
      TABLE dog{
        int id; //unique ID for index
        std::string dog_name;
        int age;
        name owner; //eos account name, owner of dogs
        //get primary key by ID variable
        uint64_t primary_key() const{return id;}
        //get dogs by owner index
        uint64_t by_owner() const{return owner.value;}
      };//end table dog

then you define your multi-index

      //define table type index
      typedef multi_index<"dogs"_n, dog, indexed_by<"byowner"_n, const_mem_fun<dog, uint64_t, &dog::by_owner>>> dog_index;

Hope you find this useful.
If you have any more questions, please let us know so we can help you! :slight_smile:

Carlos Z.

I am having trouble getting my table to build. When I look at the abi file, it is not listed. I am not sure why. Also, my tree looks different than the one in the video. Here’s mine


Notice, that pet.cpp file has an arrow beside it. In the video it is not there. any advice? Also, the program says that I need to:

hellooworld was working before, but the tree wasn’t right, so in trying to fix the tree, I may have moved, deleted or otherwise broke the code. any suggestions? I understand that you aren’t looking at my code, so what what file can I send you so that you can troubleshoot and give me direction?

here’s my hellooworld.hpp file:

#ifndef HELLOOWORLD
#define HELLOOWORLD

#include <eosio.hpp>

#include <pet.hpp>
CONTRACT HELLOOWORLD : public eosio:: contract
{
public:
    using eosio::contract::contract;
    ACTION hi(eosio::name const & nm);
    ACTION addpet(uint64_t const id, eosio::name const & owner, eosio::name const & pet_name, uint64_t const age, eosio::name const &type);
    };

    #endif

Thanks,

This morning I was looking at my code again and I found the following error:
#include <eosio.hpp>” should have been “#include <eosio/eosio.hpp>” When I made this change, I got fourteen errors. rrrrrrrr!!!
here’s the list:

The program advanced me before I saw all the videos in the last lesson I would really like to start the lesson again if that is possible.

1 Like

hey @dani88, hope you are great.

You should also include your hellooworld.hpp file into your cpp

#include <hellooworld.hpp> 

Carlos Z