1

Contract A created a multi-index table pets like

pets(_self, _self);
...
pets.emplace(user1,...);

Now in contract B, I would like to update a row like

pets(N(A), N(A));
...
pets.modify(pet, user1, ...);

When I try that I get an error:

with error: Assert Exception (10)
table_obj.code == receiver: db access violation

What is wrong? How to access a table from another contract?

Edit:
For read see here: https://eosio.stackexchange.com/a/70/1509

Update: The error was due to a bad serialization. The correct error says it all, and is:

Error 3050003: eosio_assert_message assertion failure
Error Details:
assertion failure with message: cannot modify objects in table of another contract

My solution (14 July 2018)

I am sending an action from contract B to contract A as describe here How to send an action from one contract to another?

  • 1
    Yes, you can't modify other contract's table in your contract, that's read only, only pet contract can do modify operation – Jimmy Guo Jul 13 '18 at 7:43
  • @JimmyGuo Even if I have control over both contracts? – friedger Jul 13 '18 at 7:44
  • Right, the code must be equals to receiver. – Jimmy Guo Jul 13 '18 at 7:45
  • Here code is "contract A" and receiver is "contract B", correct? – friedger Jul 13 '18 at 7:46
  • 1
    yes, you're right – Jimmy Guo Jul 13 '18 at 7:48
1

What the OP has discovered is that you can only read contracts from a contract after declaring them in your contract, so you have to define a different way of doing this which I believe can be done relatively easily.

Option A

So if we have contract A wanting to modify contract B's table we could set that up as follows.

If we use the listen command for nodeos:

Config Options for eosio::history_plugin:
  -f [ --filter-on ] arg                Track actions which match
                                        receiver:action:actor. Actor may be
                                        blank to include all. Receiver and
                                        Action may not be blank.

Then we can configure it to listen to it for actions signed by your contract as well as the user sending the action. The function can be empty, we're only interested in seeing the action and it's associated metadata pushed to the chain. We can then take the information from that action, trusting that it's legitimate because your other contract A's key and user A's key have signed, and modify a table in contract B.

Example of empty function: https://steemit.com/eos/@leordev/eos-todo-dapp-free-ram-model-and-state-management-eos-redux-3

Option B:

Have both tables in the same contract. Contracts A's resource cost (CPU/NET/RAM) + B's cost is relatively the same if they're under the same account or 2 separate accounts.

I guess you could say that since the contract would be larger that it would require more CPU to process each time; however, I think that would be pretty marginal at first but something to consider depending on how complex the contract is.

| improve this answer | |
  • What about option C: to send an action to contract A from contract B and let contract A modify the table? I am not sure how that works permission-wise. – friedger Jul 13 '18 at 18:17

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.