github.com/lmittmann/w3@v0.20.0/module/eth/block.go (about)

     1  package eth
     2  
     3  import (
     4  	"encoding/json"
     5  	"math/big"
     6  
     7  	"github.com/ethereum/go-ethereum/common"
     8  	"github.com/ethereum/go-ethereum/core/types"
     9  	"github.com/lmittmann/w3/internal/module"
    10  	"github.com/lmittmann/w3/w3types"
    11  )
    12  
    13  // BlockByHash requests the block with the given hash with full transactions.
    14  func BlockByHash(hash common.Hash) w3types.RPCCallerFactory[*types.Block] {
    15  	return module.NewFactory(
    16  		"eth_getBlockByHash",
    17  		[]any{hash, true},
    18  		module.WithRetWrapper(blockRetWrapper),
    19  	)
    20  }
    21  
    22  // BlockByNumber requests the block with the given number with full
    23  // transactions. If number is nil, the latest block is requested.
    24  func BlockByNumber(number *big.Int) w3types.RPCCallerFactory[*types.Block] {
    25  	return module.NewFactory(
    26  		"eth_getBlockByNumber",
    27  		[]any{module.BlockNumberArg(number), true},
    28  		module.WithRetWrapper(blockRetWrapper),
    29  	)
    30  }
    31  
    32  // BlockTxCountByHash requests the number of transactions in the block with the
    33  // given hash.
    34  func BlockTxCountByHash(hash common.Hash) w3types.RPCCallerFactory[uint] {
    35  	return module.NewFactory(
    36  		"eth_getBlockTransactionCountByHash",
    37  		[]any{hash},
    38  		module.WithRetWrapper(module.HexUintRetWrapper),
    39  	)
    40  }
    41  
    42  // BlockTxCountByNumber requests the number of transactions in the block with
    43  // the given number.
    44  func BlockTxCountByNumber(number *big.Int) w3types.RPCCallerFactory[uint] {
    45  	return module.NewFactory(
    46  		"eth_getBlockTransactionCountByNumber",
    47  		[]any{module.BlockNumberArg(number)},
    48  		module.WithRetWrapper(module.HexUintRetWrapper),
    49  	)
    50  }
    51  
    52  // HeaderByHash requests the header with the given hash.
    53  func HeaderByHash(hash common.Hash) w3types.RPCCallerFactory[*types.Header] {
    54  	return module.NewFactory[*types.Header](
    55  		"eth_getBlockByHash",
    56  		[]any{hash, false},
    57  	)
    58  }
    59  
    60  // HeaderByNumber requests the header with the given number. If number is nil,
    61  // the latest header is requested.
    62  func HeaderByNumber(number *big.Int) w3types.RPCCallerFactory[*types.Header] {
    63  	return module.NewFactory[*types.Header](
    64  		"eth_getBlockByNumber",
    65  		[]any{module.BlockNumberArg(number), false},
    66  	)
    67  }
    68  
    69  func blockRetWrapper(ret **types.Block) any { *ret = new(types.Block); return &rpcBlock{*ret} }
    70  
    71  type rpcBlock struct{ *types.Block }
    72  
    73  func (b *rpcBlock) UnmarshalJSON(data []byte) error {
    74  	var header types.Header
    75  	if err := json.Unmarshal(data, &header); err != nil {
    76  		return err
    77  	}
    78  
    79  	var blockExtraData struct {
    80  		Transactions []*types.Transaction `json:"transactions"`
    81  		Withdrawals  []*types.Withdrawal  `json:"withdrawals"`
    82  	}
    83  	if err := json.Unmarshal(data, &blockExtraData); err != nil {
    84  		return err
    85  	}
    86  
    87  	*b.Block = *types.NewBlockWithHeader(&header).
    88  		WithBody(types.Body{
    89  			Transactions: blockExtraData.Transactions,
    90  			Withdrawals:  blockExtraData.Withdrawals,
    91  		})
    92  	return nil
    93  }