4

Using the go-ethereum library, I'm able to call contract methods using the generated Go bindings:

balance, err := wallet.Balance(&bind.CallOpts{
    Pending: false,
    From:    sender,
    Context: ctx,
})

However, I'd like to make the above method call for a specific block number.

To do this I would need to do two things:

  1. Get the latest block number.

There doesn't seem to be a function to do this dirrectly with the Ethereum client https://godoc.org/github.com/ethereum/go-ethereum/ethclient.

In web3.js there's a getBlockNumber() method, but I couldn't find the equivalent in Go.

  1. Use the obtained block number to call the balance method on the smart contract.

The bind.CallOpts object doesn't allow you to specify the block number directly.

How would I go about achieving this using the go-ethereum library?

1
  1. Get the latest block number:

    blockHeader, err := ethClient.HeaderByNumber(context.Background(), nil)
    if err != nil {
        return err
    }
    
    log.Printf("Last block: %s", blockHeader.Number)
    
  2. Use the obtained block number to call the balance method on the smart contract:

    // import "github.com/ethereum/go-ethereum/common/hexutil"
    data, err := hexutil.Decode("0xb69ef8a8") // First 4 bytes of keccak256("balance()")
    if err != nil {
        return err
    }
    callMsg := ethereum.CallMsg{
        To:   contractAddress,
        Data: data,
    }
    response := ethClient.CallContract(context.Background(), callMsg, blockHeader.Number)
    

    You can specify any block number as *big.Int instead of blockHeader.Number.

0

Since go-ethereum version 1.8.20 you can make calls to contracts at a specific block number by specifying the BlockNumber field in the CallOpts{} object.

https://godoc.org/github.com/ethereum/go-ethereum/accounts/abi/bind#CallOpts

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.