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  }