EIP-7834: Separate Metadata Section for EOF

Discussion topic for EIP-7834

Update Log

External Reviews

None as of 2024-12-09.

Outstanding Issues

None as of 2024-12-09.

Summary

This EIP proposes a separate section for contract metadata in the EOF. Initially discussed at EOF Implementers Call #62 · Issue #1192 · ethereum/pm · GitHub.

Solidity appends contract metadata in the runtime bytecode in legacy bytecode (see playground.sourcify.dev). The current practice already makes it difficult to locate these in nested contracts and makes source-code verification difficult.

The tentative practice in EOF for any “metadata” in the Solidity compiler is to add it in the beginning of the data_section. However, changes to the size of data_section do affect the contract’s code by shifting DATALOADN offsets. This makes it impossible to verify two identical contracts with different metadata sizes.

Solidity’s default metadata is just one current example. Other kinds of metadata might be needed by any tooling or contract developer in the future. It is good practice to have a separate section for contract metadata that is unreachable by the code, and any changes to its size do not affect the actual code.

2 Likes

Discussed this somewhat offline in the discord and on an EOF call, and wanted to point out that it increases EVM complexity without any in-protocol benefit. Metadata can be implemented using other in-EVM approaches. For example, in Vyper, metadata about the runtime code lives in the initcode. This serves two purposes: it makes it unreachable from runtime code, and also reduces runtime code size (which is both expensive and subject to the EIP-170 hard limit).

@kuzdogan pointed out that that might be inconvenient for off-chain tooling to index, so another approach would be issuing an event (like log VyperMetadata(metadata_bytes)) at the time of contract creation for indexers to consume. This is slightly more expensive than the initcode approach, but still cheaper than storing in runtime code, and also achieves the unreachability goal as logs also exist as a a kind of metadata within the EVM which is unreadable from EVM code. The point is that there are in-EVM approaches which work today for this, so the goals of this EIP can be achieved without burning a new section kind.

With the EIP-7834 section we can still use the vyper approach to metadata. The initcode container is the container that has the metadata section, and the deployed contracts do not have the metadata section. Then users can go back through chain history to look at the contract creation to get the metadata. Whether compilers attach metadata to the initcode container or the runtime container is a choice the compiler will make.

I do think there is net-positive protocol benefit to this section. Right now we don’t have any place to associate with code data that is not accessible durring execution and can be used for whatever purpose that the code producer wants. The first pass would be for compilers to store their validation information, but I also see that regulated L2s may need to attach “legends” to their contracts that regulators may want for their own purposes. If we continue to drop these into the execution-accessible data section then we make the math more complex as to where to go for extra aux-data, and it makes it possible to create aux-data that could “mask” the metadata.

In it’s current form, where it is a segment of the EOF code that is ignored at runtime and treated as opaque, it frees up a lot more design space further down the supply chain.

1 Like