diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 43a33e9921..2f2285066f 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -491,6 +491,53 @@ func NewPublicBlockChainAPI(b Backend) *PublicBlockChainAPI { return &PublicBlockChainAPI{b} } +// GetBlockReceipts returns all the transaction receipts for the given block hash. +func (s *PublicBlockChainAPI) GetBlockReceipts(ctx context.Context, hash common.Hash) ([]map[string]interface{}, error) { + receipts, err := s.b.GetReceipts(ctx, hash) + if err != nil { + return nil, err + } + fieldses := make([]map[string]interface{}, 0, len(receipts)) + for _, receipt := range receipts { + tx, blockHash, blockNumber, index := rawdb.ReadTransaction(s.b.ChainDb(), receipt.TxHash) + var signer types.Signer = types.FrontierSigner{} + if tx.Protected() { + signer = types.NewEIP155Signer(tx.ChainId()) + } + from, _ := types.Sender(signer, tx) + + fields := map[string]interface{}{ + "blockHash": blockHash, + "blockNumber": hexutil.Uint64(blockNumber), + "transactionHash": hash, + "transactionIndex": hexutil.Uint64(index), + "from": from, + "to": tx.To(), + "gasUsed": hexutil.Uint64(receipt.GasUsed), + "cumulativeGasUsed": hexutil.Uint64(receipt.CumulativeGasUsed), + "contractAddress": nil, + "logs": receipt.Logs, + "logsBloom": receipt.Bloom, + } + + // Assign receipt status or post state. + if len(receipt.PostState) > 0 { + fields["root"] = hexutil.Bytes(receipt.PostState) + } else { + fields["status"] = hexutil.Uint(receipt.Status) + } + if receipt.Logs == nil { + fields["logs"] = [][]*types.Log{} + } + // If the ContractAddress is 20 0x0 bytes, assume it is not a contract creation + if receipt.ContractAddress != (common.Address{}) { + fields["contractAddress"] = receipt.ContractAddress + } + fieldses = append(fieldses, fields) + } + return fieldses, nil +} + // BlockNumber returns the block number of the chain head. func (s *PublicBlockChainAPI) BlockNumber() hexutil.Uint64 { header, _ := s.b.HeaderByNumber(context.Background(), rpc.LatestBlockNumber) // latest header should always be available