---
eip: 7620
title: EOF Contract Creation
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: Stagnant
type: Standards Track
category: Core
created: 2024-02-12
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 `RETURNCODE` to provide a way to create contracts using EOF containers.

## Motivation

This EIP uses terminology from the [EIP-3540](./eip-3540.md) which introduces the EOF format.

EOF aims to remove code observability, which is a prerequisite to legacy EVM contract creation logic using legacy-style create transactions, `CREATE` or `CREATE2`, because both the initcode and code are available to the EVM and can be manipulated. On the same premise, EOF removes opcodes like `CODECOPY` and `EXTCODECOPY`, introducing EOF subcontainers as a replacement to cater for factory contracts creating other contracts.

The new instructions introduced in this EIP operate on EOF containers enabling factory contract use case that legacy EVM has.

## Specification

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174.

Wherever not explicitly listed, the rules of EOF contract creation, as well as the `EOFCREATE` instruction, should be identical or analogous to those of `CREATE2` instruction. This includes but is not limited to:

- behavior on `accessed_addresses` and address collision ([EIP-684](./eip-684.md) and [EIP-2929](./eip-2929.md))
- EVM execution frame created for the `EOFCREATE` initcode - memory, account context etc.
- nonce bumping of the account of newly created contract [EIP-161](./eip-161.md)
- balance checking and transfer for the creation endowment (`value` argument)
    
### Parameters

