Please note, this is not a duplicate of the following:

How to get all the transactions made by a token address

How to explore all transactions for a given account?

How can all transactions sent to an address be found?

Because the answers to those questions do not detail a strategy which includes basic algorithms and RPC API calls. Also, some are to find the transactions for a given account (which we are assuming is a user account, not a contract account), we want to find the balance, account number, public key (where available) for a given ERC20 contract.

We understand that the only way to get all the transactions for a contract is to read the entire blockchain.

We are guessing the algorithm might be something like this:

  1. get the current block height (use: eth_blockNumber api call "result" field)
  2. for block = 0 to block height.
    1. call eth_getBlockByNumber with params (block,true)
    2. for each transaction in block:
    3. ???

The transaction data returned by getBlockByNumber has this:

"blockHash": "0xa3ed1fddf13549037bcf69666b2ac5c4eb0216c5f457953aa80cca2a4966d52a",
"blockNumber": "0x58efa0",
"from": "0x58bbdacf0aab30d59d213eb429aaf73849d9e16a",
"gas": "0xcbbb",
"gasPrice": "0x170cdc1e00",
"hash": "0x5fbe18632af562eebd1526c7bbaa0aa0a9c280d1b8779125b75f5fea4d88d529",
"input": "0xa9059cbb0000000000000000000000000d54193d0eb520e9848e6d893947ddf6f24377710000000000000000000000000000000000000000000000000000000838c722a8",
"nonce": "0x8",
"to": "0xf230b790e05390fc8295f4d3f60332c93bed42e2",
"transactionIndex": "0x0",
"value": "0x0",
"v": "0x26",
"r": "0xc0da57cb5b7fb286ca34c6b4b75480801f9a76afa32c18ab3c619544196541c",
"s": "0x7bcc0c7d4f891330ea3a6287cbe3df89270761480df4335faf517e3cb22cb41"

This basically gives us the from account, to account, amount and public key of the sender (via . Presumably, we can keep an internal database of every transfer form every account to every other account, from block 0 to the head. How do we know which transfers are associated with a particular ERC20 Contract? Here I am assuming that from and to accounts are user accounts, nothing to do with the contract. Or is a contract just an account? So we would then need to follow the chain of transactions away from that origin account?

We are assuming there is no public service to do this. Etherscan does not seem to have any methods to pull the data for a given contract. They do have a "contract getabi" and "get a list of Normal transactions by address", but we dont know the addresses yet (we only know the contract address). They do have a "Get a list of "ERC20 - Token Transfer Events" by Address" but it does not document what this returns, and it is limited to the last 10,000 transactions, and we need more than this.

My experience is with BTC. I know that ethereum is different, and ERC20 contacts keep balances rather than UTXOs. Anther strategy might be to ignore all the transactions, if there is a away to get all accounts for a contract, and all balances for those accounts?

Etherscan talks about normal and internal transactions. Can we ignore internal transactions?

If we assume that a contract address is the same as a from address, i.e. the same as an account number, then the algorithm might be something like this:

  1. put the contract account A in the list of watched accounts W. Each watched account is an address and a balance.
  2. get the target block height
  3. for blockloop = 0 to target block height.
    1. call eth_getBlockByNumber with params (block,true)
    2. for each transaction in block:
    3. if the from address is in the watched list, and to address is not, then add to address to W, set its balance as the tranaction value, and deduct value from the from address.
    4. if the from address is in the watched list, and the to address is already in the list, then subtract amount from the from address balance, and add it to the to address balance.
    5. if the to address is in the watch list, but form address is not, then this is an error.

This relies on the fact that any transfer from A to B (Where A is the smart contract address), or from B to C, is always in the coin we are looking for (and not some other smart contract coin or ETH. This does not seem to be the case. We are seeing trasnfers form A to B, then B to C, where the transfer from B to C was not for our coin, but for some other coin.

eth_getTransactionByHash returns the following data:

hash: DATA, 32 Bytes - hash of the transaction.
nonce: QUANTITY - the number of transactions made by the sender prior to this one.
blockHash: DATA, 32 Bytes - hash of the block where this transaction was in. null when the transaction is pending.
blockNumber: QUANTITY - block number where this transaction was in. null when the transaction is pending.
transactionIndex: QUANTITY - integer of the transactions index position in the block.
from: DATA, 20 Bytes - address of the sender.
to: DATA, 20 Bytes - address of the receiver. null when its a contract creation transaction.
value: QUANTITY - value transferred in Wei.
gasPrice: QUANTITY - price paid per gas in Wei.
gas: QUANTITY - gas used.
input: DATA - the data send along with the transaction.

There is nothing we can see here which says which "coin" the transfer is for. Sometimes the "input data" shows a sweep function is called in etherscan, but the contract we are looking at has no sweep function defined (it is a pure ERC20 contract).

For example, this is a TRX transfer calling a sweep function


But the TRX contract has no sweep function:


When we try to decode the balances using eth_gettransactionbyhash it is not working. We are getting non TRX transactions, an incomplete list of accounts, and wildly incorrect balances.

  • once the block is processed, the order of transactions is guaranteed to be the same all the time.
    – Nulik
    Commented Jun 21, 2018 at 22:49
  • I am also working on this, I already have a solution that parses all the blockchain and puts it to SQL. It is open source and it is available on github, but it is not yet finished, so I didn't announce it yet. Right now I am working on processing tokens, so all your requirements are covered by my project. You can wait for me to finish it and you won't have to code anything at all. Or, we can work together and finish it quicker. Put your email in your profile, I will contact you and send you the link.
    – Nulik
    Commented Jun 21, 2018 at 23:03
  • @nulik email added. Commented Jun 22, 2018 at 5:38
  • no seeing it. All i can see is the text "Nothing" in your profile
    – Nulik
    Commented Jun 22, 2018 at 11:10
  • [email protected] Commented Jun 22, 2018 at 12:29


Your Answer

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

Browse other questions tagged or ask your own question.