16

I tried to look for inside the EOS repository and contracts examples but I could not find anything like this. I want to know how can I read another contract table.

So, as an example: my contract needs to check the balance of EOS tokens of an specific account. How can I do that reading from eosio.token contract?

2 Answers 2

16

When declaring a multi_index to use as a table a contract (eg. contracta) you would typically create a struct and typedef similar to this:

// @abi table myobjects
struct myobject {
    name sender;
    // ... other properties here

   EOSLIB_SERIALIZE(myobject, (sender)(...))
}

typedef multi_index<N(myobjects), myobject> myobjects_t;

and then create an instance to use within the contracta code:

auto db = myobjects_t(_self, _self);

The first _self refers to the code that defined the table and the second refers to the scope for the table in this case both are referring to contracta.

In order for contractb to have access to that data it would need to also define the struct and typedef as above but when creating an instance for access the _self would be replaced by N(contracta) and if the scope for the table is also _self that should also be the same.

The struct would need to have the same property names, types and order of definition and also be serialised in the same order. The ABI name and index type would also need to match. Then the data would be accessible for reading as if it's in the same contract. If both contracts are part of your own code the common structs and typedefs could be declared and shared in a common header (.hpp). Otherwise the structs could be reverse engineered into C++ from reading the ABI code from the blockchain using get_code.

3
  • 1
    wow! thanks, it simply makes sense. I will test it with eosio.token balance! May 8, 2018 at 23:16
  • I use this method in dawn 4.1 version, but it didn't work. accounts accountstable(N(eosio.token), _self); const auto &ac = accountstable.get(CORE_SYMBOL); return ac.balance; anything wrong in my code?
    – yang24201
    May 23, 2018 at 16:14
  • to make it a bit clearer if contractb needs access access to table which is modified by contracta .. the instantiation of table within contractb should be myobjects_t( N(contracta), N(contracta) ) and then perform the usual crud operations .. right? May 23, 2018 at 22:48
0

if a contract account contractact1 has a table named people, and you want to fetch the data in that table from within the contractact2 contract account then you need to :

  1. provide the exact same definition of that struct [[eosio::table]] people{}; in your contract(contractact2) and,
  2. use the exact same typedef/ using statement for the people table as it was written in the main contract contractact1.
  3. finally in the action of your contract (contractact2) you need to instantiate that table with two arguments 'contract name on which the actual code for this table is' & 'scope of the table'. They are of type name and uint64_t respectively. so e.g we can say, accounts accountset("eosio.token"_n,"eosio.token"_n.value); where account is the typedef and accountset is our custom name.

Your Answer

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

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