ERC721 是以太坊上的一种非同质化代币(NFT,Non-Fungible Token)标准,由 William Entriken、Dieter Shirley、Jacob Evans 和 Nastassia Sachs 在 2018 年提出。与 ERC20 代币不同,ERC721 代币是独一无二的,每个代币都有唯一的标识符(Token ID),因此适用于表示独一无二的资产,如数字艺术品、收藏品、游戏道具等。
ERC721 标准的完整定义
ERC721 标准定义了 NFT 合约必须实现的最小接口,包括函数和事件。以下是 ERC721 标准的详细内容。
1. 必须实现的函数
ERC721 标准规定了以下 9 个必须实现的函数:
1.1 balanceOf
- 功能: 返回指定地址拥有的 NFT 数量。
- 函数签名:
function balanceOf(address owner) external view returns (uint256);
1.2 ownerOf
- 功能: 返回指定
tokenId
的所有者地址。 - 函数签名:
function ownerOf(uint256 tokenId) external view returns (address);
1.3 safeTransferFrom
- 功能: 将 NFT 从当前所有者转移到另一个地址。如果目标地址是合约,则必须实现
onERC721Received
函数。 - 函数签名:
function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;
1.4 transferFrom
- 功能: 将 NFT 从当前所有者转移到另一个地址。不检查目标地址是否是合约。
- 函数签名:
function transferFrom(address from, address to, uint256 tokenId) external;
1.5 approve
- 功能: 授权另一个地址(
approved
)管理指定的tokenId
。 - 函数签名:
function approve(address approved, uint256 tokenId) external;
1.6 setApprovalForAll
- 功能: 授权或取消授权另一个地址(
operator
)管理调用者所有的 NFT。 - 函数签名:
function setApprovalForAll(address operator, bool approved) external;
1.7 getApproved
- 功能: 返回被授权管理指定
tokenId
的地址。 - 函数签名:
function getApproved(uint256 tokenId) external view returns (address);
1.8 isApprovedForAll
- 功能: 检查
operator
是否被授权管理owner
的所有 NFT。 - 函数签名:
function isApprovedForAll(address owner, address operator) external view returns (bool);
1.9 onERC721Received
- 功能: 当 NFT 被转移到合约地址时,目标合约必须实现此函数以接收 NFT。
- 函数签名:
function onERC721Received(address operator, address from, uint256 tokenId, bytes calldata data) external returns (bytes4);
2. 必须实现的事件
ERC721 标准规定了以下 3 个必须实现的事件:
2.1 Transfer
- 触发条件: 当 NFT 的所有权从一个地址转移到另一个地址时触发。
- 事件签名:
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
2.2 Approval
- 触发条件: 当某个地址被授权管理指定的
tokenId
时触发。 - 事件签名:
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
2.3 ApprovalForAll
- 触发条件: 当
owner
授权或取消授权operator
管理其所有 NFT 时触发。 - 事件签名:
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
3. 可选的功能
除了必须实现的函数和事件外,ERC721 标准还建议实现以下 可选功能:
3.1 name
- 功能: 返回 NFT 集合的名称(例如 “MyNFT”)。
- 函数签名:
function name() external view returns (string memory);
3.2 symbol
- 功能: 返回 NFT 集合的符号(例如 “MNFT”)。
- 函数签名:
function symbol() external view returns (string memory);
3.3 tokenURI
- 功能: 返回指定
tokenId
的元数据 URI(通常是 JSON 文件链接)。 - 函数签名:
function tokenURI(uint256 tokenId) external view returns (string memory);
4. 完整的 ERC721 实现示例
以下是一个简单的 ERC721 代币实现示例:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
contract MyNFT is ERC721 {
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;
constructor() ERC721("MyNFT", "MNFT") {}
function mint(address to) public returns (uint256) {
_tokenIds.increment();
uint256 newTokenId = _tokenIds.current();
_mint(to, newTokenId);
return newTokenId;
}
function tokenURI(uint256 tokenId) public view override returns (string memory) {
require(_exists(tokenId), "Token does not exist");
return string(abi.encodePacked("https://mynft.com/token/", Strings.toString(tokenId)));
}
}
5. ERC721 的重要注意事项
-
唯一性:
- 每个
tokenId
必须是唯一的,不能重复。
- 每个
-
元数据:
tokenURI
返回的元数据通常是一个 JSON 文件链接,包含 NFT 的名称、描述、图像等信息。
-
安全转账:
- 使用
safeTransferFrom
时,如果目标地址是合约,则必须实现onERC721Received
函数,否则转账会失败。
- 使用
-
授权管理:
approve
用于授权单个 NFT,而setApprovalForAll
用于授权所有 NFT。
-
Gas 费用:
- NFT 的转账和授权操作可能会消耗较多的 Gas,尤其是在链上存储大量元数据时。
6. 总结
ERC721 标准是以太坊上用于非同质化代币(NFT)的核心标准,适用于表示独一无二的资产。通过实现 ERC721 标准,开发者可以创建与其他以太坊应用程序(如钱包、市场和游戏)兼容的 NFT。完整的 ERC721 实现不仅包括必须实现的函数和事件,还应遵循最佳实践,确保 NFT 的安全性和互操作性。
标签:function,tokenId,uint256,介绍,NFT,ERC721,详细,address From: https://blog.csdn.net/qq_43258522/article/details/145197095