3

If I am using eosio.token as my token contract (or I know my token contract during compile time), the following code will work.

accounts accountstable(N(eosio.token), account);
auto itr_a = accountstable.begin();
eosio::print (itr_a->balance);

However, I want to store the token contract account as a configuration within the contract. It looks like this:

struct config
    {
        account_name token_contract;
        account_name     primary_key() const { return token_contract; }
        EOSLIB_SERIALIZE(config, (token_contract));
    };

    typedef eosio::multi_index<N(configs), config> config_table;

When I replace the name of the token contract from the hard-coded token name in the initial example, it doesn't provide the correct information. It provides some random long integer that I think is from the wrong memory location.

accounts accountstable(N(itr->token_contract), account);
auto itr_a = accountstable.begin();
eosio::print (itr_a->balance);

How can I store the token contract name (and the symbol for that matter) dynamically in a config multi_index within the smart contract so that I can check the balance and perform transfers?

3
  • Did you see the extended_symbol type?
    – slim2k
    Jul 22, 2018 at 23:23
  • I looked at it but I did not see a way to use that to get the symbol characters.
    – Max
    Jul 23, 2018 at 0:10
  • @Max you should mark one of the answers as accepted so that other people can benefit from the info in this question. Jul 27, 2018 at 2:40

2 Answers 2

1

@Max your approach is good, but I think you can make it cleaner by using the token symbol directly doing something similar to what I did here: https://github.com/andresberrios/token_ram_recovery/blob/master/token_ram_recovery.cpp#L9

Specifically, getting the parameter as a string type and then converting it to a symbol_type:

symbol_type sym = string_to_symbol(0, symbol.c_str());

and then using it for comparisons with sym.name().

I would also recommend using a find or get instead of iterating through the whole index of the accounts table, since the primary key of the table is the symbol name anyway:

struct account {
    asset    balance;
    uint64_t primary_key()const { return balance.symbol.name(); }
};

Example using get:

auto balance = accountstable.get(sym.name(), "<Error message for when it's not found>");

This makes actual use of the index and you get much better performance.

0

I solved this by saving an example asset from the "init" method. And then, when I need to find that asset type in the token contract, I just loop until I find it. Then I know that I'm on the right asset. Ideally, I would just use the symbol characters, but I was unsure how to get this as a string.

struct config
    {
        account_name token_contract;
        asset        example_asset;
        account_name     primary_key() const { return token_contract; }

        EOSLIB_SERIALIZE(config, (token_contract)(example_asset));
    };



asset get_balance(const account_name account)
    {
        config_table config(_self, _self);
        auto itr = config.begin();
        eosio_assert(itr != config.end(), "token contract is not set");

        accounts accountstable(itr->token_contract, account);
        auto itr_a = accountstable.begin();

        while (itr_a != accountstable.end() && itr_a->balance.symbol != itr->example_asset.symbol) {
            itr_a++;
        }

        return itr_a->balance;
    }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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