5

By calling a running Ethereum node through the getBalance API, you can get the Ethereum balance N blocks back as explained here. This is useful if you would only like to trust a balance which has been sufficiently confirmed by the network.

Is the same possible for ERC20 tokens? Does there exist a service that can show me what the token balance for a given address was 5 blocks ago?

Thorkil Værge
  • 4,220
  • 2
  • 16
  • 38

2 Answers2

8

Yes, you can do this. With web3.js 0.2x.x, note from https://github.com/ethereum/wiki/wiki/JavaScript-API#contract-methods that all calls to contracts take an optional block number.

So the following will get the balance of an account at a specific block number:

tokenContract.balanceOf(account, {}, blockNumber);

I believe the syntax for web3.js 1.0.0-beta is something like this, but double check the documentation:

tokenContract.methods.balanceOf(account).call({}, blockNumber);

If you're using raw JSON-RPC calls, eth_call takes a block number as a second parameter too.

user19510
  • 27,999
  • 2
  • 30
  • 48
  • This worked for me. In Nethereum (for C#) I had to use: balanceInBaseUnits = await function.CallAsync(new BlockParameter(relevantBlockNumber), _owner); – Thorkil Værge Mar 15 '18 at 12:06
  • 1
    To be able to read all historic data, I think you need to have the Parity node running with the pruning mode set to "archive". – Thorkil Værge Nov 29 '18 at 15:33
  • 1
    For a comparison of how geth and Parity handles this, see https://ethereum.stackexchange.com/questions/3332/what-is-the-parity-light-pruning-mode – Thorkil Værge Nov 29 '18 at 15:35
2

As you mentioned, to get the ETH balance of an address you need to do this:

eth.getBalance("<ADDRESS_HERE>", <BLOCK_NUMBER>);

If you want to get the balance of an ERC20 token, you need to make a call to that token's contract. To do this you will need three things:

  • The token contract address.
  • Your account address.
  • The token contract’s ABI.

So, you need instantiate the contract ABI by doing:

> var tokenContract = eth.contract([{
     "type":"function",
     "name":"balanceOf",
     "constant":true,
     "payable":false,
     "inputs":[{"name":"","type":"address"}],
     "outputs":[{"name":"","type":"uint256","value":"0"}]
}]);

And then you can do:

> var erc20ContractAddress = "<ADSRESS_OF_TOKEN'S_CONTRACT>";
> var account = "YOUR_ADDRESS";
> tokenContract.at(erc20ContractAddress).balanceOf(account);

This outputs the token balance in plain tokens, i.e. without showing a decimal point.

  • 2
    Thank you. But I think I stated the question poorly. I am asking about the ERC20 balance N blocks ago, not the current one. I have edited my question. – Thorkil Værge Mar 15 '18 at 07:43