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

     1  # ZVM tool
     2  
     3  The ZVM tool provides a few useful subcommands to facilitate testing at the ZVM
     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 `zvm 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.reward value           (default: 0)
    48      --state.fork value             (default: "Shanghai")
    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      Seed    []byte                      `json:"seed"`
    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      CurrentRandom     *big.Int           `json:"currentRandom"`
    92      CurrentBaseFee    *big.Int           `json:"currentBaseFee"`
    93      ParentGasUsed     uint64             `json:"parentGasUsed"`
    94      ParentGasLimit    uint64             `json:"parentGasLimit"`
    95      ParentTimestamp   uint64             `json:"parentTimestamp"`
    96      BlockHashes       map[uint64]common.Hash `json:"blockHashes"`
    97  }
    98  type Withdrawal struct {
    99      Index          uint64         `json:"index"`
   100      ValidatorIndex uint64         `json:"validatorIndex"`
   101      Recipient      common.Address `json:"recipient"`
   102      Amount         *big.Int       `json:"amount"`
   103  }
   104  ```
   105  
   106  ##### `txs`
   107  
   108  The `txs` object is an array of any of the transaction types: `DynamicFeeTx`.
   109  
   110  ```go
   111  type AccessList []AccessTuple
   112  type AccessTuple struct {
   113  	Address     common.Address `json:"address"        gencodec:"required"`
   114  	StorageKeys []common.Hash  `json:"storageKeys"    gencodec:"required"`
   115  }
   116  type DynamicFeeTx struct {
   117  	ChainID    *big.Int        `json:"chainId"`
   118  	Nonce      uint64          `json:"nonce"`
   119  	GasTipCap  *big.Int        `json:"maxPriorityFeePerGas"`
   120  	GasFeeCap  *big.Int        `json:"maxFeePerGas"`
   121  	Gas        uint64          `json:"gas"`
   122  	To         *common.Address `json:"to"`
   123  	Value      *big.Int        `json:"value"`
   124  	Data       []byte          `json:"data"`
   125  	AccessList AccessList      `json:"accessList"`
   126  	PublicKey  *big.Int        `json:"publicKey"`
   127  	Signature  *big.Int        `json:"signature"`
   128    Seed       *common.Hash    `json:"seed"`
   129  }
   130  ```
   131  
   132  ##### `result`
   133  
   134  The `result` object is output after a transition is executed. It includes
   135  information about the post-transition environment.
   136  
   137  ```go
   138  type ExecutionResult struct {
   139      StateRoot   common.Hash    `json:"stateRoot"`
   140      TxRoot      common.Hash    `json:"txRoot"`
   141      ReceiptRoot common.Hash    `json:"receiptsRoot"`
   142      LogsHash    common.Hash    `json:"logsHash"`
   143      Bloom       types.Bloom    `json:"logsBloom"`
   144      Receipts    types.Receipts `json:"receipts"`
   145      Rejected    []*rejectedTx  `json:"rejected,omitempty"`
   146      GasUsed     uint64         `json:"gasUsed"`
   147      BaseFee     *big.Int       `json:"currentBaseFee,omitempty"`
   148  }
   149  ```
   150  
   151  #### Error codes and output
   152  
   153  All logging should happen against the `stderr`.
   154  There are a few (not many) errors that can occur, those are defined below.
   155  
   156  ##### ZVM-based errors (`2` to `9`)
   157  
   158  - Other ZVM error. Exit code `2`
   159  - Failed configuration: when a non-supported or invalid fork was specified. Exit code `3`.
   160  - Block history is not supplied, but needed for a `BLOCKHASH` operation. If `BLOCKHASH`
   161    is invoked targeting a block which history has not been provided for, the program will
   162    exit with code `4`.
   163  
   164  ##### IO errors (`10`-`20`)
   165  
   166  - Invalid input json: the supplied data could not be marshalled.
   167    The program will exit with code `10`
   168  - IO problems: failure to load or save files, the program will exit with code `11`
   169  
   170  ```
   171  # This should exit with 3
   172  ./zvm t8n --input.alloc=./testdata/1/alloc.json --input.txs=./testdata/1/txs.json --input.env=./testdata/1/env.json --state.fork=Shanghai 2>/dev/null
   173  exitcode:3 OK
   174  ```
   175  #### Forks
   176  ### Basic usage
   177  
   178  The chain configuration to be used for a transition is specified via the
   179  `--state.fork` CLI flag. A list of possible values and configurations can be
   180  found in [`tests/init.go`](tests/init.go).
   181  
   182  #### Examples
   183  ##### Basic usage
   184  
   185  Invoking it with the provided example files
   186  ```
   187  ./zvm t8n --input.alloc=./testdata/1/alloc.json --input.txs=./testdata/1/txs.json --input.env=./testdata/1/env.json --state.fork=Shanghai
   188  ```
   189  Two resulting files:
   190  
   191  `alloc.json`:
   192  ```json
   193  {
   194    "Z20687fa825ab4ad40a89c303f22f65fef9778555": {
   195      "balance": "0xebd44d22b000",
   196      "nonce": "0x1"
   197    },
   198    "Za94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
   199      "balance": "0x5ffd4878be161d74",
   200      "nonce": "0xac"
   201    }
   202  }
   203  ```
   204  `result.json`:
   205  ```json
   206  {
   207    "stateRoot": "0x9ea46a9c1f83e9309b94788db918c497b966bcd64a7bc1e1353411b90f21da90",
   208    "txRoot": "0xb59ce316b58ffc4c817b5765f6b3bc830c950c1bdce9dcd2898eb9bbc1c8de23",
   209    "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa",
   210    "logsHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
   211    "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
   212    "receipts": [
   213      {
   214        "type": "0x2",
   215        "root": "0x",
   216        "status": "0x1",
   217        "cumulativeGasUsed": "0x5208",
   218        "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
   219        "logs": null,
   220        "transactionHash": "0x6973b7b3c04e2bd83821853ea3022a57604d903dd644f4a6289555a8c886c21d",
   221        "contractAddress": "Z0000000000000000000000000000000000000000",
   222        "gasUsed": "0x5208",
   223        "effectiveGasPrice": null,
   224        "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
   225        "transactionIndex": "0x0"
   226      }
   227    ],
   228    "rejected": [
   229      {
   230        "index": 1,
   231        "error": "nonce too low: address Z20687Fa825ab4AD40A89C303F22F65FEf9778555, tx: 0 state: 1"
   232      }
   233    ],
   234    "gasUsed": "0x5208",
   235    "currentBaseFee": "0x3b9aca00",
   236    "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
   237  }
   238  ```
   239  
   240  We can make them spit out the data to e.g. `stdout` like this:
   241  ```
   242  ./zvm 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=Shanghai
   243  ```
   244  Output:
   245  ```json
   246  {
   247    "alloc": {
   248      "Z8a8eafb1cf62bfbeb1741769dae1a9dd47996192": {
   249        "balance": "0xfeed1a9d",
   250        "nonce": "0x1"
   251      },
   252      "Za94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
   253        "balance": "0x5ffd4878be161d74",
   254        "nonce": "0xac"
   255      },
   256      "Zc94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
   257        "balance": "0xa410"
   258      }
   259    },
   260    "result": {
   261      "stateRoot": "0x84208a19bc2b46ada7445180c1db162be5b39b9abc8c0a54b05d32943eae4e13",
   262      "txRoot": "0xc4761fd7b87ff2364c7c60b6c5c8d02e522e815328aaea3f20e3b7b7ef52c42d",
   263      "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2",
   264      "logsHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
   265      "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
   266      "receipts": [
   267        {
   268          "root": "0x",
   269          "status": "0x1",
   270          "cumulativeGasUsed": "0x5208",
   271          "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
   272          "logs": null,
   273          "transactionHash": "0x0557bacce3375c98d806609b8d5043072f0b6a8bae45ae5a67a00d3a1a18d673",
   274          "contractAddress": "Z0000000000000000000000000000000000000000",
   275          "gasUsed": "0x5208",
   276          "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
   277          "transactionIndex": "0x0"
   278        }
   279      ],
   280      "rejected": [
   281        {
   282          "index": 1,
   283          "error": "nonce too low: address Z8A8eAFb1cf62BfBeb1741769DAE1a9dd47996192, tx: 0 state: 1"
   284        }
   285      ],
   286      "gasUsed": "0x5208"
   287    }
   288  }
   289  ```
   290  
   291  #### Future EIPS
   292  
   293  It is also possible to experiment with future eips that are not yet defined in a hard fork.
   294  Example, putting EIP-1344 into Shanghai: 
   295  ```
   296  ./zvm t8n --state.fork=Shanghai+1344 --input.pre=./testdata/1/pre.json --input.txs=./testdata/1/txs.json --input.env=/testdata/1/env.json
   297  ```
   298  
   299  #### Block history
   300  
   301  The `BLOCKHASH` opcode requires blockhashes to be provided by the caller, inside the `env`.
   302  If a required blockhash is not provided, the exit code should be `4`:
   303  Example where blockhashes are provided: 
   304  ```
   305  ./zvm t8n --input.alloc=./testdata/3/alloc.json --input.txs=./testdata/3/txs.json --input.env=./testdata/3/env.json  --trace --state.fork=Shanghai
   306  
   307  ```
   308  
   309  ```
   310  cat trace-0-0x72fadbef39cd251a437eea619cfeda752271a5faaaa2147df012e112159ffb81.jsonl | grep BLOCKHASH -C2
   311  ```
   312  ```
   313  {"pc":0,"op":96,"gas":"0x5f58ef8","gasCost":"0x3","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"PUSH1"}
   314  {"pc":2,"op":64,"gas":"0x5f58ef5","gasCost":"0x14","memSize":0,"stack":["0x1"],"depth":1,"refund":0,"opName":"BLOCKHASH"}
   315  {"pc":3,"op":0,"gas":"0x5f58ee1","gasCost":"0x0","memSize":0,"stack":["0xdac58aa524e50956d0c0bae7f3f8bb9d35381365d07804dd5b48a5a297c06af4"],"depth":1,"refund":0,"opName":"STOP"}
   316  {"output":"","gasUsed":"0x17"}
   317  ```
   318  
   319  In this example, the caller has not provided the required blockhash:
   320  ```
   321  ./zvm t8n --input.alloc=./testdata/4/alloc.json --input.txs=./testdata/4/txs.json --input.env=./testdata/4/env.json --trace --state.fork=Shanghai
   322  ERROR(4): getHash(3) invoked, blockhash for that block not provided
   323  ```
   324  Error code: 4
   325  
   326  #### Chaining
   327  
   328  Another thing that can be done, is to chain invocations:
   329  ```
   330  ./zvm t8n --input.alloc=./testdata/1/alloc.json --input.txs=./testdata/1/txs.json --input.env=./testdata/1/env.json --state.fork=Shanghai --output.alloc=stdout | ./zvm t8n --input.alloc=stdin --input.env=./testdata/1/env.json --input.txs=./testdata/1/txs.json --state.fork=Shanghai
   331  
   332  ```
   333  What happened here, is that we first applied two identical transactions, so the second one was rejected. 
   334  Then, taking the poststate alloc as the input for the next state, we tried again to include
   335  the same two transactions: this time, both failed due to too low nonce.
   336  
   337  In order to meaningfully chain invocations, one would need to provide meaningful new `env`, otherwise the
   338  actual blocknumber (exposed to the ZVM) would not increase.
   339  
   340  #### Transactions in RLP form
   341  
   342  It is possible to provide already-signed transactions as input to, using an `input.txs` which ends with the `rlp` suffix.
   343  The input format for RLP-form transactions is _identical_ to the _output_ format for block bodies. Therefore, it's fully possible
   344  to use the zvm to go from `json` input to `rlp` input.
   345  
   346  The following command takes **json** the transactions in `./testdata/13/txs.json` and signs them. After execution, they are output to `signed_txs.rlp`.:
   347  ```
   348  ./zvm t8n --state.fork=Shanghai --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
   349  INFO [08-29|20:19:29.728] Trie dumping started                     root=7fe86c..0f502d
   350  INFO [08-29|20:19:29.728] Trie dumping complete                    accounts=3 elapsed="149.584µs"
   351  INFO [08-29|20:19:29.729] Wrote file                               file=alloc.json
   352  INFO [08-29|20:19:29.730] Wrote file                               file=alloc_jsontx.json
   353  INFO [08-29|20:19:29.730] Wrote file                               file=signed_txs.rlp
   354  ```
   355  
   356  The `output.body` is the rlp-list of transactions, encoded in hex and placed in a string a'la `json` encoding rules:
   357  ```
   358  cat signed_txs.rlp
   359  "0xf93882b91c3e02f91c3a010180820fa08284d09411111111111111111111111111111111111111118080c0b90a20021550bd5da1c85fd90968e44f4cee7610bc421bf058a2ee8aa7dbf95a226f66377ceb9f37d72e591a27b13697087bf897cd59175144bdae11281122dfe91238f3a0ec80f6956899ab553d8fb42de20ca5dc2f5811f4d523553d278cdc4da920a00dcab2420e01166812b3b8794e2b8c1b5271da32d65291263128954e5fc5fc860bec6e47f7b208149be4e3a279d7088f7ce9381c0df75f2f34663ea4cb1aa74fba31f0532416209784ca2a49d0b065276684abe5b5758d8bcad0193f0dfec19b0874b50a0e4972da7c0b0ccc45c2540b80366f5ea2421df88a62b25301e522ef3502de513420b0315d244ff02ef01ee3514022375b18b94c3e4d382ba30ad06633ab5b470ee6ffe90d9129033b439e8a58ffdad4b2e0f858624e54c0aa1245b68dc770da4fb0bac22fd10f1f769b420fb50ff0eaedf88892c279e64aa8485fe304404af905eeae30fee055047591f57b5e047ae4eca27fa46f9c4d88abd639ffa0ae1d19901f234eef0e18468bc5a7a5be73e59b0cc500fdb75821d6773ce72d72abc2ea09ae01a3b808c81e5543b6fcad0ec73cb7dd381af06f84b9a4f81678b76220ced8d541fb52b538dbef798ae9dba4f35e2986e43c4ebd29495d5a4e36a589f95757273829c8012d550e2e17f7295b77aa004175e8bd63c48db5c865a5f36b905e7e536bfc50c281a41e7806dd19a3b8408e5900ac94ae75811099d70c6f80d0866e7f66c476b3ad67463ea2927140ce0cfeeeac4d3931459695bcc44e432b42a08fe34d35e21c4ed5a095e6cdf03a1b9fcb84b4f59501d729b131027719f65956c298fe44181dad4b12098b9e46b22d2955da315cd99b1e584ef16daca7a126f92a2a3044643c80e42763296739c8f44f22ebb5d865f87c7252f49c65ee503300eee88d68280fe027b1f32b9ee7e4e271c323f9c1f8a3c5d1c6d27db8790f44013b23639c8652d415497bbe17be802d9354c7c37a2f89a07b26e7c3c1e9701e257439eb7f5805d42ded3d1e9ce7093ce50b5f85431be25952abbbe983b3f5fc0f0e0d3d186762975217ecddfa1bde013aef25066647b024b20f96764d023d4c2ecbd6f4b60a5ec5cdb9ea06cbb46e5e1689c676ac07b032f575beebd64f6cbb848aff61cc3d31f5738dd84147f068ae490abde41e6abb6bb78f8a69e9a2764445b283daf8f470ece266945ed0e6e6b04db956048b89fbf991314d0bcb759b7320286bbce6b1463f30ef1fce7620aca10ed6613ba122da09af632a7a7026f0976d761f0e4af730071621c5fc4b6acb7a62c2b65c185abe8f049c860ad44b1f5bad540108c880581622e8580615b2890195b534be3d17885662a6174b75d337a009886e877631c617c4387739bf6c43418cc6ec3c8f64cb6ae91d51c9e11fcaa824ba8d9ebacef6afd707d3955377ed00e4f439fbdf4c07ec4cc159fc0edb7b323d232a184a1fff7d6715cd9593b77fcf96cbdacc58e2a0773475ec9525dd1718e4ccea94533e2ababd85118ab559934bfa67c696d97a46a20b4c655b217485445d739582601890014db304bed45f3fc4134c910b348631cbee4f62d0e569026c5a9a728bb0643797834276e365da7c14a72ca6fcec957df46c48c9fa9990be1f6121986c086b29cc361bed01f778a839ef04edf4fe70461b4eb638ad7a1939d21f41ad38d9b72bfdc9178447f23bfa2b9ae23eacd7d9a43f6ab52229ec15103bc03403e01276cddaf8b8974dfb8cd8835d21725fe3551988a9c368bba3940c6f933baa1c22267c35a4e8fc1f5b700c35971c2f29bf414667601cbbe3117e9f9d7a92e1c18d6720c30b51d66ac993e5b9705481e07b95c1a6a773f30900e5895553283fc2847fd884e778275671b4f31182d1e760dd0b71eabda035263b0719f4772fdd049cf7b17675059166d0f3b46336a5596a3e57d8f5c19fd622b1ea1ca7133fbb2ee2ad538c8b8ca6ec134ef78a00a7e42acef7fc0f64fa0f06a28b25729da0df3afdecd066e498ea20ba8a6f8e60c593ce696965af9cb0f6a40226fd6dd666de5d1331eebf741b45bc1c3c3ecd1214a6eca53431b07f908d7f4887a267eff2bb8725d6507bc6f539fd7d75479ec4bf651dd1cb84a896ebc96ecd10f827e0cfcdb1e4281d61a8a5c63469f437f3526c738c84ba71d63551615f741c9b25a33e171d000439594a9120abdad066d11663db1c654f57270e32e71b6c8841dbe60de9d2cbdba6166ef3e197a238a4af64ccd1c54328255a142d9b25d78c28534d1272cd1d23666550eed8ea4b3595dc31b31ac1681fe42914ca9f521836ca94695acb3d062a825266325cfa7bb496a7be2593a1d2c0c9a4cc00e8c9ee6b39ef3c4fbb51cc5cd7f187af76e29ddcf63f101bedc29309b593ac2e609565cdf0d5caea8fe8b473f808b07b9e5ee9bdc0c6bdce761688f4ba714318dfe7f82b4cac83e8db0cd87f4ff1051d5d04dda764409a38060af43190e3b0b6f0263a96c311a57d520af6d0a6afefa5fcd891951aa746072b8890c8bd483e660572b286fdcabd198b2eb0b7e24542496b2a90eb4bee3a2c74937573346fd12615c23364a546405d948f45f43f205bfcf56d3becf65209d194516768d56ab343eafcad2c7eaa4ea7ef55bfbcccd06577c4e269bd6e16758e075828596682edde62a93093437649b19d7ee025974044857e93e98551df75c03c05d6189c1b47e56c5e5767e45276791a35564685b61e2b80e46be0e3bd4beafa2ddb76228d938d1e177cab32a74c46abdefa2d075190b910032d615bcf3e1e4af0a36007880c6522231f5006e234afd7d69e59be87b8849842ee239f9d2c3de2dab648b0b6b5f3e996a1b98dffc19fe16819d5121df6af74a72f664f2ef4b4fcf10db17baf7ca8061ebdd9ba0d2d20da90b8f70c885f40421f5049fc7521abf5051ed7a30d4bf3716172f47b9b878a200ec929a5403c9d28b9d427236499151eda02f5a7cf53837f522a8fe2990b55f8d8343ffb50cfc3b7ad5ac1417135fa77434074cc607bf017ed485bd91e034b42d114346cce75ea05f542ee1f211f19829b227968f652e484ea4b1c0348771505cd4fa95d4f60bf6ac5df9833c6236661277de0b7db6c788235a8c6afeb3d76a514db70e1c6e0c51a53952c662310a11f6463b9263d92f7df817a41108a3130795944b5b009b7f2c87f878aba6f295423a3600f809a3e71517ca301815f7f25f46144ab9a3a03c1438388d4a9d589a1ad715aa1a59d0335c6045e683ff99a076c45d1a4fa4d3525d3e777ac5cd0307aa11848434dc383984502aaa2f25b865a6619fea11ff1ff8a6f8a7f2eaceda2b74c0458bd883f4cb9a1c1e9eadc27f52b6c5236391616898e245bf663128018b8fd58ed8914210f80169c65e9199c424405cbe9a4db846039f54b4ca9c759f4503f1482bf399db074258586896ffe18dd4c398205858047c8ba8a09808ec28a64f1844aa6d18377a9ab5c7e28d90a7298a71c228b1206cc75a110c7f2a24f305b0a93bd1a8e3f67a1879a31f96f7618e8f1d5dbd4ae09b5dd2540edbf49a833b2d0542c9235c6724e7f525ec6d1850a22fe9aaa76415618f7f334184e74077ae974bf58bc2d6fc706b9b8ac2554785f051e0b73025a5f9b511ebd131f1dd7cde4e7250551e1398a784e76b911f368ec98e2957798eaa7f69645d31e5c3759f32449382ebbe646252479674210a49ea8de4b7cb5f77c09826242680145463e7a863d2bf7677888d4a4ff42c4107355fe5e7b724eb3c60dda3d121b4d0f247716aab01e7f1c5143bb76391cf1a9bbe0c32af64341f58edcfd5ec79bfa414c6fbd91dcca9d26f28df8321c3f6eb7697a7845f02175dcac13252a0710f0d103c146171e6f884942464165dfb0af9508358a17027a3b4dc467365a3b22cff91e30e53453f855211c7e8e410b0eca8b9fde76c040e309d888c1f6fc2d17c74dd4af80bf382b290a1d6b9b74329f9fc2d0f2ba241771e748cc2c7915a27e9e6eacacd46b3c3451bd64db750268d2ae700aa723461daec35790c4981c79a5d03c90cd8d3b6dfea8381209b871e87bcb586a97094b4ac7d027b3286b4639a5c0495b246f03d1948e5ebb414a6172f34188f94432db03d24d1ce1e30ab55df478f8081bd8a1f5f33766aeb8e5267ffebbf04b3ceba8fc6cc2a1e2b1309eff7bb674b769ca917af38e39e1099f52580eba7b20ca2d0f0dee798d3f94b935db8c1fbc3202f521d0c6f4ffc947fe3f35701533dbd9ce411899120107581c28547e4a18c94d219661d53e98f5064d52ec25cce8697ffe81fb11bc47d8844e78bba7e555889cc85e91c43433c618ac61c94f0a31e3fde9fc9dd40907397625584a8c893bff68a88e7c9d339cfe587fa206defaf41ea36b30ce2b72a743abb11a30031d5d2a14c529603fbd107f7f38df7b85d986e0052161730b08833988c6aa6c298417cd7f1c0f3c949801e72b917514129ebf6f31be8db7f774cda2eb62ab0efe63223136ef09249191c13830d7becae21334807f60421204b57a86a9d74e2f2adeacd6708be6c01d8babdd36273773224a1529217a78213e0c55ebfdea8b94dd72744bdc011030299f527cf3c4c0708d30e47e7558fc325fb53be7bc68311a3bc2f1bb12a8b33a1be66c46dac8eec57bca949f0d3dcb0926c3c405ffdf3e34caf9e6869bb99d4031cac4a322ceb1c4ba3157bfdf83f23d02c063f20f2e1d2a3049a305713de5b66dfce1edf13e3c2875d174d84b79b911ae85c3092664ff30c1998a5f762934d0a7d6d5da287c43d45f3f11be5b0276338ce3ca1c8adc1bd0d03d8dda6ace92435a7d80007624607594b270df9e71029a9fefb3eee82ce02c8050c379f9f38d85e6c80e444eb66d0574e469740df32cbe457bd8c35de69ba814814365a5d36d1df54434691338ca38c479d41b3f5992fb7d8b157aa2479327f0cfcffd255b567a2b6e258b53aff88926c93c558d0ea4409c74a3474bed6a5bf17d53f0f621091829e156c7a5cd1becaff40cfceb5f3fd0536b029bcac72154f09109fcdb8b5d50cc72a94d8ae300593251a7b8211479b6bd159e9fc6e7d4b8ebd465463a268439b27081fbfdb35e65653f26a79f2f501ba8cf13fc7c468bde6061aaf74d256254eaae7f7cd87b9204bcf6ff5e2ffb70deecf4720dfbc25823e3d6071ba0f7635ba263d1e7e50612bd71994224bfcde53322732ded88c1651651e57f8d7813f80838e294b6012ed966111461c95989a666a556170715976c3992a534a14fc6da63c04308ec26333899e3c873e2d47c56ba1c3d2e75ef84048e900dcfff7a4ea345fa774e48cca0ee3e807f72c87eb3abd48d9031e8f854ead5c3f78db4dd58507e8f01c698441a9c3c16c8b676b2cca57080eeeafd658615898eaa3b2269975f3f49a31131ff570cb97023c4afb5e9752267d753cab0114fd5fff028fa64f224a268b8ede7bff87e8c50fc47371ef232dad71cff8079e57fc14cbec6dc4804543e2e7c55e2132108fa753f1e7004e3348cd50421696a97df016db010713bcc02996b67d8c312d3af4f60e7602e78ba0cca615e9098c6d7a49c7658bc2ecdb791419fb3b3f5869604522b51b3f23ef4ddea8be8e4a5c7e5ac608bf998abdecdd6f3999d92b5a727c07d2ca36421cc66e952aab1e1d25c3bfc8984ca80ad8b72123563f7dcb0f90f9f0d2c7c186546c303f73c51e56d812ec52535b503803e88ce52f6a01f759110719c8c43dd48e532b93ac78112711335b82a422f9dd271ce3350b21e5e16c941b19d40703002ab4a3e2f53c2d1ba1012f6f75692ea509c2d4e00a9145b7cf042c7d7690866b7ea748573d7cda65d3623a7430102d2218d54f0ff6e029f0c66a676ad79092bd10df8c35e1617fd893a9ddd030968fd885db6e24084159eaffd1321a3f7c3ed4d92aa9c0cf17d468ae1d752ed8b054dd45d7c7a18fe839d155c5ad3f61bebb0bebdb6bfda27e96858e47c7d7b4097cb41e5cf6dce1b91f39dcc439f84d10cf2d4cac34c5e85be25369357fca6adac9df86d06444c66389a3f9ab54cb60cd56352f95bdcd4a8ae2ac5448dc6e6a84fa1ef9044347222858daf50a19541a7c078dd86735fa9053400dd915021f2709bb5774a6dc66f1864f96d04cca568de871cc0142346b91fb2a653e9181c3f530cf2f53930683d455ac45d16024ed461627bb8d75d4c90d450f54afc34c175cfcc073fa16a2969c6cf46338176f9d71b0a199e60a5c6956873cfb64c4e571ece362c3631c74a6bf6d480c6976565dc4a9fb125d384b60df4b3000652acb34773a28c5375186e5be24a81c84750dd4f4d80feda72d1a71c4d1d167fff92db3908fb0a9c3064fd536524a0f65d3ab7def1b803c3bee7c022113027d67e24a0c9c3e659b02c440525d12bad5e60148f228f00ab294cc50b18dd5a7ce14122242f3f51916a1dc19c7567350c18e775c8903471982c91bfffe121bcf09dd1583ef13e51bca2e3e87d797b0a5c55983cc89cd20c90a985c7fae5c172e353d93b6f65ad4781c5f69aea9b297bdc7e7c548ebb53debff7b4db8fc16950b4138a83d523f7a555c93a15cde2336ebf89cdf832d3db310a22658833de78d296ed73468b65d47da5fc13ceed0004736d052e5212dfb2bcfe8a8509b3034dadaafa69d50232baec13da64f950a7d9f546d926d9b641e365c14ed1107f459b9b917187b74f9d127b073df289091b43ee12282474960d41b378ba6cfcdcb910dce99b9c156e919cb62678a2e32933f9498f6915ae8abf34e307d69b55ad6d6e2be791e26408010650c3a02f2bc9355ccbbd5fbfa841c42aa05fd30f39beb8415de4c5e3c48b40570fc33651b092bea3bc987ad9af1b78c789c04815ef2065ecea60900df8ef920e5f94d5ac2a65e6cf871c12d04ebce12a324b77416f844f4b5ccfda8739773601b1f233c3cdb9e67dc8166925387eabcdfa49179753cc1cf59fe690525d008a2f5ee793c231d558d0bf34e1984876be96296ce9ae6dd1663c8901889ba42dce2acffff30aee4d8f7989d6c3925039b088afe21e3d2f71f01f7802ecde32416eed1f8eb362fc3f732850364c222fc6b87d4919015b708b166bb09f7cb8e215ad7360008563704675a4e225d4d635e8a01bb5df202221ca0ae3555a930e7a308e218a7b9b3b9d409bba3036bb2d393ba97f0da1fb00f0ecc4c31587c8327cc43c7e8417f324d9708e2b88f3555b81a15b886ffa7f31d8caee9d9d852f681ad2c3b548df6738e0f64cf52ddcac6d9b72767992b67a6e4c33cfc1130470d46b44867a7fe735308342d57c12f9af1ab0698a862a24330c718ae25bed3b463820a7a05b4c76a5904fe978092d005fe6deab58c95ba1fc328da952285558b7243aeb456e9e62368188f6d05bd9eba56c2e6d42a969016779d5919acf9e447896d18f0983dfb665f02273cb1166979a2b24f50d3e7c6fbc3585b5ad93b6a0ba7beeed4634ee9682a164fc929116cd73413d9b4845511d0e8d6874560378fd019b5870acab52776c3fba7297eebfa91c5bd62fbf5d85d52711aff3053f5872b2b6fabed71e89a98acbc3904c463185d8e863082a52546a30bd011c07110056d5a57301cf0a880783a262e0f81a53464b9428b58c3980641dc4b97cdfca44c08110cd92813a097a59f618b53709528ae650d9a872bbadc8ad95e9beef3fd306189cccbdf13afd74690a144507ffeea8f14df56d819cb9bf0f9e362f33f2cb19f94d62a290c04e6184edfacf532ec3685c365d60ad005131fc903fd3979eb77a17bc3fec39707db0f2d09cec5a5d10bac327072309b2973869f5ec77cc423a74f454a0188ddbcfd464e64b9c84164f5ecd46f9d622268b59cc62c113a37007cb0b33947161ed2e0ca6177c83c1c4d9f3f5cca599da708b48cebd5b40b2e8e034836ff6df78ed990110674d875872b71311ad6f1a7149d7846a48c50c1b991049a4593be11e36b98fbc64b0b265c729df2b7e7b216d19d5cb9d51c152c4ae34c361035736d6844a730057839fc7ff36c15055d458c68109b11c9d2b2da25c2083fd2113d2e4e2a73068abe35f9dfcaef4f65a3d6590d952ef103ff6dd0ebc390d2ee8084701da864e983423f530d9909a17cbe20f55f099d131632de79dd921c3dc23a66dc892728e682d7c28bb0a230dbce3adb858aa951fd76e78a911ba7d0113b2bc0f6d016d44e6f360b585165096cb55397ff14f2f529a9f1a421bd361e9b40644139d7dc5598b98485d6b33f7af96ba06855809ca1d6b9266e82d98e4c9df54936912fe2dd5196fdc8169ea6f4f14151dd23d05a095a1b4bcaec15ba702a63e9051402bce30940b56341c8bcda4973040cb092bc7abc2c1de58e2a9045e37af92d61dccd7eea69c0739250834f3c38326b7cc74609d49b67555eee22f091275a8ea414412f37ec8dea207e9a026ff5f5933496e438d47d006d75be0b32354b2c8bb2752771bd14327d2ecc162f555875f850a9e02714f955c4fcbd66d418d868b6b59cc10dc7103d08b2f49d553551668cb6f0ed6dfd9efa33f00b414940cf57f8ef650c8a2d495874d99f55b3fae157791a3d230e688334e68b2fc42fe982c658878fb52ca5dfa257f285fd3d364d2ec856c199cbb8313ce7cf1c216b3008139fe46d2b86076dd7556db86ce557446f0c7d58d23c5ac7130ddf60bc7a24392c0d809c0c80849d3b431baea1f5a21ca2f830814386d4b41953c8a4afbedbd5482f26be59cdd7f78ff5fcdb514391d4750dbdd0cfe5176296d0013e9cbab1223ca3e0ef32b01bf3c5de9bd24936b4dceeb93db49826fb7a1f4459f39e9cb6cf2ea944235fd0b0f672c4a93a47021b316476151bdfcbb803b0b9a691ecfb8cd12e776c180da81f7c458b209ba4a5b5975e15e090609bad891259451d58555b058595436745dc57d5e0122b4c5f3f4d33d9a03c86d7a5f8b70941433f738a67d64017a31c20ace68df5ffb73091e7369a6a6a19159b333f026bf8bcee4cf1752398ffa82d9e0d094c39067cbe36d158df066624efd4eaf5e2f32dff274948a8e299a0cfe7ab1c01cf614d0ed896064a3b445d76eb3c933aadb1726ec36b249f7e48636012057430749ec2ffec4ba9ef44fd118fc57af4bf83f0be36bba3a48c89f92f7046f670944d1251337e68a2c8ba090439f145ca296a5f686bbc420652debb1ec6648f806ab6c1ebb0b6c104d1e264c6f9dddfadb21281e2e72e170407429d43a2ef7a4a4706b5a73d9459afb7a3ad31a9a71bfe109a43e59d701e138c911f469f983ccca2553a8a1d542491fb5e6e5bce65e15cf7b815481617d3740152772128c38c64c5af759756d92515c2d3f59bb5640ec6aa5f0f3bebc630eb9c511c9f03e8074886b083dbb8ea0e97317e6e7d94f247dd1aa356f32e32c76bfa4fb26b8a79ac59eced85058235d404e6419a48d3bdb52c47542ab1e11a53ca2e3a1bbaaf7a840ba8862d83ae0d45a7185738c4c6832782eb2ea78165b3be9e42212f5329a7bab8c05cab8521ba1a20c0c6310c11a90f163a041e9f84cc0e6387b5e08758af87ac5ac3cb13551cd0fc4e5645fac788262bfc6930422cd05b0d5c70bd496645a169ce2a8b26bb858321cf62896f843b40e612d44704571e41394661b7a6c770c4d1ea789252db7bdf191416c851159b2793810b3965fefb1655ae2371dda7ea72c584fc271dcf303b32cb4ba27aa4622bce16f43fbb4591d263651c8fb4ca7d172c96ee54260866bf292fa8f07b85844e1b2eb1dad43bb1b1acbbfd72097ecef3c4b9834fb3b4a1bd6b571496297e61bf5743a05fa68715466346812089104c534ae35b3c9d017334eb9e02caa4cd88b07811e036febecb4ec2f2bd4926e2a1da77da07970eb90d626c683a37fb11f2d51ffe5ddc712ca6cc17b7acd487b0bbbd0988df903ac33a77a8a5e6747eab48c9dd524a6ce32843df76491cc837fd2a55ba188b8b720daf317fc44c8c5005bc75c39090f55b5268a7ba93486241a3b9ee001dcdf206519e38166b0383156da9db6b9c198a6dd515c7ec3078fb1b5e22a67cdcfd6e00e6a707592a12f64d009384e080c0e2477b0d6db0000000000000000000000000000000000000000000000000000000000000000000000000003070c12181b1e26b91c3e02f91c3a010280820fa08284d09411111111111111111111111111111111111111118080c0b90a20021550bd5da1c85fd90968e44f4cee7610bc421bf058a2ee8aa7dbf95a226f66377ceb9f37d72e591a27b13697087bf897cd59175144bdae11281122dfe91238f3a0ec80f6956899ab553d8fb42de20ca5dc2f5811f4d523553d278cdc4da920a00dcab2420e01166812b3b8794e2b8c1b5271da32d65291263128954e5fc5fc860bec6e47f7b208149be4e3a279d7088f7ce9381c0df75f2f34663ea4cb1aa74fba31f0532416209784ca2a49d0b065276684abe5b5758d8bcad0193f0dfec19b0874b50a0e4972da7c0b0ccc45c2540b80366f5ea2421df88a62b25301e522ef3502de513420b0315d244ff02ef01ee3514022375b18b94c3e4d382ba30ad06633ab5b470ee6ffe90d9129033b439e8a58ffdad4b2e0f858624e54c0aa1245b68dc770da4fb0bac22fd10f1f769b420fb50ff0eaedf88892c279e64aa8485fe304404af905eeae30fee055047591f57b5e047ae4eca27fa46f9c4d88abd639ffa0ae1d19901f234eef0e18468bc5a7a5be73e59b0cc500fdb75821d6773ce72d72abc2ea09ae01a3b808c81e5543b6fcad0ec73cb7dd381af06f84b9a4f81678b76220ced8d541fb52b538dbef798ae9dba4f35e2986e43c4ebd29495d5a4e36a589f95757273829c8012d550e2e17f7295b77aa004175e8bd63c48db5c865a5f36b905e7e536bfc50c281a41e7806dd19a3b8408e5900ac94ae75811099d70c6f80d0866e7f66c476b3ad67463ea2927140ce0cfeeeac4d3931459695bcc44e432b42a08fe34d35e21c4ed5a095e6cdf03a1b9fcb84b4f59501d729b131027719f65956c298fe44181dad4b12098b9e46b22d2955da315cd99b1e584ef16daca7a126f92a2a3044643c80e42763296739c8f44f22ebb5d865f87c7252f49c65ee503300eee88d68280fe027b1f32b9ee7e4e271c323f9c1f8a3c5d1c6d27db8790f44013b23639c8652d415497bbe17be802d9354c7c37a2f89a07b26e7c3c1e9701e257439eb7f5805d42ded3d1e9ce7093ce50b5f85431be25952abbbe983b3f5fc0f0e0d3d186762975217ecddfa1bde013aef25066647b024b20f96764d023d4c2ecbd6f4b60a5ec5cdb9ea06cbb46e5e1689c676ac07b032f575beebd64f6cbb848aff61cc3d31f5738dd84147f068ae490abde41e6abb6bb78f8a69e9a2764445b283daf8f470ece266945ed0e6e6b04db956048b89fbf991314d0bcb759b7320286bbce6b1463f30ef1fce7620aca10ed6613ba122da09af632a7a7026f0976d761f0e4af730071621c5fc4b6acb7a62c2b65c185abe8f049c860ad44b1f5bad540108c880581622e8580615b2890195b534be3d17885662a6174b75d337a009886e877631c617c4387739bf6c43418cc6ec3c8f64cb6ae91d51c9e11fcaa824ba8d9ebacef6afd707d3955377ed00e4f439fbdf4c07ec4cc159fc0edb7b323d232a184a1fff7d6715cd9593b77fcf96cbdacc58e2a0773475ec9525dd1718e4ccea94533e2ababd85118ab559934bfa67c696d97a46a20b4c655b217485445d739582601890014db304bed45f3fc4134c910b348631cbee4f62d0e569026c5a9a728bb0643797834276e365da7c14a72ca6fcec957df46c48c9fa9990be1f6121986c086b29cc361bed01f778a839ef04edf4fe70461b4eb638ad7a1939d21f41ad38d9b72bfdc9178447f23bfa2b9ae23eacd7d9a43f6ab52229ec15103bc03403e01276cddaf8b8974dfb8cd8835d21725fe3551988a9c368bba3940c6f933baa1c22267c35a4e8fc1f5b700c35971c2f29bf414667601cbbe3117e9f9d7a92e1c18d6720c30b51d66ac993e5b9705481e07b95c1a6a773f30900e5895553283fc2847fd884e778275671b4f31182d1e760dd0b71eabda035263b0719f4772fdd049cf7b17675059166d0f3b46336a5596a3e57d8f5c19fd622b1ea1ca7133fbb2ee2ad538c8b8ca6ec134ef78a00a7e42acef7fc0f64fa0f06a28b25729da0df3afdecd066e498ea20ba8a6f8e60c593ce696965af9cb0f6a40226fd6dd666de5d1331eebf741b45bc1c3c3ecd1214a6eca53431b07f908d7f4887a267eff2bb8725d6507bc6f539fd7d75479ec4bf651dd1cb84a896ebc96ecd10f827e0cfcdb1e4281d61a8a5c63469f437f3526c738c84ba71d63551615f741c9b25a33e171d000439594a9120abdad066d11663db1c654f57270e32e71b6c8841dbe60de9d2cbdba6166ef3e197a238a4af64ccd1c54328255a142d9b25d78c28534d1272cd1d23666550eed8ea4b3595dc31b31ac1681fe42914ca9f521836ca94695acb3d062a825266325cfa7bb496a7be2593a1d2c0c9a4cc00e8c9ee6b39ef3c4fbb51cc5cd7f187af76e29ddcf63f101bedc29309b593ac2e609565cdf0d5caea8fe8b473f808b07b9e5ee9bdc0c6bdce761688f4ba714318dfe7f82b4cac83e8db0cd87f4ff1051d5d04dda764409a38060af43190e3b0b6f0263a96c311a57d520af6d0a6afefa5fcd891951aa746072b8890c8bd483e660572b286fdcabd198b2eb0b7e24542496b2a90eb4bee3a2c74937573346fd12615c23364a546405d948f45f43f205bfcf56d3becf65209d194516768d56ab343eafcad2c7eaa4ea7ef55bfbcccd06577c4e269bd6e16758e075828596682edde62a93093437649b19d7ee025974044857e93e98551df75c03c05d6189c1b47e56c5e5767e45276791a35564685b61e2b80e46be0e3bd4beafa2ddb76228d938d1e177cab32a74c46abdefa2d075190b910032d615bcf3e1e4af0a36007880c6522231f5006e234afd7d69e59be87b8849842ee239f9d2c3de2dab648b0b6b5f3e996a1b98dffc19fe16819d5121df6af74a72f664f2ef4b4fcf10db17baf7ca8061ebdd9ba0d2d20da90b8f70c885f40421f5049fc7521abf5051ed7a30d4bf3716172f47b9b878a200ec929a5403c9d28b9d427236499151eda02f5a7cf53837f522a8fe2990b55f8d8343ffb50cfc3b7ad5ac1417135fa77434074cc607bf017ed485bd91e034b42d114346cce75ea05f542ee1f211f19829b227968f652e484ea4b1c0348771505cd4fa95d4f60bf6ac5df9833c6236661277de0b7db6c788235a8c6afeb3d76a514db70e1c6e0c51a53952c662310a11f6463b9263d92f7df817a41108a3130795944b5b009b7f2c87f878aba6f295423a3600f809a3e71517ca301815f7f25f46144ab9a3a03c1438388d4a9d589a1ad715aa1a59d0335c6045e683ff99a076c45d1a4fa4d3525d3e777ac5cd0307aa11848434dc383984502aaa2f25b865a6619fea11ff1ff8a6f8a7f2eaceda2b74c0458bd883f4cb9a1c1e9eadc27f52b6c5236391616898e245bf663128018b8fd58ed8914210f80169c65e9199c424405cbe9a4db846039f54b4ca9c759f4503f1482bf399db074258586896ffe18dd4c398205858047c8ba8a09808ec28a64f1844aa6d18377a9ab5c7e28d90a7298a71c228b1206cc75a110c7f2a24f305b0a93bd1a8e3f67a1879a31f96f7618e8f1d5dbd4ae09b5dd2540edbf49a833b2d0542c9235c6724e7f525ec6d1850a22fe9aaa76415618f7f334184e74077ae974bf58bc2d6fc706b9b8ac2554785f051e0b73025a5f9b511ebd131f1dd7cde4e7250551e1398a784e76b911f33edcdbf73ab1a2db691e86c7481a4e0103beafd927281a6c04794430591a9299c8b9142cd0ba208adf3a5d12730203f6b1e4fc85e03d839f6887638706e5bf8055a83532f57d83a220bb77a26ef2c6a5092299999c9a5c271b3b20c315ed83366a05369fe739d4f8c5b9ec29d3180bab5ad160611dcf8deea6e26979aeccad9cf6bb333001266d17da0dbb11195412c027272e01e51ca59c496637483323f2e41ba180e49c95f559d65c912a9a38663e969d3bd6334b727ffad42aa7190d0de3ca36a48542abce135f904410e91a1fd27062dcf15a71e85a28ede35636ad240831fcc928cc39a49e44913d7bf8eff453febdcfe091f565c086f13f98d977a61f2fdc335bd6a9c469db4992c411a0c198801e319a4962af79fc52c226847a649ad263cb9c553d3896685e0ba60b678f08bed295120083305d4ccca67ab6fc183786805d40b3b598b18fa5fb1becdfbac68e4957ba675c28ce8a08d16f2b1d7064e87230216dbd365f7e1382c758814a99c148db668c7499fbf4e2678239dcbe5d4fd67f6905e204d1cd2956f76af5cdf1224ee44f277bc3c299c48ee40007b17fe1dbfe36dd6abdd3f037f69e8f4f0bab54343e8a473ce4699c5334fbfaf4f551e74f78bfe31868459d56e9817e3d18aa84e417f243834d2de0b9f3b405c318fe0115cfae516c8c868a057488a1728a2517bbc34403fe337d852a13e2a75566c05a16c25b2ee882fa634867733a7567396f497110de035c722dd70861a9b73d2377a5da8e8acffaf02ed8df4f176e25ec1d50df9e6287a8ac915786b65763328634db13182df96944927568a81c1dd7e07ac06a9a16a3f93c2fce6de2967633b3f7876226ee872351d34bf1ed90de053a77a4b3ae154760be9cf730f0713b6a1d796e3fd23e0d45af9a22652df12529bd33974c09c592b3a9d56b5b160c1263f2111de6521869e9f6bb9c5a385135766dc347dbb9acebc69409c3810225c6c0867f071bf5e28afcac349d4f71eacb06e16338ac2eb1b290d6fa9845e67b9cbe2be6828ede10f4584aaf8124f7ea7eb4b23e870141efe3b4fa9ea08d5b2182200770d30451d80f4f30fff1bc533a51a95cf5d3c3a2f2b16cc1cdb840b11a424b7da14eb07a4d9814f18e139133315db389d397870d2294d78450dc52d4f250ef947d70e074b45f1c406b07c6ab089e916f36362814f89e80387bd189afc95f6eb4e6736588e09efc6769a943077b083051fbd82cc875feb705f32471bf3a38cf7f9ba078385ae9faa83daab1689b4a9adb6c26f06b7cf9e5456de303471b72619f77ed29014133fe8ee8649bdd8a9ef5fb4501b8cd3746ea263b7e134ee196ffe3c392f556ebc4e644e62ca354543277dac8c513d89a5a1a50aa1f6b09a88702fb0416f98e3f48acc9332d01671627e879958cd19720b9e9c83d0e0c6be830646454908e3e3e850cee34e3fbf059dc56fae3f2ac57ae3ff3138a23c4303ceea31aba547b427c31fcca077e68761b9aaec1926b8cb56f3060d88a3be593c1d2f3db0cb997f18d85f0e5e506935948c9ee72fd9724097f223dfaac2097636f63130b0e23d5dfe15e972fe6a11e79313b14c40a7ec3ead6fe451e7d0cc98df98c1af0e851239d46e419597781c3c2f807140628dc19d1ca15e9f0ad00e2c1bdf37676b7b0d9a002ed283b62121bdc344a4fdc8606290fbf18f61de5e192d5d86cd348762a8737a0a3f8a5ec72ddd62427ead08d56abb918f6b1924fc788b3cf3c5ac933aade37f4dce5da9874f0c73cd289f2cd9edf33e689826b3370289d97b6122e8663420cbd1457dba431b1f6cde368ae196384b68029f34fce21b09162851f450a555252df74c5a16b5feeb5fcc0087a9d514623582895343c2a9120cf3bc29bd715a27e34808d3a8d04faaa655c4e8f030466eb1bb3eb0cb745342f6197b42f56e231b07ac3ebbaa9f423a3be3d8e0fa7714beaa5ae37da480ebd2ad969671592be38d9685c27736183baa51581265df016786fd69abc1db310ece80a14a1867eb66ee7426e7723aa57c3bd4ffd527873b1930a2809ab115abbc6b7ba2f70578a1ce5c8ffdcd042ee4c08cd9e5226b111e9629de1f52d8ecf6aa19f3cf69b8ae2097534681ec60d441912836403e61a1e0dc542e47356d5e82220f88c0357429673fb8e6a9d4db483c00119a1fd9b55b423b52d9406838d3c2de0a6953510207efc06de95f22cb8fb538eb893a320da0dd59f8742118b3808f97dc2aeb7ddb5e475bf28d3762ea697230e868730afe9ea35d3e004edbbf17dc817e719b13788226e64159845f174a8963e432a9b57dc0ea4c45041767f52d6ae4b38486a355362a6bac98b60464afc1dd106efd117d90e470528fa738fe26cd19fd73ded0f41475499ecb8bc5699d28cd8ae05e9d9b76b44032c91dcfcbfa735aa4c3d2383f5dd5ba11b95df971fad53234661b4a079db741beb291311b5e21f965b44fcc0551cff27e44f76355fe4f4b1621ae0df8015aa81ce64a70e0d6be05dc6bee99bc2e35e50297c7f950a3db998ace193147107aa089082387808c9776353eb89d6ec90d0760bff48a1c645a1e6f2dfb3655f77d5d6b60978dceeed4bf16cbb511831a877ad7884310b97fb632238109b81c70b1de766fc7015c9c7c4ddd2ac593c912ad7acbd23944cb993ecefcb17b09c0b6d08cf207024bc420800950410704e59b486f772495a9970eeca7fb2771063a9e79b7d0e030f4278f9d93be77b618ca49214c16111d1ca783a10e7415e1d4eb684d0f6e48c7f8d8ac02c39f7babedef0d5513608ac17d446a9868c63f1e86b006d4f8bc2dc7ab493768b0101797048de0dbe7185d948a48c4ca87d3025381d579e46ee0fe9d035871ad97bf284b896cf89d040d8d171ebfc7bc752c0ea390b80a1d4d4a8c5dda346651a639bf92f9a022daa2dce0855f68844b54db335012828e2a2916fb2e8292a0cf6723a6411019337ff35c6aea04a5030c112c852e9578130ede02db58151652eda31e1aa2933b147ec1b407f08023c1dde76931d81fbfaab16b5a7bfde09cb9c3cde3e26fd3ae29e21c264229982c17adde651e7af488d93b15ec1466406dad75622daccfc5e67a844d7013bc0ef4908a7b1aedd94099974979eebf5d1f46dc0f54d1cdf917cc9d072a5ddebf7a064c124fadc3b3eeae939988a16ab62b4ef51587562593f4f94f1c3d83873eca4b7eb0658d8c239175bc40fbb9dd4b53b18f2f697f85fefa46b5f031f94a8d4543a19b853d4fdd3d6eb20a4e27f53d765096bc6e8f668236f3f8e5c8ca59182f761ab91e20a37c90fe96a4f6985f0b493abc66c34266832f81a69b3ea07a7e63657105d1b84737ff8eb13c062689821aead5045319f1cca4d31ce52806c8f618efbb663ae113ec9cc4b55ea642b0b5782b98e8d7680f95e5dd02346fbcd42dbdb7555106b743470187233cb00f5e171238fe3692adaf5d313b114bd677e8d2637daf86f484766028b0f4c1b028659364f623f612fb31c3d1a6860e80d981c6c5704ee28fa6f198fa8229f12734a2fdc920ee577f5f910bba90d627eb55bbf6024a5916f4a617cbc166c1b8d11db7dff8cd98a9aa103c94aa735e6eecc639dde0ddd5815c3e2061e232e8ebc5313e17d9ca539198f06cc73a3f3ad270f6c00b22df9ddc5a8052d4435f60b35fa63cbcc85308d8073e32a361ecbaf4f2af3b8032419a7d76a39237f058913475b2cbf761c62c8f01d35bb9aad9d5c5c08c2418b6690ece918a6904bf0cb001913fb2693249a5ffafef8d4951adb292335f56399b4b70f0c452c0b34ac7d59a3e39934bab3232fa56d50ab105a3a69c77240224a376e9df8392677cf6dd6410004a49f85b84289a94ddfb56e0c97994494fe687950cfa3ffa9da62fe47d0ef6aeb1ca143d4c3cd571c166d73d5f8998163f3cbbc6e074f0953929196bb3113ac24c0a7d5f8e2fbd493cad9174d197a8ccc1ae5bb6bddf1647059d43d61454ba6a3556097516e5c86664abf87bd827cc5fe3ae2e42ee22c2df01a1d39daac80e05773a43e39ba753b017614c42a0f863b733de02448833b1e7e05c31cc1448c252b869c442ba8818d16664828a1f606cf6bc39ef72495bbef5e0797a6328c1d63d4f4428f8df5df2aba8ca678cfc5518fb8db88b8ecde7c4b8a5d441a454a369bcbd43fb1aa5922ad02ecf5cc7f5fa94609be554238270cdcf11d39a59c65862acc0cccdb77131a9ad5b7df33db905cb393af6763707404a78e733f2bb13c5e4c9b8c6f11c36e84e0e6cdd6943835124f6cdf2423920a9c91a6941ef0211901f4e09acdf7ad46a5f8c93dda249d699a66dcc70c161b3f3ee78c178831a840af1b39d9d726b99301528abf2df32c51aa021f06332938b0362a1678feeb045291f59c21f6c9a2133e96a6c2190bcdffcc9e21cf75e79fc272a9330c0b530cb8aa8210e9582a19a5b40c89dbe9b603a89c9610088b3e6ea01691112f7a186632522bdc15314f395c89c7ef76518379c55969eee78a06c6ab6685a21f93f3d48c93194107c7751ec49a4dd719b2e24654a7f97ba3be46c64efba4c2f4dfdf7cd29ed828605c6e4b63033936df8b588fffad6aed5573ea55a707cb8b9f0d689eb14232846c8a76d7630d719ca7abc9c6930a8f60ed0a0d33908565a5067c5a437548f86bfc9f830ce46f4b85eaed5ee2cae995b158ef1a2fb6d835f3b516ce77f2ac8ac2802cb10b5c3e7581e45b73582f2f69c065341a01981a0844dc3b19455502e7af0165764dd5f3ce5d65c4fd3cabf76c4e1e6b790b9fd37e654f87947a7c8ce1b1a0ad5d6bd55db16c701b5f9c0b774ca0faa424e25c47fd498ea5be8a65770e0a9793b9cc222cf5e6f1bac5cf63cbec37fd3a5616d0b93e35eed1c668d1b2629f4859ed5cc10e7f55a6ab34c72f229d0bfdb85bc3a619f04b8b31e8435e3b41c0ae31087a1159cbca7189951ca6a954c83aca52d3c9fbda23fd9f42ebc7be0654722075ccd3945cc41a85d2b989000df19f3cc1579069265fea47fd32a149230ccd7fd91cbe39e076e5449187d3e0eeb7465d918b0b110671d24b01514ba327e9ed3e9e7b11217765e37d73e04b369d10a3f05822d9d41897dd8d44463280882e4064d5146c040e2a438e88fdc5ccb1d2f8a7756f3ddc77a3a2a69f8a0581360e057eb2f5977a52e9f8c7767fd0b22922ac07d92c27cfb80e071ef43a8d5d3d10e69f07bfbd2d8997c4022d45cca76c75708ed41946630527670a344a59dfd3da0a2f4bf0d7f8cdcf330cffbd0cd0a13c482cc78570be4c9c9021195b90de3605eadb0f8f991c0973925cefccfdb4bb4e730a1458f5a3df029631a084c77e7691f5ba11a677bc67dc5f2bfe120a1ce6f722a522204a0aa197627d862eed12d39bc0ed54de1589fba8c9f3d48ed85b29535d5f94da19cfcf3786daf8b0d42bbd97b2ec0437ad2cf3edcde0fe7cc8c15124452dbcb215504fa431286d122ef97f462afa226821fddbf98ca23b2225eaeec39e5eb069c3248564ddcb18d6db341c1ba8cac42d3898ca56ce007438d2000cc72ed00f5e97baf3488ddf97d46bc5109935aaa1353a86315cb2d687b9623b8d01b28412f24b70fc891255068f5979ebe10953aca92e348a70149ae4dc2f46301c0dfc505ffbfa04edc73f990b5ffb314414be92336f2b4af65ded4ca7788b8600eeb08b6fcc9717395dc983b1f757295d7f8dde29e5a3b17660a0a3735730777a1a89ddd266058935ceeb2b357a4e2518eb8d35109a4f3f212006190ae76dbfc899a2391895b9d2b9eec275a5f20e6f4fda5dd94a959675f3a5fb36cdbbcf7311fae580a3b2aa6ddf142c99e1786a99d1112d705ab64da20b04668e9115a069e0031e638932f7c607d647ffe816e5f818c89d2f1c88d6cde79855e55622e9d575e659846f7ff2a883503b24a9e3d1816a23a0dc6c7905d2f1bc1298eafafe9063a02f488c0550dbd4dfdbb2ef5e9bb3e561dc72a372b6667175974cc1a4ec36b2e738145886b20254efee4c815faa8948462152ac58d51cf1289b07036b5297116c941c4340c13788a507e27ee3057561edcf670e91ac5e98cb614ab1e9c5873e07e81be1b26e1b7f93fe89e5cf4f99e8f986452039f22ac1c3c27761ca590d8059c814651408a38319a098dd4f8814d33d651331fed41b1118caf8cc817f24bfbd5cfe093e9696cd2c97cf8689b32a1b7a97fddd7a29197d0ebe305b6c2bcd81a58eb4ed3ab6c4f3e2d2a76ba185ee777a8f812af97844276b8e4b951133ca4edc83933e8b0d54ac7f87dea4e99308719b7feab8589ee20d2520bf0b8d6eb031a47c354139ba3694ae0a6a3c5fa71b965ec837049d9f91fc87f6e5719941578cf4394d708386d70877858e9eabc1dee0e72d2f335c5f6e778baccfdaf1f246474d688d9b9eccd41c202b3c49b1bf54a3acb3e0ecf900000000000000000000000000000000000000040a14212a2e3138"
   360  ```
   361  
   362  We can use `rlpdump` to check what the contents are: 
   363  ```
   364  rlpdump -hex $(cat signed_txs.rlp | jq -r )
   365  [
   366    02f91c3a010180820fa08284d09411111111111111111111111111111111111111118080c0b90a20021550bd5da1c85fd90968e44f4cee7610bc421bf058a2ee8aa7dbf95a226f66377ceb9f37d72e591a27b13697087bf897cd59175144bdae11281122dfe91238f3a0ec80f6956899ab553d8fb42de20ca5dc2f5811f4d523553d278cdc4da920a00dcab2420e01166812b3b8794e2b8c1b5271da32d65291263128954e5fc5fc860bec6e47f7b208149be4e3a279d7088f7ce9381c0df75f2f34663ea4cb1aa74fba31f0532416209784ca2a49d0b065276684abe5b5758d8bcad0193f0dfec19b0874b50a0e4972da7c0b0ccc45c2540b80366f5ea2421df88a62b25301e522ef3502de513420b0315d244ff02ef01ee3514022375b18b94c3e4d382ba30ad06633ab5b470ee6ffe90d9129033b439e8a58ffdad4b2e0f858624e54c0aa1245b68dc770da4fb0bac22fd10f1f769b420fb50ff0eaedf88892c279e64aa8485fe304404af905eeae30fee055047591f57b5e047ae4eca27fa46f9c4d88abd639ffa0ae1d19901f234eef0e18468bc5a7a5be73e59b0cc500fdb75821d6773ce72d72abc2ea09ae01a3b808c81e5543b6fcad0ec73cb7dd381af06f84b9a4f81678b76220ced8d541fb52b538dbef798ae9dba4f35e2986e43c4ebd29495d5a4e36a589f95757273829c8012d550e2e17f7295b77aa004175e8bd63c48db5c865a5f36b905e7e536bfc50c281a41e7806dd19a3b8408e5900ac94ae75811099d70c6f80d0866e7f66c476b3ad67463ea2927140ce0cfeeeac4d3931459695bcc44e432b42a08fe34d35e21c4ed5a095e6cdf03a1b9fcb84b4f59501d729b131027719f65956c298fe44181dad4b12098b9e46b22d2955da315cd99b1e584ef16daca7a126f92a2a3044643c80e42763296739c8f44f22ebb5d865f87c7252f49c65ee503300eee88d68280fe027b1f32b9ee7e4e271c323f9c1f8a3c5d1c6d27db8790f44013b23639c8652d415497bbe17be802d9354c7c37a2f89a07b26e7c3c1e9701e257439eb7f5805d42ded3d1e9ce7093ce50b5f85431be25952abbbe983b3f5fc0f0e0d3d186762975217ecddfa1bde013aef25066647b024b20f96764d023d4c2ecbd6f4b60a5ec5cdb9ea06cbb46e5e1689c676ac07b032f575beebd64f6cbb848aff61cc3d31f5738dd84147f068ae490abde41e6abb6bb78f8a69e9a2764445b283daf8f470ece266945ed0e6e6b04db956048b89fbf991314d0bcb759b7320286bbce6b1463f30ef1fce7620aca10ed6613ba122da09af632a7a7026f0976d761f0e4af730071621c5fc4b6acb7a62c2b65c185abe8f049c860ad44b1f5bad540108c880581622e8580615b2890195b534be3d17885662a6174b75d337a009886e877631c617c4387739bf6c43418cc6ec3c8f64cb6ae91d51c9e11fcaa824ba8d9ebacef6afd707d3955377ed00e4f439fbdf4c07ec4cc159fc0edb7b323d232a184a1fff7d6715cd9593b77fcf96cbdacc58e2a0773475ec9525dd1718e4ccea94533e2ababd85118ab559934bfa67c696d97a46a20b4c655b217485445d739582601890014db304bed45f3fc4134c910b348631cbee4f62d0e569026c5a9a728bb0643797834276e365da7c14a72ca6fcec957df46c48c9fa9990be1f6121986c086b29cc361bed01f778a839ef04edf4fe70461b4eb638ad7a1939d21f41ad38d9b72bfdc9178447f23bfa2b9ae23eacd7d9a43f6ab52229ec15103bc03403e01276cddaf8b8974dfb8cd8835d21725fe3551988a9c368bba3940c6f933baa1c22267c35a4e8fc1f5b700c35971c2f29bf414667601cbbe3117e9f9d7a92e1c18d6720c30b51d66ac993e5b9705481e07b95c1a6a773f30900e5895553283fc2847fd884e778275671b4f31182d1e760dd0b71eabda035263b0719f4772fdd049cf7b17675059166d0f3b46336a5596a3e57d8f5c19fd622b1ea1ca7133fbb2ee2ad538c8b8ca6ec134ef78a00a7e42acef7fc0f64fa0f06a28b25729da0df3afdecd066e498ea20ba8a6f8e60c593ce696965af9cb0f6a40226fd6dd666de5d1331eebf741b45bc1c3c3ecd1214a6eca53431b07f908d7f4887a267eff2bb8725d6507bc6f539fd7d75479ec4bf651dd1cb84a896ebc96ecd10f827e0cfcdb1e4281d61a8a5c63469f437f3526c738c84ba71d63551615f741c9b25a33e171d000439594a9120abdad066d11663db1c654f57270e32e71b6c8841dbe60de9d2cbdba6166ef3e197a238a4af64ccd1c54328255a142d9b25d78c28534d1272cd1d23666550eed8ea4b3595dc31b31ac1681fe42914ca9f521836ca94695acb3d062a825266325cfa7bb496a7be2593a1d2c0c9a4cc00e8c9ee6b39ef3c4fbb51cc5cd7f187af76e29ddcf63f101bedc29309b593ac2e609565cdf0d5caea8fe8b473f808b07b9e5ee9bdc0c6bdce761688f4ba714318dfe7f82b4cac83e8db0cd87f4ff1051d5d04dda764409a38060af43190e3b0b6f0263a96c311a57d520af6d0a6afefa5fcd891951aa746072b8890c8bd483e660572b286fdcabd198b2eb0b7e24542496b2a90eb4bee3a2c74937573346fd12615c23364a546405d948f45f43f205bfcf56d3becf65209d194516768d56ab343eafcad2c7eaa4ea7ef55bfbcccd06577c4e269bd6e16758e075828596682edde62a93093437649b19d7ee025974044857e93e98551df75c03c05d6189c1b47e56c5e5767e45276791a35564685b61e2b80e46be0e3bd4beafa2ddb76228d938d1e177cab32a74c46abdefa2d075190b910032d615bcf3e1e4af0a36007880c6522231f5006e234afd7d69e59be87b8849842ee239f9d2c3de2dab648b0b6b5f3e996a1b98dffc19fe16819d5121df6af74a72f664f2ef4b4fcf10db17baf7ca8061ebdd9ba0d2d20da90b8f70c885f40421f5049fc7521abf5051ed7a30d4bf3716172f47b9b878a200ec929a5403c9d28b9d427236499151eda02f5a7cf53837f522a8fe2990b55f8d8343ffb50cfc3b7ad5ac1417135fa77434074cc607bf017ed485bd91e034b42d114346cce75ea05f542ee1f211f19829b227968f652e484ea4b1c0348771505cd4fa95d4f60bf6ac5df9833c6236661277de0b7db6c788235a8c6afeb3d76a514db70e1c6e0c51a53952c662310a11f6463b9263d92f7df817a41108a3130795944b5b009b7f2c87f878aba6f295423a3600f809a3e71517ca301815f7f25f46144ab9a3a03c1438388d4a9d589a1ad715aa1a59d0335c6045e683ff99a076c45d1a4fa4d3525d3e777ac5cd0307aa11848434dc383984502aaa2f25b865a6619fea11ff1ff8a6f8a7f2eaceda2b74c0458bd883f4cb9a1c1e9eadc27f52b6c5236391616898e245bf663128018b8fd58ed8914210f80169c65e9199c424405cbe9a4db846039f54b4ca9c759f4503f1482bf399db074258586896ffe18dd4c398205858047c8ba8a09808ec28a64f1844aa6d18377a9ab5c7e28d90a7298a71c228b1206cc75a110c7f2a24f305b0a93bd1a8e3f67a1879a31f96f7618e8f1d5dbd4ae09b5dd2540edbf49a833b2d0542c9235c6724e7f525ec6d1850a22fe9aaa76415618f7f334184e74077ae974bf58bc2d6fc706b9b8ac2554785f051e0b73025a5f9b511ebd131f1dd7cde4e7250551e1398a784e76b911f368ec98e2957798eaa7f69645d31e5c3759f32449382ebbe646252479674210a49ea8de4b7cb5f77c09826242680145463e7a863d2bf7677888d4a4ff42c4107355fe5e7b724eb3c60dda3d121b4d0f247716aab01e7f1c5143bb76391cf1a9bbe0c32af64341f58edcfd5ec79bfa414c6fbd91dcca9d26f28df8321c3f6eb7697a7845f02175dcac13252a0710f0d103c146171e6f884942464165dfb0af9508358a17027a3b4dc467365a3b22cff91e30e53453f855211c7e8e410b0eca8b9fde76c040e309d888c1f6fc2d17c74dd4af80bf382b290a1d6b9b74329f9fc2d0f2ba241771e748cc2c7915a27e9e6eacacd46b3c3451bd64db750268d2ae700aa723461daec35790c4981c79a5d03c90cd8d3b6dfea8381209b871e87bcb586a97094b4ac7d027b3286b4639a5c0495b246f03d1948e5ebb414a6172f34188f94432db03d24d1ce1e30ab55df478f8081bd8a1f5f33766aeb8e5267ffebbf04b3ceba8fc6cc2a1e2b1309eff7bb674b769ca917af38e39e1099f52580eba7b20ca2d0f0dee798d3f94b935db8c1fbc3202f521d0c6f4ffc947fe3f35701533dbd9ce411899120107581c28547e4a18c94d219661d53e98f5064d52ec25cce8697ffe81fb11bc47d8844e78bba7e555889cc85e91c43433c618ac61c94f0a31e3fde9fc9dd40907397625584a8c893bff68a88e7c9d339cfe587fa206defaf41ea36b30ce2b72a743abb11a30031d5d2a14c529603fbd107f7f38df7b85d986e0052161730b08833988c6aa6c298417cd7f1c0f3c949801e72b917514129ebf6f31be8db7f774cda2eb62ab0efe63223136ef09249191c13830d7becae21334807f60421204b57a86a9d74e2f2adeacd6708be6c01d8babdd36273773224a1529217a78213e0c55ebfdea8b94dd72744bdc011030299f527cf3c4c0708d30e47e7558fc325fb53be7bc68311a3bc2f1bb12a8b33a1be66c46dac8eec57bca949f0d3dcb0926c3c405ffdf3e34caf9e6869bb99d4031cac4a322ceb1c4ba3157bfdf83f23d02c063f20f2e1d2a3049a305713de5b66dfce1edf13e3c2875d174d84b79b911ae85c3092664ff30c1998a5f762934d0a7d6d5da287c43d45f3f11be5b0276338ce3ca1c8adc1bd0d03d8dda6ace92435a7d80007624607594b270df9e71029a9fefb3eee82ce02c8050c379f9f38d85e6c80e444eb66d0574e469740df32cbe457bd8c35de69ba814814365a5d36d1df54434691338ca38c479d41b3f5992fb7d8b157aa2479327f0cfcffd255b567a2b6e258b53aff88926c93c558d0ea4409c74a3474bed6a5bf17d53f0f621091829e156c7a5cd1becaff40cfceb5f3fd0536b029bcac72154f09109fcdb8b5d50cc72a94d8ae300593251a7b8211479b6bd159e9fc6e7d4b8ebd465463a268439b27081fbfdb35e65653f26a79f2f501ba8cf13fc7c468bde6061aaf74d256254eaae7f7cd87b9204bcf6ff5e2ffb70deecf4720dfbc25823e3d6071ba0f7635ba263d1e7e50612bd71994224bfcde53322732ded88c1651651e57f8d7813f80838e294b6012ed966111461c95989a666a556170715976c3992a534a14fc6da63c04308ec26333899e3c873e2d47c56ba1c3d2e75ef84048e900dcfff7a4ea345fa774e48cca0ee3e807f72c87eb3abd48d9031e8f854ead5c3f78db4dd58507e8f01c698441a9c3c16c8b676b2cca57080eeeafd658615898eaa3b2269975f3f49a31131ff570cb97023c4afb5e9752267d753cab0114fd5fff028fa64f224a268b8ede7bff87e8c50fc47371ef232dad71cff8079e57fc14cbec6dc4804543e2e7c55e2132108fa753f1e7004e3348cd50421696a97df016db010713bcc02996b67d8c312d3af4f60e7602e78ba0cca615e9098c6d7a49c7658bc2ecdb791419fb3b3f5869604522b51b3f23ef4ddea8be8e4a5c7e5ac608bf998abdecdd6f3999d92b5a727c07d2ca36421cc66e952aab1e1d25c3bfc8984ca80ad8b72123563f7dcb0f90f9f0d2c7c186546c303f73c51e56d812ec52535b503803e88ce52f6a01f759110719c8c43dd48e532b93ac78112711335b82a422f9dd271ce3350b21e5e16c941b19d40703002ab4a3e2f53c2d1ba1012f6f75692ea509c2d4e00a9145b7cf042c7d7690866b7ea748573d7cda65d3623a7430102d2218d54f0ff6e029f0c66a676ad79092bd10df8c35e1617fd893a9ddd030968fd885db6e24084159eaffd1321a3f7c3ed4d92aa9c0cf17d468ae1d752ed8b054dd45d7c7a18fe839d155c5ad3f61bebb0bebdb6bfda27e96858e47c7d7b4097cb41e5cf6dce1b91f39dcc439f84d10cf2d4cac34c5e85be25369357fca6adac9df86d06444c66389a3f9ab54cb60cd56352f95bdcd4a8ae2ac5448dc6e6a84fa1ef9044347222858daf50a19541a7c078dd86735fa9053400dd915021f2709bb5774a6dc66f1864f96d04cca568de871cc0142346b91fb2a653e9181c3f530cf2f53930683d455ac45d16024ed461627bb8d75d4c90d450f54afc34c175cfcc073fa16a2969c6cf46338176f9d71b0a199e60a5c6956873cfb64c4e571ece362c3631c74a6bf6d480c6976565dc4a9fb125d384b60df4b3000652acb34773a28c5375186e5be24a81c84750dd4f4d80feda72d1a71c4d1d167fff92db3908fb0a9c3064fd536524a0f65d3ab7def1b803c3bee7c022113027d67e24a0c9c3e659b02c440525d12bad5e60148f228f00ab294cc50b18dd5a7ce14122242f3f51916a1dc19c7567350c18e775c8903471982c91bfffe121bcf09dd1583ef13e51bca2e3e87d797b0a5c55983cc89cd20c90a985c7fae5c172e353d93b6f65ad4781c5f69aea9b297bdc7e7c548ebb53debff7b4db8fc16950b4138a83d523f7a555c93a15cde2336ebf89cdf832d3db310a22658833de78d296ed73468b65d47da5fc13ceed0004736d052e5212dfb2bcfe8a8509b3034dadaafa69d50232baec13da64f950a7d9f546d926d9b641e365c14ed1107f459b9b917187b74f9d127b073df289091b43ee12282474960d41b378ba6cfcdcb910dce99b9c156e919cb62678a2e32933f9498f6915ae8abf34e307d69b55ad6d6e2be791e26408010650c3a02f2bc9355ccbbd5fbfa841c42aa05fd30f39beb8415de4c5e3c48b40570fc33651b092bea3bc987ad9af1b78c789c04815ef2065ecea60900df8ef920e5f94d5ac2a65e6cf871c12d04ebce12a324b77416f844f4b5ccfda8739773601b1f233c3cdb9e67dc8166925387eabcdfa49179753cc1cf59fe690525d008a2f5ee793c231d558d0bf34e1984876be96296ce9ae6dd1663c8901889ba42dce2acffff30aee4d8f7989d6c3925039b088afe21e3d2f71f01f7802ecde32416eed1f8eb362fc3f732850364c222fc6b87d4919015b708b166bb09f7cb8e215ad7360008563704675a4e225d4d635e8a01bb5df202221ca0ae3555a930e7a308e218a7b9b3b9d409bba3036bb2d393ba97f0da1fb00f0ecc4c31587c8327cc43c7e8417f324d9708e2b88f3555b81a15b886ffa7f31d8caee9d9d852f681ad2c3b548df6738e0f64cf52ddcac6d9b72767992b67a6e4c33cfc1130470d46b44867a7fe735308342d57c12f9af1ab0698a862a24330c718ae25bed3b463820a7a05b4c76a5904fe978092d005fe6deab58c95ba1fc328da952285558b7243aeb456e9e62368188f6d05bd9eba56c2e6d42a969016779d5919acf9e447896d18f0983dfb665f02273cb1166979a2b24f50d3e7c6fbc3585b5ad93b6a0ba7beeed4634ee9682a164fc929116cd73413d9b4845511d0e8d6874560378fd019b5870acab52776c3fba7297eebfa91c5bd62fbf5d85d52711aff3053f5872b2b6fabed71e89a98acbc3904c463185d8e863082a52546a30bd011c07110056d5a57301cf0a880783a262e0f81a53464b9428b58c3980641dc4b97cdfca44c08110cd92813a097a59f618b53709528ae650d9a872bbadc8ad95e9beef3fd306189cccbdf13afd74690a144507ffeea8f14df56d819cb9bf0f9e362f33f2cb19f94d62a290c04e6184edfacf532ec3685c365d60ad005131fc903fd3979eb77a17bc3fec39707db0f2d09cec5a5d10bac327072309b2973869f5ec77cc423a74f454a0188ddbcfd464e64b9c84164f5ecd46f9d622268b59cc62c113a37007cb0b33947161ed2e0ca6177c83c1c4d9f3f5cca599da708b48cebd5b40b2e8e034836ff6df78ed990110674d875872b71311ad6f1a7149d7846a48c50c1b991049a4593be11e36b98fbc64b0b265c729df2b7e7b216d19d5cb9d51c152c4ae34c361035736d6844a730057839fc7ff36c15055d458c68109b11c9d2b2da25c2083fd2113d2e4e2a73068abe35f9dfcaef4f65a3d6590d952ef103ff6dd0ebc390d2ee8084701da864e983423f530d9909a17cbe20f55f099d131632de79dd921c3dc23a66dc892728e682d7c28bb0a230dbce3adb858aa951fd76e78a911ba7d0113b2bc0f6d016d44e6f360b585165096cb55397ff14f2f529a9f1a421bd361e9b40644139d7dc5598b98485d6b33f7af96ba06855809ca1d6b9266e82d98e4c9df54936912fe2dd5196fdc8169ea6f4f14151dd23d05a095a1b4bcaec15ba702a63e9051402bce30940b56341c8bcda4973040cb092bc7abc2c1de58e2a9045e37af92d61dccd7eea69c0739250834f3c38326b7cc74609d49b67555eee22f091275a8ea414412f37ec8dea207e9a026ff5f5933496e438d47d006d75be0b32354b2c8bb2752771bd14327d2ecc162f555875f850a9e02714f955c4fcbd66d418d868b6b59cc10dc7103d08b2f49d553551668cb6f0ed6dfd9efa33f00b414940cf57f8ef650c8a2d495874d99f55b3fae157791a3d230e688334e68b2fc42fe982c658878fb52ca5dfa257f285fd3d364d2ec856c199cbb8313ce7cf1c216b3008139fe46d2b86076dd7556db86ce557446f0c7d58d23c5ac7130ddf60bc7a24392c0d809c0c80849d3b431baea1f5a21ca2f830814386d4b41953c8a4afbedbd5482f26be59cdd7f78ff5fcdb514391d4750dbdd0cfe5176296d0013e9cbab1223ca3e0ef32b01bf3c5de9bd24936b4dceeb93db49826fb7a1f4459f39e9cb6cf2ea944235fd0b0f672c4a93a47021b316476151bdfcbb803b0b9a691ecfb8cd12e776c180da81f7c458b209ba4a5b5975e15e090609bad891259451d58555b058595436745dc57d5e0122b4c5f3f4d33d9a03c86d7a5f8b70941433f738a67d64017a31c20ace68df5ffb73091e7369a6a6a19159b333f026bf8bcee4cf1752398ffa82d9e0d094c39067cbe36d158df066624efd4eaf5e2f32dff274948a8e299a0cfe7ab1c01cf614d0ed896064a3b445d76eb3c933aadb1726ec36b249f7e48636012057430749ec2ffec4ba9ef44fd118fc57af4bf83f0be36bba3a48c89f92f7046f670944d1251337e68a2c8ba090439f145ca296a5f686bbc420652debb1ec6648f806ab6c1ebb0b6c104d1e264c6f9dddfadb21281e2e72e170407429d43a2ef7a4a4706b5a73d9459afb7a3ad31a9a71bfe109a43e59d701e138c911f469f983ccca2553a8a1d542491fb5e6e5bce65e15cf7b815481617d3740152772128c38c64c5af759756d92515c2d3f59bb5640ec6aa5f0f3bebc630eb9c511c9f03e8074886b083dbb8ea0e97317e6e7d94f247dd1aa356f32e32c76bfa4fb26b8a79ac59eced85058235d404e6419a48d3bdb52c47542ab1e11a53ca2e3a1bbaaf7a840ba8862d83ae0d45a7185738c4c6832782eb2ea78165b3be9e42212f5329a7bab8c05cab8521ba1a20c0c6310c11a90f163a041e9f84cc0e6387b5e08758af87ac5ac3cb13551cd0fc4e5645fac788262bfc6930422cd05b0d5c70bd496645a169ce2a8b26bb858321cf62896f843b40e612d44704571e41394661b7a6c770c4d1ea789252db7bdf191416c851159b2793810b3965fefb1655ae2371dda7ea72c584fc271dcf303b32cb4ba27aa4622bce16f43fbb4591d263651c8fb4ca7d172c96ee54260866bf292fa8f07b85844e1b2eb1dad43bb1b1acbbfd72097ecef3c4b9834fb3b4a1bd6b571496297e61bf5743a05fa68715466346812089104c534ae35b3c9d017334eb9e02caa4cd88b07811e036febecb4ec2f2bd4926e2a1da77da07970eb90d626c683a37fb11f2d51ffe5ddc712ca6cc17b7acd487b0bbbd0988df903ac33a77a8a5e6747eab48c9dd524a6ce32843df76491cc837fd2a55ba188b8b720daf317fc44c8c5005bc75c39090f55b5268a7ba93486241a3b9ee001dcdf206519e38166b0383156da9db6b9c198a6dd515c7ec3078fb1b5e22a67cdcfd6e00e6a707592a12f64d009384e080c0e2477b0d6db0000000000000000000000000000000000000000000000000000000000000000000000000003070c12181b1e26,
   367    02f91c3a010280820fa08284d09411111111111111111111111111111111111111118080c0b90a20021550bd5da1c85fd90968e44f4cee7610bc421bf058a2ee8aa7dbf95a226f66377ceb9f37d72e591a27b13697087bf897cd59175144bdae11281122dfe91238f3a0ec80f6956899ab553d8fb42de20ca5dc2f5811f4d523553d278cdc4da920a00dcab2420e01166812b3b8794e2b8c1b5271da32d65291263128954e5fc5fc860bec6e47f7b208149be4e3a279d7088f7ce9381c0df75f2f34663ea4cb1aa74fba31f0532416209784ca2a49d0b065276684abe5b5758d8bcad0193f0dfec19b0874b50a0e4972da7c0b0ccc45c2540b80366f5ea2421df88a62b25301e522ef3502de513420b0315d244ff02ef01ee3514022375b18b94c3e4d382ba30ad06633ab5b470ee6ffe90d9129033b439e8a58ffdad4b2e0f858624e54c0aa1245b68dc770da4fb0bac22fd10f1f769b420fb50ff0eaedf88892c279e64aa8485fe304404af905eeae30fee055047591f57b5e047ae4eca27fa46f9c4d88abd639ffa0ae1d19901f234eef0e18468bc5a7a5be73e59b0cc500fdb75821d6773ce72d72abc2ea09ae01a3b808c81e5543b6fcad0ec73cb7dd381af06f84b9a4f81678b76220ced8d541fb52b538dbef798ae9dba4f35e2986e43c4ebd29495d5a4e36a589f95757273829c8012d550e2e17f7295b77aa004175e8bd63c48db5c865a5f36b905e7e536bfc50c281a41e7806dd19a3b8408e5900ac94ae75811099d70c6f80d0866e7f66c476b3ad67463ea2927140ce0cfeeeac4d3931459695bcc44e432b42a08fe34d35e21c4ed5a095e6cdf03a1b9fcb84b4f59501d729b131027719f65956c298fe44181dad4b12098b9e46b22d2955da315cd99b1e584ef16daca7a126f92a2a3044643c80e42763296739c8f44f22ebb5d865f87c7252f49c65ee503300eee88d68280fe027b1f32b9ee7e4e271c323f9c1f8a3c5d1c6d27db8790f44013b23639c8652d415497bbe17be802d9354c7c37a2f89a07b26e7c3c1e9701e257439eb7f5805d42ded3d1e9ce7093ce50b5f85431be25952abbbe983b3f5fc0f0e0d3d186762975217ecddfa1bde013aef25066647b024b20f96764d023d4c2ecbd6f4b60a5ec5cdb9ea06cbb46e5e1689c676ac07b032f575beebd64f6cbb848aff61cc3d31f5738dd84147f068ae490abde41e6abb6bb78f8a69e9a2764445b283daf8f470ece266945ed0e6e6b04db956048b89fbf991314d0bcb759b7320286bbce6b1463f30ef1fce7620aca10ed6613ba122da09af632a7a7026f0976d761f0e4af730071621c5fc4b6acb7a62c2b65c185abe8f049c860ad44b1f5bad540108c880581622e8580615b2890195b534be3d17885662a6174b75d337a009886e877631c617c4387739bf6c43418cc6ec3c8f64cb6ae91d51c9e11fcaa824ba8d9ebacef6afd707d3955377ed00e4f439fbdf4c07ec4cc159fc0edb7b323d232a184a1fff7d6715cd9593b77fcf96cbdacc58e2a0773475ec9525dd1718e4ccea94533e2ababd85118ab559934bfa67c696d97a46a20b4c655b217485445d739582601890014db304bed45f3fc4134c910b348631cbee4f62d0e569026c5a9a728bb0643797834276e365da7c14a72ca6fcec957df46c48c9fa9990be1f6121986c086b29cc361bed01f778a839ef04edf4fe70461b4eb638ad7a1939d21f41ad38d9b72bfdc9178447f23bfa2b9ae23eacd7d9a43f6ab52229ec15103bc03403e01276cddaf8b8974dfb8cd8835d21725fe3551988a9c368bba3940c6f933baa1c22267c35a4e8fc1f5b700c35971c2f29bf414667601cbbe3117e9f9d7a92e1c18d6720c30b51d66ac993e5b9705481e07b95c1a6a773f30900e5895553283fc2847fd884e778275671b4f31182d1e760dd0b71eabda035263b0719f4772fdd049cf7b17675059166d0f3b46336a5596a3e57d8f5c19fd622b1ea1ca7133fbb2ee2ad538c8b8ca6ec134ef78a00a7e42acef7fc0f64fa0f06a28b25729da0df3afdecd066e498ea20ba8a6f8e60c593ce696965af9cb0f6a40226fd6dd666de5d1331eebf741b45bc1c3c3ecd1214a6eca53431b07f908d7f4887a267eff2bb8725d6507bc6f539fd7d75479ec4bf651dd1cb84a896ebc96ecd10f827e0cfcdb1e4281d61a8a5c63469f437f3526c738c84ba71d63551615f741c9b25a33e171d000439594a9120abdad066d11663db1c654f57270e32e71b6c8841dbe60de9d2cbdba6166ef3e197a238a4af64ccd1c54328255a142d9b25d78c28534d1272cd1d23666550eed8ea4b3595dc31b31ac1681fe42914ca9f521836ca94695acb3d062a825266325cfa7bb496a7be2593a1d2c0c9a4cc00e8c9ee6b39ef3c4fbb51cc5cd7f187af76e29ddcf63f101bedc29309b593ac2e609565cdf0d5caea8fe8b473f808b07b9e5ee9bdc0c6bdce761688f4ba714318dfe7f82b4cac83e8db0cd87f4ff1051d5d04dda764409a38060af43190e3b0b6f0263a96c311a57d520af6d0a6afefa5fcd891951aa746072b8890c8bd483e660572b286fdcabd198b2eb0b7e24542496b2a90eb4bee3a2c74937573346fd12615c23364a546405d948f45f43f205bfcf56d3becf65209d194516768d56ab343eafcad2c7eaa4ea7ef55bfbcccd06577c4e269bd6e16758e075828596682edde62a93093437649b19d7ee025974044857e93e98551df75c03c05d6189c1b47e56c5e5767e45276791a35564685b61e2b80e46be0e3bd4beafa2ddb76228d938d1e177cab32a74c46abdefa2d075190b910032d615bcf3e1e4af0a36007880c6522231f5006e234afd7d69e59be87b8849842ee239f9d2c3de2dab648b0b6b5f3e996a1b98dffc19fe16819d5121df6af74a72f664f2ef4b4fcf10db17baf7ca8061ebdd9ba0d2d20da90b8f70c885f40421f5049fc7521abf5051ed7a30d4bf3716172f47b9b878a200ec929a5403c9d28b9d427236499151eda02f5a7cf53837f522a8fe2990b55f8d8343ffb50cfc3b7ad5ac1417135fa77434074cc607bf017ed485bd91e034b42d114346cce75ea05f542ee1f211f19829b227968f652e484ea4b1c0348771505cd4fa95d4f60bf6ac5df9833c6236661277de0b7db6c788235a8c6afeb3d76a514db70e1c6e0c51a53952c662310a11f6463b9263d92f7df817a41108a3130795944b5b009b7f2c87f878aba6f295423a3600f809a3e71517ca301815f7f25f46144ab9a3a03c1438388d4a9d589a1ad715aa1a59d0335c6045e683ff99a076c45d1a4fa4d3525d3e777ac5cd0307aa11848434dc383984502aaa2f25b865a6619fea11ff1ff8a6f8a7f2eaceda2b74c0458bd883f4cb9a1c1e9eadc27f52b6c5236391616898e245bf663128018b8fd58ed8914210f80169c65e9199c424405cbe9a4db846039f54b4ca9c759f4503f1482bf399db074258586896ffe18dd4c398205858047c8ba8a09808ec28a64f1844aa6d18377a9ab5c7e28d90a7298a71c228b1206cc75a110c7f2a24f305b0a93bd1a8e3f67a1879a31f96f7618e8f1d5dbd4ae09b5dd2540edbf49a833b2d0542c9235c6724e7f525ec6d1850a22fe9aaa76415618f7f334184e74077ae974bf58bc2d6fc706b9b8ac2554785f051e0b73025a5f9b511ebd131f1dd7cde4e7250551e1398a784e76b911f33edcdbf73ab1a2db691e86c7481a4e0103beafd927281a6c04794430591a9299c8b9142cd0ba208adf3a5d12730203f6b1e4fc85e03d839f6887638706e5bf8055a83532f57d83a220bb77a26ef2c6a5092299999c9a5c271b3b20c315ed83366a05369fe739d4f8c5b9ec29d3180bab5ad160611dcf8deea6e26979aeccad9cf6bb333001266d17da0dbb11195412c027272e01e51ca59c496637483323f2e41ba180e49c95f559d65c912a9a38663e969d3bd6334b727ffad42aa7190d0de3ca36a48542abce135f904410e91a1fd27062dcf15a71e85a28ede35636ad240831fcc928cc39a49e44913d7bf8eff453febdcfe091f565c086f13f98d977a61f2fdc335bd6a9c469db4992c411a0c198801e319a4962af79fc52c226847a649ad263cb9c553d3896685e0ba60b678f08bed295120083305d4ccca67ab6fc183786805d40b3b598b18fa5fb1becdfbac68e4957ba675c28ce8a08d16f2b1d7064e87230216dbd365f7e1382c758814a99c148db668c7499fbf4e2678239dcbe5d4fd67f6905e204d1cd2956f76af5cdf1224ee44f277bc3c299c48ee40007b17fe1dbfe36dd6abdd3f037f69e8f4f0bab54343e8a473ce4699c5334fbfaf4f551e74f78bfe31868459d56e9817e3d18aa84e417f243834d2de0b9f3b405c318fe0115cfae516c8c868a057488a1728a2517bbc34403fe337d852a13e2a75566c05a16c25b2ee882fa634867733a7567396f497110de035c722dd70861a9b73d2377a5da8e8acffaf02ed8df4f176e25ec1d50df9e6287a8ac915786b65763328634db13182df96944927568a81c1dd7e07ac06a9a16a3f93c2fce6de2967633b3f7876226ee872351d34bf1ed90de053a77a4b3ae154760be9cf730f0713b6a1d796e3fd23e0d45af9a22652df12529bd33974c09c592b3a9d56b5b160c1263f2111de6521869e9f6bb9c5a385135766dc347dbb9acebc69409c3810225c6c0867f071bf5e28afcac349d4f71eacb06e16338ac2eb1b290d6fa9845e67b9cbe2be6828ede10f4584aaf8124f7ea7eb4b23e870141efe3b4fa9ea08d5b2182200770d30451d80f4f30fff1bc533a51a95cf5d3c3a2f2b16cc1cdb840b11a424b7da14eb07a4d9814f18e139133315db389d397870d2294d78450dc52d4f250ef947d70e074b45f1c406b07c6ab089e916f36362814f89e80387bd189afc95f6eb4e6736588e09efc6769a943077b083051fbd82cc875feb705f32471bf3a38cf7f9ba078385ae9faa83daab1689b4a9adb6c26f06b7cf9e5456de303471b72619f77ed29014133fe8ee8649bdd8a9ef5fb4501b8cd3746ea263b7e134ee196ffe3c392f556ebc4e644e62ca354543277dac8c513d89a5a1a50aa1f6b09a88702fb0416f98e3f48acc9332d01671627e879958cd19720b9e9c83d0e0c6be830646454908e3e3e850cee34e3fbf059dc56fae3f2ac57ae3ff3138a23c4303ceea31aba547b427c31fcca077e68761b9aaec1926b8cb56f3060d88a3be593c1d2f3db0cb997f18d85f0e5e506935948c9ee72fd9724097f223dfaac2097636f63130b0e23d5dfe15e972fe6a11e79313b14c40a7ec3ead6fe451e7d0cc98df98c1af0e851239d46e419597781c3c2f807140628dc19d1ca15e9f0ad00e2c1bdf37676b7b0d9a002ed283b62121bdc344a4fdc8606290fbf18f61de5e192d5d86cd348762a8737a0a3f8a5ec72ddd62427ead08d56abb918f6b1924fc788b3cf3c5ac933aade37f4dce5da9874f0c73cd289f2cd9edf33e689826b3370289d97b6122e8663420cbd1457dba431b1f6cde368ae196384b68029f34fce21b09162851f450a555252df74c5a16b5feeb5fcc0087a9d514623582895343c2a9120cf3bc29bd715a27e34808d3a8d04faaa655c4e8f030466eb1bb3eb0cb745342f6197b42f56e231b07ac3ebbaa9f423a3be3d8e0fa7714beaa5ae37da480ebd2ad969671592be38d9685c27736183baa51581265df016786fd69abc1db310ece80a14a1867eb66ee7426e7723aa57c3bd4ffd527873b1930a2809ab115abbc6b7ba2f70578a1ce5c8ffdcd042ee4c08cd9e5226b111e9629de1f52d8ecf6aa19f3cf69b8ae2097534681ec60d441912836403e61a1e0dc542e47356d5e82220f88c0357429673fb8e6a9d4db483c00119a1fd9b55b423b52d9406838d3c2de0a6953510207efc06de95f22cb8fb538eb893a320da0dd59f8742118b3808f97dc2aeb7ddb5e475bf28d3762ea697230e868730afe9ea35d3e004edbbf17dc817e719b13788226e64159845f174a8963e432a9b57dc0ea4c45041767f52d6ae4b38486a355362a6bac98b60464afc1dd106efd117d90e470528fa738fe26cd19fd73ded0f41475499ecb8bc5699d28cd8ae05e9d9b76b44032c91dcfcbfa735aa4c3d2383f5dd5ba11b95df971fad53234661b4a079db741beb291311b5e21f965b44fcc0551cff27e44f76355fe4f4b1621ae0df8015aa81ce64a70e0d6be05dc6bee99bc2e35e50297c7f950a3db998ace193147107aa089082387808c9776353eb89d6ec90d0760bff48a1c645a1e6f2dfb3655f77d5d6b60978dceeed4bf16cbb511831a877ad7884310b97fb632238109b81c70b1de766fc7015c9c7c4ddd2ac593c912ad7acbd23944cb993ecefcb17b09c0b6d08cf207024bc420800950410704e59b486f772495a9970eeca7fb2771063a9e79b7d0e030f4278f9d93be77b618ca49214c16111d1ca783a10e7415e1d4eb684d0f6e48c7f8d8ac02c39f7babedef0d5513608ac17d446a9868c63f1e86b006d4f8bc2dc7ab493768b0101797048de0dbe7185d948a48c4ca87d3025381d579e46ee0fe9d035871ad97bf284b896cf89d040d8d171ebfc7bc752c0ea390b80a1d4d4a8c5dda346651a639bf92f9a022daa2dce0855f68844b54db335012828e2a2916fb2e8292a0cf6723a6411019337ff35c6aea04a5030c112c852e9578130ede02db58151652eda31e1aa2933b147ec1b407f08023c1dde76931d81fbfaab16b5a7bfde09cb9c3cde3e26fd3ae29e21c264229982c17adde651e7af488d93b15ec1466406dad75622daccfc5e67a844d7013bc0ef4908a7b1aedd94099974979eebf5d1f46dc0f54d1cdf917cc9d072a5ddebf7a064c124fadc3b3eeae939988a16ab62b4ef51587562593f4f94f1c3d83873eca4b7eb0658d8c239175bc40fbb9dd4b53b18f2f697f85fefa46b5f031f94a8d4543a19b853d4fdd3d6eb20a4e27f53d765096bc6e8f668236f3f8e5c8ca59182f761ab91e20a37c90fe96a4f6985f0b493abc66c34266832f81a69b3ea07a7e63657105d1b84737ff8eb13c062689821aead5045319f1cca4d31ce52806c8f618efbb663ae113ec9cc4b55ea642b0b5782b98e8d7680f95e5dd02346fbcd42dbdb7555106b743470187233cb00f5e171238fe3692adaf5d313b114bd677e8d2637daf86f484766028b0f4c1b028659364f623f612fb31c3d1a6860e80d981c6c5704ee28fa6f198fa8229f12734a2fdc920ee577f5f910bba90d627eb55bbf6024a5916f4a617cbc166c1b8d11db7dff8cd98a9aa103c94aa735e6eecc639dde0ddd5815c3e2061e232e8ebc5313e17d9ca539198f06cc73a3f3ad270f6c00b22df9ddc5a8052d4435f60b35fa63cbcc85308d8073e32a361ecbaf4f2af3b8032419a7d76a39237f058913475b2cbf761c62c8f01d35bb9aad9d5c5c08c2418b6690ece918a6904bf0cb001913fb2693249a5ffafef8d4951adb292335f56399b4b70f0c452c0b34ac7d59a3e39934bab3232fa56d50ab105a3a69c77240224a376e9df8392677cf6dd6410004a49f85b84289a94ddfb56e0c97994494fe687950cfa3ffa9da62fe47d0ef6aeb1ca143d4c3cd571c166d73d5f8998163f3cbbc6e074f0953929196bb3113ac24c0a7d5f8e2fbd493cad9174d197a8ccc1ae5bb6bddf1647059d43d61454ba6a3556097516e5c86664abf87bd827cc5fe3ae2e42ee22c2df01a1d39daac80e05773a43e39ba753b017614c42a0f863b733de02448833b1e7e05c31cc1448c252b869c442ba8818d16664828a1f606cf6bc39ef72495bbef5e0797a6328c1d63d4f4428f8df5df2aba8ca678cfc5518fb8db88b8ecde7c4b8a5d441a454a369bcbd43fb1aa5922ad02ecf5cc7f5fa94609be554238270cdcf11d39a59c65862acc0cccdb77131a9ad5b7df33db905cb393af6763707404a78e733f2bb13c5e4c9b8c6f11c36e84e0e6cdd6943835124f6cdf2423920a9c91a6941ef0211901f4e09acdf7ad46a5f8c93dda249d699a66dcc70c161b3f3ee78c178831a840af1b39d9d726b99301528abf2df32c51aa021f06332938b0362a1678feeb045291f59c21f6c9a2133e96a6c2190bcdffcc9e21cf75e79fc272a9330c0b530cb8aa8210e9582a19a5b40c89dbe9b603a89c9610088b3e6ea01691112f7a186632522bdc15314f395c89c7ef76518379c55969eee78a06c6ab6685a21f93f3d48c93194107c7751ec49a4dd719b2e24654a7f97ba3be46c64efba4c2f4dfdf7cd29ed828605c6e4b63033936df8b588fffad6aed5573ea55a707cb8b9f0d689eb14232846c8a76d7630d719ca7abc9c6930a8f60ed0a0d33908565a5067c5a437548f86bfc9f830ce46f4b85eaed5ee2cae995b158ef1a2fb6d835f3b516ce77f2ac8ac2802cb10b5c3e7581e45b73582f2f69c065341a01981a0844dc3b19455502e7af0165764dd5f3ce5d65c4fd3cabf76c4e1e6b790b9fd37e654f87947a7c8ce1b1a0ad5d6bd55db16c701b5f9c0b774ca0faa424e25c47fd498ea5be8a65770e0a9793b9cc222cf5e6f1bac5cf63cbec37fd3a5616d0b93e35eed1c668d1b2629f4859ed5cc10e7f55a6ab34c72f229d0bfdb85bc3a619f04b8b31e8435e3b41c0ae31087a1159cbca7189951ca6a954c83aca52d3c9fbda23fd9f42ebc7be0654722075ccd3945cc41a85d2b989000df19f3cc1579069265fea47fd32a149230ccd7fd91cbe39e076e5449187d3e0eeb7465d918b0b110671d24b01514ba327e9ed3e9e7b11217765e37d73e04b369d10a3f05822d9d41897dd8d44463280882e4064d5146c040e2a438e88fdc5ccb1d2f8a7756f3ddc77a3a2a69f8a0581360e057eb2f5977a52e9f8c7767fd0b22922ac07d92c27cfb80e071ef43a8d5d3d10e69f07bfbd2d8997c4022d45cca76c75708ed41946630527670a344a59dfd3da0a2f4bf0d7f8cdcf330cffbd0cd0a13c482cc78570be4c9c9021195b90de3605eadb0f8f991c0973925cefccfdb4bb4e730a1458f5a3df029631a084c77e7691f5ba11a677bc67dc5f2bfe120a1ce6f722a522204a0aa197627d862eed12d39bc0ed54de1589fba8c9f3d48ed85b29535d5f94da19cfcf3786daf8b0d42bbd97b2ec0437ad2cf3edcde0fe7cc8c15124452dbcb215504fa431286d122ef97f462afa226821fddbf98ca23b2225eaeec39e5eb069c3248564ddcb18d6db341c1ba8cac42d3898ca56ce007438d2000cc72ed00f5e97baf3488ddf97d46bc5109935aaa1353a86315cb2d687b9623b8d01b28412f24b70fc891255068f5979ebe10953aca92e348a70149ae4dc2f46301c0dfc505ffbfa04edc73f990b5ffb314414be92336f2b4af65ded4ca7788b8600eeb08b6fcc9717395dc983b1f757295d7f8dde29e5a3b17660a0a3735730777a1a89ddd266058935ceeb2b357a4e2518eb8d35109a4f3f212006190ae76dbfc899a2391895b9d2b9eec275a5f20e6f4fda5dd94a959675f3a5fb36cdbbcf7311fae580a3b2aa6ddf142c99e1786a99d1112d705ab64da20b04668e9115a069e0031e638932f7c607d647ffe816e5f818c89d2f1c88d6cde79855e55622e9d575e659846f7ff2a883503b24a9e3d1816a23a0dc6c7905d2f1bc1298eafafe9063a02f488c0550dbd4dfdbb2ef5e9bb3e561dc72a372b6667175974cc1a4ec36b2e738145886b20254efee4c815faa8948462152ac58d51cf1289b07036b5297116c941c4340c13788a507e27ee3057561edcf670e91ac5e98cb614ab1e9c5873e07e81be1b26e1b7f93fe89e5cf4f99e8f986452039f22ac1c3c27761ca590d8059c814651408a38319a098dd4f8814d33d651331fed41b1118caf8cc817f24bfbd5cfe093e9696cd2c97cf8689b32a1b7a97fddd7a29197d0ebe305b6c2bcd81a58eb4ed3ab6c4f3e2d2a76ba185ee777a8f812af97844276b8e4b951133ca4edc83933e8b0d54ac7f87dea4e99308719b7feab8589ee20d2520bf0b8d6eb031a47c354139ba3694ae0a6a3c5fa71b965ec837049d9f91fc87f6e5719941578cf4394d708386d70877858e9eabc1dee0e72d2f335c5f6e778baccfdaf1f246474d688d9b9eccd41c202b3c49b1bf54a3acb3e0ecf900000000000000000000000000000000000000040a14212a2e3138,
   368  ]
   369  ```
   370  Now, we can now use those (or any other already signed transactions), as input, like so: 
   371  ```
   372  ./zvm t8n --state.fork=Shanghai --input.alloc=./testdata/13/alloc.json --input.txs=./signed_txs.rlp --input.env=./testdata/13/env.json --output.result=alloc_rlptx.json
   373  INFO [08-29|20:20:43.691] Trie dumping started                     root=7fe86c..0f502d
   374  INFO [08-29|20:20:43.691] Trie dumping complete                    accounts=3 elapsed="142.292µs"
   375  INFO [08-29|20:20:43.691] Wrote file                               file=alloc.json
   376  INFO [08-29|20:20:43.691] Wrote file                               file=alloc_rlptx.json
   377  ```
   378  You might have noticed that the results from these two invocations were stored in two separate files. 
   379  And we can now finally check that they match.
   380  ```
   381  cat alloc_jsontx.json | jq .stateRoot && cat alloc_rlptx.json | jq .stateRoot
   382  "0x7fe86c15fc609c9e60ce82000d90d9e2bd57cc541abe691c3ebd888b4a0f502d"
   383  "0x7fe86c15fc609c9e60ce82000d90d9e2bd57cc541abe691c3ebd888b4a0f502d"
   384  ```
   385  
   386  ## Transaction tool
   387  
   388  The transaction tool is used to perform static validity checks on transactions such as:
   389  * intrinsic gas calculation
   390  * max values on integers
   391  * fee semantics, such as `maxFeePerGas < maxPriorityFeePerGas`
   392  * newer tx types on old forks
   393  
   394  ### Examples
   395  
   396  ```
   397  ./zvm t9n --state.fork Shanghai --input.txs testdata/15/signed_txs.rlp
   398  [
   399    {
   400      "address": "Z2014ae9f42335b44f94ee97d6248c0f55f0ee16e",
   401      "hash": "0x815bdb20d68fb0844a6efc5fa63ceecfdf1dbf920ab4f088bdcefbe33e402e52",
   402      "intrinsicGas": "0x5208"
   403    },
   404    {
   405      "address": "Z2014ae9f42335b44f94ee97d6248c0f55f0ee16e",
   406      "hash": "0x4e91af0609b40a35c409645a201f7c07f5bba8c51f853356ba92f459ce8821e7",
   407      "intrinsicGas": "0x5208"
   408    }
   409  ]
   410  ```
   411  ## Block builder tool (b11r)
   412  
   413  The `zvm b11r` tool is used to assemble and seal full block rlps.
   414  
   415  ### Specification
   416  
   417  #### Command line params
   418  
   419  Command line params that need to be supported are:
   420  
   421  ```
   422      --input.header value        `stdin` or file name of where to find the block header to use. (default: "header.json")
   423      --input.txs value           `stdin` or file name of where to find the transactions list in RLP form. (default: "txs.rlp")
   424      --output.basedir value      Specifies where output files are placed. Will be created if it does not exist.
   425      --output.block value        Determines where to put the alloc of the post-state. (default: "block.json")
   426                                  <file> - into the file <file>
   427                                  `stdout` - into the stdout output
   428                                  `stderr` - into the stderr output
   429      --verbosity value           Sets the verbosity level. (default: 3)
   430  ```
   431  
   432  #### Objects
   433  
   434  ##### `header`
   435  
   436  The `header` object is a consensus header.
   437  
   438  ```go=
   439  type Header struct {
   440          ParentHash  common.Hash       `json:"parentHash"`
   441          Coinbase    *common.Address   `json:"miner"`
   442          Root        common.Hash       `json:"stateRoot"         gencodec:"required"`
   443          TxHash      *common.Hash      `json:"transactionsRoot"`
   444          ReceiptHash *common.Hash      `json:"receiptsRoot"`
   445          Bloom       types.Bloom       `json:"logsBloom"`
   446          Number      *big.Int          `json:"number"            gencodec:"required"`
   447          GasLimit    uint64            `json:"gasLimit"          gencodec:"required"`
   448          GasUsed     uint64            `json:"gasUsed"`
   449          Time        uint64            `json:"timestamp"         gencodec:"required"`
   450          Extra       []byte            `json:"extraData"`
   451          Random   common.Hash          `json:"prevRandao"`
   452          Nonce       *types.BlockNonce `json:"nonce"`
   453          BaseFee     *big.Int          `json:"baseFeePerGas"`
   454  }
   455  ```
   456  #### `txs`
   457  
   458  The `txs` object is a list of RLP-encoded transactions in hex representation.
   459  
   460  ```go=
   461  type Txs []string
   462  ```
   463  
   464  #### `output`
   465  
   466  The `output` object contains two values, the block RLP and the block hash.
   467  
   468  ```go=
   469  type BlockInfo struct {
   470      Rlp  []byte      `json:"rlp"`
   471      Hash common.Hash `json:"hash"`
   472  }
   473  ```
   474  
   475  ## A Note on Encoding
   476  
   477  The encoding of values for `zvm` utility attempts to be relatively flexible. It
   478  generally supports hex-encoded or decimal-encoded numeric values, and
   479  hex-encoded byte values (like `common.Address`, `common.Hash`, etc). When in
   480  doubt, the [`execution-apis`](https://github.com/ethereum/execution-apis) way
   481  of encoding should always be accepted.
   482  
   483  ## Testing
   484  
   485  There are many test cases in the [`cmd/zvm/testdata`](./testdata) directory.
   486  These fixtures are used to power the `t8n` tests in
   487  [`t8n_test.go`](./t8n_test.go). The best way to verify correctness of new `zvm`
   488  implementations is to execute these and verify the output and error codes match
   489  the expected values.
   490