github.com/jimmyx0x/go-ethereum@v1.10.28/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 `addres\` 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 neccesary 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