github.com/theQRL/go-zond@v0.1.1/cmd/evm/README.md (about)

     1  # EVM tool
     2  
     3  The EVM tool provides a few useful subcommands to facilitate testing at the EVM
     4  layer.
     5  
     6  * transition tool    (`t8n`) : a stateless state transition utility
     7  * transaction tool   (`t9n`) : a transaction validation utility
     8  * block builder tool (`b11r`): a block assembler utility
     9  
    10  ## State transition tool (`t8n`)
    11  
    12  
    13  The `evm t8n` tool is a stateless state transition utility. It is a utility
    14  which can
    15  
    16  1. Take a prestate, including
    17    - Accounts,
    18    - Block context information,
    19    - Previous blockshashes (*optional)
    20  2. Apply a set of transactions,
    21  3. Apply a mining-reward (*optional),
    22  4. And generate a post-state, including
    23    - State root, transaction root, receipt root,
    24    - Information about rejected transactions,
    25    - Optionally: a full or partial post-state dump
    26  
    27  ### Specification
    28  
    29  The idea is to specify the behaviour of this binary very _strict_, so that other
    30  node implementors can build replicas based on their own state-machines, and the
    31  state generators can swap between a \`geth\`-based implementation and a \`parityvm\`-based
    32  implementation.
    33  
    34  #### Command line params
    35  
    36  Command line params that need to be supported are
    37  
    38  ```
    39      --input.alloc value            (default: "alloc.json")
    40      --input.env value              (default: "env.json")
    41      --input.txs value              (default: "txs.json")
    42      --output.alloc value           (default: "alloc.json")
    43      --output.basedir value        
    44      --output.body value           
    45      --output.result value          (default: "result.json")
    46      --state.chainid value          (default: 1)
    47      --state.fork value             (default: "GrayGlacier")
    48      --state.reward value           (default: 0)
    49      --trace.memory                 (default: false)
    50      --trace.nomemory               (default: true)
    51      --trace.noreturndata           (default: true)
    52      --trace.nostack                (default: false)
    53      --trace.returndata             (default: false)
    54  ```
    55  #### Objects
    56  
    57  The transition tool uses JSON objects to read and write data related to the transition operation. The
    58  following object definitions are required.
    59  
    60  ##### `alloc`
    61  
    62  The `alloc` object defines the prestate that transition will begin with.
    63  
    64  ```go
    65  // Map of address to account definition.
    66  type Alloc map[common.Address]Account
    67  // Genesis account. Each field is optional.
    68  type Account struct {
    69      Code       []byte                           `json:"code"`
    70      Storage    map[common.Hash]common.Hash      `json:"storage"`
    71      Balance    *big.Int                         `json:"balance"`
    72      Nonce      uint64                           `json:"nonce"`
    73      SecretKey  []byte                            `json:"secretKey"`
    74  }
    75  ```
    76  
    77  ##### `env`
    78  
    79  The `env` object defines the environmental context in which the transition will
    80  take place.
    81  
    82  ```go
    83  type Env struct {
    84      // required
    85      CurrentCoinbase  common.Address      `json:"currentCoinbase"`
    86      CurrentGasLimit  uint64              `json:"currentGasLimit"`
    87      CurrentNumber    uint64              `json:"currentNumber"`
    88      CurrentTimestamp uint64              `json:"currentTimestamp"`
    89      Withdrawals      []*Withdrawal       `json:"withdrawals"`
    90      // optional
    91      CurrentDifficulty *big.Int           `json:"currentDifficuly"`
    92      CurrentRandom     *big.Int           `json:"currentRandom"`
    93      CurrentBaseFee    *big.Int           `json:"currentBaseFee"`
    94      ParentDifficulty  *big.Int           `json:"parentDifficulty"`
    95      ParentGasUsed     uint64             `json:"parentGasUsed"`
    96      ParentGasLimit    uint64             `json:"parentGasLimit"`
    97      ParentTimestamp   uint64             `json:"parentTimestamp"`
    98      BlockHashes       map[uint64]common.Hash `json:"blockHashes"`
    99      ParentUncleHash   common.Hash        `json:"parentUncleHash"`
   100      Ommers            []Ommer            `json:"ommers"`
   101  }
   102  type Ommer struct {
   103      Delta   uint64         `json:"delta"`
   104      Address common.Address `json:"address"`
   105  }
   106  type Withdrawal struct {
   107      Index          uint64         `json:"index"`
   108      ValidatorIndex uint64         `json:"validatorIndex"`
   109      Recipient      common.Address `json:"recipient"`
   110      Amount         *big.Int       `json:"amount"`
   111  }
   112  ```
   113  
   114  ##### `txs`
   115  
   116  The `txs` object is an array of any of the transaction types: `LegacyTx`,
   117  `AccessListTx`, or `DynamicFeeTx`.
   118  
   119  ```go
   120  type LegacyTx struct {
   121  	Nonce     uint64          `json:"nonce"`
   122  	GasPrice  *big.Int        `json:"gasPrice"`
   123  	Gas       uint64          `json:"gas"`
   124  	To        *common.Address `json:"to"`
   125  	Value     *big.Int        `json:"value"`
   126  	Data      []byte          `json:"data"`
   127  	V         *big.Int        `json:"v"`
   128  	R         *big.Int        `json:"r"`
   129  	S         *big.Int        `json:"s"`
   130      SecretKey *common.Hash    `json:"secretKey"`
   131  }
   132  type AccessList []AccessTuple
   133  type AccessTuple struct {
   134  	Address     common.Address `json:"address"        gencodec:"required"`
   135  	StorageKeys []common.Hash  `json:"storageKeys"    gencodec:"required"`
   136  }
   137  type AccessListTx struct {
   138  	ChainID    *big.Int        `json:"chainId"`
   139  	Nonce      uint64          `json:"nonce"`
   140  	GasPrice   *big.Int        `json:"gasPrice"`
   141  	Gas        uint64          `json:"gas"`
   142  	To         *common.Address `json:"to"`
   143  	Value      *big.Int        `json:"value"`
   144  	Data       []byte          `json:"data"`
   145  	AccessList AccessList      `json:"accessList"`
   146  	V          *big.Int        `json:"v"`
   147  	R          *big.Int        `json:"r"`
   148  	S          *big.Int        `json:"s"`
   149      SecretKey  *common.Hash     `json:"secretKey"`
   150  }
   151  type DynamicFeeTx struct {
   152  	ChainID    *big.Int        `json:"chainId"`
   153  	Nonce      uint64          `json:"nonce"`
   154  	GasTipCap  *big.Int        `json:"maxPriorityFeePerGas"`
   155  	GasFeeCap  *big.Int        `json:"maxFeePerGas"`
   156  	Gas        uint64          `json:"gas"`
   157  	To         *common.Address `json:"to"`
   158  	Value      *big.Int        `json:"value"`
   159  	Data       []byte          `json:"data"`
   160  	AccessList AccessList      `json:"accessList"`
   161  	V          *big.Int        `json:"v"`
   162  	R          *big.Int        `json:"r"`
   163  	S          *big.Int        `json:"s"`
   164      SecretKey  *common.Hash     `json:"secretKey"`
   165  }
   166  ```
   167  
   168  ##### `result`
   169  
   170  The `result` object is output after a transition is executed. It includes
   171  information about the post-transition environment.
   172  
   173  ```go
   174  type ExecutionResult struct {
   175      StateRoot   common.Hash    `json:"stateRoot"`
   176      TxRoot      common.Hash    `json:"txRoot"`
   177      ReceiptRoot common.Hash    `json:"receiptsRoot"`
   178      LogsHash    common.Hash    `json:"logsHash"`
   179      Bloom       types.Bloom    `json:"logsBloom"`
   180      Receipts    types.Receipts `json:"receipts"`
   181      Rejected    []*rejectedTx  `json:"rejected,omitempty"`
   182      Difficulty  *big.Int       `json:"currentDifficulty"`
   183      GasUsed     uint64         `json:"gasUsed"`
   184      BaseFee     *big.Int       `json:"currentBaseFee,omitempty"`
   185  }
   186  ```
   187  
   188  #### Error codes and output
   189  
   190  All logging should happen against the `stderr`.
   191  There are a few (not many) errors that can occur, those are defined below.
   192  
   193  ##### EVM-based errors (`2` to `9`)
   194  
   195  - Other EVM error. Exit code `2`
   196  - Failed configuration: when a non-supported or invalid fork was specified. Exit code `3`.
   197  - Block history is not supplied, but needed for a `BLOCKHASH` operation. If `BLOCKHASH`
   198    is invoked targeting a block which history has not been provided for, the program will
   199    exit with code `4`.
   200  
   201  ##### IO errors (`10`-`20`)
   202  
   203  - Invalid input json: the supplied data could not be marshalled.
   204    The program will exit with code `10`
   205  - IO problems: failure to load or save files, the program will exit with code `11`
   206  
   207  ```
   208  # This should exit with 3
   209  ./evm t8n --input.alloc=./testdata/1/alloc.json --input.txs=./testdata/1/txs.json --input.env=./testdata/1/env.json --state.fork=Frontier+1346 2>/dev/null
   210  exitcode:3 OK
   211  ```
   212  #### Forks
   213  ### Basic usage
   214  
   215  The chain configuration to be used for a transition is specified via the
   216  `--state.fork` CLI flag. A list of possible values and configurations can be
   217  found in [`tests/init.go`](tests/init.go).
   218  
   219  #### Examples
   220  ##### Basic usage
   221  
   222  Invoking it with the provided example files
   223  ```
   224  ./evm t8n --input.alloc=./testdata/1/alloc.json --input.txs=./testdata/1/txs.json --input.env=./testdata/1/env.json --state.fork=Berlin
   225  ```
   226  Two resulting files:
   227  
   228  `alloc.json`:
   229  ```json
   230  {
   231   "0x8a8eafb1cf62bfbeb1741769dae1a9dd47996192": {
   232    "balance": "0xfeed1a9d",
   233    "nonce": "0x1"
   234   },
   235   "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
   236    "balance": "0x5ffd4878be161d74",
   237    "nonce": "0xac"
   238   },
   239   "0xc94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
   240    "balance": "0xa410"
   241   }
   242  }
   243  ```
   244  `result.json`:
   245  ```json
   246  {
   247   "stateRoot": "0x84208a19bc2b46ada7445180c1db162be5b39b9abc8c0a54b05d32943eae4e13",
   248   "txRoot": "0xc4761fd7b87ff2364c7c60b6c5c8d02e522e815328aaea3f20e3b7b7ef52c42d",
   249   "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2",
   250   "logsHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
   251   "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
   252   "receipts": [
   253    {
   254     "root": "0x",
   255     "status": "0x1",
   256     "cumulativeGasUsed": "0x5208",
   257     "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
   258     "logs": null,
   259     "transactionHash": "0x0557bacce3375c98d806609b8d5043072f0b6a8bae45ae5a67a00d3a1a18d673",
   260     "contractAddress": "0x0000000000000000000000000000000000000000",
   261     "gasUsed": "0x5208",
   262     "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
   263     "transactionIndex": "0x0"
   264    }
   265   ],
   266   "rejected": [
   267    {
   268     "index": 1,
   269     "error": "nonce too low: address 0x8A8eAFb1cf62BfBeb1741769DAE1a9dd47996192, tx: 0 state: 1"
   270    }
   271   ],
   272   "currentDifficulty": "0x20000",
   273   "gasUsed": "0x5208"
   274  }
   275  ```
   276  
   277  We can make them spit out the data to e.g. `stdout` like this:
   278  ```
   279  ./evm t8n --input.alloc=./testdata/1/alloc.json --input.txs=./testdata/1/txs.json --input.env=./testdata/1/env.json --output.result=stdout --output.alloc=stdout --state.fork=Berlin
   280  ```
   281  Output:
   282  ```json
   283  {
   284    "alloc": {
   285      "0x8a8eafb1cf62bfbeb1741769dae1a9dd47996192": {
   286        "balance": "0xfeed1a9d",
   287        "nonce": "0x1"
   288      },
   289      "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
   290        "balance": "0x5ffd4878be161d74",
   291        "nonce": "0xac"
   292      },
   293      "0xc94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
   294        "balance": "0xa410"
   295      }
   296    },
   297    "result": {
   298      "stateRoot": "0x84208a19bc2b46ada7445180c1db162be5b39b9abc8c0a54b05d32943eae4e13",
   299      "txRoot": "0xc4761fd7b87ff2364c7c60b6c5c8d02e522e815328aaea3f20e3b7b7ef52c42d",
   300      "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2",
   301      "logsHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
   302      "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
   303      "receipts": [
   304        {
   305          "root": "0x",
   306          "status": "0x1",
   307          "cumulativeGasUsed": "0x5208",
   308          "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
   309          "logs": null,
   310          "transactionHash": "0x0557bacce3375c98d806609b8d5043072f0b6a8bae45ae5a67a00d3a1a18d673",
   311          "contractAddress": "0x0000000000000000000000000000000000000000",
   312          "gasUsed": "0x5208",
   313          "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
   314          "transactionIndex": "0x0"
   315        }
   316      ],
   317      "rejected": [
   318        {
   319          "index": 1,
   320          "error": "nonce too low: address 0x8A8eAFb1cf62BfBeb1741769DAE1a9dd47996192, tx: 0 state: 1"
   321        }
   322      ],
   323      "currentDifficulty": "0x20000",
   324      "gasUsed": "0x5208"
   325    }
   326  }
   327  ```
   328  
   329  #### About Ommers
   330  
   331  Mining rewards and ommer rewards might need to be added. This is how those are applied:
   332  
   333  - `block_reward` is the block mining reward for the miner (`0xaa`), of a block at height `N`.
   334  - For each ommer (mined by `0xbb`), with blocknumber `N-delta`
   335     - (where `delta` is the difference between the current block and the ommer)
   336     - The account `0xbb` (ommer miner) is awarded `(8-delta)/ 8 * block_reward`
   337     - The account `0xaa` (block miner) is awarded `block_reward / 32`
   338  
   339  To make `t8n` apply these, the following inputs are required:
   340  
   341  - `--state.reward`
   342    - For ethash, it is `5000000000000000000` `wei`,
   343    - If this is not defined, mining rewards are not applied,
   344    - A value of `0` is valid, and causes accounts to be 'touched'.
   345  - For each ommer, the tool needs to be given an `address\` and a `delta`. This
   346    is done via the `ommers` field in `env`.
   347  
   348  Note: the tool does not verify that e.g. the normal uncle rules apply,
   349  and allows e.g two uncles at the same height, or the uncle-distance. This means that
   350  the tool allows for negative uncle reward (distance > 8)
   351  
   352  Example:
   353  `./testdata/5/env.json`:
   354  ```json
   355  {
   356    "currentCoinbase": "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
   357    "currentDifficulty": "0x20000",
   358    "currentGasLimit": "0x750a163df65e8a",
   359    "currentNumber": "1",
   360    "currentTimestamp": "1000",
   361    "ommers": [
   362      {"delta":  1, "address": "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" },
   363      {"delta":  2, "address": "0xcccccccccccccccccccccccccccccccccccccccc" }
   364    ]
   365  }
   366  ```
   367  When applying this, using a reward of `0x08`
   368  Output:
   369  ```json
   370  {
   371    "alloc": {
   372      "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa": {
   373        "balance": "0x88"
   374      },
   375      "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb": {
   376        "balance": "0x70"
   377      },
   378      "0xcccccccccccccccccccccccccccccccccccccccc": {
   379        "balance": "0x60"
   380      }
   381    }
   382  }
   383  ```
   384  #### Future EIPS
   385  
   386  It is also possible to experiment with future eips that are not yet defined in a hard fork.
   387  Example, putting EIP-1344 into Frontier: 
   388  ```
   389  ./evm t8n --state.fork=Frontier+1344 --input.pre=./testdata/1/pre.json --input.txs=./testdata/1/txs.json --input.env=/testdata/1/env.json
   390  ```
   391  
   392  #### Block history
   393  
   394  The `BLOCKHASH` opcode requires blockhashes to be provided by the caller, inside the `env`.
   395  If a required blockhash is not provided, the exit code should be `4`:
   396  Example where blockhashes are provided: 
   397  ```
   398  ./evm t8n --input.alloc=./testdata/3/alloc.json --input.txs=./testdata/3/txs.json --input.env=./testdata/3/env.json  --trace --state.fork=Berlin
   399  
   400  ```
   401  
   402  ```
   403  cat trace-0-0x72fadbef39cd251a437eea619cfeda752271a5faaaa2147df012e112159ffb81.jsonl | grep BLOCKHASH -C2
   404  ```
   405  ```
   406  {"pc":0,"op":96,"gas":"0x5f58ef8","gasCost":"0x3","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"PUSH1"}
   407  {"pc":2,"op":64,"gas":"0x5f58ef5","gasCost":"0x14","memSize":0,"stack":["0x1"],"depth":1,"refund":0,"opName":"BLOCKHASH"}
   408  {"pc":3,"op":0,"gas":"0x5f58ee1","gasCost":"0x0","memSize":0,"stack":["0xdac58aa524e50956d0c0bae7f3f8bb9d35381365d07804dd5b48a5a297c06af4"],"depth":1,"refund":0,"opName":"STOP"}
   409  {"output":"","gasUsed":"0x17"}
   410  ```
   411  
   412  In this example, the caller has not provided the required blockhash:
   413  ```
   414  ./evm t8n --input.alloc=./testdata/4/alloc.json --input.txs=./testdata/4/txs.json --input.env=./testdata/4/env.json --trace --state.fork=Berlin
   415  ERROR(4): getHash(3) invoked, blockhash for that block not provided
   416  ```
   417  Error code: 4
   418  
   419  #### Chaining
   420  
   421  Another thing that can be done, is to chain invocations:
   422  ```
   423  ./evm t8n --input.alloc=./testdata/1/alloc.json --input.txs=./testdata/1/txs.json --input.env=./testdata/1/env.json --state.fork=Berlin --output.alloc=stdout | ./evm t8n --input.alloc=stdin --input.env=./testdata/1/env.json --input.txs=./testdata/1/txs.json --state.fork=Berlin
   424  
   425  ```
   426  What happened here, is that we first applied two identical transactions, so the second one was rejected. 
   427  Then, taking the poststate alloc as the input for the next state, we tried again to include
   428  the same two transactions: this time, both failed due to too low nonce.
   429  
   430  In order to meaningfully chain invocations, one would need to provide meaningful new `env`, otherwise the
   431  actual blocknumber (exposed to the EVM) would not increase.
   432  
   433  #### Transactions in RLP form
   434  
   435  It is possible to provide already-signed transactions as input to, using an `input.txs` which ends with the `rlp` suffix.
   436  The input format for RLP-form transactions is _identical_ to the _output_ format for block bodies. Therefore, it's fully possible
   437  to use the evm to go from `json` input to `rlp` input.
   438  
   439  The following command takes **json** the transactions in `./testdata/13/txs.json` and signs them. After execution, they are output to `signed_txs.rlp`.:
   440  ```
   441  ./evm t8n --state.fork=London --input.alloc=./testdata/13/alloc.json --input.txs=./testdata/13/txs.json --input.env=./testdata/13/env.json --output.result=alloc_jsontx.json --output.body=signed_txs.rlp
   442  INFO [12-27|09:25:11.102] Trie dumping started                     root=e4b924..6aef61
   443  INFO [12-27|09:25:11.102] Trie dumping complete                    accounts=3 elapsed="275.66µs"
   444  INFO [12-27|09:25:11.102] Wrote file                               file=alloc.json
   445  INFO [12-27|09:25:11.103] Wrote file                               file=alloc_jsontx.json
   446  INFO [12-27|09:25:11.103] Wrote file                               file=signed_txs.rlp
   447  ```
   448  
   449  The `output.body` is the rlp-list of transactions, encoded in hex and placed in a string a'la `json` encoding rules:
   450  ```
   451  cat signed_txs.rlp
   452  "0xf8d2b86702f864010180820fa08284d09411111111111111111111111111111111111111118080c001a0b7dfab36232379bb3d1497a4f91c1966b1f932eae3ade107bf5d723b9cb474e0a06261c359a10f2132f126d250485b90cf20f30340801244a08ef6142ab33d1904b86702f864010280820fa08284d09411111111111111111111111111111111111111118080c080a0d4ec563b6568cd42d998fc4134b36933c6568d01533b5adf08769270243c6c7fa072bf7c21eac6bbeae5143371eef26d5e279637f3bd73482b55979d76d935b1e9"
   453  ```
   454  
   455  We can use `rlpdump` to check what the contents are: 
   456  ```
   457  rlpdump -hex $(cat signed_txs.rlp | jq -r )
   458  [
   459    02f864010180820fa08284d09411111111111111111111111111111111111111118080c001a0b7dfab36232379bb3d1497a4f91c1966b1f932eae3ade107bf5d723b9cb474e0a06261c359a10f2132f126d250485b90cf20f30340801244a08ef6142ab33d1904,
   460    02f864010280820fa08284d09411111111111111111111111111111111111111118080c080a0d4ec563b6568cd42d998fc4134b36933c6568d01533b5adf08769270243c6c7fa072bf7c21eac6bbeae5143371eef26d5e279637f3bd73482b55979d76d935b1e9,
   461  ]
   462  ```
   463  Now, we can now use those (or any other already signed transactions), as input, like so: 
   464  ```
   465  ./evm t8n --state.fork=London --input.alloc=./testdata/13/alloc.json --input.txs=./signed_txs.rlp --input.env=./testdata/13/env.json --output.result=alloc_rlptx.json
   466  INFO [12-27|09:25:11.187] Trie dumping started                     root=e4b924..6aef61
   467  INFO [12-27|09:25:11.187] Trie dumping complete                    accounts=3 elapsed="123.676µs"
   468  INFO [12-27|09:25:11.187] Wrote file                               file=alloc.json
   469  INFO [12-27|09:25:11.187] Wrote file                               file=alloc_rlptx.json
   470  ```
   471  You might have noticed that the results from these two invocations were stored in two separate files. 
   472  And we can now finally check that they match.
   473  ```
   474  cat alloc_jsontx.json | jq .stateRoot && cat alloc_rlptx.json | jq .stateRoot
   475  "0xe4b924a6adb5959fccf769d5b7bb2f6359e26d1e76a2443c5a91a36d826aef61"
   476  "0xe4b924a6adb5959fccf769d5b7bb2f6359e26d1e76a2443c5a91a36d826aef61"
   477  ```
   478  
   479  ## Transaction tool
   480  
   481  The transaction tool is used to perform static validity checks on transactions such as:
   482  * intrinsic gas calculation
   483  * max values on integers
   484  * fee semantics, such as `maxFeePerGas < maxPriorityFeePerGas`
   485  * newer tx types on old forks
   486  
   487  ### Examples
   488  
   489  ```
   490  ./evm t9n --state.fork Homestead --input.txs testdata/15/signed_txs.rlp
   491  [
   492    {
   493      "error": "transaction type not supported",
   494      "hash": "0xa98a24882ea90916c6a86da650fbc6b14238e46f0af04a131ce92be897507476"
   495    },
   496    {
   497      "error": "transaction type not supported",
   498      "hash": "0x36bad80acce7040c45fd32764b5c2b2d2e6f778669fb41791f73f546d56e739a"
   499    }
   500  ]
   501  ```
   502  ```
   503  ./evm t9n --state.fork London --input.txs testdata/15/signed_txs.rlp
   504  [
   505    {
   506      "address": "0xd02d72e067e77158444ef2020ff2d325f929b363",
   507      "hash": "0xa98a24882ea90916c6a86da650fbc6b14238e46f0af04a131ce92be897507476",
   508      "intrinsicGas": "0x5208"
   509    },
   510    {
   511      "address": "0xd02d72e067e77158444ef2020ff2d325f929b363",
   512      "hash": "0x36bad80acce7040c45fd32764b5c2b2d2e6f778669fb41791f73f546d56e739a",
   513      "intrinsicGas": "0x5208"
   514    }
   515  ]
   516  ```
   517  ## Block builder tool (b11r)
   518  
   519  The `evm b11r` tool is used to assemble and seal full block rlps.
   520  
   521  ### Specification
   522  
   523  #### Command line params
   524  
   525  Command line params that need to be supported are:
   526  
   527  ```
   528      --input.header value        `stdin` or file name of where to find the block header to use. (default: "header.json")
   529      --input.ommers value        `stdin` or file name of where to find the list of ommer header RLPs to use.
   530      --input.txs value           `stdin` or file name of where to find the transactions list in RLP form. (default: "txs.rlp")
   531      --output.basedir value      Specifies where output files are placed. Will be created if it does not exist.
   532      --output.block value        Determines where to put the alloc of the post-state. (default: "block.json")
   533                                  <file> - into the file <file>
   534                                  `stdout` - into the stdout output
   535                                  `stderr` - into the stderr output
   536      --seal.clique value         Seal block with Clique. `stdin` or file name of where to find the Clique sealing data.
   537      --seal.ethash               Seal block with ethash. (default: false)
   538      --seal.ethash.dir value     Path to ethash DAG. If none exists, a new DAG will be generated.
   539      --seal.ethash.mode value    Defines the type and amount of PoW verification an ethash engine makes. (default: "normal")
   540      --verbosity value           Sets the verbosity level. (default: 3)
   541  ```
   542  
   543  #### Objects
   544  
   545  ##### `header`
   546  
   547  The `header` object is a consensus header.
   548  
   549  ```go=
   550  type Header struct {
   551          ParentHash  common.Hash       `json:"parentHash"`
   552          OmmerHash   *common.Hash      `json:"sha3Uncles"`
   553          Coinbase    *common.Address   `json:"miner"`
   554          Root        common.Hash       `json:"stateRoot"         gencodec:"required"`
   555          TxHash      *common.Hash      `json:"transactionsRoot"`
   556          ReceiptHash *common.Hash      `json:"receiptsRoot"`
   557          Bloom       types.Bloom       `json:"logsBloom"`
   558          Difficulty  *big.Int          `json:"difficulty"`
   559          Number      *big.Int          `json:"number"            gencodec:"required"`
   560          GasLimit    uint64            `json:"gasLimit"          gencodec:"required"`
   561          GasUsed     uint64            `json:"gasUsed"`
   562          Time        uint64            `json:"timestamp"         gencodec:"required"`
   563          Extra       []byte            `json:"extraData"`
   564          MixDigest   common.Hash       `json:"mixHash"`
   565          Nonce       *types.BlockNonce `json:"nonce"`
   566          BaseFee     *big.Int          `json:"baseFeePerGas"`
   567  }
   568  ```
   569  #### `ommers`
   570  
   571  The `ommers` object is a list of RLP-encoded ommer blocks in hex
   572  representation.
   573  
   574  ```go=
   575  type Ommers []string
   576  ```
   577  
   578  #### `txs`
   579  
   580  The `txs` object is a list of RLP-encoded transactions in hex representation.
   581  
   582  ```go=
   583  type Txs []string
   584  ```
   585  
   586  #### `clique`
   587  
   588  The `clique` object provides the necessary information to complete a clique
   589  seal of the block.
   590  
   591  ```go=
   592  var CliqueInfo struct {
   593          Key       *common.Hash    `json:"secretKey"`
   594          Voted     *common.Address `json:"voted"`
   595          Authorize *bool           `json:"authorize"`
   596          Vanity    common.Hash     `json:"vanity"`
   597  }
   598  ```
   599  
   600  #### `output`
   601  
   602  The `output` object contains two values, the block RLP and the block hash.
   603  
   604  ```go=
   605  type BlockInfo struct {
   606      Rlp  []byte      `json:"rlp"`
   607      Hash common.Hash `json:"hash"`
   608  }
   609  ```
   610  
   611  ## A Note on Encoding
   612  
   613  The encoding of values for `evm` utility attempts to be relatively flexible. It
   614  generally supports hex-encoded or decimal-encoded numeric values, and
   615  hex-encoded byte values (like `common.Address`, `common.Hash`, etc). When in
   616  doubt, the [`execution-apis`](https://github.com/ethereum/execution-apis) way
   617  of encoding should always be accepted.
   618  
   619  ## Testing
   620  
   621  There are many test cases in the [`cmd/evm/testdata`](./testdata) directory.
   622  These fixtures are used to power the `t8n` tests in
   623  [`t8n_test.go`](./t8n_test.go). The best way to verify correctness of new `evm`
   624  implementations is to execute these and verify the output and error codes match
   625  the expected values.
   626