ERC-8048: Onchain Metadata for Token Registries

Introduces a new standard for storing arbitrary metadata directly onchain for ERC-721, ERC-1155, ERC-6909, and ERC-8004 registries.

Key features:

  • Key-value pair interface: string keys mapped to bytes values for each token
  • Required metadata() function and MetadataSet event
  • Backwards compatible with existing token standards
  • Enables trustless AI agents, proof of personhood, and custom metadata

This addresses the long-felt need for uniform onchain metadata storage while avoiding gas inefficiencies.

Note on Standard History:

This onchain metadata standard was originally introduced as part of ERC-8041 on September 30, 2025 (commit 13f11f2). ERC-8041 later pivoted to focus on fixed-supply agent collections, so this core metadata functionality is being reintroduced as a standalone standard.

2 Likes

This ERC is extremely useful, in my opinion, for anything involving tokenized assets, onchain collectibles, and agents.

I suggest changing the name of the getter function to just metadata(). This is because, across the most prominent EIPs, none of the getter functions use the get prefix to indicate that it is indeed a getter.

For example, ERC-20 doesn’t have getName() or getDecimals(); it is just name() and decimals(). This should follow the same principles

1 Like

Also having two values for key in the event is kind of pointless and a waste of gas, it should be only one:

event MetadataSet(uint256 indexed tokenId, string indexed key, bytes value);

Opened a PR with the suggested changes:

Regarding what you said about the two topics having a purpose, I don’t see it, maybe I’m not looking in the right place, but what would be the scenario where a user might want to used indexedKey instead of key, why not just indexed the key, and call it a day?

Also I’ve foud it extremy useful having a keys() so entities interacting with the smart contract know what keys are stored in the the metadadata mapping, but I dont think it should be attached to ERC, what do you think? @nxt3d

The reason for having the indexed key and the non-indexed key is that for new key values that are unknown, we need to have the unhashed name of the key.

1 Like

I am fine either way, if we wanted to include it in this ERC, or it could be a new one.

The only issue is that for very long lists of keys it becomes gas inefficient to update new values.

Maybe there should be some other type of system, such as a function called keys() that could also include an index keys(<index-number>).

1 Like

I made an update to the examples section. I thought this could be a bit more useful for agent developers.

——————–

Adds a concrete Examples subsection for tokenizing an agent as an NFT: each token ID is the agent; metadata stores UTF-8 in bytes.

Changes

  • Replaces the old short agentWallet / agentName snippet with AI agent metadata (NFT as agent).

  • Documents two key patterns: context (Markdown, optional embedded JSON for machine-readable fields) and endpoint[<type>] (lowercase types: mcp, a2a, ag-ui, …).

  • Includes a fenced Markdown + json sample for context (swap agent, official token list, tokenListUri as IPFS).

  • Lists example endpoint[mcp], endpoint[a2a], endpoint[ag-ui] values.

@rafael-abuawad

1 Like

Hi there, we’d like to use the ERC-8048 standard with our existing NFT project, Normies. Since the project is already deployed, we can’t modify the core contract to utilize it directly. However, we do have an external renderer contract where we’ve forwarded the tokenURI function. Is it possible to add an optional extension that allows us to implement this standard via our renderer contract instead? Thanks.

Hey! I just added an optional Onchain Metadata Contract Reference extension to solve this issue. You can keep your deployed contract as-is and add a top-level “metadata_contract” field to the JSON your renderer returns, pointing to an external contract that implements metadata(uint256, string). Clients that don’t know about it just ignore the field, so nothing breaks.

1 Like

Thank you! This is going to be helpful for us and many other NFT collections.

1 Like

I think the ERC is becoming too opinionated, shouldn’t we strive to keep it as minimal as possible. For example there is no mint implementation on the ERC20 that was the right call because it allowed anyone to implement mint however they wanted, bringing this up for discussion

What do you think? @nxt3d

1 Like

Also, I’ve create a simple module implementation for this ERC in Vyper

1 Like

The Onchain Metadata Contract Reference is an optional extension, so it might not affect the core ERC? However, it could be split into a new ERC to make this one more compact.