diff --git a/EIPS/eip-3540.md b/EIPS/eip-3540.md index 4ed663016ef069..05ec4ae0dad73a 100644 --- a/EIPS/eip-3540.md +++ b/EIPS/eip-3540.md @@ -110,28 +110,29 @@ header := kind_data, data_size, terminator body := types_section, code_section+, container_section*, data_section -types_section := (inputs, outputs, max_stack_height)+ +types_section := (inputs, outputs, max_stack_increase)+ ``` *note: `,` is a concatenation operator, `+` should be interpreted as "one or more" of the preceding item, `*` should be interpreted as "zero or more" of the preceding item, and `[item]` should be interpreted as an optional item.* #### Header -| name | length | value | description | -|------------------------|----------|---------------|--------------------------------------------------------------------------------------------------------------| -| magic | 2 bytes | 0xEF00 | | -| version | 1 byte | 0x01 | EOF version | -| kind_type | 1 byte | 0x01 | kind marker for type section | -| type_size | 2 bytes | 0x0004-0x1000 | 16-bit unsigned big-endian integer denoting the length of the type section content, 4 bytes per code section | -| kind_code | 1 byte | 0x02 | kind marker for code size section | -| num_code_sections | 2 bytes | 0x0001-0x0400 | 16-bit unsigned big-endian integer denoting the number of the code sections | -| code_size | 2 bytes | 0x0001-0xFFFF | 16-bit unsigned big-endian integer denoting the length of the code section content | -| kind_container | 1 byte | 0x03 | kind marker for container size section | -| num_container_sections | 2 bytes | 0x0001-0x0100 | 16-bit unsigned big-endian integer denoting the number of the container sections | -| container_size | 2 bytes | 0x0001-0xFFFF | 16-bit unsigned big-endian integer denoting the length of the container section content | -| kind_data | 1 byte | 0x04 | kind marker for data size section | -| data_size | 2 bytes | 0x0000-0xFFFF | 16-bit unsigned big-endian integer denoting the length of the data section content (*) | -| terminator | 1 byte | 0x00 | marks the end of the header | +| name | length | value | description | +|------------------------|---------|-----------------------|--------------------------------------------------------------------------------------------------------------| +| magic | 2 bytes | 0xEF00 | | +| version | 1 byte | 0x01 | EOF version | +| kind_type | 1 byte | 0x01 | kind marker for type section | +| type_size | 2 bytes | 0x0004-0x1000 | 16-bit unsigned big-endian integer denoting the length of the type section content, 4 bytes per code section | +| kind_code | 1 byte | 0x02 | kind marker for code size section | +| num_code_sections | 2 bytes | 0x0001-0x0400 | 16-bit unsigned big-endian integer denoting the number of the code sections | +| code_size | 2 bytes | 0x0001-0xFFFF | 16-bit unsigned big-endian integer denoting the length of the code section content | +| kind_container | 1 byte | 0x03 | kind marker for container size section | +| num_container_sections | 2 bytes | 0x0001-0x0100 | 16-bit unsigned big-endian integer denoting the number of the container sections | +| container_size | 4 bytes | 0x00000001-0xFFFFFFFF | 32-bit unsigned big-endian integer denoting the length of the container section content | +| | 1 byte | 0x04 | old kind maker for data section size. This section kind should not be reused. | +| kind_data | 1 byte | 0xff | kind marker for data size section | +| data_size | 2 bytes | 0x0000-0xFFFF | 16-bit unsigned big-endian integer denoting the length of the data section content (*) | +| terminator | 1 byte | 0x00 | marks the end of the header | (*) For not yet deployed containers this can be greater than the actual content length. @@ -142,7 +143,7 @@ types_section := (inputs, outputs, max_stack_height)+ | types_section | variable | n/a | stores code section metadata | | inputs | 1 byte | 0x00-0x7F | number of stack elements the code section consumes | | outputs | 1 byte | 0x00-0x7F | number of stack elements the code section returns | -| max_stack_height | 2 bytes | 0x0000-0x03FF | maximum number of elements ever placed onto the operand stack by the code section | +| max_stack_increase | 2 bytes | 0x0000-0x03FF | Additional number of elements ever placed onto the operand stack by the code section | | code_section | variable | n/a | arbitrary bytecode | | container_section | variable | n/a | arbitrary EOF-formatted container | | data_section | variable | n/a | arbitrary sequence of bytes | diff --git a/EIPS/eip-4750.md b/EIPS/eip-4750.md index 76c94b69eccb06..81b0da4be406af 100644 --- a/EIPS/eip-4750.md +++ b/EIPS/eip-4750.md @@ -32,7 +32,9 @@ Furthermore, it aims to improve analysis opportunities by encoding the number of The type section of EOF containers must adhere to following requirements: 1. The section is comprised of a list of metadata where the metadata index in the type section corresponds to a code section index. Therefore, the type section size MUST be `n * 4` bytes, where `n` is the number of code sections. -2. Each metadata item has 3 attributes: a uint8 `inputs`, a uint8 `outputs`, and a uint16 `max_stack_height`. *Note:* This implies that there is a limit of 255 stack for the input and in the output. This is further restricted to 127 stack items, because the upper bit of both the input and output bytes are reserved for future use (`outputs == 0x80` is already used in EOF1 to denote non-returning functions, as introduced in a separate EIP). `max_stack_height` is further defined in [EIP-5450](./eip-5450.md). +2. Each metadata item has 3 attributes: a uint8 `inputs`, a uint8 `outputs`, and a uint16 `max_stack_increase`\ + *Note:* This implies that there is a limit of 255 stack for the input and in the output. This is further restricted to 127 stack items, because the upper bit of both the input and output bytes are reserved for future use (`outputs == 0x80` is already used in EOF1 to denote non-returning functions, as introduced in a separate EIP). `max_stack_increase` is further defined in [EIP-5450](./eip-5450.md).\ + *Note:* [EIP-5450](./eip-5450.md) will perform stack validation that will ensure `output` is less than or equal to `inputs` + `max_stack_increase` 3. The 0th code section MUST have 0 inputs and 0 outputs. Refer to [EIP-3540](./eip-3540.md) to see the full structure of a well-formed EOF bytecode. @@ -60,7 +62,7 @@ First we define several helper values: - `type[i].inputs = type_section_contents[i * 4]` - number of inputs of ith code section - `type[i].outputs = type_section_contents[i * 4 + 1]` - number of outputs of ith code section -- `type[i].max_stack_height = type_section_contents[i * 4 + 2:i * 4 + 4]` - maximum operand stack height of ith code section +- `type[i].max_stack_increase = type_section_contents[i * 4 + 2:i * 4 + 4]` - extra operand stack height in excess of inputs of ith code section If the code is valid EOF1, the following execution rules apply: @@ -68,7 +70,7 @@ If the code is valid EOF1, the following execution rules apply: 1. Has one immediate argument,`target_section_index`, encoded as a 16-bit unsigned big-endian value. 2. *Note:* EOF validation [EIP-5450](./eip-5450.md) guarantees that operand stack has enough items to use as callee's inputs. -3. If operand stack size exceeds `1024 - type[target_section_index].max_stack_height + type[target_section_index].inputs` (i.e. if the called function may exceed the global stack height limit), execution results in exceptional halt. This also guarantees that the stack height after the call is within the limits. +3. If operand stack size exceeds `1024 - type[target_section_index].max_stack_increase` (i.e. if the called function may exceed the global stack height limit), execution results in exceptional halt. This also guarantees that the stack height after the call is within the limits. 4. If return stack already has `1024` items, execution results in exceptional halt. 5. Charges 5 gas. 6. Pops nothing and pushes nothing to operand stack. diff --git a/EIPS/eip-5450.md b/EIPS/eip-5450.md index e546311640b6c8..736e6c339ff78f 100644 --- a/EIPS/eip-5450.md +++ b/EIPS/eip-5450.md @@ -59,9 +59,9 @@ In the second validation phase control-flow analysis is performed on the code. *Terminating instructions* refers to the instructions either: - ending function execution: `RETF`, `JUMPF`, or -- ending call frame execution: `STOP`, `RETURN`, `RETURNCONTRACT`, `REVERT`, `INVALID`. +- ending call frame execution: `STOP`, `RETURN`, `RETURNCODE`, `REVERT`, `INVALID`. -*note: `JUMPF` and `RETURNCONTRACT` are introduced in separate EIPs.* +*note: `JUMPF` and `RETURNCODE` are introduced in separate EIPs.* *Forward jump* refers to any of `RJUMP`/`RJUMPI`/`RJUMPV` instruction with relative offset greater than or equal to 0. *Backwards jump* refers to any of `RJUMP`/`RJUMPI`/`RJUMPV` instruction with relative offset less than 0, including jumps to the same jump instruction. @@ -81,7 +81,7 @@ For each instruction: - for `JUMPF` into non-returning function the recorded stack height lower bound must be at least the number of inputs of the target function according to its type defined in the type section, - for any other instruction the recorded stack height lower bound must be at least the number of inputs required by instruction, - there is no additional check for terminating instructions other than `RETF` and `JUMPF`, this implies that extra items left on stack at instruction ending EVM execution are allowed. - 2. For `CALLF` and `JUMPF` **check** for possible stack overflow: if recorded stack height upper bound is greater than `1024 - types[target_section_index].max_stack_height + types[target_section_index].inputs`, validation fails. + 2. For `CALLF` and `JUMPF` **check** for possible stack overflow: if recorded stack height upper bound is greater than `1024 - types[target_section_index].max_stack_increase`, validation fails. 3. Compute new stack height bounds after the instruction execution. Upper and lower bound are updated by the same value: - after `CALLF` stack height bounds are adjusted by adding `types[target_section_index].outputs - types[target_section_index].inputs`, - after any other non-terminating instruction stack height bounds are adjusted by subtracting the number of instruction inputs and adding the number of instruction outputs, @@ -100,7 +100,7 @@ After all instructions are visited, determine the function maximum operand stack 1. Compute the maximum stack height as the maximum of all recorded stack height upper bounds. 2. **Check** if the maximum stack height does not exceed the limit of 1023 (`0x3FF`). -3. **Check** if the maximum stack height matches the corresponding code section's `max_stack_height` within the type section. +3. **Check** if the maximum stack height matches the corresponding code section's maximum stack height (which is `inputs` + `max_stack_increase`) within the type section. The computational and space complexity of this pass is *O(len(code))*. Each instruction is visited at most once. @@ -124,7 +124,7 @@ Any code section validated according to operand stack validation has the followi ### Stack overflow check only in CALLF/JUMPF -In this EIP, we provide a more efficient variant of the EVM where stack overflow check is performed only in `CALLF` and `JUMPF` instructions using the called function's `max_stack_height` information. This decreases flexibility of an EVM program because `max_stack_height` corresponds to the worst-case control-flow path in the function. +In this EIP, we provide a more efficient variant of the EVM where stack overflow check is performed only in `CALLF` and `JUMPF` instructions using the called function's `inputs` and `max_stack_increase` information. This decreases flexibility of an EVM program because the calculated maximum stack corresponds to the worst-case control-flow path in the function. ### Unreachable code diff --git a/EIPS/eip-6206.md b/EIPS/eip-6206.md index c92bad5006b6b4..b6061f558d4b02 100644 --- a/EIPS/eip-6206.md +++ b/EIPS/eip-6206.md @@ -38,7 +38,7 @@ The first code section MUST have 0 inputs and be non-returning. A new instruction, `JUMPF (0xe5)`, is introduced. 1. `JUMPF` has one immediate argument, `target_section_index`, encoded as a 16-bit unsigned big-endian value. -2. If the operand stack size exceeds `1024 - type[target_section_index].max_stack_height + type[target_section_index].inputs` (i.e. if the called function may exceed the global stack height limit), execution results in an exceptional halt. This guarantees that the target function does not exceed global stack height limit. +2. If the operand stack size exceeds `1024 - type[target_section_index].max_stack_increase (i.e. if the called function may exceed the global stack height limit), execution results in an exceptional halt. This guarantees that the target function does not exceed global stack height limit. 3. `JUMPF` sets `current_section_index` to `target_section_index` and `PC` to `0`, but does not change the return stack. Execution continues in the target section. 4. `JUMPF` costs 5 gas. 5. `JUMPF` neither pops nor pushes anything to the operand stack. @@ -54,7 +54,7 @@ Let the definition of `type[i]` be inherited from [EIP-4750](./eip-4750.md) and * The stack height validation at `JUMPF` depends on whether the target section is non-returning: * `JUMPF` into returning section (`type[target_section_index].outputs` does not equal `0x80`): `stack_height_min` and `stack_height_max` MUST be equal to `type[current_section_index].outputs - type[target_section_index].outputs + type[target_section_index].inputs`. This means that target section can output less stack elements than the original code section called by the top element on the return stack, if the current code section leaves the delta `type[current_section_index].outputs - type[target_section_index].outputs` element(s) on the stack. * `JUMPF` into non-returning section (`type[target_section_index].outputs` equals `0x80`): `stack_height_min` MUST be greater than or equal to `type[target_section_index].inputs`. -* Stack overflow check at `JUMPF`: `stack_height_max` MUST be less than or equal to `1024 - types[target_section_index].max_stack_height + types[target_section_index].inputs`. +* Stack overflow check at `JUMPF`: `stack_height_max` MUST be less than or equal to `1024 - types[target_section_index].max_stack_increase`. * `JUMPF` is considered terminating instruction, i.e. does not have successor instructions in code validation and MAY be final instruction in the section. * The code validation defined in [EIP-4200](./eip-4200.md) also fails if any `RJUMP*` offset points to one of the two bytes directly following a `JUMPF` instruction. diff --git a/EIPS/eip-7620.md b/EIPS/eip-7620.md index 7a664ec2184361..4f364d7f258537 100644 --- a/EIPS/eip-7620.md +++ b/EIPS/eip-7620.md @@ -1,7 +1,7 @@ --- eip: 7620 title: EOF Contract Creation -description: Introduce `EOFCREATE` and `RETURNCONTRACT` instructions +description: Introduce `EOFCREATE` and `RETURNCODE` instructions author: Alex Beregszaszi (@axic), Paweł Bylica (@chfast), Andrei Maiboroda (@gumb0), Piotr Dobaczewski (@pdobacz) discussions-to: https://ethereum-magicians.org/t/eip-7620-eof-contract-creation-instructions/18625 status: Review @@ -13,7 +13,7 @@ requires: 170, 684, 2929, 3540, 3541, 3670 ## Abstract -EVM Object Format (EOF) removes the possibility to create contracts using `CREATE` or `CREATE2` instructions. We introduce a new/replacement method in form of pair of instructions : `EOFCREATE` and `RETURNCONTRACT` to provide a way to create contracts using EOF containers. +EVM Object Format (EOF) removes the possibility to create contracts using `CREATE` or `CREATE2` instructions. We introduce a new/replacement method in form of pair of instructions : `EOFCREATE` and `RETURNCODE` to provide a way to create contracts using EOF containers. ## Motivation @@ -40,7 +40,7 @@ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "S We introduce two new instructions on the same block number [EIP-3540](./eip-3540.md) is activated on: 1. `EOFCREATE` (`0xec`) -2. `RETURNCONTRACT` (`0xee`) +2. `RETURNCODE` (`0xee`) ### Execution Semantics @@ -51,7 +51,7 @@ We introduce two new instructions on the same block number [EIP-3540](./eip-3540 #### Overview of the new contract creation flow -In EOF EVM, new bytecode is delivered by means of creation transactions (with an empty `to`) in the form of an EOF container (`initcontainer`). Such a container may contain arbitrarily deeply nesting subcontainers. The `initcontainer` and its subcontainers are recursively validated according to all the validation rules applicable for the EOF version in question. Next, the 0th code section of the `initcontainer` is executed and may eventually call a `RETURNCONTRACT` instruction, which will refer to a subcontainer to be finally deployed to an address. +In EOF EVM, new bytecode is delivered by means of creation transactions (with an empty `to`) in the form of an EOF container (`initcontainer`). Such a container may contain arbitrarily deeply nesting subcontainers. The `initcontainer` and its subcontainers are recursively validated according to all the validation rules applicable for the EOF version in question. Next, the 0th code section of the `initcontainer` is executed and may eventually call a `RETURNCODE` instruction, which will refer to a subcontainer to be finally deployed to an address. EOF creation transactions (ones with an empty `to` and with `data` starting with `EF00` magic) are defined in detail in [EIP-7698](./eip-7698.md). @@ -64,29 +64,29 @@ Details on each instruction follow in the next sections. - deduct `TX_CREATE_COST` gas - halt with exceptional failure if the current frame is in `static-mode`. - read immediate operand `initcontainer_index`, encoded as 8-bit unsigned value -- pop `value`, `salt`, `input_offset`, `input_size` from the operand stack +- pop `salt`, `input_offset`, `input_size`, `value` from the operand stack - perform (and charge for) memory expansion using `[input_offset, input_size]` - load initcode EOF subcontainer at `initcontainer_index` in the container from which `EOFCREATE` is executed - let `initcontainer` be that EOF container, and `initcontainer_size` its length in bytes declared in its parent container header -- deduct `GAS_KECCAK256_WORD * ((initcontainer_size + 31) // 32)` gas (hashing charge) - check that current call depth is below `STACK_DEPTH_LIMIT` and that caller balance is enough to transfer `value` - in case of failure return 0 on the stack, caller's nonce is not updated and gas for initcode execution is not consumed. - caller's memory slice `[input_offset:input_size]` is used as calldata - execute the container and deduct gas for execution. The 63/64th rule from [EIP-150](./eip-150.md) applies. - increment `sender` account's nonce -- calculate `new_address` as `keccak256(0xff || sender || salt || keccak256(initcontainer))[12:]` +- calculate `new_address` as `keccak256(0xff || sender || salt)[12:]` - behavior on `accessed_addresses` and address collision is same as `CREATE2` (rules for `CREATE2` from [EIP-684](./eip-684.md) and [EIP-2929](./eip-2929.md) apply to `EOFCREATE`) - an unsuccessful execution of initcode results in pushing `0` onto the stack - can populate returndata if execution `REVERT`ed -- a successful execution ends with initcode executing `RETURNCONTRACT{deploy_container_index}(aux_data_offset, aux_data_size)` instruction (see below). After that: - - load deploy EOF subcontainer at `deploy_container_index` in the container from which `RETURNCONTRACT` is executed +- a successful execution ends with initcode executing `RETURNCODE{deploy_container_index}(aux_data_offset, aux_data_size)` instruction (see below). After that: + - load deploy EOF subcontainer at `deploy_container_index` in the container from which `RETURNCODE` is executed - concatenate data section with `(aux_data_offset, aux_data_offset + aux_data_size)` memory segment and update data size in the header - if updated deploy container size exceeds `MAX_CODE_SIZE` instruction exceptionally aborts - set `state[new_address].code` to the updated deploy container + - set `state[new_address].nonce` to 1 - push `new_address` onto the stack - deduct `GAS_CODE_DEPOSIT * deployed_code_size` gas -#### `RETURNCONTRACT` +#### `RETURNCODE` - read immediate operand `deploy_container_index`, encoded as 8-bit unsigned value - pop two values from the operand stack: `aux_data_offset`, `aux_data_size` referring to memory section that will be appended to deployed container's data @@ -101,12 +101,12 @@ We extend code section validation rules (as defined in [EIP-3670](./eip-3670.md) 1. `EOFCREATE` `initcontainer_index` must be less than `num_container_sections` 2. `EOFCREATE` the subcontainer pointed to by `initcontainer_index` must have its `len(data_section)` equal `data_size`, i.e. data section content is exactly as the size declared in the header (see [Data section lifecycle](#data-section-lifecycle)) 3. `EOFCREATE` the subcontainer pointed to by `initcontainer_index` must not contain either a `RETURN` or `STOP` instruction -4. `RETURNCONTRACT` `deploy_container_index` must be less than `num_container_sections` -5. `RETURNCONTRACT` the subcontainer pointed to `deploy_container_index` must not contain a `RETURNCONTRACT` instruction -6. It is an error for a container to contain both `RETURNCONTRACT` and either of `RETURN` or `STOP` +4. `RETURNCODE` `deploy_container_index` must be less than `num_container_sections` +5. `RETURNCODE` the subcontainer pointed to `deploy_container_index` must not contain a `RETURNCODE` instruction +6. It is an error for a container to contain both `RETURNCODE` and either of `RETURN` or `STOP` 7. It is an error for a subcontainer to never be referenced in its parent container -8. It is an error for a given subcontainer to be referenced by both `RETURNCONTRACT` and `EOFCREATE` -9. `RJUMP`, `RJUMPI` and `RJUMPV` immediate argument value (jump destination relative offset) validation: code section is invalid in case offset points to the byte directly following either `EOFCREATE` or `RETURNCONTRACT` instruction. +8. It is an error for a given subcontainer to be referenced by both `RETURNCODE` and `EOFCREATE` +9. `RJUMP`, `RJUMPI` and `RJUMPV` immediate argument value (jump destination relative offset) validation: code section is invalid in case offset points to the byte directly following either `EOFCREATE` or `RETURNCODE` instruction. ### Data Section Lifecycle @@ -134,8 +134,8 @@ pre_deploy_data_section | static_aux_data | dynamic_aux_data where: -- `aux_data` is the data which is appended to `pre_deploy_data_section` on `RETURNCONTRACT` instruction. -- `static_aux_data` is a subrange of `aux_data`, which size is known before `RETURNCONTRACT` and equals `pre_deploy_data_size - len(pre_deploy_data_section)`. +- `aux_data` is the data which is appended to `pre_deploy_data_section` on `RETURNCODE` instruction. +- `static_aux_data` is a subrange of `aux_data`, which size is known before `RETURNCODE` and equals `pre_deploy_data_size - len(pre_deploy_data_section)`. - `dynamic_aux_data` is the remainder of `aux_data`. `data_size` in the deployed container header is updated to be equal `len(data_section)`. @@ -155,24 +155,26 @@ The data section is appended to during contract creation and also its size needs All of these alternatives either complicated the otherwise simple data structures or took away useful features (like the dynamically sized portion of the data section). +### `CREATE`/`CREATE2` reactions to valid EOF code + +During development of this EIP there was initially behavior changes for `CREATE` and `CREATE2` when the provided code was valid EOF. This required looping in EOF parsing into the existing create instructions to produce a different outcome. The implementors decided that the outcome should be the same for valid and invalid EOF, since the legacy create operations can never create EOF code, and a different outcome could result in a form of code introspection we aim to eliminate. So all references to changes in the legacy create opcodes were removed, and we relied on existing specs to cover their behavior. + ## Backwards Compatibility This change poses no risk to backwards compatibility, as it is introduced at the same time EIP-3540 is. The new instructions are not introduced for legacy bytecode (code which is not EOF formatted), and the contract creation options do not change for legacy bytecode. -`CREATE` and `CREATE2` calls with `EF00` initcode fail early without executing the initcode. Previously, in both cases the initcode execution would begin and fail on the first undefined instruction `EF`. - ## Test Cases -Creation transaction, `CREATE` and `CREATE2` cannot have its *code* starting with `0xEF`, but such cases are covered already in [EIP-3541](./eip-3541.md). However, new cases must be added where `CREATE` or `CREATE2` have its *initcode* being (validly or invalidly) EOF formatted: +Creation transaction, `CREATE` and `CREATE2` cannot have its *code* starting with `0xEF`, but such cases are covered already in [EIP-3541](./eip-3541.md). However, this should be veified as part of the `CREATE`/`CREATE2` test suiteds: -| Initcode | Expected result | -| - | - | -| `0xEF` | initcode starts execution and fails | -| `0xEF01` | initcode starts execution and fails | -| `0xEF5f` | initcode starts execution and fails | -| `0xEF00` | `CREATE` / `CREATE2` fails early, returns 0 and keeps sender nonce intact | -| `0xEF0001` | as above | -| valid EOFv1 container | as above | +| Initcode | Expected result | +|-----------------------|----------------------------------------------------------| +| `0xEF` | Exceptional abort without execution | +| `0xEF01` | Exceptional abort without execution | +| `0xEF5f` | Exceptional abort without execution | +| `0xEF00` | `CREATE` / `CREATE2` Exceptional abort without execution | +| `0xEF0001` | Exceptional abort without execution | +| valid EOFv1 container | Exceptional abort without execution | ## Security Considerations diff --git a/EIPS/eip-7692.md b/EIPS/eip-7692.md index f0e7661ee0d16e..2cbcf8babd371c 100644 --- a/EIPS/eip-7692.md +++ b/EIPS/eip-7692.md @@ -28,7 +28,7 @@ This Meta EIP lists the EIPs which belong to the EVM Object Format (EOF) proposa - [EIP-663](./eip-663.md): SWAPN, DUPN and EXCHANGE instructions - [EIP-7069](./eip-7069.md): Revamped CALL instructions - [EIP-7620](./eip-7620.md): EOF Contract Creation -- [EIP-7698](./eip-7698.md): EOF - Creation transaction +- [EIP-7873](./eip-7873.md): EOF - TXCREATE and InitcodeTransaction type ## Rationale diff --git a/EIPS/eip-7698.md b/EIPS/eip-7698.md index 85679e5ecc519b..a294e025d84864 100644 --- a/EIPS/eip-7698.md +++ b/EIPS/eip-7698.md @@ -13,7 +13,7 @@ requires: 3540 ## Abstract -Creation transactions (i.e. the ones with empty `to`) can be used to deploy EOF contracts by providing EOF initcontainer concatenated with `calldata` for initcontainer execution in transaction's `data`. Initcontainer execution is similar to its execution during `EOFCREATE` instruction, ending with `RETURNCONTRACT` instruction. New account address calculation is based on sender's address and nonce. +Creation transactions (i.e. the ones with empty `to`) can be used to deploy EOF contracts by providing EOF initcontainer concatenated with `calldata` for initcontainer execution in transaction's `data`. Initcontainer execution is similar to its execution during `EOFCREATE` instruction, ending with `RETURNCODE` instruction. New account address calculation is based on sender's address and nonce. ## Motivation @@ -43,9 +43,9 @@ In case a creation transaction (transaction with empty `to`) has `data` starting 4. If EOF header parsing or full container validation fails, transaction is considered valid and failing. Gas for initcode execution is not consumed, only intrinsic creation transaction costs are charged. 5. `calldata` part of transaction `data` that follows `initcontainer` is treated as calldata to pass into the execution frame. 6. Execute the container and deduct gas for execution. - 1. Calculate `new_address` as `keccak256(sender || sender_nonce)[12:]` - 2. A successful execution ends with initcode executing `RETURNCONTRACT{deploy_container_index}(aux_data_offset, aux_data_size)` instruction. After that: - - load deploy-contract from EOF subcontainer at `deploy_container_index` in the container from which `RETURNCONTRACT` is executed, + 1. Calculate `new_address` as `keccak256(0xff || sender || sender_nonce)[12:]` + 2. A successful execution ends with initcode executing `RETURNCODE{deploy_container_index}(aux_data_offset, aux_data_size)` instruction. After that: + - load deploy-contract from EOF subcontainer at `deploy_container_index` in the container from which `RETURNCODE` is executed, - concatenate data section with `(aux_data_offset, aux_data_offset + aux_data_size)` memory segment and update data size in the header, - let `deployed_code_size` be updated deploy container size, - if `deployed_code_size > MAX_CODE_SIZE` instruction exceptionally aborts, diff --git a/EIPS/eip-7701.md b/EIPS/eip-7701.md index b50c9f3991775c..1f250974d07c42 100644 --- a/EIPS/eip-7701.md +++ b/EIPS/eip-7701.md @@ -76,7 +76,7 @@ header := kind_data, data_size, terminator body := types_section, entry_points_section, code_section+, container_section*, data_section -types_section := (inputs, outputs, max_stack_height)+ +types_section := (inputs, outputs, max_stack_increase)+ entry_points_section := (entry_point_role, target_section_index, target_section_flags)+ ``` diff --git a/EIPS/eip-7834.md b/EIPS/eip-7834.md index 0b4376bdbdaebf..ed08547399af20 100644 --- a/EIPS/eip-7834.md +++ b/EIPS/eip-7834.md @@ -49,29 +49,30 @@ header := kind_data, data_size, terminator body := types_section, code_section+, container_section*, [metadata_section], data_section -types_section := (inputs, outputs, max_stack_height)+ +types_section := (inputs, outputs, max_stack_increase)+ ``` ### Header | name | length | value | description | -| ------------- | ------- | ------------- | --------------------------------------------------------------------------------------- | +|---------------|---------|---------------|-----------------------------------------------------------------------------------------| | ... | ... | ... | ... | +| kind_reserved | 1 byte | 0x04 | old kind maker for data section size. This section kind should not be reused. | | kind_metadata | 1 byte | 0x05 | kind marker for metadata size section | | metadata_size | 2 bytes | 0x0001-0xFFFF | 16-bit unsigned big-endian integer denoting the length of the metadata section content | -| kind_data | 1 byte | 0x04 | kind marker for data size section | +| kind_data | 1 byte | 0xff | kind marker for data size section | | data_size | 2 bytes | 0x0000-0xFFFF | 16-bit unsigned big-endian integer denoting the length of the data section content (\*) | | terminator | 1 byte | 0x00 | marks the end of the header | ### Body | name | length | value | description | -| ---------------- | -------- | ----- | --------------------------- | +|------------------|----------|-------|-----------------------------| | ... | ... | ... | ... | | metadata_section | variable | n/a | arbitrary sequence of bytes | | data_section | variable | n/a | arbitrary sequence of bytes | -The strucure and the encoding of the `metadata_section` is not defined by this EIP. It is left to the compilers, tooling, or the contract developers to define the encoding and the content. The current practice by the Solidity and Vyper compilers is to use CBOR encoding. +The structure and the encoding of the `metadata_section` is not defined by this EIP. It is left to the compilers, tooling, or the contract developers to define the encoding and the content. The current practice by the Solidity and Vyper compilers is to use CBOR encoding. ## Rationale diff --git a/EIPS/eip-7873.md b/EIPS/eip-7873.md index 861854addb1bd9..9a9aa7a2a96201 100644 --- a/EIPS/eip-7873.md +++ b/EIPS/eip-7873.md @@ -23,7 +23,7 @@ Creation transaction and creation instructions `CREATE` and `CREATE2` are means Additionally, the new instruction and transaction type introduced in this EIP enable contracts to create other contracts using initcode from the transaction data, which in legacy EVM is achieved via a combination of `CREATE` or `CREATE2` and loading the initcode from calldata. -This mechanism complements `EOFCREATE` and `RETURNCONTRACT` instructions from [EIP-7620](./eip-7620.md), and thus all use cases of contract creation that are available in legacy EVM are enabled for EOF. +This mechanism complements `EOFCREATE` and `RETURNCODE` instructions from [EIP-7620](./eip-7620.md), and thus all use cases of contract creation that are available in legacy EVM are enabled for EOF. ## Specification @@ -110,7 +110,7 @@ Introduce a new instruction on the same block number [EIP-3540](./eip-3540.md) i - deduct `TX_CREATE_COST` gas - halt with exceptional failure if the current frame is in `static-mode`. -- pop `tx_initcode_hash`, `value`, `salt`, `input_offset`, `input_size` from the operand stack +- pop `tx_initcode_hash`, `salt`, `input_offset`, `input_size`, `value` from the operand stack - perform (and charge for) memory expansion using `[input_offset, input_size]` - load initcode EOF container from the transaction `initcodes` array which hashes to `tx_initcode_hash` - fails (returns 0 on the stack) if such initcode does not exist in the transaction, or if called from a transaction of `TransactionType` other than `INITCODE_TX_TYPE` @@ -131,11 +131,12 @@ Introduce a new instruction on the same block number [EIP-3540](./eip-3540.md) i - an unsuccessful execution of initcode results in pushing `0` onto the stack - can populate returndata if execution `REVERT`ed - `sender`'s nonce stays updated -- a successful execution ends with initcode executing `RETURNCONTRACT{deploy_container_index}(aux_data_offset, aux_data_size)` instruction (see [EIP-7620](./eip-7620.md)). After that: - - load deploy EOF subcontainer at `deploy_container_index` in the container from which `RETURNCONTRACT` is executed +- a successful execution ends with initcode executing `RETURNCODE{deploy_container_index}(aux_data_offset, aux_data_size)` instruction (see [EIP-7620](./eip-7620.md)). After that: + - load deploy EOF subcontainer at `deploy_container_index` in the container from which `RETURNCODE` is executed - concatenate data section with `(aux_data_offset, aux_data_offset + aux_data_size)` memory segment and update data size in the header - if updated deploy container size exceeds `MAX_CODE_SIZE`, instruction exceptionally aborts - set `state[new_address].code` to the updated deploy container + - set `state[new_address].nonce` to 1 - push `new_address` onto the stack - deduct `GAS_CODE_DEPOSIT * deployed_code_size` gas @@ -213,8 +214,6 @@ This change poses no risk to backwards compatibility, as it is introduced at the Needs discussion. - - ## Copyright Copyright and related rights waived via [CC0](../LICENSE.md).