2

What is the best way to store fields specific for contract, for example if contract has 3 fields (2 strings, 1 uint64_t) and they can be changed? Should I create new table for this, it would always be one entry basically with 3 fields? I heard about singleton but can not figure out how to do it, maybe some example?

Cheers

5

If there is only one instance to be created, I agree you should use a singleton for your case instead of a table directly, as this is what singletons are used for.

For API, you can check the eosio/singleton.hpp file, and here's a quick example using a singleton:

#include<eosio/eosio.hpp>
#include<eosio/singleton.hpp>

class singleton_example : eosio::contract {
    public:
        singleton_example(account_name account) :
            eosio::contract(account),
            singleton_object(_self, _self)
            {}

        void store(account_name account, uint64_t value1, uint64_t value2) {
            require_auth(account);
            singleton_object.set(sing{value1, value2}, account);
        }

        void get(account_name account) {
            require_auth(account);
            auto results = singleton_object.get();
            eosio::print(results.value1, results.value2);
        }


    private:
        struct sing {
            uint64_t value1;
            uint64_t value2;
        };

        typedef eosio::singleton<"singleton"_n, sing> single;

        single singleton_object;
};

EOSIO_ABI(singleton_example, (store)(get))
| improve this answer | |
  • 1
    Nice! I wasn't aware that there was already an implementation of that abstraction. – Andres Berrios Jul 25 '18 at 13:18
  • 1
    EOSIO.CDT 1.5 singleton now requires uint64_t for the second parameter of the constructor. There's no direct conversion from the name object to it. Just change the constructor to: singleton_object(_self, _self.value) – Jason Bert Mar 12 '19 at 8:48
1

Yes, as you're saying, it should simply be a single table with a single row that contains your data as a struct with the 3 fields.

You would need to define your struct and table as something like this:

//@abi table state i64
struct state {
    string field1;
    string field2;
    uint64_t field3;

    // Set the primary key to a constant value to store only one row
    uint64_t primary_key() const { return 0; }
};

And then you can use it inside an action like this:

state_table s_table(_self, _self);

// Write to the state for the first time
s_table.emplace(_self, [&](state& row) {
    row.field1 = "something";
    row.field2 = "something else";
    row.field3 = 1234;
});
// Update the state
s_table.modify(state_table.begin(), 0, [&](state& row) {
    row.field1 = "something new";
    row.field2 = "some other thing";
    row.field3 = 12345;
});

// Read from the state
state saved_state = s_table.get(0, "Error message for when state is not set yet");
| improve this answer | |
0

Thank you for your answer Andreas Berrios. As of EOS CDT 1.3 release, the syntax has changed. I updated the code:

struct [[eosio::table]] state_struct {
    std::string field1;
    std::string field2;
    uint64_t field3;

    // Set the primary key to a constant value to store only one row
    uint64_t primary_key() const { return 0; }
    EOSLIB_SERIALIZE(state_struct,(field1)(field2)(field3))
};
typedef eosio::multi_index<"tablename"_n,state_struct> s_table;

s_table state_table(_self, _self.value);

// Write to the state for the first time
state_table.emplace(_self, [&](state_struct& row) {
    row.field1 = "something";
    row.field2 = "something else";
    row.field3 = 1234;
});
// Update the state
s_table state_table(_self, _self.value);
state_table.modify(state_table.begin(), _self, [&](state_struct& row) {
    row.field1 = "something new";
    row.field2 = "some other thing";
    row.field3 = 12345;
});
// Read from the state
state_struct saved_state = state_table.get(0, "Error message for when state is not set yet");
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.