ERC721 非同质化代币标准
ERC721 非同质化代币标准
摘要
该标准允许在智能合约中实现用于 NFT 的标准 API。该标准提供了跟踪和转移 NFT 的基本功能,是一个允许钱包/经纪人/拍卖应用程序在以太坊上处理 NFT 的标准接口。
ERC721 接口
任何 ERC721 兼容合约都必须实现 ERC721 和 ERC165 接口。
Transfer
- 在 NFT 的所有权发生改变时需要触发。
- 在 NFT 被创建(
_from == 0
)和被销毁(_to == 0
)该事件触发。
Approval
- 在 NFT 的批准地址(approved address)改变或重新设置时触发。
- 零地址意味着没有批准地址。
- 当 Transfer 事件触发时,这也意味着该 NFT 的批准地址被设置为空(none)。
ApprovalForALL
- 在为所有者(owner)启用或禁用 operator 时触发。
- 该 operator 可以管理该所有者的所有 NFT。
balanceOf
- @notice 统计一个所有者的所有 NFT 数量。
- @dev 分配给零地址的 NFT 被认为是无效的,对于零地址的查询会
throw
。 - @para 参数
_owner
是要查询的地址。 - @return 返回值是该地址的 NFT 数量。
ownerOf
- @notice 找到 NFT 的所有者。
- @dev 分配给零地址的 NFT 被认为是无效的,对于它们的查询应当
throw
。 - @para 参数
_tokenId
是 NFT 的标识符。 - @return 返回值是该 NFT 的所有者地址。
safeTransferFrom
- @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
时发送。
- @notice 将一个 NFT 的所有权从一个地址转换到另一个地址。
- @dev¶ 与上一个函数工作原理相同,除了要发送的
data
被设为""
。
transferFrom
- @notice 转移一个 NFT 的所有权 - 调用者负责确认
_to
能够接收 NFT,否则它们可能会永久丢失。 - @dev 函数会
throw
除非msg.sender
是该 NFT 的当前所有者、授权的 operater 或批准地址。如果_from
不是当前所有者则会throw
。如果_to
是零地址则会throw
。如果_tokenId
不是有效的 NFT 则会throw
。 - @para 参数
_from
是 NFT 的当前所有者;_to
是新的所有者;_tokenId
是要转换的 NFT。
approve
- @notice 改变或重申(reaffirm)一个 NFT 的批准地址。
- @dev 零地址意味着没有批准地址。除非
msg.sender
是当前 NFT 所有者或当前所有者的授权 operator,否则会throw
。 - @para 参数
_approved
是新的批准的 NFT controller;_tokenId
是要批准的 NFT。
setApprovalForAll
- @notice 启用或禁用第三方(“operator”)管理所有
msg.sender
资产的批准。 - @dev 触发 ApprovalForAll 事件。合约必须允许每个所有者的多个 operator。
- @para 参数
_operator
是要添加到授权 operator 集合中的地址;_approved
为 true 表示 operator 被批准,为 false 表示撤销批准。
getApproved
- @notice 获取单个 NFT 的批准地址。
- @dev 如果
_tokenId
不是有效的 NFT 则throw
。 - @para 参数
_tokenId
是要查询批准地址的 NFT。 - @return 返回值是该 NFT 的批准地址,为零则表示没有批准地址。
isApprovedForAll
- @notice 查询一个地址是否是另一个地址的授权 operator。
- @para 参数
_owner
是拥有 NFT 的地址;_operator
是代表所有者执行的地址。 - @return 如果
_operator
是_owner
的一个批准 operator 则返回 true,否则返回 false。
ERC165 接口
EIP-165: Standard Interface Detection
supportsInterface
- @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
- @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
- @notice 本合约中 NFT 集合的描述性名称。
symbol
- @notice 本合约中 NFT 的缩写名称。
tokenURL
- @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
- @notice 统计该合约的跟踪的 NFT。
- @return 该合约跟踪的有效 NFT 数量,其中的每一个都有已分配和可查询的不为零地址的所有者。
tokenByIndex
- @notice 枚举有效的 NFT
- @dev 如果
_index
>=totalSupply()
则函数throw
。 - @para 参数
_index
表示小于totalSupply()
的一个计数器。 - @return 返回值是第
_index
个 NFT 的代币标识符(未指定排序顺序)。
tokenOfOwnerByIndex
- @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/