From cb338be877dc3398d563b932a7536cfd3070acd7 Mon Sep 17 00:00:00 2001 From: Daniel Liu <139250065@qq.com> Date: Tue, 26 Aug 2025 15:14:06 +0800 Subject: [PATCH] ethclient: allow calling contracts at a specific block hash #28084 (#1383) --- ethclient/ethclient.go | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/ethclient/ethclient.go b/ethclient/ethclient.go index f6ecb97d32..f00cdf7154 100644 --- a/ethclient/ethclient.go +++ b/ethclient/ethclient.go @@ -381,6 +381,13 @@ func (ec *Client) BalanceAt(ctx context.Context, account common.Address, blockNu return (*big.Int)(&result), err } +// BalanceAtHash returns the wei balance of the given account. +func (ec *Client) BalanceAtHash(ctx context.Context, account common.Address, blockHash common.Hash) (*big.Int, error) { + var result hexutil.Big + err := ec.c.CallContext(ctx, &result, "eth_getBalance", account, rpc.BlockNumberOrHashWithHash(blockHash, false)) + return (*big.Int)(&result), err +} + // StorageAt returns the value of key in the contract storage of the given account. // The block number can be nil, in which case the value is taken from the latest known block. func (ec *Client) StorageAt(ctx context.Context, account common.Address, key common.Hash, blockNumber *big.Int) ([]byte, error) { @@ -389,6 +396,13 @@ func (ec *Client) StorageAt(ctx context.Context, account common.Address, key com return result, err } +// StorageAtHash returns the value of key in the contract storage of the given account. +func (ec *Client) StorageAtHash(ctx context.Context, account common.Address, key common.Hash, blockHash common.Hash) ([]byte, error) { + var result hexutil.Bytes + err := ec.c.CallContext(ctx, &result, "eth_getStorageAt", account, key, rpc.BlockNumberOrHashWithHash(blockHash, false)) + return result, err +} + // CodeAt returns the contract code of the given account. // The block number can be nil, in which case the code is taken from the latest known block. func (ec *Client) CodeAt(ctx context.Context, account common.Address, blockNumber *big.Int) ([]byte, error) { @@ -397,6 +411,13 @@ func (ec *Client) CodeAt(ctx context.Context, account common.Address, blockNumbe return result, err } +// CodeAtHash returns the contract code of the given account. +func (ec *Client) CodeAtHash(ctx context.Context, account common.Address, blockHash common.Hash) ([]byte, error) { + var result hexutil.Bytes + err := ec.c.CallContext(ctx, &result, "eth_getCode", account, rpc.BlockNumberOrHashWithHash(blockHash, false)) + return result, err +} + // NonceAt returns the account nonce of the given account. // The block number can be nil, in which case the nonce is taken from the latest known block. func (ec *Client) NonceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (uint64, error) { @@ -405,6 +426,13 @@ func (ec *Client) NonceAt(ctx context.Context, account common.Address, blockNumb return uint64(result), err } +// NonceAtHash returns the account nonce of the given account. +func (ec *Client) NonceAtHash(ctx context.Context, account common.Address, blockHash common.Hash) (uint64, error) { + var result hexutil.Uint64 + err := ec.c.CallContext(ctx, &result, "eth_getTransactionCount", account, rpc.BlockNumberOrHashWithHash(blockHash, false)) + return uint64(result), err +} + // Filters // FilterLogs executes a filter query.