CREATEF
=======
In general, replace CREATE3/CREATE4 with CREATEF, where the same executing contract is used for initcode, but a different code section other than 0 is used.
Problem
-------
Using the factory pattern will require two levels of nesting if done in a EOF container. First there is the executing container, then there is the container that holds the exec code, then there will be the deployed contract itself.
```
+-----------------------------+
| Factory Contract |
| +-------------------------+ |
| | Child contract initcode | |
| | +----------------+ | |
| | | Child Contract | | |
| | +----------------+ | |
| +-------------------------+ |
+-----------------------------+
```
There will be three separate EOF headers to parse. Let's not forget, this also has to be deployed, so the master deployer will have _at least_ 3 layers of nested contracts.
```
+---------------------------------+
| Factory Contract Deployer |
| +-----------------------------+ |
| | Factory Contract | |
| | +-------------------------+ | |
| | | Child contract initcode | | |
| | | +----------------+ | | |
| | | | Child Contract | | | |
| | | +----------------+ | | |
| | +-------------------------+ | |
| +-----------------------------+ |
+---------------------------------+
```
Solution
--------
Instead of going to a separate EOF container that contains initcode, the current container will contain the initcode at a different code setcion than the main entry point. The CREATEF call, instead of pointing to a subcointainer, will point to a code section to perform the pre-deployment initialization.
```
+--------------------------------------+
| Factory Contract |
| sections 0-n Normal factory code |
| section m Child contract initcode |
| +----------------+ |
| | Child Contract | |
| +----------------+ |
+--------------------------------------+
```
This also allows for multiple contract to re-use subroutines from other initcode and the main factory code. A single CREATEF operation replaces CREATE3/CREATE4 and two return operations replace RETURNCONTRAcT, one referencing a EOF subcontainer index and one referening a hash of a container in the transaction body of a new transaction type.
* CREATEF Operation
* deduct 32000 gas
* read uint8 operand initcodesection_index
* pops value, salt, data_offset, data_size from the stack
* deduct 8 * ((initcontainer_size + 31) // 32) gas (EIP-3860 + hashing charge)
* calculate new_address as keccak256(0xff |\| sender |\| salt |\| inicodesection_index |\| keccak256(container))[12:]
* Creates a new stack frame executing under the new address, but with the existing container. Execution starts with the first byte of the referened code section
* an unsuccesful execution of initcode results in pushing 0 onto the stack
* set state[new_address].code to the updated container
* push new_address onto the stack
* RETURN and STOP are not allowed (abort execution)
* RETF at the top of the return stack is similarly not allowed
* deduct 200 * deployed_code_size gas
* if initcode container or deployed container is invalid, instruction’s execution ends with the result 0 pushed on stack. The caller’s nonce remains increased and all creation gas is deducted.
Instead of two create variants there are two contract return variants
* RETURN_CONTRACT_INDEX instruction
* loads uint8 immediate container_index
* exceptional halt if the container does not have a subcontainer at that index
* exceptional halt if subcontainer code is EOF invalid (unless we settle on deep validation for containers from an external source)
* pops two values from the stack: aux_data_offset, aux_data_size
* Appends the aux data to the subcontainer, and re-writes the header if needed to accomodate the added data
* cost 0 gas + 1 byte per final contract size
* instruction exceptionally aborts if invoked not in “initcode mode”
* RETURN_CONTRACT_HASH instruction
* pops three values from the stack: codehash, aux_data_offset, aux_data_size
* Searches for code with the codehash in specified locations
* For EOF1 this will be a new transaction type that has extra "data" fields that hold containers, like CREATE4
* Account Abstraction systems can combine multiple creat calls into one TX without concern about the transaction indexes.
* L2s/L3s and ZK systems may want to create a "library" of know contracts by hash, that are pre-loaded and pre-compiled.
* exceptional halt if subcontainer code is EOF invalid (validation is always performed)
* Appends the aux data to the subcontainer, and re-writes the header if needed to accomodate the added data
* cost 0 gas + 1 byte per final contract size
* instruction exceptionally aborts if invoked not in “initcode mode”
The two return operations could be combined if we added a magic rule that any return value with 30 or more leading zeros refers to a container index. Or if we also refered to the subcontainers by hash.