diff --git a/EIPS/eip-4788.md b/EIPS/eip-4788.md index e7608fe8ac8a60..25f8b0f19d7612 100644 --- a/EIPS/eip-4788.md +++ b/EIPS/eip-4788.md @@ -29,9 +29,9 @@ restaking constructions, smart contract bridges, MEV mitigations and more. | constants | value | |--- |--- | | `FORK_TIMESTAMP` | TBD | -| `HISTORY_BUFFER_LENGTH` | `98304` | +| `HISTORY_BUFFER_LENGTH` | `8191` | | `SYSTEM_ADDRESS` | `0xfffffffffffffffffffffffffffffffffffffffe` | -| `BEACON_ROOTS_ADDRESS` | `0xbEac00dDB15f3B6d645C48263dC93862413A222D` | +| `BEACON_ROOTS_ADDRESS` | `0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02` | ### Background @@ -87,6 +87,7 @@ The beacon roots contract has two operations: `get` and `set`. The input itself * Callers provide the `timestamp` they are querying encoded as 32 bytes in big-endian format. * If the input is not exactly 32 bytes, the contract must revert. +* If the input is equal to 0, the contract must revert. * Given `timestamp`, the contract computes the storage index in which the timestamp is stored by computing the modulo `timestamp % HISTORY_BUFFER_LENGTH` and reads the value. * If the `timestamp` does not match, the contract must revert. * Finally, the beacon root associated with the timestamp is returned to the user. It is stored at `timestamp % HISTORY_BUFFER_LENGTH + HISTORY_BUFFER_LENGTH`. @@ -109,6 +110,9 @@ def get(): if len(evm.calldata) != 32: evm.revert() + if to_uint256_be(evm.calldata) == 0: + evm.revert() + timestamp_idx = to_uint256_be(evm.calldata) % HISTORY_BUFFER_LENGTH timestamp = storage.get(timestamp_idx) @@ -130,21 +134,13 @@ def set(): ##### Bytecode -The exact initcode to deploy is shared below. +The exact contract bytecode is shared below. ```asm -push1 0x58 -dup1 -push1 0x09 -push0 -codecopy -push0 -return - caller push20 0xfffffffffffffffffffffffffffffffffffffffe eq -push1 0x44 +push1 0x4d jumpi push1 0x20 @@ -158,16 +154,21 @@ push0 revert jumpdest -push3 0x018000 push0 calldataload -mod dup1 +iszero +push1 0x49 +jumpi + +push3 0x001fff +dup2 +mod +swap1 +dup2 sload -push0 -calldataload eq -push1 0x37 +push1 0x3c jumpi push0 @@ -175,7 +176,7 @@ push0 revert jumpdest -push3 0x018000 +push3 0x001fff add sload push0 @@ -185,7 +186,12 @@ push0 return jumpdest -push3 0x018000 +push0 +push0 +revert + +jumpdest +push3 0x001fff timestamp mod timestamp @@ -194,7 +200,7 @@ sstore push0 calldataload swap1 -push3 0x018000 +push3 0x001fff add sstore stop @@ -210,20 +216,22 @@ by working backwards from the desired deployment transaction: "type": "0x0", "nonce": "0x0", "to": null, - "gas": "0x27eac", + "gas": "0x3d090", "gasPrice": "0xe8d4a51000", "maxPriorityFeePerGas": null, "maxFeePerGas": null, "value": "0x0", - "input": "0x60588060095f395ff33373fffffffffffffffffffffffffffffffffffffffe14604457602036146024575f5ffd5b620180005f350680545f35146037575f5ffd5b6201800001545f5260205ff35b6201800042064281555f359062018000015500", + "input": "0x60618060095f395ff33373fffffffffffffffffffffffffffffffffffffffe14604d57602036146024575f5ffd5b5f35801560495762001fff810690815414603c575f5ffd5b62001fff01545f5260205ff35b5f5ffd5b62001fff42064281555f359062001fff015500", "v": "0x1b", "r": "0x539", - "s": "0x133700f3a77843802897db", - "hash": "0x14789a20c0508b81ab7a0287a12a3a41ca960aa18244af8e98689e37ed569f07" + "s": "0x1b9b6eb1f0", + "hash": "0xdf52c2d3bbe38820fff7b5eaab3db1b91f8e1412b56497d88388fb5d4ea1fde0" } ``` -The sender of the transaction can be calculated as `0x3e266d3c3a70c238bdddafef1ba06fbd58958d70`. The address of the first contract deployed from the account is `rlp([sender, 0])` which equals `0xbEac00dDB15f3B6d645C48263dC93862413A222D`. This is how `BEACON_ROOTS_ADDRESS` is determined. Although this style of contract creation is not tied to any specific initcode like create2 is, the synthetic address is cryptographically bound to the input data of the transaction (e.g. the initcode). +Note, the input in the transaction has a simple constructor prefixing the desired runtime code. + +The sender of the transaction can be calculated as `0x0B799C86a49DEeb90402691F1041aa3AF2d3C875`. The address of the first contract deployed from the account is `rlp([sender, 0])` which equals `0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02`. This is how `BEACON_ROOTS_ADDRESS` is determined. Although this style of contract creation is not tied to any specific initcode like create2 is, the synthetic address is cryptographically bound to the input data of the transaction (e.g. the initcode). ### Block processing