# Solidity极简入门 ERC721专题:2. ERC721相关接口 **Published by:** [0xAA](https://paragraph.com/@wtfacademy/) **Published on:** 2022-04-24 **URL:** https://paragraph.com/@wtfacademy/solidity-erc721-2-erc721 ## Content 我最近在重新学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,和间接引用的ERC165的IERC165.sol。这一讲我们将逐个介绍这4个接口合约。IERC165接口首先我们介绍一下EIP165(以太坊改进建议第165条),他的目的是创建一个标准方法来发布和检测智能合约实现的接口。讲一个去年年底发生的真实事件,PeopleDAO有个朋友错转了4000w枚PEOPLE到代币合约。但合约没有实现转出代币的功能,只能进不能出,这些代币直接锁死在里面销毁了。试想一下,如果在转账的时候自动判断接收方合约是否实现了相应的接口,没实现的话就revert交易,很多错转代币的悲剧都不会发生。EIP165就是干这个的,而ERC165就是EIP165的实现。 IERC165是ERC165的接口合约,只有一个函数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实现了IERC721,IERC721Metadata和IERC165的接口,查询的时候会返回true;否则返回false。我会在进阶内容中更详细的介绍function selector和interfaceId。IERC721IERC721是ERC721的接口合约,里面包括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包括:Transfer事件:在转账时被释放,记录代币的发出地址from,接收地址to和tokenid。Approval事件:在授权时释放,记录approve的发出地址owner,被授权地址approved和tokenid。ApprovalForAll事件:在批量授权时释放,记录approve的发出地址owner,被授权地址operator和是否被授权approved。其中function包括:balanceOf:参数为要查询的地address,返回该地址的NFT持有量balance。ownerOf:参数为要查询的tokenId,返回这个tokenId的主人owner。safeTransferFrom:安全转账(如果接收方是合约地址,会要求实现ERC721的接收接口)。参数为转出地址from,接收地址to和tokenId。transferFrom:普通转账(不检查对方是否实现ERC721的接收接口),参数为转出地址from,接收地址to和tokenId。approve:授权,批准另一个地址使用你的NFT。参数为被授权地址approve和tokenId。getApproved:查询NFT被批准给了哪个地址,参数为tokenId,返回被批准的地址approve。setApprovalForAll:将自己持有的这类NFT批量授权给某个地址,参数为被授权的地址operator和是否授权approved。isApprovedForAll:查询某人的NFT是否批量授权给了某个地址,参数为授权方owner和被授权地址operator,返回bool。safeTransferFrom:安全转账,与3.不同的地方在于参数里面包含了data,可以做额外处理。IERC721Receiverinterface IERC721Receiver { function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); } IERC721Receiver接口包含了一个函数onERC721Received()。这个函数会在safeTransferFrom()中被调用,代币的接收合约必须实现这个接口才能转账成功。IERC721Metadatainterface 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); } IERC721Metadata是ERC721的拓展接口,实现了3个查询metadata的常用函数:name():返回代币名称。symbol():返回代币代号tokenURI():通过tokenId查询metadata所在url。总结本文是ERC721专题的第二讲,我们介绍了ERC721主合约调用的4个接口合约IERC165,IERC721,IERC721Receiver和IERC721Metadata。下一讲终于该介绍ERC721主合约了!LFG!延伸阅读EIP165中文提案 ## Publication Information - [0xAA](https://paragraph.com/@wtfacademy/): Publication homepage - [All Posts](https://paragraph.com/@wtfacademy/): More posts from this publication - [RSS Feed](https://api.paragraph.com/blogs/rss/@wtfacademy): Subscribe to updates - [Twitter](https://twitter.com/0xAA_Science): Follow on Twitter