github.com/cryptotooltop/go-ethereum@v0.0.0-20231103184714-151d1922f3e5/ethclient/ethclient.go (about)

     1  // Copyright 2016 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  // Package ethclient provides a client for the Ethereum RPC API.
    18  package ethclient
    19  
    20  import (
    21  	"context"
    22  	"encoding/json"
    23  	"errors"
    24  	"fmt"
    25  	"math/big"
    26  
    27  	"github.com/scroll-tech/go-ethereum"
    28  	"github.com/scroll-tech/go-ethereum/common"
    29  	"github.com/scroll-tech/go-ethereum/common/hexutil"
    30  	"github.com/scroll-tech/go-ethereum/core/types"
    31  	"github.com/scroll-tech/go-ethereum/rpc"
    32  )
    33  
    34  // Client defines typed wrappers for the Ethereum RPC API.
    35  type Client struct {
    36  	c *rpc.Client
    37  }
    38  
    39  // Dial connects a client to the given URL.
    40  func Dial(rawurl string) (*Client, error) {
    41  	return DialContext(context.Background(), rawurl)
    42  }
    43  
    44  func DialContext(ctx context.Context, rawurl string) (*Client, error) {
    45  	c, err := rpc.DialContext(ctx, rawurl)
    46  	if err != nil {
    47  		return nil, err
    48  	}
    49  	return NewClient(c), nil
    50  }
    51  
    52  // NewClient creates a client that uses the given RPC client.
    53  func NewClient(c *rpc.Client) *Client {
    54  	return &Client{c}
    55  }
    56  
    57  // SetHeader expose the function, in able to set http header.
    58  func (ec *Client) SetHeader(key, value string) {
    59  	ec.c.SetHeader(key, value)
    60  }
    61  
    62  func (ec *Client) Close() {
    63  	ec.c.Close()
    64  }
    65  
    66  // Blockchain Access
    67  
    68  // ChainID retrieves the current chain ID for transaction replay protection.
    69  func (ec *Client) ChainID(ctx context.Context) (*big.Int, error) {
    70  	var result hexutil.Big
    71  	err := ec.c.CallContext(ctx, &result, "eth_chainId")
    72  	if err != nil {
    73  		return nil, err
    74  	}
    75  	return (*big.Int)(&result), err
    76  }
    77  
    78  // BlockByHash returns the given full block.
    79  //
    80  // Note that loading full blocks requires two requests. Use HeaderByHash
    81  // if you don't need all transactions or uncle headers.
    82  func (ec *Client) BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error) {
    83  	return ec.getBlock(ctx, "eth_getBlockByHash", hash, true)
    84  }
    85  
    86  // BlockByNumber returns a block from the current canonical chain. If number is nil, the
    87  // latest known block is returned.
    88  //
    89  // Note that loading full blocks requires two requests. Use HeaderByNumber
    90  // if you don't need all transactions or uncle headers.
    91  func (ec *Client) BlockByNumber(ctx context.Context, number *big.Int) (*types.Block, error) {
    92  	return ec.getBlock(ctx, "eth_getBlockByNumber", toBlockNumArg(number), true)
    93  }
    94  
    95  // BlockNumber returns the most recent block number
    96  func (ec *Client) BlockNumber(ctx context.Context) (uint64, error) {
    97  	var result hexutil.Uint64
    98  	err := ec.c.CallContext(ctx, &result, "eth_blockNumber")
    99  	return uint64(result), err
   100  }
   101  
   102  type rpcBlock struct {
   103  	Hash         common.Hash      `json:"hash"`
   104  	Transactions []rpcTransaction `json:"transactions"`
   105  	UncleHashes  []common.Hash    `json:"uncles"`
   106  }
   107  
   108  func (ec *Client) getBlock(ctx context.Context, method string, args ...interface{}) (*types.Block, error) {
   109  	var raw json.RawMessage
   110  	err := ec.c.CallContext(ctx, &raw, method, args...)
   111  	if err != nil {
   112  		return nil, err
   113  	} else if len(raw) == 0 {
   114  		return nil, ethereum.NotFound
   115  	}
   116  	// Decode header and transactions.
   117  	var head *types.Header
   118  	var body rpcBlock
   119  	if err := json.Unmarshal(raw, &head); err != nil {
   120  		return nil, err
   121  	}
   122  	if err := json.Unmarshal(raw, &body); err != nil {
   123  		return nil, err
   124  	}
   125  	// Quick-verify transaction and uncle lists. This mostly helps with debugging the server.
   126  	if head.UncleHash == types.EmptyUncleHash && len(body.UncleHashes) > 0 {
   127  		return nil, fmt.Errorf("server returned non-empty uncle list but block header indicates no uncles")
   128  	}
   129  	if head.UncleHash != types.EmptyUncleHash && len(body.UncleHashes) == 0 {
   130  		return nil, fmt.Errorf("server returned empty uncle list but block header indicates uncles")
   131  	}
   132  	if head.TxHash == types.EmptyRootHash && len(body.Transactions) > 0 {
   133  		return nil, fmt.Errorf("server returned non-empty transaction list but block header indicates no transactions")
   134  	}
   135  	if head.TxHash != types.EmptyRootHash && len(body.Transactions) == 0 {
   136  		return nil, fmt.Errorf("server returned empty transaction list but block header indicates transactions")
   137  	}
   138  	// Load uncles because they are not included in the block response.
   139  	var uncles []*types.Header
   140  	if len(body.UncleHashes) > 0 {
   141  		uncles = make([]*types.Header, len(body.UncleHashes))
   142  		reqs := make([]rpc.BatchElem, len(body.UncleHashes))
   143  		for i := range reqs {
   144  			reqs[i] = rpc.BatchElem{
   145  				Method: "eth_getUncleByBlockHashAndIndex",
   146  				Args:   []interface{}{body.Hash, hexutil.EncodeUint64(uint64(i))},
   147  				Result: &uncles[i],
   148  			}
   149  		}
   150  		if err := ec.c.BatchCallContext(ctx, reqs); err != nil {
   151  			return nil, err
   152  		}
   153  		for i := range reqs {
   154  			if reqs[i].Error != nil {
   155  				return nil, reqs[i].Error
   156  			}
   157  			if uncles[i] == nil {
   158  				return nil, fmt.Errorf("got null header for uncle %d of block %x", i, body.Hash[:])
   159  			}
   160  		}
   161  	}
   162  	// Fill the sender cache of transactions in the block.
   163  	txs := make([]*types.Transaction, len(body.Transactions))
   164  	for i, tx := range body.Transactions {
   165  		if tx.From != nil {
   166  			setSenderFromServer(tx.tx, *tx.From, body.Hash)
   167  		}
   168  		txs[i] = tx.tx
   169  	}
   170  	return types.NewBlockWithHeader(head).WithBody(txs, uncles), nil
   171  }
   172  
   173  // HeaderByHash returns the block header with the given hash.
   174  func (ec *Client) HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) {
   175  	var head *types.Header
   176  	err := ec.c.CallContext(ctx, &head, "eth_getBlockByHash", hash, false)
   177  	if err == nil && head == nil {
   178  		err = ethereum.NotFound
   179  	}
   180  	return head, err
   181  }
   182  
   183  // HeaderByNumber returns a block header from the current canonical chain. If number is
   184  // nil, the latest known header is returned.
   185  func (ec *Client) HeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error) {
   186  	var head *types.Header
   187  	err := ec.c.CallContext(ctx, &head, "eth_getBlockByNumber", toBlockNumArg(number), false)
   188  	if err == nil && head == nil {
   189  		err = ethereum.NotFound
   190  	}
   191  	return head, err
   192  }
   193  
   194  type rpcTransaction struct {
   195  	tx *types.Transaction
   196  	txExtraInfo
   197  }
   198  
   199  type txExtraInfo struct {
   200  	BlockNumber *string         `json:"blockNumber,omitempty"`
   201  	BlockHash   *common.Hash    `json:"blockHash,omitempty"`
   202  	From        *common.Address `json:"from,omitempty"`
   203  }
   204  
   205  func (tx *rpcTransaction) UnmarshalJSON(msg []byte) error {
   206  	if err := json.Unmarshal(msg, &tx.tx); err != nil {
   207  		return err
   208  	}
   209  	return json.Unmarshal(msg, &tx.txExtraInfo)
   210  }
   211  
   212  // TransactionByHash returns the transaction with the given hash.
   213  func (ec *Client) TransactionByHash(ctx context.Context, hash common.Hash) (tx *types.Transaction, isPending bool, err error) {
   214  	var json *rpcTransaction
   215  	err = ec.c.CallContext(ctx, &json, "eth_getTransactionByHash", hash)
   216  	if err != nil {
   217  		return nil, false, err
   218  	} else if json == nil {
   219  		return nil, false, ethereum.NotFound
   220  	} else if _, r, _ := json.tx.RawSignatureValues(); r == nil {
   221  		return nil, false, fmt.Errorf("server returned transaction without signature")
   222  	}
   223  	if json.From != nil && json.BlockHash != nil {
   224  		setSenderFromServer(json.tx, *json.From, *json.BlockHash)
   225  	}
   226  	return json.tx, json.BlockNumber == nil, nil
   227  }
   228  
   229  // TransactionSender returns the sender address of the given transaction. The transaction
   230  // must be known to the remote node and included in the blockchain at the given block and
   231  // index. The sender is the one derived by the protocol at the time of inclusion.
   232  //
   233  // There is a fast-path for transactions retrieved by TransactionByHash and
   234  // TransactionInBlock. Getting their sender address can be done without an RPC interaction.
   235  func (ec *Client) TransactionSender(ctx context.Context, tx *types.Transaction, block common.Hash, index uint) (common.Address, error) {
   236  	// Try to load the address from the cache.
   237  	sender, err := types.Sender(&senderFromServer{blockhash: block}, tx)
   238  	if err == nil {
   239  		return sender, nil
   240  	}
   241  
   242  	// It was not found in cache, ask the server.
   243  	var meta struct {
   244  		Hash common.Hash
   245  		From common.Address
   246  	}
   247  	if err = ec.c.CallContext(ctx, &meta, "eth_getTransactionByBlockHashAndIndex", block, hexutil.Uint64(index)); err != nil {
   248  		return common.Address{}, err
   249  	}
   250  	if meta.Hash == (common.Hash{}) || meta.Hash != tx.Hash() {
   251  		return common.Address{}, errors.New("wrong inclusion block/index")
   252  	}
   253  	return meta.From, nil
   254  }
   255  
   256  // TransactionCount returns the total number of transactions in the given block.
   257  func (ec *Client) TransactionCount(ctx context.Context, blockHash common.Hash) (uint, error) {
   258  	var num hexutil.Uint
   259  	err := ec.c.CallContext(ctx, &num, "eth_getBlockTransactionCountByHash", blockHash)
   260  	return uint(num), err
   261  }
   262  
   263  // TransactionInBlock returns a single transaction at index in the given block.
   264  func (ec *Client) TransactionInBlock(ctx context.Context, blockHash common.Hash, index uint) (*types.Transaction, error) {
   265  	var json *rpcTransaction
   266  	err := ec.c.CallContext(ctx, &json, "eth_getTransactionByBlockHashAndIndex", blockHash, hexutil.Uint64(index))
   267  	if err != nil {
   268  		return nil, err
   269  	}
   270  	if json == nil {
   271  		return nil, ethereum.NotFound
   272  	} else if _, r, _ := json.tx.RawSignatureValues(); r == nil {
   273  		return nil, fmt.Errorf("server returned transaction without signature")
   274  	}
   275  	if json.From != nil && json.BlockHash != nil {
   276  		setSenderFromServer(json.tx, *json.From, *json.BlockHash)
   277  	}
   278  	return json.tx, err
   279  }
   280  
   281  // TransactionReceipt returns the receipt of a transaction by transaction hash.
   282  // Note that the receipt is not available for pending transactions.
   283  func (ec *Client) TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error) {
   284  	var r *types.Receipt
   285  	err := ec.c.CallContext(ctx, &r, "eth_getTransactionReceipt", txHash)
   286  	if err == nil {
   287  		if r == nil {
   288  			return nil, ethereum.NotFound
   289  		}
   290  	}
   291  	return r, err
   292  }
   293  
   294  type rpcProgress struct {
   295  	StartingBlock hexutil.Uint64
   296  	CurrentBlock  hexutil.Uint64
   297  	HighestBlock  hexutil.Uint64
   298  	PulledStates  hexutil.Uint64
   299  	KnownStates   hexutil.Uint64
   300  }
   301  
   302  // SyncProgress retrieves the current progress of the sync algorithm. If there's
   303  // no sync currently running, it returns nil.
   304  func (ec *Client) SyncProgress(ctx context.Context) (*ethereum.SyncProgress, error) {
   305  	var raw json.RawMessage
   306  	if err := ec.c.CallContext(ctx, &raw, "eth_syncing"); err != nil {
   307  		return nil, err
   308  	}
   309  	// Handle the possible response types
   310  	var syncing bool
   311  	if err := json.Unmarshal(raw, &syncing); err == nil {
   312  		return nil, nil // Not syncing (always false)
   313  	}
   314  	var progress *rpcProgress
   315  	if err := json.Unmarshal(raw, &progress); err != nil {
   316  		return nil, err
   317  	}
   318  	return &ethereum.SyncProgress{
   319  		StartingBlock: uint64(progress.StartingBlock),
   320  		CurrentBlock:  uint64(progress.CurrentBlock),
   321  		HighestBlock:  uint64(progress.HighestBlock),
   322  		PulledStates:  uint64(progress.PulledStates),
   323  		KnownStates:   uint64(progress.KnownStates),
   324  	}, nil
   325  }
   326  
   327  // SubscribeNewHead subscribes to notifications about the current blockchain head
   328  // on the given channel.
   329  func (ec *Client) SubscribeNewHead(ctx context.Context, ch chan<- *types.Header) (ethereum.Subscription, error) {
   330  	return ec.c.EthSubscribe(ctx, ch, "newHeads")
   331  }
   332  
   333  // GetBlockTraceByHash returns the BlockTrace given the block hash.
   334  func (ec *Client) GetBlockTraceByHash(ctx context.Context, blockHash common.Hash) (*types.BlockTrace, error) {
   335  	blockTrace := &types.BlockTrace{}
   336  	return blockTrace, ec.c.CallContext(ctx, &blockTrace, "scroll_getBlockTraceByNumberOrHash", blockHash)
   337  }
   338  
   339  // GetBlockTraceByNumber returns the BlockTrace given the block number.
   340  func (ec *Client) GetBlockTraceByNumber(ctx context.Context, number *big.Int) (*types.BlockTrace, error) {
   341  	blockTrace := &types.BlockTrace{}
   342  	return blockTrace, ec.c.CallContext(ctx, &blockTrace, "scroll_getBlockTraceByNumberOrHash", toBlockNumArg(number))
   343  }
   344  
   345  type rpcRowConsumption struct {
   346  	RowConsumption types.RowConsumption `json:"rowConsumption"`
   347  }
   348  
   349  // UnmarshalJSON unmarshals from JSON.
   350  func (r *rpcRowConsumption) UnmarshalJSON(input []byte) error {
   351  	type rpcRowConsumption struct {
   352  		RowConsumption types.RowConsumption `json:"rowConsumption"`
   353  	}
   354  	var dec rpcRowConsumption
   355  	if err := json.Unmarshal(input, &dec); err != nil {
   356  		return err
   357  	}
   358  	if dec.RowConsumption == nil {
   359  		return errors.New("missing required field 'RowConsumption' for rpcRowConsumption")
   360  	}
   361  	r.RowConsumption = dec.RowConsumption
   362  	return nil
   363  }
   364  
   365  // GetBlockByNumberOrHash returns the requested block
   366  func (ec *Client) GetBlockByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*types.BlockWithRowConsumption, error) {
   367  	var raw json.RawMessage
   368  	var err error
   369  	if number, ok := blockNrOrHash.Number(); ok {
   370  		err = ec.c.CallContext(ctx, &raw, "scroll_getBlockByNumber", number, true)
   371  	}
   372  	if hash, ok := blockNrOrHash.Hash(); ok {
   373  		err = ec.c.CallContext(ctx, &raw, "scroll_getBlockByHash", hash, true)
   374  	}
   375  	if err != nil {
   376  		return nil, err
   377  	} else if len(raw) == 0 {
   378  		return nil, ethereum.NotFound
   379  	}
   380  	// Decode header and transactions.
   381  	var head *types.Header
   382  	var body rpcBlock
   383  	var rpcRc rpcRowConsumption
   384  	var rc *types.RowConsumption
   385  	if err := json.Unmarshal(raw, &head); err != nil {
   386  		return nil, err
   387  	}
   388  	if err := json.Unmarshal(raw, &body); err != nil {
   389  		return nil, err
   390  	}
   391  	if err := json.Unmarshal(raw, &rpcRc); err != nil {
   392  		// don't return error here if there is no RowConsumption data, because many l2geth nodes will not have this data
   393  		// instead of error l2_watcher and other services that require RowConsumption should check it
   394  		rc = nil
   395  	} else {
   396  		rc = &rpcRc.RowConsumption
   397  	}
   398  	// Quick-verify transaction and uncle lists. This mostly helps with debugging the server.
   399  	if head.UncleHash == types.EmptyUncleHash && len(body.UncleHashes) > 0 {
   400  		return nil, fmt.Errorf("server returned non-empty uncle list but block header indicates no uncles")
   401  	}
   402  	if head.UncleHash != types.EmptyUncleHash && len(body.UncleHashes) == 0 {
   403  		return nil, fmt.Errorf("server returned empty uncle list but block header indicates uncles")
   404  	}
   405  	if head.TxHash == types.EmptyRootHash && len(body.Transactions) > 0 {
   406  		return nil, fmt.Errorf("server returned non-empty transaction list but block header indicates no transactions")
   407  	}
   408  	if head.TxHash != types.EmptyRootHash && len(body.Transactions) == 0 {
   409  		return nil, fmt.Errorf("server returned empty transaction list but block header indicates transactions")
   410  	}
   411  	// Load uncles because they are not included in the block response.
   412  	var uncles []*types.Header
   413  	if len(body.UncleHashes) > 0 {
   414  		uncles = make([]*types.Header, len(body.UncleHashes))
   415  		reqs := make([]rpc.BatchElem, len(body.UncleHashes))
   416  		for i := range reqs {
   417  			reqs[i] = rpc.BatchElem{
   418  				Method: "eth_getUncleByBlockHashAndIndex",
   419  				Args:   []interface{}{body.Hash, hexutil.EncodeUint64(uint64(i))},
   420  				Result: &uncles[i],
   421  			}
   422  		}
   423  		if err := ec.c.BatchCallContext(ctx, reqs); err != nil {
   424  			return nil, err
   425  		}
   426  		for i := range reqs {
   427  			if reqs[i].Error != nil {
   428  				return nil, reqs[i].Error
   429  			}
   430  			if uncles[i] == nil {
   431  				return nil, fmt.Errorf("got null header for uncle %d of block %x", i, body.Hash[:])
   432  			}
   433  		}
   434  	}
   435  	// Fill the sender cache of transactions in the block.
   436  	txs := make([]*types.Transaction, len(body.Transactions))
   437  	for i, tx := range body.Transactions {
   438  		if tx.From != nil {
   439  			setSenderFromServer(tx.tx, *tx.From, body.Hash)
   440  		}
   441  		txs[i] = tx.tx
   442  	}
   443  	block := types.NewBlockWithHeader(head).WithBody(txs, uncles)
   444  	return &types.BlockWithRowConsumption{
   445  		Block:          block,
   446  		RowConsumption: rc,
   447  	}, nil
   448  }
   449  
   450  // SubscribeNewBlockTrace subscribes to block execution trace when a new block is created.
   451  func (ec *Client) SubscribeNewBlockTrace(ctx context.Context, ch chan<- *types.BlockTrace) (ethereum.Subscription, error) {
   452  	return ec.c.EthSubscribe(ctx, ch, "newBlockTrace")
   453  }
   454  
   455  // State Access
   456  
   457  // NetworkID returns the network ID (also known as the chain ID) for this chain.
   458  func (ec *Client) NetworkID(ctx context.Context) (*big.Int, error) {
   459  	version := new(big.Int)
   460  	var ver string
   461  	if err := ec.c.CallContext(ctx, &ver, "net_version"); err != nil {
   462  		return nil, err
   463  	}
   464  	if _, ok := version.SetString(ver, 10); !ok {
   465  		return nil, fmt.Errorf("invalid net_version result %q", ver)
   466  	}
   467  	return version, nil
   468  }
   469  
   470  // BalanceAt returns the wei balance of the given account.
   471  // The block number can be nil, in which case the balance is taken from the latest known block.
   472  func (ec *Client) BalanceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (*big.Int, error) {
   473  	var result hexutil.Big
   474  	err := ec.c.CallContext(ctx, &result, "eth_getBalance", account, toBlockNumArg(blockNumber))
   475  	return (*big.Int)(&result), err
   476  }
   477  
   478  // StorageAt returns the value of key in the contract storage of the given account.
   479  // The block number can be nil, in which case the value is taken from the latest known block.
   480  func (ec *Client) StorageAt(ctx context.Context, account common.Address, key common.Hash, blockNumber *big.Int) ([]byte, error) {
   481  	var result hexutil.Bytes
   482  	err := ec.c.CallContext(ctx, &result, "eth_getStorageAt", account, key, toBlockNumArg(blockNumber))
   483  	return result, err
   484  }
   485  
   486  // CodeAt returns the contract code of the given account.
   487  // The block number can be nil, in which case the code is taken from the latest known block.
   488  func (ec *Client) CodeAt(ctx context.Context, account common.Address, blockNumber *big.Int) ([]byte, error) {
   489  	var result hexutil.Bytes
   490  	err := ec.c.CallContext(ctx, &result, "eth_getCode", account, toBlockNumArg(blockNumber))
   491  	return result, err
   492  }
   493  
   494  // NonceAt returns the account nonce of the given account.
   495  // The block number can be nil, in which case the nonce is taken from the latest known block.
   496  func (ec *Client) NonceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (uint64, error) {
   497  	var result hexutil.Uint64
   498  	err := ec.c.CallContext(ctx, &result, "eth_getTransactionCount", account, toBlockNumArg(blockNumber))
   499  	return uint64(result), err
   500  }
   501  
   502  // Filters
   503  
   504  // FilterLogs executes a filter query.
   505  func (ec *Client) FilterLogs(ctx context.Context, q ethereum.FilterQuery) ([]types.Log, error) {
   506  	var result []types.Log
   507  	arg, err := toFilterArg(q)
   508  	if err != nil {
   509  		return nil, err
   510  	}
   511  	err = ec.c.CallContext(ctx, &result, "eth_getLogs", arg)
   512  	return result, err
   513  }
   514  
   515  // SubscribeFilterLogs subscribes to the results of a streaming filter query.
   516  func (ec *Client) SubscribeFilterLogs(ctx context.Context, q ethereum.FilterQuery, ch chan<- types.Log) (ethereum.Subscription, error) {
   517  	arg, err := toFilterArg(q)
   518  	if err != nil {
   519  		return nil, err
   520  	}
   521  	return ec.c.EthSubscribe(ctx, ch, "logs", arg)
   522  }
   523  
   524  func toFilterArg(q ethereum.FilterQuery) (interface{}, error) {
   525  	arg := map[string]interface{}{
   526  		"address": q.Addresses,
   527  		"topics":  q.Topics,
   528  	}
   529  	if q.BlockHash != nil {
   530  		arg["blockHash"] = *q.BlockHash
   531  		if q.FromBlock != nil || q.ToBlock != nil {
   532  			return nil, fmt.Errorf("cannot specify both BlockHash and FromBlock/ToBlock")
   533  		}
   534  	} else {
   535  		if q.FromBlock == nil {
   536  			arg["fromBlock"] = "0x0"
   537  		} else {
   538  			arg["fromBlock"] = toBlockNumArg(q.FromBlock)
   539  		}
   540  		arg["toBlock"] = toBlockNumArg(q.ToBlock)
   541  	}
   542  	return arg, nil
   543  }
   544  
   545  // Pending State
   546  
   547  // PendingBalanceAt returns the wei balance of the given account in the pending state.
   548  func (ec *Client) PendingBalanceAt(ctx context.Context, account common.Address) (*big.Int, error) {
   549  	var result hexutil.Big
   550  	err := ec.c.CallContext(ctx, &result, "eth_getBalance", account, "pending")
   551  	return (*big.Int)(&result), err
   552  }
   553  
   554  // PendingStorageAt returns the value of key in the contract storage of the given account in the pending state.
   555  func (ec *Client) PendingStorageAt(ctx context.Context, account common.Address, key common.Hash) ([]byte, error) {
   556  	var result hexutil.Bytes
   557  	err := ec.c.CallContext(ctx, &result, "eth_getStorageAt", account, key, "pending")
   558  	return result, err
   559  }
   560  
   561  // PendingCodeAt returns the contract code of the given account in the pending state.
   562  func (ec *Client) PendingCodeAt(ctx context.Context, account common.Address) ([]byte, error) {
   563  	var result hexutil.Bytes
   564  	err := ec.c.CallContext(ctx, &result, "eth_getCode", account, "pending")
   565  	return result, err
   566  }
   567  
   568  // PendingNonceAt returns the account nonce of the given account in the pending state.
   569  // This is the nonce that should be used for the next transaction.
   570  func (ec *Client) PendingNonceAt(ctx context.Context, account common.Address) (uint64, error) {
   571  	var result hexutil.Uint64
   572  	err := ec.c.CallContext(ctx, &result, "eth_getTransactionCount", account, "pending")
   573  	return uint64(result), err
   574  }
   575  
   576  // PendingTransactionCount returns the total number of transactions in the pending state.
   577  func (ec *Client) PendingTransactionCount(ctx context.Context) (uint, error) {
   578  	var num hexutil.Uint
   579  	err := ec.c.CallContext(ctx, &num, "eth_getBlockTransactionCountByNumber", "pending")
   580  	return uint(num), err
   581  }
   582  
   583  // Contract Calling
   584  
   585  // CallContract executes a message call transaction, which is directly executed in the VM
   586  // of the node, but never mined into the blockchain.
   587  //
   588  // blockNumber selects the block height at which the call runs. It can be nil, in which
   589  // case the code is taken from the latest known block. Note that state from very old
   590  // blocks might not be available.
   591  func (ec *Client) CallContract(ctx context.Context, msg ethereum.CallMsg, blockNumber *big.Int) ([]byte, error) {
   592  	var hex hexutil.Bytes
   593  	err := ec.c.CallContext(ctx, &hex, "eth_call", toCallArg(msg), toBlockNumArg(blockNumber))
   594  	if err != nil {
   595  		return nil, err
   596  	}
   597  	return hex, nil
   598  }
   599  
   600  // PendingCallContract executes a message call transaction using the EVM.
   601  // The state seen by the contract call is the pending state.
   602  func (ec *Client) PendingCallContract(ctx context.Context, msg ethereum.CallMsg) ([]byte, error) {
   603  	var hex hexutil.Bytes
   604  	err := ec.c.CallContext(ctx, &hex, "eth_call", toCallArg(msg), "pending")
   605  	if err != nil {
   606  		return nil, err
   607  	}
   608  	return hex, nil
   609  }
   610  
   611  // SuggestGasPrice retrieves the currently suggested gas price to allow a timely
   612  // execution of a transaction.
   613  func (ec *Client) SuggestGasPrice(ctx context.Context) (*big.Int, error) {
   614  	var hex hexutil.Big
   615  	if err := ec.c.CallContext(ctx, &hex, "eth_gasPrice"); err != nil {
   616  		return nil, err
   617  	}
   618  	return (*big.Int)(&hex), nil
   619  }
   620  
   621  // SuggestGasTipCap retrieves the currently suggested gas tip cap after 1559 to
   622  // allow a timely execution of a transaction.
   623  func (ec *Client) SuggestGasTipCap(ctx context.Context) (*big.Int, error) {
   624  	var hex hexutil.Big
   625  	if err := ec.c.CallContext(ctx, &hex, "eth_maxPriorityFeePerGas"); err != nil {
   626  		return nil, err
   627  	}
   628  	return (*big.Int)(&hex), nil
   629  }
   630  
   631  // EstimateGas tries to estimate the gas needed to execute a specific transaction based on
   632  // the current pending state of the backend blockchain. There is no guarantee that this is
   633  // the true gas limit requirement as other transactions may be added or removed by miners,
   634  // but it should provide a basis for setting a reasonable default.
   635  func (ec *Client) EstimateGas(ctx context.Context, msg ethereum.CallMsg) (uint64, error) {
   636  	var hex hexutil.Uint64
   637  	err := ec.c.CallContext(ctx, &hex, "eth_estimateGas", toCallArg(msg))
   638  	if err != nil {
   639  		return 0, err
   640  	}
   641  	return uint64(hex), nil
   642  }
   643  
   644  // SendTransaction injects a signed transaction into the pending pool for execution.
   645  //
   646  // If the transaction was a contract creation use the TransactionReceipt method to get the
   647  // contract address after the transaction has been mined.
   648  func (ec *Client) SendTransaction(ctx context.Context, tx *types.Transaction) error {
   649  	data, err := tx.MarshalBinary()
   650  	if err != nil {
   651  		return err
   652  	}
   653  	return ec.c.CallContext(ctx, nil, "eth_sendRawTransaction", hexutil.Encode(data))
   654  }
   655  
   656  func toBlockNumArg(number *big.Int) string {
   657  	if number == nil {
   658  		return "latest"
   659  	}
   660  	latest := big.NewInt(int64(rpc.LatestBlockNumber))
   661  	if number.Cmp(latest) == 0 {
   662  		return "latest"
   663  	}
   664  	pending := big.NewInt(int64(rpc.PendingBlockNumber))
   665  	if number.Cmp(pending) == 0 {
   666  		return "pending"
   667  	}
   668  	finalized := big.NewInt(int64(rpc.FinalizedBlockNumber))
   669  	if number.Cmp(finalized) == 0 {
   670  		return "finalized"
   671  	}
   672  	safe := big.NewInt(int64(rpc.SafeBlockNumber))
   673  	if number.Cmp(safe) == 0 {
   674  		return "safe"
   675  	}
   676  	return hexutil.EncodeBig(number)
   677  }
   678  
   679  func toCallArg(msg ethereum.CallMsg) interface{} {
   680  	arg := map[string]interface{}{
   681  		"from": msg.From,
   682  		"to":   msg.To,
   683  	}
   684  	if len(msg.Data) > 0 {
   685  		arg["data"] = hexutil.Bytes(msg.Data)
   686  	}
   687  	if msg.Value != nil {
   688  		arg["value"] = (*hexutil.Big)(msg.Value)
   689  	}
   690  	if msg.Gas != 0 {
   691  		arg["gas"] = hexutil.Uint64(msg.Gas)
   692  	}
   693  	if msg.GasPrice != nil {
   694  		arg["gasPrice"] = (*hexutil.Big)(msg.GasPrice)
   695  	}
   696  	return arg
   697  }