EOS Tables Discussion

Welcome to the thread about EOS Tables. Here you can discuss everything about the table videos and potential problems that you might stumble upon.

Is it possible to store an array, dynamic array or struct as a value within a multi_index table with EOS.io?
Take this struct and table definition for example;

// @abi table players i64
struct Players {
	uint64_t 		account;
	string		    display_name;
	uint64_t 		balance = 0;
	uint64_t		tickets[];
	uint64_t		regions[];
	bool			approved = false;
	bool			active = false;
	bool			flagged = false;

	auto primary_key() const { return account; };
	EOSLIB_SERIALIZE(Players, (account)(display_name)(balance)(tickets)(region)(approved)(active)(flagged));
};

typedef multi_index<N(Players), Players> player_table;
1 Like

You keep mentioning quizzes in the course videos. Where can I find these?

Hi,

Iā€™m not sure if you can store arrays in tables. Either way itā€™s probably a bad design anyway. You would rather want to have a separate table for the tickets for example. So you would maybe have 3 tables, Players, Tickets and Regions. Where the id of an account can map from one table to another.

Usually they are below the video. Which section are you looking at specifically?

Thanks @filip, but what about if a player had multiple tickets? How can I do a one-to-many relationship to reference multiple Ticket primary_keys within one Player?

Iā€™m not sure if there is any special support for foreign keys for example. But you could accomplish the same thing on your own by creating a column in for example the Ticket table with a PlayerId. So you move that information out of the Player table completely. Let me know if you need further explanation.

Thanks @filip, Iā€™ve figured out two solutions.
One is using C++ vectors within the table struct.

struct Players {
    name              account;
    vector<uint64_t>  tickets; // An array of ticket primary keys
    // ~ Primary key and ABI serialisation
}

struct Tickets {
    uint64_t       id;
    // ~ Primary key and ABI serialisation
}

The other solution is like you mentioned, a table of players (minus tickets), and a table of tickets with a secondary index referencing the owner (player).

struct Players {
    name           account
    // ~ Primary key and ABI serialisation
}

struct Tickets {
    uint64_t       id;
    name           owner; // Reference player account
    // ~ Primary key and ABI serialisation
}

The downside of this method is performing multiple queries and business logic from a front end which can only access tables from nodeos and not getter functions.

1 Like

Thank you for digging @MitchPierias. Iā€™m happy we can all learn from each other and contribute to this community.

Iā€™m wondering the same thing. You always mention to complete the quizzes and I donā€™t remember seeing any on your videos. Iā€™m currently on " Publishing and Interacting with Tables".

(Using Firefox)

1 Like

Yes, itā€™s a mistake on my part. I say ā€œRemember to do the quizzes way to oftenā€. It became my ending phrase for many videos and I realized later on that itā€™s not suitable to have quizzes for every video. My conclusion was that there should be quizzes for most of the more theoretical videos, but not on all practical coding videos. So there is nothing wrong on your side. This is a simple mistake on my part that I hope to correct in the future.

Thanks for the reply, Filip! I just didnā€™t know if I was missing something. Anyway, I finished the course and I enjoyed it thoroughly!

Thanks to you and Ivan for a great course!

1 Like

hi Filip,
i have the code working but a little confused by the typedef expression. i am familiar with typedefs but confused by the <N(history), entry> notation.
many thanks, paul.

1 Like

It takes two arguments. First one is the name of the table, second is the struct name.

The N() function converts the plain text name history into a uint64_t name, used by eos.

Was that clear?

Hi Flip,
Yes thatā€™s clear - thankyou.

i see on the eos developer site the following example

typedef eosio::multi_index<ā€œpollā€_n, poll> pollstable;

They also add a note to say "The thing to note here is tablename parameter where we use the operator ā€œ_nā€ to convert the string ā€œpollā€ to an eosio::name. The struct eosio::name wraps uint64_t to provide ā€˜safeā€™ names, and is part of the ā€˜composite keyā€™ used to identify data belonging to the multi index table. The operator _n replaces the N() macro. We use the struct as the second parameter "

thank you, Paul

That is for another version of the build tools. They replaced the syntax of N(history) to ā€œhistoryā€_n. If you select version 1.2 you can see the syntax of the version we are using.

@filip , it would be nice to have a larger font in the videos.
It might be ok to use the existing font in the daily workā€¦ But hey, you are making a demo and the viewers are supposed to follow really quickly.

I appreciate the job you make composing this content. And I hope you would add a bit more care about the viewers. Thanks.

P.S. Lastly, the target audience is programmers who are likely to have worse sight than average. Please keep this in mind too.

Thank you for your feedback. I have gotten this feedback a lot and I apologize for the small fonts. I hope to be able to redo the eos videos soon.

1 Like

Made a small change to make it work. Iā€™m using version 1.6.1


#include < eosio/eosio.hpp >

using namespace eosio;

CONTRACT helloworld : public contract {
  public:
      using contract::contract;
      helloworld(name reciever, name code, datastream ds): contract(reciever, code, ds){}

      ACTION hi(name user){
        require_auth(user);
        print("Welcome, ", name{user}, ". You can add(user, firstName, lastName, age), or erase(user)");
      }
      ACTION add(name user, std::string firstName, std::string lastName, uint64_t age){
        require_auth(user);
        entry_index tab(get_self(), get_first_receiver().value);
        add_name(user, firstName, lastName, age);
      }
      ACTION erase(name user){
        require_auth(user);
        entry_index tab(get_self(), get_first_receiver().value);
        erase_name(user);
      }

  private:
      TABLE entry
      {
        name user;
        std::string firstName;
        std::string lastName;
        uint64_t age;
        uint64_t primary_key() const {return user.value;}
      };

      typedef multi_index<"tab"_n, entry> entry_index;

      void erase_name(name user){
        entry_index tab(get_self(), get_first_receiver().value);
        auto i = tab.find(user.value);
        check(i != tab.end(), "entry dont exist");

        tab.erase(i);
      }
      void add_name(name user, std::string firstName, std::string lastName, uint64_t age){
        entry_index tab(get_self(), get_first_receiver().value);
        auto i = tab.find(user.value);
        check(i == tab.end(), "entry already exists");

        tab.emplace(user, [&](auto& row){
          row.user = user;
          row.firstName = firstName;
          row.lastName = lastName;
          row.age = age;
        });
      }


};

1 Like

I just purchased your courses and specifically paid the monthly fee for your EOS smart contract course. I am disappointed that it is so out of date. There are C++ Macros to make the syntax easier to understand and thereā€™s a IDE that makes various things easier so command line isnā€™t necessary.

From what I understood from the youtube videos that let me to the teachable site to purchase your courses is that EOS smart contracts was itā€™s own course. I am further disappointed to find that it is such a small portion of a single course and out of date.

Are there any plans to update these courses to make them more relevant ?