ERC721 非同质化代币标准

ERC721 非同质化代币标准

以太坊改进建议:EIP-721: Non-Fungible Token Standard

摘要

该标准允许在智能合约中实现用于 NFT 的标准 API。该标准提供了跟踪和转移 NFT 的基本功能,是一个允许钱包/经纪人/拍卖应用程序在以太坊上处理 NFT 的标准接口。

ERC721 接口

任何 ERC721 兼容合约都必须实现 ERC721 和 ERC165 接口。

Transfer

event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);
  • 在 NFT 的所有权发生改变时需要触发。
  • 在 NFT 被创建(_from == 0)和被销毁(_to == 0)该事件触发。

Approval

event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId);
  • 在 NFT 的批准地址(approved address)改变或重新设置时触发。
  • 零地址意味着没有批准地址。
  • 当 Transfer 事件触发时,这也意味着该 NFT 的批准地址被设置为空(none)。

ApprovalForALL

event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);
  • 在为所有者(owner)启用或禁用 operator 时触发。
  • 该 operator 可以管理该所有者的所有 NFT。

balanceOf

function balanceOf(address _owner) external view returns (uint256);
  • @notice 统计一个所有者的所有 NFT 数量。
  • @dev 分配给零地址的 NFT 被认为是无效的,对于零地址的查询会 throw
  • @para 参数 _owner 是要查询的地址。
  • @return 返回值是该地址的 NFT 数量。

ownerOf

function ownerOf(uint256 _tokenId) external view returns (address);
  • @notice 找到 NFT 的所有者。
  • @dev 分配给零地址的 NFT 被认为是无效的,对于它们的查询应当 throw
  • @para 参数 _tokenId 是 NFT 的标识符。
  • @return 返回值是该 NFT 的所有者地址。

safeTransferFrom

function safeTransferFrom(address _from, address _to, uint256 _tokenIdm, bytes data) external payable;
  • @notice 将一个 NFT 的所有权从一个地址转换到另一个地址。
  • @dev 除非是 msg.sender 是该 NFT 的当前所有者、授权的 operator 或批准地址,否则会 throw。如果 _from 不是当前所有者则会 throw。如果 _to 是零地址则会 throw。如果 _tokenId 不是有效的 NFT 则会 throw。当转换完成,该函数会检查 _to 是否是一个智能合约(code size > 0)。如果是,则会在 _to 上调用 onERC721Received,并且如果返回值不是 bytes4(keccak256("onERC721Received(address,address,uint256,bytes)")) 则会 throw
  • @para 参数 _from 是当前 NFT 的所有者;_to 是新的所有者;_tokenId 是要转换的 NFT;data 是未指定格式的附加数据,在调用 _to 时发送。
function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable;
  • @notice 将一个 NFT 的所有权从一个地址转换到另一个地址。
  • @dev&para 与上一个函数工作原理相同,除了要发送的 data 被设为 ""

transferFrom

function  transferFrom(address _from, address _to, uint256 _tokenId) external payable;
  • @notice 转移一个 NFT 的所有权 - 调用者负责确认 _to 能够接收 NFT,否则它们可能会永久丢失。
  • @dev 函数会 throw 除非 msg.sender 是该 NFT 的当前所有者、授权的 operater 或批准地址。如果 _from 不是当前所有者则会 throw。如果 _to 是零地址则会 throw。如果 _tokenId 不是有效的 NFT 则会 throw
  • @para 参数 _from 是 NFT 的当前所有者;_to 是新的所有者;_tokenId 是要转换的 NFT。

approve

function approve(address _approved, uint256 _tokenId) external payable;
  • @notice 改变或重申(reaffirm)一个 NFT 的批准地址。
  • @dev 零地址意味着没有批准地址。除非 msg.sender 是当前 NFT 所有者或当前所有者的授权 operator,否则会 throw
  • @para 参数 _approved 是新的批准的 NFT controller;_tokenId 是要批准的 NFT。

setApprovalForAll

function setApprovalForAll(address _operator, bool _approved) external;
  • @notice 启用或禁用第三方(“operator”)管理所有 msg.sender 资产的批准。
  • @dev 触发 ApprovalForAll 事件。合约必须允许每个所有者的多个 operator。
  • @para 参数 _operator 是要添加到授权 operator 集合中的地址;_approved 为 true 表示 operator 被批准,为 false 表示撤销批准。

getApproved

