• 区块链 | ERC721 标准


    目录

    正文

    1  ERC721 接口

    事件

    方法

    2  ERC165 接口

    3  可选实现接口:ERC721Metadata

    4  可选实现接口:ERC721Enumerable

    补充说明

    1  NTF IDs

    2  与 ERC-20 的兼容性

    3  交易、挖矿、销毁


    🥕原文:剖析非同质化代币 ERC721 标准

    🥕写在前面:本文属搬运博客,自己留存学习。

    正文

    ERC721 作为一个合约标准,提供了在实现 ERC721 代币时必须要遵守的协议,要求每个 ERC721 标准合约需要实现「ERC721」及「ERC165」接口。ERC721 标准的合约一旦被部署,它将负责跟踪在以太坊上创建的代币。

    1  ERC721 接口

    ERC721 的接口定义如下。

    1. interface ERC721 {
    2. /// event
    3. /// function
    4. }

    事件

    1. event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);
    2. event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId);
    3. event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);
    • Transfer 事件:当任何 NFT 的所有权通过任何机制发生变化时触发此事件。此事件在 NFT 被创建(from == 0)和销毁(to == 0)时触发。例外情况:在合约创建期间,可以创建并分配任意数量的 NFT 而不触发 Transfer 事件。在任何转移时,该 NFT 上的被授权地址将被重置为无。
    • Approval 事件:当 NFT 的被授权地址被更改或确立时触发此事件。零地址表示没有被授权地址。当 Transfer 事件被触发时,这也表示该 NFT 上的被授权地址被重置为无。
    • ApprovalForAll 事件:这个事件在操作员为某个所有者启用或禁用时触发。这个操作员可以管理所有者的所有 NFT 。 

    方法

    1. function balanceOf(address _owner) external view returns (uint256);
    2. function ownerOf(uint256 _tokenId) external view returns (address);
    3. function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes data) external payable;
    4. function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable;
    5. function transferFrom(address _from, address _to, uint256 _tokenId) external payable;
    6. function approve(address _approved, uint256 _tokenId) external payable;
    7. function setApprovalForAll(address _operator, bool _approved) external;
    8. function getApproved(uint256 _tokenId) external view returns (address);
    9. function isApprovedForAll(address _owner, address _operator) external view returns (bool);

    接口说明:

    • balanceOf( ):返回 _owner 持有的 NFTs 的数量。
    • ownerOf( ):返回 _tokenId 对应代币的持有者的地址。
    • approve( ):授予地址 _to 具有 _tokenId 的控制权,方法成功后需触发 Approval 事件。
    • setApprovalForAll( ):授予地址 _operator 具有所有 NFTs 的控制权,成功后需触发 ApprovalForAll 事件。
    • getApproved( ), isApprovedForAll( ):用于查询授权。
    • safeTransferFrom( ):转移 NFT 所有权,一次成功的转移操作必须发起 Transer 事件。
    • transferFrom( ):用来转移 NFTs,方法成功后需触发 Transfer 事件。调用者自己确认 _to 地址能正常接收 NFT,否则将丢失此 NFT 。此函数实现时需要检查下面条件的前四条。

    也就是说,transferFrom( ) 满足调用 safeTransferFrom( ) 的条件的前四条即可。

    调用 safeTransferFrom( ) 的条件:

    1. 调用者 msg.sender 应该是当前 _tokenId 的所有者或被授权的地址;
    2. _from 必须是 _tokenId 的所有者;
    3. _tokenId 应该是当前合约正在监测的 NFTs 中的任何一个;
    4. _to 地址不应该为 0;
    5. 如果 _to 是一个合约,则应该调用它的 onERC721Received 方法,并且检查其返回值。如果返回值不为 bytes4(keccak256("onERC721Received(address,uint256,bytes)")),则抛出异常。

    一个可接收 NFT 的合约必须实现 ERC721TokenReceiver 接口:

    1. interface ERC721TokenReceiver {
    2. /// @return `bytes4(keccak256("onERC721Received(address,uint256,bytes)"))`
    3. function onERC721Received(address _from, uint256 _tokenId, bytes data) external returns(bytes4);
    4. }

    2  ERC165 接口

    ERC165 的接口定义如下:

    1. interface ERC165 {
    2. function supportsInterface(bytes4 interfaceID) external view returns (bool);
    3. }

    ERC165 同样是一个合约标准,这个标准要求合约提供其实现了哪些接口,这样在与合约进行交互的时候可以先调用此接口进行查询。

    interfaceID 为函数选择器,计算方式有两种,如:bytes4(keccak256('supportsInterface(bytes4)')); 或 ERC165.supportsInterface.selector,多个函数的接口 ID 为函数选择器的异或值。

    就是说可以通过 ERC165 查询 ERC721 实现了哪些接口?

    3  可选实现接口:ERC721Metadata

    ERC721Metadata 接口用于提供合约的元数据:name,symbol 以及 URI,其接口定义如下:

    1. interface ERC721Metadata {
    2. function name() external pure returns (string _name);
    3. function symbol() external pure returns (string _symbol);
    4. function tokenURI(uint256 _tokenId) external view returns (string);
    5. }

    接口说明:

    • name( ):返回合约名字,尽管是可选,但强烈建议实现,即便是返回空字符串。
    • symbol( ):返回合约代币符号,尽管是可选,但强烈建议实现,即便是返回空字符串。
    • tokenURI( ):返回 _tokenId 所对应的外部资源文件的 URI(通常是 IPFS 或 HTTP(S) 路径)。

    外部资源文件需要包含名字、描述、图片,其格式的要求如下: 

    1. {
    2. "title": "Asset Metadata",
    3. "type": "object",
    4. "properties": {
    5. "name": {
    6. "type": "string",
    7. "description": "Identifies the asset to which this NFT represents",
    8. },
    9. "description": {
    10. "type": "string",
    11. "description": "Describes the asset to which this NFT represents",
    12. },
    13. "image": {
    14. "type": "string",
    15. "description": "A URI pointing to a resource with mime type image/* representing the asset to which this NFT represents. Consider making any images at a width between 320 and 1080 pixels and aspect ratio between 1.91:1 and 4:5 inclusive.",
    16. }
    17. }
    18. }

    采用的是 JSON 格式。

    4  可选实现接口:ERC721Enumerable

    ERC721Enumerable 的主要目的是提高合约中 NTF 的可访问性,其接口定义如下:

    1. interface ERC721Enumerable {
    2. function totalSupply() external view returns (uint256);
    3. function tokenByIndex(uint256 _index) external view returns (uint256);
    4. function tokenOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256);
    5. }

    接口说明:

    • totalSupply( ):返回 NFT 总量。
    • tokenByIndex( ):通过索引返回对应的 tokenId 。
    • tokenOfOwnerByIndex( ):所有者可以一次拥有多个的 NFT,此函数返回 _owner 拥有的 NFT 列表中对应索引的 tokenId 。

    NFT 总量应该就是该 NFT 合约铸造的 NFT 代币的总量吧?

    补充说明

    1  NTF IDs

    NTF 的 ID,即 tokenId,在合约中用唯一的 uint265 进行标识,每个 NFT 的 ID 在智能合约的生命周期内不允许改变。推荐的实现方式有:

    • 第一种:从 0 开始,每新加一个 NFT,NTF 的 ID 加 1 。
    • 第二种:使用 sha3 后 uuid 转换为 NTF 的 ID 。

    2  与 ERC-20 的兼容性

    ERC721 标准尽可能遵循 ERC-20 的语义,但由于同质代币与非同质代币之间的根本差异,并不能完全兼容 ERC-20 。

    3  交易、挖矿、销毁

    在实现 transter 相关接口时除了满足上面的的条件外,我们可以根据需要添加自己的逻辑,如加入黑名单等。同时挖矿、销毁尽管不是标准的一部分,我们可以根据需要实现。


    官方:ERC-721: Non-Fungible Token Standard

  • 相关阅读:
    Mysql 学习(十 三)InnoDB的BufferPool
    css实现滚动视差效果
    GIC/ITS代码分析(13)LPI中断虚拟化之KVM中ITS设备的模拟
    康耐视visionpro脚本CogRectangleAffine ,CogPolygon图形限定框,边界显示(划痕缺陷案例分享)
    【C语言刷LeetCode】592. 分数加减运算(M)
    服务器多线机房怎么判断
    Mpeg-Niacin 甲氧基-聚乙二醇-烟酸,Mpeg-NOTA甲氧基聚乙二醇-NOTA
    onnx删除无用属性
    trivy【3】自定义扫描策略
    矩阵转置python的实现
  • 原文地址:https://blog.csdn.net/m0_64140451/article/details/138161048