ERC-8049: Contract-Level Onchain Metadata

Summary

Introduces a standard for storing contract-level metadata onchain. Extends ERC-7572’s concept with onchain storage. Optionally supports ERC-8042’s Diamond Storage pattern for cross-chain compatibility and upgradable contracts.

Key Features

  • Flexible Implementation: Choose simple mapping or Diamond Storage based on your needs

  • Two Reference Implementations: Basic (minimal code) and Diamond Storage examples

  • Optional Diamond Storage: Uses ERC-8042 for predictable storage locations when needed

  • Cross-Chain Compatible: Diamond Storage keeps slots consistent across deployments

  • ERC-7572 Compatible: Maintains compatibility with existing contract metadata standards

  • Upgradable Support: Metadata persists through contract upgrades

Technical Details

  • Simple string-key, bytes-value metadata interface

  • Optional Diamond Storage pattern with namespace "erc8049.contract.metadata.storage"

  • Support for name, description, image, collaborators, etc.

  • Validated with comprehensive test suite

Example Use Cases

Basic Contract Information:

  • name: “MyToken”

  • description: “A decentralized exchange for trading ERC-20 tokens”

  • version: “1.0.0”

Contract ENS Naming:

Any contract can store its ENS name using this standard:

  • ens_name: “mycontract.eth”

Collaborators:

Store multiple addresses as project collaborators:

  • collaborators: abi.encodePacked(address1, address2, address3)

This enables contracts to self-identify with metadata while maintaining flexibility. Use the simple implementation for basic needs, or Diamond Storage for cross-chain consistency and upgradable contracts.

Even though Diamond is also my favourite, I would consider using diamond storage here as the implementation detail.

Meaning, the standard’s interface can be implemented by different ways - e.g. even by a pure function :slight_smile:

One of the goals of this ERC is to make it easier to prove metadata cross-chain. Diamond storage makes this very easy to do, whereas just calling the data using functions doesn’t provide any standard location for the storage values. It’s true that Diamond Storage could be optional. Maybe that would be a better way to go. :thinking:

Can you elaborate more on this? Do you mean by calling eth_getStorageAt or using RIP7728 L1SLOAD?

Also, for eth_getProof (EIP-1186: RPC-Method to get Merkle Proofs - eth_getProof), given only the key and implementing ERC-8049, it’s possible to do an inclusion proof without inspecting the storage layout of the data.

I decided to make Diamond Storage optional. This will generally limit the complexity required to implement this ERC.