I'm currently using the geth implementation. The problem is currently I am tracking erc20 token transfers using purely the erc20 contract event logs and filtering for Transfer event, then saving that in a database with the following basic struct

type Transfer struct {

The problem is that in the geth implementation there is a concerning comment on the log struct at https://github.com/ethereum/go-ethereum/blob/master/core/types/log.go

// Log represents a contract log event. These events are generated by the LOG opcode and
// stored/indexed by the node.
type Log struct {
    // Consensus fields:
    // address of the contract that generated the event
    Address common.Address `json:"address" gencodec:"required"`
    // list of topics provided by the contract.
    Topics []common.Hash `json:"topics" gencodec:"required"`
    // supplied by the contract, usually ABI-encoded
    Data []byte `json:"data" gencodec:"required"`

    // Derived fields. These fields are filled in by the node
    // but not secured by consensus.
    // block in which the transaction was included
    BlockNumber uint64 `json:"blockNumber"`
    // hash of the transaction
    TxHash common.Hash `json:"transactionHash" gencodec:"required"`
    // index of the transaction in the block
    TxIndex uint `json:"transactionIndex"`
    // hash of the block in which the transaction was included
    BlockHash common.Hash `json:"blockHash"`
    // index of the log in the block
    Index uint `json:"logIndex"`

    // The Removed field is true if this log was reverted due to a chain reorganisation.
    // You must pay attention to this field if you receive logs through a filter query.
    Removed bool `json:"removed"`

It says that I shouldn't trust the log txHash, BlockNumber since they are not secured by concensus. As a result, I'm looking for another to correctly keep track of all erc20 transfers using a different method. I'm currently thinking of looping through all the txs in a block and checking the receipts for transfer events relating to the specific erc20 contract I'm concerned about. Is this a correct approach? Is there anything I'm missing?

  • The comment is due to the protocol not providing a cryptographic proof for those fields. Those field could be determined from the transaction execution. To get those fields in a trustlessly manner you need to run your own node. IMHO as long as you trust the node providing that data it should fine to use them.
    – Ismael
    Commented Oct 24, 2022 at 6:27
  • I can have my own node but would those fields be derived from the node that submitted the transaction or from my own node to which I am making API call to filter event logs from a block?
    – bhuynh
    Commented Nov 7, 2022 at 17:13
  • A transaction execution is based on the current ethereum world state. It shouldn't depend on the node that submitted the transaction. A full node current world state could be verified with cryptographic proofs, likewise a transaction execution could be verified.
    – Ismael
    Commented Nov 9, 2022 at 5:36

1 Answer 1


The most effective way to track all ERC-20 transfers would be using a Subgrpah to index ERC-20 data. This way, you will have all of the ERC-20-related information ready to be queried at any time.

This guide shows you how to develop and deploy a subgraph using Chainstack to do exactly this.

Indexing ERC-20 token balance

The subgraph you deploy following this article indexes every ERC-20 token balance of every address, as well as every transfer.

Subgraphs overall are a super efficient way to index and use this kind of data; you can find more tutorials on how they work and how to use them on the Chainstack docs | Chainstack subgraphs.

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.