@@ -656,10 +656,10 @@ func (s *PublicBlockChainAPI) GetHeaderByHash(ctx context.Context, hash common.H
656
656
}
657
657
658
658
// GetBlockByNumber returns the requested canonical block.
659
- // * When blockNr is -1 the chain head is returned.
660
- // * When blockNr is -2 the pending chain head is returned.
661
- // * When fullTx is true all transactions in the block are returned, otherwise
662
- // only the transaction hash is returned.
659
+ // - When blockNr is -1 the chain head is returned.
660
+ // - When blockNr is -2 the pending chain head is returned.
661
+ // - When fullTx is true all transactions in the block are returned, otherwise
662
+ // only the transaction hash is returned.
663
663
func (s * PublicBlockChainAPI ) GetBlockByNumber (ctx context.Context , number rpc.BlockNumber , fullTx bool ) (map [string ]interface {}, error ) {
664
664
block , err := s .b .BlockByNumber (ctx , number )
665
665
if block != nil && err == nil {
@@ -816,6 +816,68 @@ func (args *CallArgs) ToMessage(globalGasCap uint64) types.Message {
816
816
return msg
817
817
}
818
818
819
+ // GetBlockReceipts returns the block receipts for the given block hash or number or tag.
820
+ func (api * PublicBlockChainAPI ) GetBlockReceipts (ctx context.Context , blockNrOrHash rpc.BlockNumberOrHash ) ([]map [string ]interface {}, error ) {
821
+ block , err := api .b .BlockByNumberOrHash (ctx , blockNrOrHash )
822
+ if block == nil || err != nil {
823
+ // When the block doesn't exist, the RPC method should return JSON null
824
+ // as per specification.
825
+ return nil , nil
826
+ }
827
+ receipts , err := api .b .GetReceipts (ctx , block .Hash ())
828
+ if err != nil {
829
+ return nil , err
830
+ }
831
+ txs := block .Transactions ()
832
+ if len (txs ) != len (receipts ) {
833
+ return nil , fmt .Errorf ("receipts length mismatch: %d vs %d" , len (txs ), len (receipts ))
834
+ }
835
+
836
+ blockHash := block .Hash ()
837
+ blockNumber := block .NumberU64 ()
838
+ txReceipts := make ([]map [string ]interface {}, 0 , len (txs ))
839
+ for i , receipt := range receipts {
840
+ tx := txs [i ]
841
+ var signer types.Signer = types.FrontierSigner {}
842
+ if tx .Protected () {
843
+ signer = types .NewEIP155Signer (tx .ChainId ())
844
+ }
845
+ from , _ := types .Sender (signer , tx )
846
+
847
+ fields := map [string ]interface {}{
848
+ "blockHash" : blockHash ,
849
+ "blockNumber" : hexutil .Uint64 (blockNumber ),
850
+ "transactionHash" : tx .Hash (),
851
+ "transactionIndex" : hexutil .Uint64 (i ),
852
+ "from" : from ,
853
+ "to" : tx .To (),
854
+ "gasUsed" : hexutil .Uint64 (receipt .GasUsed ),
855
+ "cumulativeGasUsed" : hexutil .Uint64 (receipt .CumulativeGasUsed ),
856
+ "contractAddress" : nil ,
857
+ "logs" : receipt .Logs ,
858
+ "logsBloom" : receipt .Bloom ,
859
+ }
860
+
861
+ // Assign receipt status or post state.
862
+ if len (receipt .PostState ) > 0 {
863
+ fields ["root" ] = hexutil .Bytes (receipt .PostState )
864
+ } else {
865
+ fields ["status" ] = hexutil .Uint (receipt .Status )
866
+ }
867
+ if receipt .Logs == nil {
868
+ fields ["logs" ] = [][]* types.Log {}
869
+ }
870
+ // If the ContractAddress is 20 0x0 bytes, assume it is not a contract creation
871
+ if receipt .ContractAddress != (common.Address {}) {
872
+ fields ["contractAddress" ] = receipt .ContractAddress
873
+ }
874
+
875
+ txReceipts = append (txReceipts , fields )
876
+ }
877
+
878
+ return txReceipts , nil
879
+ }
880
+
819
881
// OverrideAccount indicates the overriding fields of account during the execution
820
882
// of a message call.
821
883
// Note, state and stateDiff can't be specified at the same time. If state is
0 commit comments