function getApproved(uint256 _tokenId) external view returns (address);
  • @notice 获取单个 NFT 的批准地址。
  • @dev 如果 _tokenId 不是有效的 NFT 则 throw
  • @para 参数 _tokenId 是要查询批准地址的 NFT。
  • @return 返回值是该 NFT 的批准地址,为零则表示没有批准地址。

isApprovedForAll

function isApprovedForAll(address _owner, address _operator) external view returns (bool);
  • @notice 查询一个地址是否是另一个地址的授权 operator。
  • @para 参数 _owner 是拥有 NFT 的地址;_operator 是代表所有者执行的地址。
  • @return 如果 _operator_owner 的一个批准 operator 则返回 true,否则返回 false。

ERC165 接口

EIP-165: Standard Interface Detection

supportsInterface

function supportsInterface(bytes4 interfaceID) external view returns (bool);
  • @notice 查询一个合约是否实现了一个接口。
  • @para 参数 interfaceID 是接口标识符(identifier)。
  • @dev 接口标识在 ERC165 中规定。该函数使用小于 30,000 的 gas。
  • @return 如果合约实现了 interfaceId 并且 interfaceID 不是 0xffffffff,则返回 true;否则返回 false

ERC721TokenReceiver 接口

如果一个钱包(wallet)/经纪人(broker)/拍卖应用程序(auction application)将接受安全转账,那么它必须实现钱包接口(wallet interface)。

注意,该接口的 ERC-165 标识符为 0x150b7a02

onERC721Received

function onERC721Received(address _operator, address _from, uint256 _tokenId, bytes _data) external returns(bytes4);
  • @notice 处理一个 NFT 的收据。
  • @dev ERC721 智能合约在 transfer 之后在接收者上调用该函数。该函数可能 throw 来回滚或拒绝转移(transfer)。除魔法值(magic value)之外的返回必须引起交易回滚。注意,合约地址永远是消息发送方。
  • @para 参数 _operator 是调用 safeTransferFrom 函数的地址;_from 是之前拥有代币的地址;_tokenId 是被转移的 NFT 的标识符;_data 是没有指定格式的附加数据。
  • @return bytes4(keccak256("onERC721Received(address,address,uint256,bytes)")) 除非函数 throw

ERC721Metadata 接口

**元数据扩展(metadata extension)**对于ERC-721智能合约是可选的。这允许查询智能合约的名称和关于 NFT 所代表的资产的详细信息。

注意,该接口的 ERC-165 标识符为 0x5b5e139f

name

function name() external view returns (string _name);
  • @notice 本合约中 NFT 集合的描述性名称。

symbol

function symbol() external view returns (string _symbol)
  • @notice 本合约中 NFT 的缩写名称。

tokenURL

function tokenURL(uint256 _tokenId) external view returns (string)
  • @notice 给定资产的唯一的统一资源描述符(URL)。
  • @dev 如果 _tokenId 不是有效的 NFT 则 throw。URL 在 RFC 3986 中定义。URL 可能指向一个符合 “ERC721 Metadata JSON Schema” 的 JSON 文件。

ERC721Enumerable 接口

**枚举扩展(enumeration extension)**对于 ERC-721 智能合约是可选的。这允许您的合约发布完整的 NFT 列表,并使它们可被发现。

注意,该接口的 ERC-165 标识符为 0x780e9d63

totalSupply

function totalSupply() external view returns (uint256);
  • @notice 统计该合约的跟踪的 NFT。
  • @return 该合约跟踪的有效 NFT 数量,其中的每一个都有已分配和可查询的不为零地址的所有者。

tokenByIndex

function tokenByIndex(uint256 _index) external view returns (uint256);
  • @notice 枚举有效的 NFT
  • @dev 如果 _index >= totalSupply() 则函数 throw
  • @para 参数 _index 表示小于 totalSupply() 的一个计数器。
  • @return 返回值是第 _index 个 NFT 的代币标识符(未指定排序顺序)。

tokenOfOwnerByIndex

function tokenOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256);
  • @notice 枚举分配给一个所有者的 NFT。
  • @dev 如果 _index >= balanceOf(_owner)_owner 是零地址,则函数 throw,这代表无效的 NFT。
  • @para 参数 _owner 是我们对其拥有的 NFT 感兴趣的一个地址;_index 是一个小于 balanceOf(_owner) 的计数器。
  • @return 返回值是分配给 _owner 的第 _index 个 NFT 的代币标识符(未指定排序顺序)。

ERC721 非同质化代币标准
https://alphafitz.com/2022/10/23/erc721-non-fungible-token-standard/
作者
alphafitz
发布于
2022年10月23日
许可协议