github.com/mister-meeseeks/go-ethereum@v1.9.7/cmd/geth/retesteth_copypaste.go (about) 1 // Copyright 2019 The go-ethereum Authors 2 // This file is part of go-ethereum. 3 // 4 // go-ethereum is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU 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 // go-ethereum 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 General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with go-ethereum. If not, see <http://www.gnu.org/licenses/>. 16 17 package main 18 19 import ( 20 "math/big" 21 22 "github.com/ethereum/go-ethereum/common" 23 "github.com/ethereum/go-ethereum/common/hexutil" 24 "github.com/ethereum/go-ethereum/core/types" 25 ) 26 27 // RPCTransaction represents a transaction that will serialize to the RPC representation of a transaction 28 type RPCTransaction struct { 29 BlockHash common.Hash `json:"blockHash"` 30 BlockNumber *hexutil.Big `json:"blockNumber"` 31 From common.Address `json:"from"` 32 Gas hexutil.Uint64 `json:"gas"` 33 GasPrice *hexutil.Big `json:"gasPrice"` 34 Hash common.Hash `json:"hash"` 35 Input hexutil.Bytes `json:"input"` 36 Nonce hexutil.Uint64 `json:"nonce"` 37 To *common.Address `json:"to"` 38 TransactionIndex hexutil.Uint `json:"transactionIndex"` 39 Value *hexutil.Big `json:"value"` 40 V *hexutil.Big `json:"v"` 41 R *hexutil.Big `json:"r"` 42 S *hexutil.Big `json:"s"` 43 } 44 45 // newRPCTransaction returns a transaction that will serialize to the RPC 46 // representation, with the given location metadata set (if available). 47 func newRPCTransaction(tx *types.Transaction, blockHash common.Hash, blockNumber uint64, index uint64) *RPCTransaction { 48 var signer types.Signer = types.FrontierSigner{} 49 if tx.Protected() { 50 signer = types.NewEIP155Signer(tx.ChainId()) 51 } 52 from, _ := types.Sender(signer, tx) 53 v, r, s := tx.RawSignatureValues() 54 55 result := &RPCTransaction{ 56 From: from, 57 Gas: hexutil.Uint64(tx.Gas()), 58 GasPrice: (*hexutil.Big)(tx.GasPrice()), 59 Hash: tx.Hash(), 60 Input: hexutil.Bytes(tx.Data()), 61 Nonce: hexutil.Uint64(tx.Nonce()), 62 To: tx.To(), 63 Value: (*hexutil.Big)(tx.Value()), 64 V: (*hexutil.Big)(v), 65 R: (*hexutil.Big)(r), 66 S: (*hexutil.Big)(s), 67 } 68 if blockHash != (common.Hash{}) { 69 result.BlockHash = blockHash 70 result.BlockNumber = (*hexutil.Big)(new(big.Int).SetUint64(blockNumber)) 71 result.TransactionIndex = hexutil.Uint(index) 72 } 73 return result 74 } 75 76 // newRPCTransactionFromBlockIndex returns a transaction that will serialize to the RPC representation. 77 func newRPCTransactionFromBlockIndex(b *types.Block, index uint64) *RPCTransaction { 78 txs := b.Transactions() 79 if index >= uint64(len(txs)) { 80 return nil 81 } 82 return newRPCTransaction(txs[index], b.Hash(), b.NumberU64(), index) 83 } 84 85 // newRPCTransactionFromBlockHash returns a transaction that will serialize to the RPC representation. 86 func newRPCTransactionFromBlockHash(b *types.Block, hash common.Hash) *RPCTransaction { 87 for idx, tx := range b.Transactions() { 88 if tx.Hash() == hash { 89 return newRPCTransactionFromBlockIndex(b, uint64(idx)) 90 } 91 } 92 return nil 93 } 94 95 // RPCMarshalBlock converts the given block to the RPC output which depends on fullTx. If inclTx is true transactions are 96 // returned. When fullTx is true the returned block contains full transaction details, otherwise it will only contain 97 // transaction hashes. 98 func RPCMarshalBlock(b *types.Block, inclTx bool, fullTx bool) (map[string]interface{}, error) { 99 head := b.Header() // copies the header once 100 fields := map[string]interface{}{ 101 "number": (*hexutil.Big)(head.Number), 102 "hash": b.Hash(), 103 "parentHash": head.ParentHash, 104 "nonce": head.Nonce, 105 "mixHash": head.MixDigest, 106 "sha3Uncles": head.UncleHash, 107 "logsBloom": head.Bloom, 108 "stateRoot": head.Root, 109 "miner": head.Coinbase, 110 "difficulty": (*hexutil.Big)(head.Difficulty), 111 "extraData": hexutil.Bytes(head.Extra), 112 "size": hexutil.Uint64(b.Size()), 113 "gasLimit": hexutil.Uint64(head.GasLimit), 114 "gasUsed": hexutil.Uint64(head.GasUsed), 115 "timestamp": hexutil.Uint64(head.Time), 116 "transactionsRoot": head.TxHash, 117 "receiptsRoot": head.ReceiptHash, 118 } 119 120 if inclTx { 121 formatTx := func(tx *types.Transaction) (interface{}, error) { 122 return tx.Hash(), nil 123 } 124 if fullTx { 125 formatTx = func(tx *types.Transaction) (interface{}, error) { 126 return newRPCTransactionFromBlockHash(b, tx.Hash()), nil 127 } 128 } 129 txs := b.Transactions() 130 transactions := make([]interface{}, len(txs)) 131 var err error 132 for i, tx := range txs { 133 if transactions[i], err = formatTx(tx); err != nil { 134 return nil, err 135 } 136 } 137 fields["transactions"] = transactions 138 } 139 140 uncles := b.Uncles() 141 uncleHashes := make([]common.Hash, len(uncles)) 142 for i, uncle := range uncles { 143 uncleHashes[i] = uncle.Hash() 144 } 145 fields["uncles"] = uncleHashes 146 147 return fields, nil 148 }