EOF bootstrapping

Options

Here are the options for EOF bootstrapping which are considered in combination with TXCREATE opcode and the InitcodeTransaction, as specced in EIP-7873. Current status (EIP-7873 with legacy EVM code enabling TXCREATE opcode) is good, but there was feedback that some features (improvements on multichain deployments and having a default deployment method) would still be nice to have and there are alternatives to consider. The doc attempts to gather these in one spot and list their differences.

For the reference, EIP-7873 specifies that TXCREATE calculates new_address as keccak256(0xff || sender32 || salt)[12:].

NOTE that (1.) and (2.) are previous designs which are kept here only for reference, as they both have been superseded by the baseline (3.)

  1. (* obsolete previous design) Creator Contract predeploy
  2. (* obsolete previous design) EIP-7698 - eof creation tx with to: nil and EOF initcontainer prepended to input calldata in tx.data
  3. Allowing TXCREATE in legacy EVM, disallowing to: nil for InitcodeTransactions (current EIP-7873)
  4. Allowing to: nil InitcodeTransactions doing:
    if tx.to is null:
      assert len(initcodes) == 1
      run(initcodes[0])
    
    Calculate new_address like for an ordinary to: nil creation tx (nonce based)
  5. Allowing to: nil InitcodeTransactions which interprets tx.data = <tx_initcode_hash> || <salt> || <input...> as TXCREATE arguments. tx.initcodes[tx_initcode_hash] is run with input as input.
    Calculate new_address as keccak256(0xff || initcode_hash || input || salt)[12:] (**).
  6. (middle ground between (4.) and (5.)) Allowing to: nil InitcodeTransactions which interprets tx.data = <salt> || <input...> and executes
    if tx.to is null:
      assert len(initcodes) == 1
      run(initcodes[0])
    
    Calculate new_address as keccak256(0xff || keccak256(initcodes[0]) || input || salt)[12:]. (**)

(**) - new_address hashing scheme doesn’t include sender as it makes it possible to make a multichain deployment independent of holding a particular private key. However, it makes it less of a default deployment method as it makes the deployment front-runnable, c.f. similar discussion.

Comparison

Legend:

(1.) (*) (2.) (*) (3.) (4.) (5.) (6.)
improved multichain deployment support ❌❌ (***)
has default deployment method
clean ⚠️
extendable in future forks
easy fork transition
avoids contract audit
trivial testing
Creator Contract predeploy
Create via existing TX types (0,1,2)
TXCREATE as a legacy opcode
InitcodeTx (type 6) to: nil
tx.data parsing for to: nil

Features:

“Niceness” qualities: