Author: Dragan Rakita, Paradigm Translation: Shan Ouba, Golden Finance
EOF (EVM Object Format)
EOF (EVM Object Format)
EOF (EVM Object Format) is a set of small EIPs aimed at improving the EVM. It introduces a new bytecode format to prepare for the future of the EVM.
Advantages of EOF
The value of EOF is difficult to explain because it is not a single thing, and the explanation is made more complicated by the fact that it has been postponed in forks many times and has evolved over the years of development and research and different versions.
The purpose of this article is to summarize these advantages and explain them in one sentence:
Advantages:
EOF allows Gas pricing to change for opcodes
Removal of Gas Observability
Allow L2 to vary gas depending on its use case
For example, the high cost of hash operations in zk L2.
EIP-7667: Increase gas cost of hash functions.
Reduce bytecode size, lower gas usage
Early data suggests reductions in code/init code size and gas usage:
Uniswap-v3 deployment reduces init code and deployment code by 6.5%
Deploy UniswapV3Factory uses ~14% less gas, call runTest uses ~9% less gas.
ENS DNSRegistrar deployment reduces initialization code by ~6% and deployment code by ~1.5%.
ENS call proveAndClaim: uses ~10% less gas.
Allow bytecode transformation and upgradability
Removing code observability means removing PC, CREATE/CREATE2, EXTCODEHASH, EXTCODESIZE, EXTCODECOPY, CODESIZE, and CODECOPY opcodes.
Legacy contracts will not run if the code is changed.
This will allow us to make any kind of modifications to the EOF bytecode when we introduce Verkle in the future.
EOF enables opcode immediates
Opens the possibility of SWAPN, DUPN and EXCHANGE opcodes.
This gives Solidity more freedom in stack size and solves the problem of stack depth being too deep in Solidity.
Removing expensive jump target analysis
With the analysis removed, we can increase the maximum bytecode size in the future.
Static analysis becomes easier
Data and code are separated and easier to reason about.
EOF bytecode can be compiled into faster bytecode
Future proof EVM
The versioning and structure of the bytecode allow for its extensibility. This is especially useful for L2 and standardization.
An example is EIP-7701: Local Account Abstraction with EOF, adding a new header section.
Address Space Extension
Integration with the Current EVM
An important issue for developers is the effort required to implement the changes, the cost of testing, and the cost of maintaining these opcodes.
The new opcodes do not conflict with legacy opcodes, and the verification of EOF does not touch deprecated opcodes.
The encoding and decoding of EOF can be fuzz tested. Validation is a new thing, about 500 lines of code in Revm, but there are a lot of edge cases to cover and focus on getting it right in individual implementations.
Create transactions are used as carriers for the EOF bytecode, similar to EOFCREATE but requires validation before execution.
Most of the opcodes are pretty simple:
EXTCALL (0xf8), EXTDELEGATECALL (0xf9), EXTSTATICCALL (0xfb)
Has the same blueprint as the deprecated CALL, but removes the gas_limit and memory output fields.
Before RETURNDATALOAD was introduced (in a very early fork), memory output for a CALL opcode had to be set before the CALL opcode was executed. This did not allow dynamic output.
EOFCREATE and RETURNCONTRACT
EXCHANGE (0xe8), SWAPN (0xe7), DUPN (0xe6), DATACOPY (0xd3), DATASIZE (0xd2), DATALOADN (0xd1), DATALOAD (0xd0), RJUMP (0xe0), RJUMPI (0xe1), RJUMPV (0xe2), RETURNDATALOAD
CALLF (0xe3), RETF (0xe4), and JUMPF (0xe5)
Requires subroutine stack and stack verification, with a complexity of about 20-30 lines of code.
Requires about 2-3 months of work by a single developer. Testing has begun. There are currently about 2000 hand-written verification tests, and state testing work is also in progress.
The changes are concentrated in the EVM, so integration with the rest of the client depends on the client's architecture and where the bytecode is kept.
EXTCODESIZE and EXTCODEHASH need to know if the account is EOF, and return predefined values (size and hash of 0xEF00), which may slightly change the way clients integrate. One idea is to save the is_eof flag in the normal account table to skip the loading of the bytecode when calling any EXTCODE type opcode.
Impact on L2
The biggest question is why L2 does not implement these changes? Should we stop EVM improvements on Ethereum L1?
The reality is that L2 is not ready, and not only that, they do not have a platform to help integrate these innovations. Bytecode versioning helps build a platform that L2 can use, the removal of code observability helps alleviate the upgradeability problem, and the gas changes help ZK L2 eliminate the DDoS vector of gas bombs (for example, hashing in zk is very expensive).
More importantly, EOF is more than just a format, it also requires support from the language (Solidity/Vyper/Huff) and support from the toolchain to use it. It requires an ecosystem to use it, and this format provides more stability for L2 to innovate on top of it.
Disadvantages: Legacy Bytecode Still Exists
This is a common problem. Legacy bytecode will always be around, and if we don't provide an alternative, we will be stuck. With an alternative format of bytecode, in the future we can transition and remove the legacy bytecode when state expiration occurs.
Summary
EOF is not the next shiny thing, it is a maintenance EIP that fixes legacy issues from the initial EVM version, and there is no other way to solve these problems except to break it. It is necessary for the further development and future proofing of the EVM.