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.

1 Like

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

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.

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?

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

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