Skip to content
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

Add ERC: AgentNFT Extension for ERC-721 #844

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
207 changes: 207 additions & 0 deletions ERCS/erc-7860.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
---
eip: 7860
title: AgentNFT Extension for ERC-721
description: ERC-721 AgentNFT Extension, enabling on-chain identity for AI-powered entities
author: AgentBall (@agentball)
discussions-to: https://ethereum-magicians.org/t/erc-7860-agentnft-extension-for-erc-721/22502
status: Draft
type: Standards Track
category: ERC
created: 2025-01-10
requires: 165, 721
---


## **Abstract**

This EIP introduces an extension to [ERC-721](./eip-721.md) that enables NFTs to be associated with AI agents, including prompts and other agent settings. This extension allows a NFT token to store prompts and AI agent’s address, facilitating the establishment of an on-chain identity for AI-powered entities.

## **Motivation**

As artificial intelligence becomes increasingly integrated with blockchain technology, there is a growing need for standardized interfaces that enable NFTs to interact with AI systems. Current ERC-721 tokens lack native support for AI integration. However, ERC-721 tokens are non-fungible, transferable, capable of storing data, and compatible with extensions such as [ERC-6551](./eip-6551.md) wallets. These characteristics make ERC-721 a suitable standard for serving as an on-chain identity for AI agents.
At present, prompts and other relevant information are often stored in the NFT token URI without a standardized format, making recognition and application challenging. This extension addresses these limitations by providing:

1. A decentralized on-chain identity for AI agents – By associating AI agents with AgentNFTs, this extension enables them to interact with smart contracts in a highly composable manner.
2. A transferable and non-custodial asset type – AgentNFTs function as liquid assets, facilitating ownership transfers while preserving on-chain value.
3. An interface for storage and management of prompts and AI agent addresses – Each AgentNFT securely maintains its associated AI agent’s address and prompt data, ensuring consistency and interoperability.
4. Prompts and other data can be encrypted for privacy while remaining verifiable for authenticity.

## **Specification**

The extension introduces the following interface:

```
/**
* @title IAgentNFT
* @dev Interface for ERC721 AgentNFT extension that adds prompt and agent management capabilities
* This extension allows NFTs to store and manage prompts and AI Agent's corresponding address
*/
interface IAgentNFT /* is IERC165, IERC721 */ {
/**
* @dev Emitted when an address is updated for a AgentNFT
* @param tokenId The ID of the AgentNFT
* @param agent The new agent address
*/
event AgentUpdated(uint256 indexed tokenId, address indexed agent);

/**
* @dev Emitted when a prompt is updated for a AgentNFT
* @param tokenId The ID of the AgentNFT
* @param prompt The new prompt string
*/
event PromptUpdated(uint256 indexed tokenId, string prompt);

/**
* @dev Returns the current address corresponding to the AgentNFT. The address can be a wallet address or smart contract address. The AI Agent is represented by the AgentNFT of the given tokenId parameter
* @param tokenId The ID of the AgentNFT to query
* @return The address of the associated AI agent
*/
function agent(uint256 tokenId) external view returns (address);

/**
* @dev Updates the address for an AgentNFT
* @param tokenId The ID of the AgentNFT to update
* @param newAgent The new agent address to assign
*/
function updateAgent(uint256 tokenId, address newAgent) external;

/**
* @dev Returns the current prompt for a AgentNFT
* @param tokenId The ID of the AgentNFT to query
* @return The prompt string associated with the AgentNFT
*/
function prompt(uint256 tokenId) external view returns (string memory);

/**
* @dev Updates the prompt for an AgentNFT
* @param tokenId The ID of the AgentNFT to update
* @param newPrompt The new prompt string to assign
*/
function updatePrompt(uint256 tokenId, string memory newPrompt) external;
}

```

## **Rationale**

This interface is designed to be minimal yet flexible, ensuring compatibility with various use cases:

1. On-Chain Agent Prompts – Prompts are a core asset of AI agents. By storing them within AgentNFTs, they become transferable, preserving their value and utility.
2. Agent Information Authentication – On-chain information can be used for identification and authentication, enhancing transparency and trust.
3. Efficient State Querying – The interface enables seamless tracking and updating of agent information, facilitating efficient state management.

## **Backwards Compatibility**

This extension is fully backwards compatible with ERC-721.

## **Reference Implementation**

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import { ERC721 } from "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
import { IAgentNFT } from "./IAgentNFT.sol";
/**
* @title AgentNFT
* @dev Implementation of IAgentNFT, which adds prompt and agent management capabilities extension to ERC721
* This extension allows NFTs to store and manage prompts and AI Agent's corresponding address
*/
contract AgentNFT is ERC721, IAgentNFT, Ownable {
// Mapping from token ID to AI agent address
mapping(uint256 => address) private _agents;

// Mapping from token ID to prompt string
mapping(uint256 => string) private _prompts;

/**
* @dev Initializes the contract by setting a name and symbol to the AgentNFT collection
* @param name The name of the AgentNFT collection
* @param symbol The symbol of the AgentNFT collection
*/
constructor(string memory name, string memory symbol)
ERC721(name, symbol)
Ownable(msg.sender)
{}

/**
* @dev Safely mints a new AgentNFT
* @param to The address that will own the minted AgentNFT
* @param tokenId The AgentNFT id to mint
*/
function safeMint(address to, uint256 tokenId) public onlyOwner {
_safeMint(to, tokenId);
}

/**
* @dev See {IAgentNFT}
* Requirements:
* - Token must exist
*/
function agent(uint256 tokenId) public view override returns (address) {
require(ownerOf(tokenId) != address(0), "AgentNFT: token does not exist");
return _agents[tokenId];
}

/**
* @dev See {IAgentNFT-updateAgent}
* Requirements:
* - Caller must be token owner or approved
* - New agent address must not be zero address
*/
function updateAgent(uint256 tokenId, address newAgent) public override {
require(ownerOf(tokenId) == msg.sender,
"AgentNFT: caller is not owner nor approved");
require(newAgent != address(0),
"AgentNFT: new agent is zero address");
_agents[tokenId] = newAgent;
emit AgentUpdated(tokenId, newAgent);
}

/**
* @dev See {IAgentNFT-prompt}
* Requirements:
* - Token must exist
*/
function prompt(uint256 tokenId) public view override returns (string memory) {
return _prompts[tokenId];
}

/**
* @dev See {IAgentNFT-updatePrompt}
* Requirements:
* - Caller must be token owner, approved, or the assigned agent
* - New prompt must not be empty
*/
function updatePrompt(uint256 tokenId, string memory newPrompt) public override {
require(
ownerOf(tokenId) == msg.sender || getApproved(tokenId) == msg.sender || isApprovedForAll(ownerOf(tokenId), msg.sender) || msg.sender == _agents[tokenId],
"AgentNFT: caller is not owner, approved, or agent"
);
_prompts[tokenId] = newPrompt;
emit PromptUpdated(tokenId, newPrompt);
}
}
```

The reference implementation includes:

1. Storage mappings for agents and prompts
2. Events emission on state changes
3. Input validation
4. Full compatibility with ERC-721

## **Security Considerations**

1. Access Control
- Only token owners or approved operators should be able to update agents and prompts
- Implementations should validate agent addresses
2. Storage Considerations
- Implementations should consider limiting prompt string length
- Data such as prompts can be encrypted for privacy, but need to be verifiable
- Gas costs for prompt storage and updates

## **Copyright**

Copyright and related rights waived via [CC0](../LICENSE.md).
Loading