EVM Object Format (EOF)

Last week I have shared a document on the Eth R&D discord explaining some background on why some EVM changes are hard and motivation for improving the situation:

It also suggests a container format for EVM, which would enable further improvements, such as removing jumpdests, moving to static jumps, etc. While the document does not aim to provide a final, implementable solution, it is a good one for discussions.


@chriseth published his initial opinion here:

And with @chfast and @gumb0 we have looked into some other potential changes this could bring in the long term:

Can we change this EIP to just say any contract deployment that has an unused opcode as the first byte is invalid and should revert? Rather than just have a single opcode that is considered invalid? There is no good reason to start a contract with an unused opcode, and maybe we’ll want the others later.


This is technically possible, but this would block much bigger set of “data contracts” from being deployed, therefore there would be bigger chance to break some existing factory contracts.

Data contracts are deployed bytecodes with no intention for execution from which you can read data with EXTCODECOPY.

On the other hand, this increases our chance to have shorter EOF prefix.

Some middle ground would be to reject some fixed range based on the analysis of currently deployed contracts. E.g. D0-EF.

1 Like

I wonder if we should enshrine data contracts somehow? Maybe have a contract prefix specifically for them?

1 Like

If we disallow contracts starting with 0xEF then I’d say we should also explicitly mark 0xEF as an INVALID opcode (or alternatively if we want to use 0xEF at some point it should use >=1 stack items), otherwise we get these weird situations that contracts want to start using this opcode but have to push a dummy item to stack first.

I am assuming that this only disallows the code deposit starting with 0xEF, we could technically still try to CREATE a contract where the deploycode starts with 0xEF? (Just for clarification here)

1 Like

I see a much bigger risk of this change not making into London if the range is extended. I think it has merits to reject any contract with invalid starting byte, but perhaps that can be done separately and even after London.

1 Like

The first step towards this is defined under EIP-3541:

It is also considered for the upcoming London fork.

So, when we try to add TokenA and TokenB to uniswap v2, we maybe got error as create2 create a pair start with 0xEF?

1 Like

No working contract starts with 0xEF.

Ok, I’ll try to fix out that.

This first step has been accepted for London.

The next step was proposed for Shanghai:

This introduces code - data separation as the main tangible benefit to users.

Watch an overview of EIP-3540 & EIP-3541 by @axic @chfast @gumb0.

1 Like

There is also a new overview document here:

This gives an explanation of why two hard forks, gives a roadmap of different features we investigate (Shanghai, Cancun, and beyond), and links to all relevant resources.

(We plan to drop the two-hard fork explainer from EIP-3540 to simplify it.)

1 Like

As a further step, we suggest to introduce code validation with EOF: EIP-3670: EOF - Code Validation

It is proposed as a separate EIP to keep concerns separated and the EIPs shorter.

A potential way to remove the need for jumpdest analysis at execution time was published here: EIP-3690: EOF - JUMPDEST Table

1 Like

A proposal made possible by EOF is to have static jumps:

1 Like

After the London upgrade which included EIP-3541 we were able to collect all previously deployed bytecodes starting with the 0xEF byte. The following document has information about collected data and 2 possible EOF prefix values. We recommend the use 0xEF00 2-byte prefix.

EOF Prefix Selection

Has anyone looked into figuring out what https://etherscan.io/address/0xca7bf67ab492b49806e24b6e2e4ec105183caa01 does?

Given that there are only 3 contracts that start with 0xEF and two of them have (in theory) reachable owners/authors and the third doesn’t actually do anything, I think we should explore the option of an irregular state change to get rid of them so we have a completely clear 0xEF space.

This is especially true since all 3 of them were created after EIP-3541 was proposed, and I suspect at least two of them (the contracts that merely deployed 0xEF) were created explicitly to cause problems for us (the third possibly as well, but that one is slightly less clear).