forked from mirror/go-ethereum
cmd/evm: transaction validation tool (#23494)
* cmd/evm: transaction validation tool * cmd/evm: add hash to t9n tool * cmd/evm: lint nits * cmd/evm: nitpicksverkle/onleaf
parent
578bc8164d
commit
babe9b993e
@ -0,0 +1,136 @@ |
||||
// Copyright 2021 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 t8ntool |
||||
|
||||
import ( |
||||
"encoding/json" |
||||
"errors" |
||||
"fmt" |
||||
"math/big" |
||||
"os" |
||||
"strings" |
||||
|
||||
"github.com/ethereum/go-ethereum/common" |
||||
"github.com/ethereum/go-ethereum/common/hexutil" |
||||
"github.com/ethereum/go-ethereum/core/types" |
||||
"github.com/ethereum/go-ethereum/log" |
||||
"github.com/ethereum/go-ethereum/params" |
||||
"github.com/ethereum/go-ethereum/rlp" |
||||
"github.com/ethereum/go-ethereum/tests" |
||||
"gopkg.in/urfave/cli.v1" |
||||
) |
||||
|
||||
type result struct { |
||||
Error error |
||||
Address common.Address |
||||
Hash common.Hash |
||||
} |
||||
|
||||
// MarshalJSON marshals as JSON with a hash.
|
||||
func (r *result) MarshalJSON() ([]byte, error) { |
||||
type xx struct { |
||||
Error string `json:"error,omitempty"` |
||||
Address *common.Address `json:"address,omitempty"` |
||||
Hash *common.Hash `json:"hash,omitempty"` |
||||
} |
||||
var out xx |
||||
if r.Error != nil { |
||||
out.Error = r.Error.Error() |
||||
} |
||||
if r.Address != (common.Address{}) { |
||||
out.Address = &r.Address |
||||
} |
||||
if r.Hash != (common.Hash{}) { |
||||
out.Hash = &r.Hash |
||||
} |
||||
return json.Marshal(out) |
||||
} |
||||
|
||||
func Transaction(ctx *cli.Context) error { |
||||
// Configure the go-ethereum logger
|
||||
glogger := log.NewGlogHandler(log.StreamHandler(os.Stderr, log.TerminalFormat(false))) |
||||
glogger.Verbosity(log.Lvl(ctx.Int(VerbosityFlag.Name))) |
||||
log.Root().SetHandler(glogger) |
||||
|
||||
var ( |
||||
err error |
||||
) |
||||
// We need to load the transactions. May be either in stdin input or in files.
|
||||
// Check if anything needs to be read from stdin
|
||||
var ( |
||||
txStr = ctx.String(InputTxsFlag.Name) |
||||
inputData = &input{} |
||||
chainConfig *params.ChainConfig |
||||
) |
||||
// Construct the chainconfig
|
||||
if cConf, _, err := tests.GetChainConfig(ctx.String(ForknameFlag.Name)); err != nil { |
||||
return NewError(ErrorVMConfig, fmt.Errorf("failed constructing chain configuration: %v", err)) |
||||
} else { |
||||
chainConfig = cConf |
||||
} |
||||
// Set the chain id
|
||||
chainConfig.ChainID = big.NewInt(ctx.Int64(ChainIDFlag.Name)) |
||||
var body hexutil.Bytes |
||||
if txStr == stdinSelector { |
||||
decoder := json.NewDecoder(os.Stdin) |
||||
if err := decoder.Decode(inputData); err != nil { |
||||
return NewError(ErrorJson, fmt.Errorf("failed unmarshaling stdin: %v", err)) |
||||
} |
||||
// Decode the body of already signed transactions
|
||||
body = common.FromHex(inputData.TxRlp) |
||||
} else { |
||||
// Read input from file
|
||||
inFile, err := os.Open(txStr) |
||||
if err != nil { |
||||
return NewError(ErrorIO, fmt.Errorf("failed reading txs file: %v", err)) |
||||
} |
||||
defer inFile.Close() |
||||
decoder := json.NewDecoder(inFile) |
||||
if strings.HasSuffix(txStr, ".rlp") { |
||||
if err := decoder.Decode(&body); err != nil { |
||||
return err |
||||
} |
||||
} else { |
||||
return NewError(ErrorIO, errors.New("only rlp supported")) |
||||
} |
||||
} |
||||
signer := types.MakeSigner(chainConfig, new(big.Int)) |
||||
// We now have the transactions in 'body', which is supposed to be an
|
||||
// rlp list of transactions
|
||||
it, err := rlp.NewListIterator([]byte(body)) |
||||
if err != nil { |
||||
return err |
||||
} |
||||
var results []result |
||||
for it.Next() { |
||||
var tx types.Transaction |
||||
err := rlp.DecodeBytes(it.Value(), &tx) |
||||
if err != nil { |
||||
results = append(results, result{Error: err}) |
||||
continue |
||||
} |
||||
sender, err := types.Sender(signer, &tx) |
||||
if err != nil { |
||||
results = append(results, result{Error: err}) |
||||
continue |
||||
} |
||||
results = append(results, result{Address: sender, Hash: tx.Hash()}) |
||||
} |
||||
out, err := json.MarshalIndent(results, "", " ") |
||||
fmt.Println(string(out)) |
||||
return err |
||||
} |
@ -0,0 +1 @@ |
||||
"0xf901f0a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000940000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007b0101020383010203a00000000000000000000000000000000000000000000000000000000000000000880000000000000000" |
@ -0,0 +1,8 @@ |
||||
[ |
||||
{ |
||||
"error": "transaction type not supported" |
||||
}, |
||||
{ |
||||
"error": "transaction type not supported" |
||||
} |
||||
] |
@ -0,0 +1,10 @@ |
||||
[ |
||||
{ |
||||
"address": "0xd02d72e067e77158444ef2020ff2d325f929b363", |
||||
"hash": "0xa98a24882ea90916c6a86da650fbc6b14238e46f0af04a131ce92be897507476" |
||||
}, |
||||
{ |
||||
"address": "0xd02d72e067e77158444ef2020ff2d325f929b363", |
||||
"hash": "0x36bad80acce7040c45fd32764b5c2b2d2e6f778669fb41791f73f546d56e739a" |
||||
} |
||||
] |
@ -0,0 +1,47 @@ |
||||
[ |
||||
{ |
||||
"error": "transaction type not supported" |
||||
}, |
||||
{ |
||||
"error": "transaction type not supported" |
||||
}, |
||||
{ |
||||
"error": "transaction type not supported" |
||||
}, |
||||
{ |
||||
"error": "transaction type not supported" |
||||
}, |
||||
{ |
||||
"error": "transaction type not supported" |
||||
}, |
||||
{ |
||||
"error": "transaction type not supported" |
||||
}, |
||||
{ |
||||
"error": "transaction type not supported" |
||||
}, |
||||
{ |
||||
"error": "rlp: expected List" |
||||
}, |
||||
{ |
||||
"error": "rlp: expected List" |
||||
}, |
||||
{ |
||||
"error": "rlp: expected List" |
||||
}, |
||||
{ |
||||
"error": "rlp: expected List" |
||||
}, |
||||
{ |
||||
"error": "rlp: expected List" |
||||
}, |
||||
{ |
||||
"error": "rlp: expected input list for types.AccessListTx" |
||||
}, |
||||
{ |
||||
"error": "transaction type not supported" |
||||
}, |
||||
{ |
||||
"error": "transaction type not supported" |
||||
} |
||||
] |
@ -0,0 +1 @@ |
||||
"0xf8d2b86702f864010180820fa08284d09411111111111111111111111111111111111111118080c001a0b7dfab36232379bb3d1497a4f91c1966b1f932eae3ade107bf5d723b9cb474e0a06261c359a10f2132f126d250485b90cf20f30340801244a08ef6142ab33d1904b86702f864010280820fa08284d09411111111111111111111111111111111111111118080c080a0d4ec563b6568cd42d998fc4134b36933c6568d01533b5adf08769270243c6c7fa072bf7c21eac6bbeae5143371eef26d5e279637f3bd73482b55979d76d935b1e9" |
Loading…
Reference in new issue