8

Let's assume we have the standard token contract with balances:

 mapping (address => uint256) public balanceOf;

If I want to know balances of all addresses (who have ever transacted with the contract) in web3, can I somehow construct this state? I.e. I don't know the addresses themselves to call balanceOf(address) to start iterating?

12

You can't iterate over the key of balanceOf as the data stored in the mapping to represent the key is the sha3 of the specified key. From Solidity In Depth - Mappings,

The key data is not actually stored in a mapping, only its sha3 hash used to look up the value.


You could instead use the following script to find all transaction made to the account.

function getAddressesSentToAccount(myaccount, startBlockNumber, endBlockNumber) {
  if (endBlockNumber == null) {
    endBlockNumber = eth.blockNumber;
    console.log("Using endBlockNumber: " + endBlockNumber);
  }
  if (startBlockNumber == null) {
    startBlockNumber = endBlockNumber - 1000;
    console.log("Using startBlockNumber: " + startBlockNumber);
  }
  console.log("Searching for transactions to account \"" + myaccount + "\" within blocks "  + startBlockNumber + " and " + endBlockNumber + "\"");

  for (var i = startBlockNumber; i <= endBlockNumber; i++) {
    if (i % 1000 == 0) {
      console.log("Searching block " + i);
    }
    var block = eth.getBlock(i, true);
    if (block != null && block.transactions != null) {
      block.transactions.forEach( function(e) {
        if (myaccount == e.to) {
          console.log(e.blockNumber + " " + e.from + " " + web3.fromWei(e.value, "ether"));
        }
      })
    }
  }
}


To view the addresses that sent some ethers to TheDAO in the last 1000 blocks:

> getAddressesSentToAccount("0xbb9bc244d798123fde783fcc1c72d3bb8c189413")

And the output will resemble:

Searching for transactions to account "0xbb9bc244d798123fde783fcc1c72d3bb8c189413" within blocks 1485458 and 1486458"
1485461 0x0903d814bceff7efa3e91a238271f60bb0ab05bf 34
1485461 0xfbb1b73c4f0bda4f67dca266ce6ef42f520fbb98 10
1485462 0x924c251902924c7dbd4cbf166d42757fb2d146cb 70
1485465 0xdf6a69f1c0a7962113cff9e70101cec77d5fde9d 25.08851818
1485466 0x14afd9a49285d62bc8fd33fc94c1b7c98437e0c9 105
1485480 0xe9de5262a6c3cc173421f46ae1356c9b6f9b7355 10
...

To view the addresses that sent some ethers to TheDAO between blocks 1486400 and 1486410:

> getAddressesSentToAccount("0xbb9bc244d798123fde783fcc1c72d3bb8c189413", 1486400, 1486410)

And the output will resemble:

Searching for transactions to account "0xbb9bc244d798123fde783fcc1c72d3bb8c189413" within blocks 1486400 and 1486410"
1486400 0x8662bdb16c4d6eb080b45be3a5be80cc9511aac1 99
1486402 0xd0a886e00bee1aa3532182d382012697851edcd0 5
1486402 0xbd5a8c94bd8be6470644f70c8f8a33a8a55c6341 195
1486404 0x919c066b79d62581482b0ea0f11339b73ddb3dbd 8
1486406 0xd69104404a21cf359985c21988b959ace3880c83 11
1486408 0x24602a569f51e64bd54ad335be2e3f53ea9ef689 10
1486408 0x2bd46878a4b95e4299324b93afde2bd4281a8fc7 6.02962455
undefined

And How do I print my account balances and TheDAO tokens from geth will show you how you can get the balance of an account from a token contract like TheDAO.

  • Ok. This is very in-depth and good answers. However, because it's standard token contract, I can iterate over all events which are accessible through eth_getLogs. – Mikko Ohtamaa May 9 '16 at 18:58

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.