20

I have a contract with numerous complex structs. Is it possible for a second contract to iterate over this data directly?

I can't really use public accessor/getter methods as it's not possible to use structs externally, so I would have to flatten the data structure (probably make expensive copies of it too).

2 Answers 2

22

A contract cannot access another contract's storage directly.

Given contracts C1 and C2, C1 can only access the storage of C2 by invoking a method on C2 that returns data from C2's storage.

Since you are writing C2, you can access its storage from C1 and can make progress. A more specific question may help provide a more specific answer about designing your contracts (structs, flattening, copies...).


Related, there are 3 things that a contract can access from another contract: balance, code, code size.

The underlying mechanisms for doing so are the following EVM opcodes, from the Yellow Paper:

BALANCE: Get balance of the given account

EXTCODECOPY: Copy an account’s code to memory.

EXTCODESIZE: Get size of an account’s code.

Per Paul's comment, address.balance works in Solidity.

7
  • 1
    minor nit: You can access another contract's balance. address.balance works AFAICT.
    – Paul S
    Commented Feb 16, 2016 at 0:59
  • Upvoted, thanks for the reminder and I'll update answer since there's EXTCODECOPY too...
    – eth
    Commented Feb 17, 2016 at 2:56
  • 1
    @eth What if 2nd contract is contunation of first contract i.e. ` contract A{ struct egStruct{ uint number; bool value; //.... } mapping (uint => egStruct) structMapping; //...code... } contract b is A { //...code } In this case also, is it not possible to access a mapping (which is not public). Actually my specific question would be, If in this case I want to access the struct trough mapping of contract A from contract b of, then can I do it? (I tried and I am getting blank values for all)
    – 11t
    Commented Mar 28, 2017 at 22:03
  • 1
    @Rajat Write an accessor in A and you might be able to call it in b like super.nameOfAccessor(). This would be different from b accessing the storage of A directly.
    – eth
    Commented Mar 31, 2017 at 8:38
  • We cannot change the storage of a mapping variable of another contract right?
    – alper
    Commented Jan 20 at 14:32
4

Technically, all data available to any contract has to be publically available, because anyone can run a node and reproduce the entire lifetime of the contract. This means that yes, it is strictly possible for one contract to access the internal data of another, even if there is no built in way to do it.

The first answer that comes to mind is to create an oracle service with an exposed method you can call that accept the contract id and the data you want, re-runs or reads the blockchain to get it, and returns it to the caller.

I don't know if anyone has created something like this yet, but if it's vitally important for you to be able to read another contract's data, you could certainly do it.

TL;DR Yes you can, but it requires you to create a separate oracle service to do it for you, as there is no built-in method to allow it.

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.