Solidity极简入门 ERC721专题:2. ERC721相关接口

我最近在重新学solidity,巩固一下细节,也写一个“Solidity极简入门”,供小白们使用(编程大佬可以另找教程),每周更新1-3讲。

欢迎关注我的推特:@0xAA_Science

WTF技术社群discord,内有加微信群方法:链接

所有代码和教程开源在github(1024个star发课程认证,2048个star发社群NFT): github.com/AmazingAng/WTFSolidity

不知不觉我已经完成了Solidity极简教程的前13讲(基础),内容包括:Helloworld.sol,变量类型,存储位置,函数,控制流,构造函数,修饰器,事件,继承,抽象合约,接口,库,异常。在进阶内容之前,我决定做一个ERC721的专题,把之前的内容综合运用,帮助大家更好的复习基础知识,并且更深刻的理解ERC721合约。希望在学习完这个专题之后,每个人都能发行自己的NFT


ERC721相关接口

ERC721的主合约一共引用了4个接口合约:IERC721.sol, IERC721Receiver.sol, IERC721Metadata.sol,和间接引用的ERC165IERC165.sol。这一讲我们将逐个介绍这4个接口合约。

IERC165接口

首先我们介绍一下EIP165以太坊改进建议第165条),他的目的是创建一个标准方法来发布和检测智能合约实现的接口。讲一个去年年底发生的真实事件,PeopleDAO有个朋友错转了4000w枚PEOPLE到代币合约。但合约没有实现转出代币的功能,只能进不能出,这些代币直接锁死在里面销毁了。试想一下,如果在转账的时候自动判断接收方合约是否实现了相应的接口,没实现的话就revert交易,很多错转代币的悲剧都不会发生。EIP165就是干这个的,而ERC165就是EIP165的实现。

IERC165ERC165的接口合约,只有一个函数supportsInterface(),输入想查询的接口的interfaceId,返回一个bool告诉你合约是否实现了该接口。

interface IERC165 {
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

ERC721主合约对supportsInterface()的实现如下:

    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
        return
            interfaceId == type(IERC721).interfaceId ||
            interfaceId == type(IERC721Metadata).interfaceId ||
            super.supportsInterface(interfaceId);
    }

可以看到,ERC721实现了IERC721IERC721MetadataIERC165的接口,查询的时候会返回true;否则返回false。我会在进阶内容中更详细的介绍function selectorinterfaceId

IERC721

IERC721ERC721的接口合约,里面包括3个event和9个function

interface IERC721 is IERC165 {
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
    
    function balanceOf(address owner) external view returns (uint256 balance);

    function ownerOf(uint256 tokenId) external view returns (address owner);

    function safeTransferFrom(address from, address to, uint256 tokenId) external;

    function transferFrom(address from, address to, uint256 tokenId) external;

    function approve(address to, uint256 tokenId) external;

    function getApproved(uint256 tokenId) external view returns (address operator);

    function setApprovalForAll(address operator, bool _approved) external;

    function isApprovedForAll(address owner, address operator) external view returns (bool);

    function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;
}

其中event包括:

  1. Transfer事件:在转账时被释放,记录代币的发出地址from,接收地址totokenid
  2. Approval事件:在授权时释放,记录approve的发出地址owner,被授权地址approvedtokenid
  3. ApprovalForAll事件:在批量授权时释放,记录approve的发出地址owner,被授权地址operator和是否被授权approved

其中function包括:

  1. balanceOf:参数为要查询的地address,返回该地址的NFT持有量balance
  2. ownerOf:参数为要查询的tokenId,返回这个tokenId的主人owner
  3. safeTransferFrom:安全转账(如果接收方是合约地址,会要求实现ERC721的接收接口)。参数为转出地址from,接收地址totokenId
  4. transferFrom:普通转账(不检查对方是否实现ERC721的接收接口),参数为转出地址from,接收地址totokenId
  5. approve:授权,批准另一个地址使用你的NFT。参数为被授权地址approvetokenId
  6. getApproved:查询NFT被批准给了哪个地址,参数为tokenId,返回被批准的地址approve
  7. setApprovalForAll:将自己持有的这类NFT批量授权给某个地址,参数为被授权的地址operator和是否授权approved
  8. isApprovedForAll:查询某人的NFT是否批量授权给了某个地址,参数为授权方owner和被授权地址operator,返回bool
  9. safeTransferFrom:安全转账,与3.不同的地方在于参数里面包含了data,可以做额外处理。

IERC721Receiver

interface IERC721Receiver {
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

IERC721Receiver接口包含了一个函数onERC721Received()。这个函数会在safeTransferFrom()中被调用,代币的接收合约必须实现这个接口才能转账成功。

IERC721Metadata

interface IERC721Metadata is IERC721 {
    function name() external view returns (string memory);

    function symbol() external view returns (string memory);

    function tokenURI(uint256 tokenId) external view returns (string memory);
}

IERC721MetadataERC721的拓展接口,实现了3个查询metadata的常用函数:

  1. name():返回代币名称。
  2. symbol():返回代币代号
  3. tokenURI():通过tokenId查询metadata所在url

总结

本文是ERC721专题的第二讲,我们介绍了ERC721主合约调用的4个接口合约IERC165IERC721IERC721ReceiverIERC721Metadata。下一讲终于该介绍ERC721主合约了!LFG!

延伸阅读

Subscribe to 0xAA
Receive the latest updates directly to your inbox.
Mint this entry as an NFT to add it to your collection.
Verification
This entry has been permanently stored onchain and signed by its creator.