-
Couldn't load subscription status.
- Fork 796
ERC-8048: Onchain Metadata for Token Registries #1259
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
nxt3d
wants to merge
8
commits into
ethereum:master
Choose a base branch
from
nxt3d:onchain-metadata-branch
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+176
−0
Open
Changes from 2 commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
797ec4f
Add ERC: Onchain Metadata for Multi-Token and NFT Registries
nxt3d 1173b51
Update discussions-to URL for onchain metadata standard
nxt3d cfc6d93
Update ERCS/_onchain-metadata.md
nxt3d f691594
Update ERCS/_onchain-metadata.md
nxt3d 11879d8
Update ERCS/_onchain-metadata.md
nxt3d be54ee8
Rename file to erc-8048.md and update created date
nxt3d 9458f70
Update ERC-8048: Change agentId to tokenId for broader applicability
nxt3d 2acaacf
Add optional Diamond Storage to ERC-8048
nxt3d File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,127 @@ | ||
| --- | ||
| eip: XXXX | ||
| title: Onchain Metadata for Multi-Token and NFT Registries | ||
nxt3d marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| description: A key-value store interface that allows registries to store and retrieve arbitrary bytes as metadata directly onchain. | ||
| author: Prem Makeig (@nxt3d) | ||
| discussions-to: https://ethereum-magicians.org/t/add-erc-onchain-metadata-for-multi-token-and-nft-registries/25820 | ||
nxt3d marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| status: Draft | ||
| type: Standards Track | ||
| category: ERC | ||
| created: 2025-10-2 | ||
| --- | ||
|
|
||
| ## Abstract | ||
|
|
||
| This ERC defines an onchain metadata standard for multi-token and NFT registries including ERC-721, ERC-1155, ERC-6909, and ERC-8004. The standard provides a key-value store allowing for arbitrary bytes to be stored onchain. | ||
|
|
||
| ## Motivation | ||
|
|
||
| This ERC addresses the need for fully onchain metadata while maintaining compatibility with existing ERC-721, ERC-1155, ERC-6909, and ERC-8004 standards. It has been a long-felt need for developers to store metadata onchain for NFTs and other multitoken contracts; however, there has been no uniform standard way to do this. Some projects have used the tokenURI field to store metadata onchain using Data URLs, which introduces gas inefficiencies and has other downstream effects (for example making storage proofs more complex). This standard provides a uniform way to store metadata onchain, and is backwards compatible with existing ERC-721, ERC-1155, ERC-6909, and ERC-8004 standards. | ||
|
|
||
| ## Specification | ||
|
|
||
| The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174. | ||
|
|
||
| ### Scope | ||
|
|
||
| This ERC is an optional extension that MAY be implemented by any ERC-721, ERC-1155, ERC-6909, or ERC-8004 compliant registries. | ||
|
|
||
| ### Required Metadata Function and Event | ||
|
|
||
| Contracts implementing this ERC MUST implement the following interface: | ||
|
|
||
| ```solidity | ||
| interface IOnchainMetadata { | ||
| /// @notice Get metadata value for a key. | ||
| function getMetadata(uint256 agentId, string calldata key) external view returns (bytes memory); | ||
|
|
||
| /// @notice Emitted when metadata is set for a token. | ||
| event MetadataSet(uint256 indexed agentId, string indexed indexedKey, string key, bytes value); | ||
| } | ||
| ``` | ||
|
|
||
| - `getMetadata(agentId, key)`: Returns the metadata value for the given agent ID and key as bytes | ||
|
|
||
| Contracts implementing this ERC MAY also expose a `setMetadata(uint256 agentId, string calldata key, bytes calldata value)` function to allow metadata updates, with write policy determined by the contract. | ||
|
|
||
| Contracts implementing this ERC MUST emit the following event when metadata is set: | ||
|
|
||
| ```solidity | ||
| event MetadataSet(uint256 indexed agentId, string indexed indexedKey, string key, bytes value); | ||
| ``` | ||
|
|
||
| ### Key/Value Pairs | ||
|
|
||
| This ERC specifies that the key is a string type and the value is bytes type. This provides flexibility for storing any type of data while maintaining an intuitive string-based key interface. | ||
|
|
||
| ### Examples | ||
|
|
||
| The inspiration for this standard was trustless AI agents. The registry extends ERC-721 by adding getMetadata and setMetadata functions for optional extra on-chain agent metadata. | ||
|
|
||
| #### Example: Context for LLM-Facing Agent Metadata | ||
|
|
||
| Examples of keys are "agentWallet" or "agentName". | ||
|
|
||
| **Example:** | ||
|
|
||
| - Key: `"agentWallet"` | ||
| - Value: `bytes("0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6")` | ||
| - Key: `"agentName"` | ||
| - Value: `bytes("DeFi Trading Agent")` | ||
|
|
||
| #### Example: Biometric Identity for Proof of Personhood | ||
|
|
||
| A biometric identity system using open source hardware to create universal proof of personhood tokens. | ||
|
|
||
| - Key: `"biometric_hash"` → Value: `bytes(bytes32(identity_commitment))` | ||
| - Key: `"verification_time"` → Value: `bytes(bytes32(timestamp))` | ||
| - Key: `"device_proof"` → Value: `bytes(bytes32(device_attestation))` | ||
|
|
||
|
|
||
| ## Rationale | ||
|
|
||
| This design prioritizes simplicity and flexibility by using a string-key, bytes-value store that provides an intuitive interface for any type of metadata. The minimal interface with a single `getMetadata` function provides all necessary functionality while remaining backwards compatible with existing ERC-721, ERC-1155, ERC-6909, and ERC-8004 standards. The optional `setMetadata` function enables flexible access control for metadata updates. The required `MetadataSet` event provides transparent audit trails with indexed agentId and indexedKey for efficient filtering. This makes the standard suitable for diverse use cases including AI agents, proof of personhood systems, and custom metadata storage. | ||
|
|
||
| ## Backwards Compatibility | ||
|
|
||
| - Fully compatible with ERC-721, ERC-1155, ERC-6909, and ERC-8004. | ||
| - Non-supporting clients can ignore the scheme. | ||
|
|
||
| ## Reference Implementation | ||
|
|
||
| The interface is defined in the Required Metadata Function and Event section above. Here is a reference implementation: | ||
|
|
||
| ```solidity | ||
| // SPDX-License-Identifier: MIT | ||
| pragma solidity ^0.8.0; | ||
|
|
||
| import "./IOnchainMetadata.sol"; | ||
|
|
||
| contract OnchainMetadataExample is IOnchainMetadata { | ||
| // Mapping from agentId => key => value | ||
| mapping(uint256 => mapping(string => bytes)) private _metadata; | ||
|
|
||
| /// @notice Get metadata value for a key | ||
| function getMetadata(uint256 agentId, string calldata key) | ||
| external view override returns (bytes memory) { | ||
| return _metadata[agentId][key]; | ||
| } | ||
|
|
||
| /// @notice Set metadata for a token (optional implementation) | ||
| function setMetadata(uint256 agentId, string calldata key, bytes calldata value) | ||
| external { | ||
| _metadata[agentId][key] = value; | ||
| emit MetadataSet(agentId, key, key, value); | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| Implementations should follow the standard ERC-721, ERC-1155, ERC-6909, or ERC-8004 patterns while adding the required metadata function and event. | ||
|
|
||
| ## Security Considerations | ||
|
|
||
| This ERC is designed to put metadata onchain, providing security benefits through onchain storage. | ||
|
|
||
| ## Copyright | ||
|
|
||
| Copyright and related rights waived via [CC0](../LICENSE.md). | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.