aboutsummaryrefslogblamecommitdiffstats
path: root/cmd/geth/retesteth_copypaste.go
blob: e2795af7f968fc23c9c7c526a98685ace3ea8559 (plain) (tree)



















































































































































                                                                                                                         
// Copyright 2019 The go-ethereum Authors
// This file is part of go-ethereum.
//
// go-ethereum is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// go-ethereum is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.

package main

import (
    "math/big"

    "github.com/ethereum/go-ethereum/common"
    "github.com/ethereum/go-ethereum/common/hexutil"
    "github.com/ethereum/go-ethereum/core/types"
)

// RPCTransaction represents a transaction that will serialize to the RPC representation of a transaction
type RPCTransaction struct {
    BlockHash        common.Hash     `json:"blockHash"`
    BlockNumber      *hexutil.Big    `json:"blockNumber"`
    From             common.Address  `json:"from"`
    Gas              hexutil.Uint64  `json:"gas"`
    GasPrice         *hexutil.Big    `json:"gasPrice"`
    Hash             common.Hash     `json:"hash"`
    Input            hexutil.Bytes   `json:"input"`
    Nonce            hexutil.Uint64  `json:"nonce"`
    To               *common.Address `json:"to"`
    TransactionIndex hexutil.Uint    `json:"transactionIndex"`
    Value            *hexutil.Big    `json:"value"`
    V                *hexutil.Big    `json:"v"`
    R                *hexutil.Big    `json:"r"`
    S                *hexutil.Big    `json:"s"`
}

// newRPCTransaction returns a transaction that will serialize to the RPC
// representation, with the given location metadata set (if available).
func newRPCTransaction(tx *types.Transaction, blockHash common.Hash, blockNumber uint64, index uint64) *RPCTransaction {
    var signer types.Signer = types.FrontierSigner{}
    if tx.Protected() {
        signer = types.NewEIP155Signer(tx.ChainId())
    }
    from, _ := types.Sender(signer, tx)
    v, r, s := tx.RawSignatureValues()

    result := &RPCTransaction{
        From:     from,
        Gas:      hexutil.Uint64(tx.Gas()),
        GasPrice: (*hexutil.Big)(tx.GasPrice()),
        Hash:     tx.Hash(),
        Input:    hexutil.Bytes(tx.Data()),
        Nonce:    hexutil.Uint64(tx.Nonce()),
        To:       tx.To(),
        Value:    (*hexutil.Big)(tx.Value()),
        V:        (*hexutil.Big)(v),
        R:        (*hexutil.Big)(r),
        S:        (*hexutil.Big)(s),
    }
    if blockHash != (common.Hash{}) {
        result.BlockHash = blockHash
        result.BlockNumber = (*hexutil.Big)(new(big.Int).SetUint64(blockNumber))
        result.TransactionIndex = hexutil.Uint(index)
    }
    return result
}

// newRPCTransactionFromBlockIndex returns a transaction that will serialize to the RPC representation.
func newRPCTransactionFromBlockIndex(b *types.Block, index uint64) *RPCTransaction {
    txs := b.Transactions()
    if index >= uint64(len(txs)) {
        return nil
    }
    return newRPCTransaction(txs[index], b.Hash(), b.NumberU64(), index)
}

// newRPCTransactionFromBlockHash returns a transaction that will serialize to the RPC representation.
func newRPCTransactionFromBlockHash(b *types.Block, hash common.Hash) *RPCTransaction {
    for idx, tx := range b.Transactions() {
        if tx.Hash() == hash {
            return newRPCTransactionFromBlockIndex(b, uint64(idx))
        }
    }
    return nil
}

// RPCMarshalBlock converts the given block to the RPC output which depends on fullTx. If inclTx is true transactions are
// returned. When fullTx is true the returned block contains full transaction details, otherwise it will only contain
// transaction hashes.
func RPCMarshalBlock(b *types.Block, inclTx bool, fullTx bool) (map[string]interface{}, error) {
    head := b.Header() // copies the header once
    fields := map[string]interface{}{
        "number":           (*hexutil.Big)(head.Number),
        "hash":             b.Hash(),
        "parentHash":       head.ParentHash,
        "nonce":            head.Nonce,
        "mixHash":          head.MixDigest,
        "sha3Uncles":       head.UncleHash,
        "logsBloom":        head.Bloom,
        "stateRoot":        head.Root,
        "miner":            head.Coinbase,
        "difficulty":       (*hexutil.Big)(head.Difficulty),
        "extraData":        hexutil.Bytes(head.Extra),
        "size":             hexutil.Uint64(b.Size()),
        "gasLimit":         hexutil.Uint64(head.GasLimit),
        "gasUsed":          hexutil.Uint64(head.GasUsed),
        "timestamp":        hexutil.Uint64(head.Time),
        "transactionsRoot": head.TxHash,
        "receiptsRoot":     head.ReceiptHash,
    }

    if inclTx {
        formatTx := func(tx *types.Transaction) (interface{}, error) {
            return tx.Hash(), nil
        }
        if fullTx {
            formatTx = func(tx *types.Transaction) (interface{}, error) {
                return newRPCTransactionFromBlockHash(b, tx.Hash()), nil
            }
        }
        txs := b.Transactions()
        transactions := make([]interface{}, len(txs))
        var err error
        for i, tx := range txs {
            if transactions[i], err = formatTx(tx); err != nil {
                return nil, err
            }
        }
        fields["transactions"] = transactions
    }

    uncles := b.Uncles()
    uncleHashes := make([]common.Hash, len(uncles))
    for i, uncle := range uncles {
        uncleHashes[i] = uncle.Hash()
    }
    fields["uncles"] = uncleHashes

    return fields, nil
}