| Constant | Value |
| - | - |
| `TX_CREATE_COST` | Defined as `32000` in the [Ethereum Execution Layer Specs](https://github.com/ethereum/execution-specs/blob/0f9e4345b60d36c23fffaa69f70cf9cdb975f4ba/src/ethereum/shanghai/fork_types.py#L42) |
| `STACK_DEPTH_LIMIT` | Defined as `1024` in the [Ethereum Execution Layer Specs](https://github.com/ethereum/execution-specs/blob/0f9e4345b60d36c23fffaa69f70cf9cdb975f4ba/src/ethereum/shanghai/vm/interpreter.py#L60) |
| `GAS_CODE_DEPOSIT` | Defined as `200` in the [Ethereum Execution Layer Specs](https://github.com/ethereum/execution-specs/blob/0f9e4345b60d36c23fffaa69f70cf9cdb975f4ba/src/ethereum/shanghai/vm/gas.py#L44) |
| `MAX_CODE_SIZE` | Defined as `24576` in [EIP-170](./eip-170.md) |

We introduce two new instructions on the same block number [EIP-3540](./eip-3540.md) is activated on:

1. `EOFCREATE` (`0xec`)
2. `RETURNCODE` (`0xee`)

If the code is legacy bytecode, any of these instructions result in an *exceptional halt*. (*Note: This means no change to behaviour.*)

### Execution Semantics

- The instructions `CREATE`, `CREATE2` are made obsolete and rejected by validation in EOF contracts. They are only available in legacy contracts.
- If instructions `CREATE` and `CREATE2` have EOF code as initcode (starting with `EF00` magic)
    - deployment fails (returns 0 on the stack)
    - caller's nonce is not updated and gas for initcode execution is not consumed

In the context of legacy bytecode execution any of these instructions (`EOFCREATE`, `RETURNCODE`) result in an *exceptional halt*. (*Note: This means no change to behaviour.*)

#### Overview of the new contract creation flow

In EOF EVM, new bytecode is introduced to the state by means of `InitcodeTransaction` delivering an EOF container (`initcontainer`). Such a container may include 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.

`InitcodeTransactions` are defined in detail in [EIP-7873](./eip-7873.md).

`EOFCREATE` instruction is in turn a replacement of the `CREATE` and `CREATE2` legacy instructions allowing factory contracts to create other contracts. The main difference to the `InitcodeTransaction` is that the `initcontainer` is selected to be one of the subcontainers of the EOF container calling `EOFCREATE` (and not one of `transaction.initcodes`). It is worth noting that no validation is performed at this point, as it has already been done when the factory contract containing `EOFCREATE` was deployed.

Details on each instruction follow in the next sections.

#### `EOFCREATE`

- 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 `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
- 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 || sender32 || salt)[12:]`, where `sender32` is the sender address left-padded to 32 bytes with zeros
- 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 `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 needed.
    - if updated deploy container size exceeds `MAX_CODE_SIZE` instruction exceptionally aborts
    - set `state[new_address].code` to the updated deploy container
    - push `new_address` onto the stack
- deduct `GAS_CODE_DEPOSIT * deployed_code_size` gas

#### `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
- cost 0 gas + possible memory expansion for aux data
- ends initcode frame execution and returns control to EOFCREATE caller frame where `deploy_container_index` and `aux_data` are used to construct deployed contract (see above)
- instruction exceptionally aborts if after the appending, data section size would overflow the maximum data section size or underflow (i.e. be less than data section size declared in the header)

### Code Validation

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. `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 `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

**For an EOF container which has not yet been deployed**, the `data_section` is only a portion of the final `data_section` after deployment.
Let's define it as `pre_deploy_data_section` and as `pre_deploy_data_size` the `data_size` declared in that container's header.
`pre_deploy_data_size >= len(pre_deploy_data_section)`, which anticipates more data to be appended to the `pre_deploy_data_section` during the process of deploying.

```
pre_deploy_data_section
|                                      |
\___________pre_deploy_data_size______/
```

**For a deployed EOF container**, the final `data_section` becomes:

```
pre_deploy_data_section | static_aux_data | dynamic_aux_data
|                         |             |                  |
|                          \___________aux_data___________/
|                                       |                  |
\___________pre_deploy_data_size______/                    |
|                                                          |
\________________________data_size_______________________/
```

where:
    
- `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)`.

Summarizing, there are `pre_deploy_data_size` bytes in the final data section which are guaranteed to exist before the EOF container is deployed and `len(dynamic_aux_data)` bytes which are known to exist only after.
This impacts the validation and behavior of data-section-accessing instructions: `DATALOAD`, `DATALOADN`, and `DATACOPY`, see [EIP-7480](./eip-7480.md).

## Rationale

### Data section appending

The data section is appended to during contract creation and also its size needs to be updated in the header. Alternative designs were considered, where:

- additional section kinds for the data were introduced
- additional fields describing a subcontainer were introduced
- data section would be written over as opposed to being appended to, requiring it to be filled with 0 bytes prior to deployment
    
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).

### `keccak256(initcontainer)` in the `new_address` hashing scheme

`new_address = keccak256(0xff || sender || salt || keccak256(initcontainer))[12:]` was originally proposed as the way to calculate the address of newly created contract, similar, but not exactly equal, to what `CREATE2` uses.

This alternative however goes against code non-observability, because it locks in the contents of the initcontainer e.g. preventing re-writing it in some future upgrade. It also seems unnecessarily expensive: `EOFCREATE` can only pick up one of its subcontainers, yet the hash value would need to be recalculated on every execution of `EOFCREATE`.

Other ways of removing code observability, yet keeping some form of witness of the code, were considered. However, keeping only `sender` and `salt` allows the implementer of the factory contract (i.e. one containing the `EOFCREATE` instruction) to include the code witness via the `salt` anyway, if that's necessary for the particular use case. Therefore, keeping the `new_address` formula minimal is the most flexible approach with better separation of concerns.

Leaving the `keccak256(initcontainer)` out of the `new_address` hash has also the benefit of making the `new_address` independent of the metadata section (proposed for the EOF in a separate EIP), which is a desired property. Unfortunately, if a factory wants to opt into committing to a particular `initcontainer`, it needs to include it in the `salt`, and that will include the metadata section.

### `EOFCREATE` stack argument order

`EXT*CALL` instructions from [EIP-7069](./eip-7069.md) have had their stack argument order changed, as compared to that of legacy instructions `*CALL`. We follow the same change to have `EOFCREATE` stack arg order match those of `EXTCALL`.

## 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:

| 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 |

## Security Considerations

It is the EOF `InitcodeTransaction` (specified in [EIP-7873](./eip-7873.md)) which needs a detailed review and discussion as that is where external unverified code enters the state. Among others:

1. Is its complexity under control, ruling out any DoS attempts
2. Is it correctly priced and always charged for
3. Is the validation comprehensive and not allowing problematic code to be saved into the state

## Copyright

Copyright and related rights waived via [CC0](../LICENSE.md).
