ERC-7857 Private Metadata AI Agent NFT (AI Agents NFT with Private Metadata)
Final · NFTs & multi-token · created 2025-01-02
A standard for owning private data of an AI agent, such as its model, memory, and character, as an NFT, and for cryptographically verifying that the data was actually and securely handed over when it is transferred.
Why it is needed
Each AI agent has a unique model, memory, and character, and this data itself is the value of the agent. However, the existing NFT standard, ERC-721, was built on the assumption that metadata is fixed and visible to anyone. Agent metadata is different. To protect intellectual property it must be stored encrypted, and when ownership changes the data itself is the core of the deal, so it must be handed over in a way that keeps it secret yet verifiable. With existing standards, only token ownership changes, and there is no way to guarantee that the encrypted data was actually delivered, that the new owner can access that data, or that the agent runtime can confirm ownership and load the correct data. This standard solves the problem by bundling verification methods such as a trusted execution environment (TEE) or zero-knowledge proofs (ZKP) into a single interface.
What to implement
function name() external view returns (string memory);: Returns the name of the NFT collection.function symbol() external view returns (string memory);: Returns the symbol of the NFT collection.function intelligentDataOf(uint256 _tokenId) external view returns (IntelligentData[] memory);: Returns the token's current list of data entries. Each entry consists of a data description and a data hash.event DelegateAccess(address indexed _user, address indexed _assistant);: Emitted when a user delegates signing authority to an access assistant.function verifier() external view returns (IERC7857DataVerifier);: Returns the address of the verifier contract this NFT uses.function authorizeUsage(uint256 _tokenId, address _user) external;: Grants a specific user permission to use the token. Ownership and data access rights are not transferred.function revokeAuthorization(uint256 _tokenId, address _user) external;: Revokes a specific user's usage permission.function approve(address _to, uint256 _tokenId) external;: Approves an address that may transfer a specific token.function setApprovalForAll(address _operator, bool _approved) external;: Approves or revokes an address as operator for all of the caller's tokens.function delegateAccess(address _assistant) external;: Designates an assistant to perform access confirmation (signing) on the caller's behalf.function ownerOf(uint256 _tokenId) external view returns (address);: Returns the current owner of the token.function getApproved(uint256 _tokenId) external view returns (address);: Returns the address approved for the token.function getDelegateAccess(address _user) external view returns (address);: Returns the access assistant address the user designated.
In depth
Onchain verifier and offchain prover
The verification system has two components. The on-chain verifier is implemented as a smart contract, checks proofs submitted through contract calls, and returns a structured result. The off-chain prover handles encrypted data and keys and generates proofs for ownership and availability claims. The prover implementation depends on the verification method. A TEE-based one generates proofs inside trusted hardware, and a ZKP-based one generates cryptographic zero-knowledge proofs. The NFT contract publishes the address of the verifier contract it uses through the verifier() function, so because the verification logic is separated into its own interface, different methods such as TEE and ZKP can be swapped within the same framework.
Two kinds of proof
The Ownership Proof shows knowledge of the pre-image that produces the claimed dataHash and is verified onchain with verifyOwnership(). The Transfer Validity Proof is verified with verifyTransferValidity() and proves five things. It proves knowledge of the pre-image of oldDataHashes, that the plaintext decrypted with the old data key (oldKey) was re-encrypted with the new key (newKey), that the new key was encrypted with the recipient's public key (encryptedPubKey), that the hashes of the new ciphertexts are newDataHashes, and that the recipient or access assistant signed oldDataHashes, newDataHashes, and encryptedPubKey, so the data actually exists in storage. Ownership proof verification is optional. This is because ownership is checked again within the availability verification during a transfer or clone, but the source text recommends ownership verification at minting and update.
Capability differences between TEE and ZKP
In a TEE-based implementation, the prover runs inside trusted hardware, so it can safely handle the private keys of multiple parties and can re-encrypt data directly. In this case the onchain verifier checks the TEE attestation. A ZKP-based implementation, by contrast, cannot process the private keys of multiple parties because of its cryptographic properties, so the prover learns the re-encryption key. For that reason, a token transferred or cloned with the ZKP method must be re-encrypted again at the next update, and otherwise the new update contents remain continuously visible to the prover, that is, the previous owner. This difference in key handling capability affects how data transformations are managed during later use.
Three data operations: transfer, clone, and usage authorization
The standard supports three operations. A full transfer (iTransfer) hands both the data and ownership to a new owner. A clone (iClone) copies the data into a new token for the recipient and returns a new token ID, without changing ownership of the original token. Usage authorization (authorizeUsage) lets a specific user use the agent, but transfers neither ownership nor data access rights. This third method requires an environment that authenticates users and processes requests from authorized users in secret. The source text calls it a Sealed Executor. The Sealed Executor is outside the scope of the standard's definition, but it is a component the operation cannot do without. It receives the permission group by tokenId, verifies the user's signature with those public keys, and if verification succeeds, processes the request and returns the result. It can be implemented as a trusted authority where that is permitted, and otherwise with a TEE or fully homomorphic encryption (FHE).
Access Delegation and Sealed Key Delivery
The recipient can delegate the authority to sign access confirmations to an access assistant with delegateAccess(_assistant), and can query the delegation status with getDelegateAccess(_user). An access proof (AccessProof) is signed by the recipient or their assistant and consists of oldDataHash, newDataHash, nonce, encryptedPubKey, and proof. If encryptedPubKey is empty, it means the new data key is encrypted with the recipient's Ethereum public key. When a transfer or clone succeeds, the sealed key is published to the recipient through the PublishedSealedKey event, and the recipient decrypts it with their own private key to obtain the new data key. Each proof includes a nonce, and the verifier in the reference implementation records the proofs it has used to prevent the same proof from being submitted again.
Metadata Structure and Relationship to ERC-721
A token's data is represented as an array of IntelligentData structs. Each entry consists of a data description (dataDescription) and a data hash (dataHash), and is queried with intelligentDataOf(_tokenId). Only the hash and the sealed key go on-chain, while the actual data is encrypted and stored in off-chain storage. When a transfer completes, the token's data hash is updated to the hash of the newly re-encrypted ciphertext. To focus on functional data management, this standard does not inherit from existing NFT standards. However, if traditional NFT compatibility is needed, an implementation can additionally implement ERC-721. Familiar functions such as approvals (approve, setApprovalForAll) and owner lookup (ownerOf) are also defined separately within this standard.
Things to watch out for
- Proof Verification and Replay Attack Prevention: An implementation must verify every claim contained in a proof without exception, and must prevent replay attacks, in which the same proof is submitted again.
- Re-encryption Is Required at the Next Update When Using ZKP: A ZKP cannot handle the private keys of multiple parties, so the prover that sends the re-encryption key comes to know it. A token received through a transfer or clone must be re-encrypted at the next update. Otherwise, the new update contents will be visible to the previous owner.
- Off-Chain Storage and Key Management: Only the hash and the sealed key are stored on-chain, so the actual data must be stored and transmitted securely off-chain. Key management is central to secure data access.
- Access Control and Atomic State Changes: Data operations must be restricted to the token owner, and every operation must preserve integrity and availability. Important state changes such as sealed keys, ownership, and permissions must be atomic and verifiable.
- Sealed Executor Security: The Sealed Executor is outside the scope of the standard but is essential for safe operation. It must verify user signatures with the public keys of the per-tokenId permission group, process requests in a secure environment, and deliver results securely. It can be implemented as a trusted authority (where permitted), a TEE, or FHE.