Yes, in absence of a non-hacky way to supply salt
, unless we have an idea
Oh, implicitly executing one of the containers in the transaction is not what I had in mind.
I was just suggesting to have InitcodeTransaction with to = null
behave exactly the same as the current transaction types, i.e., the data
is executed as legacy EVM bytecode. This allows one to execute code that uses TXCREATE
to deploy one of the init containers included in the transaction, without returning anything so that no code is deposited (in fact, it could conclude with a call to selfdestruct ).
Iâd agree that this is⌠ugly.
We could also do something like when to = null
the transaction data is interpreted as parameters to a TXCREATE
-like operation that would get implicitly executed. This way we avoid messing with legacy code, and we have a clear thing to include in contractAddress
in the receipt.
So a tx with to = null
, initcodes = [...]
, and data = <tx_initcode_hash> || <salt> || <input...>
would have the same effect as TXCREATE
executed in the context of the calling account, the value
parameter is taken from the transaction. (Edit: I realize now that this is very similar to what the creator contract used to do, lol.)
Separate question: Am I reading the specs right that initcode container validation on TXCREATE
is not metered? That seems intuitively wrong, shouldnât there be an additional gas cost proportional to the size of the container? (Minus data sections⌠perhaps the complexity of that is the reason why it isnât charged? I could see that being charged initially and then refunded.)
Since the initcode needs to be paid for (at a high rate) from the intrinsic tx cost, and cannot be manipulated by the EVM, it was decided not to charge extra for simplicity, but also to reflect the notion that clients will only do that once per tx (and cache results). Iâm personally not 100% sold on this, but it makes sense in a way.
Here is a pre-read doc concerning EOF contract creation proposals: https://notes.ethereum.org/@ipsilon/EOF-bootstrapping
Current status (EIP-7873 with legacy EVM code enabling TXCREATE opcode) is good, but there was feedback that some features 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. Weâll discuss this in depth on the next EOF implementers call this Wednesday
There is no need to change the semantics of Type 0,1, and 2 transactions to make them invalid if they start with EF. This will cause unneeded changes to how blobk builders have to handle existing transacitons. We should keep the existing behavior in that type 0,1, and 2 transactions never parse their bodies into EOF containers and just execute when in contract creation mode.
Hereâs a PR to effect that change: Update EIP-7873: Handling of EOF containers in existing TX types. by shemnon ¡ Pull Request #9669 ¡ ethereum/EIPs ¡ GitHub
This will cause unneeded changes to how blobk builders have to handle existing transacitons
Are we 100% sure this is an issue? This rule (invalidating to: nil
& data: EF00...
has been in the specs accompanying TXCREATE since a long time, but no issues were raised until now.
I suggest we start with a Rationale subsection to elaborate on the alternatives and decision taken. Somewhere else you said the main issue you see is invalidating txs which are already in the mempool - but doesnât that happen already with other upgrades, e.g. EIP-7623?
never parse their bodies into EOF containers and just execute when in contract creation mode
If we end up with deciding that yes, that is an issue, how about an alternative that instead of proceeding to execute the 0xEF
the execution just doesnât start, leaving only the intrinsic TX gas cost consumed? I.e. like if that tx was sent to an address without code.
The currently specced mechanism aims to serve 2 purposes:
1/ stop EOF code from executing in contexts where it is invalid, and do so early on, to not have to rely on checks which run later. At one point you just want the EVM to choose legacy vs EOF path based on the 0xef00 prefix alone.
2/ not punish too hard on a common and easy to detect user mistake, which is sending valid EOF down legacy creation pipelines
The alternative rule could cater for that
Iâm sure of this. While it may have been in the spec a while, itâs impact was eclipsed by EIP-7698 where the EOF containers were parsed, and it wasnât until fairly recently that removing EIP-7698 was part of EOFv1. Now that we are moving into implementation we are understanding the impact in ways that were not readily apparent. We can still change the spec, it is not finalized.
We need to move quickly on this. Insisting on a long process will cause us to miss a key delivery window.
Those changes are related to the transaction types they occur within, and TX pools already check the costing. That EIP was just a parameter and formula change to something the TXes were doing anyway. This change is not related to the transactions it is impacting and is only present for aesthetics. It is unneeded and we can cut it to make block builders jobs easier.
That is why the tag starts with the âinvalidâ opcode. Running it as uncontained code. Itâs not a check that runs later, itâs how the EVM works.
This places a greater burden on infrastructure for things that dev tooling (like hardhat and foundry) will solve for the typical used.
Reducing the scoped of actors that need to change to handle EOF is a better rule to cater to.
Letâs have a Rationale section entry regardless of everything, you have the contents already, just need to put it in the PR. Avoiding the need to endlessly look for past decisionsâ rationales will make us quick.

That is why the tag starts with the âinvalidâ opcode. Running it as uncontained code. Itâs not a check that runs later, itâs how the EVM works.
Before you get to the point of running into an âinvalidâ opcode, you need to know if the EF00...
code should be parsed as EOF and executed (b/c itâs an account being called or TXCREATE initcode or EOFCREATE initcontainer) or not (b/c itâs in creation tx data or CREATE/CREATE2 initcode). At one point the EVM needs to check and decide, this way or the other.
Not that it is a blocker to your change, just flagging.