Skip to content

Commit 45218b4

Browse files
authored
feat(02): erc721-02 (#853)
erc721-02
1 parent f3c049c commit 45218b4

File tree

2 files changed

+135
-2
lines changed

2 files changed

+135
-2
lines changed

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@
290290

291291
### NFT
292292

293-
**第1讲:ERC721库:Address, Strings, Context** [代码](https://github.com/AmazingAng/WTF-Solidity/blob/main/Topics/ERC721) | [文章](./Topics/ERC721/1_related_libraries/readme.md)
293+
**第1讲:ERC721库:Address, Strings, Context** [代码](https://github.com/AmazingAng/WTF-Solidity/blob/main/Topics/ERC721) | [文章](https://github.com/AmazingAng/WTF-Solidity/tree/main/Topics/ERC721/1_related_libraries/readme.md)
294294

295295
**第2讲:ERC721相关接口** [代码](https://github.com/AmazingAng/WTF-Solidity/blob/main/Topics/ERC721) | [文章](https://mirror.xyz/wtfacademy.eth/4mPkMgHViRjx8OM7TAI-M-2oMfRle36ULzqlpC6S7IQ)
296296

@@ -313,7 +313,7 @@
313313
贡献者是WTF学院的基石
314314
</h4>
315315
<a href="https://github.com/AmazingAng/WTF-Solidity/graphs/contributors">
316-
<img src="https://contrib.rocks/image?repo=AmazingAng/WTFSolidity" />
316+
<img src="https://contrib.rocks/image?repo=AmazingAng/WTF-Solidity" />
317317
</a>
318318
</div>
319319

+133
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
# WTF Solidity极简入门: ERC721专题:2. ERC721相关接口
2+
3+
我最近在重新学 Solidity,巩固一下细节,也写一个“WTF Solidity极简入门”,供小白们使用(编程大佬可以另找教程),每周更新 1-3 讲。
4+
5+
推特:[@0xAA_Science](https://twitter.com/0xAA_Science)[@WTFAcademy_](https://twitter.com/WTFAcademy_)
6+
7+
社区:[Discord](https://discord.gg/5akcruXrsk)[微信群](https://docs.google.com/forms/d/e/1FAIpQLSe4KGT8Sh6sJ7hedQRuIYirOoZK_85miz3dw7vA1-YjodgJ-A/viewform?usp=sf_link)[官网 wtf.academy](https://wtf.academy)
8+
9+
所有代码和教程开源在 github: [github.com/AmazingAng/WTF-Solidity](https://github.com/AmazingAng/WTF-Solidity)
10+
11+
在进阶内容之前,我决定做一个`ERC721`的专题,把之前的内容综合运用,帮助大家更好的复习基础知识,并且更深刻的理解`ERC721`合约。希望在学习完这个专题之后,每个人都能发行自己的`NFT`
12+
13+
---
14+
15+
## ERC721相关接口
16+
17+
ERC721的主合约一共引用了4个接口合约:`IERC721.sol`, `IERC721Receiver.sol`, `IERC721Metadata.sol`,和间接引用的`ERC165``IERC165.sol`。这一讲我们将逐个介绍这4个接口合约。
18+
19+
### IERC165接口
20+
21+
首先我们介绍一下`EIP165``以太坊改进建议第165条`),他的目的是创建一个标准方法来发布和检测智能合约实现的接口。讲一个去年年底发生的真实事件,`PeopleDAO`有个朋友错转了4000w枚PEOPLE到代币合约。但合约没有实现转出代币的功能,只能进不能出,这些代币直接锁死在里面销毁了。试想一下,如果在转账的时候自动判断接收方合约是否实现了相应的接口,没实现的话就`revert`交易,很多错转代币的悲剧都不会发生。`EIP165`就是干这个的,而`ERC165`就是`EIP165`的实现。
22+
23+
`IERC165``ERC165`的接口合约,只有一个函数`supportsInterface()`,输入想查询的接口的`interfaceId`,返回一个`bool`告诉你合约是否实现了该接口。
24+
25+
```Solidity
26+
interface IERC165 {
27+
function supportsInterface(bytes4 interfaceId) external view returns (bool);
28+
}
29+
```
30+
31+
`ERC721`主合约对`supportsInterface()`的实现如下:
32+
33+
```Solidity
34+
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
35+
return
36+
interfaceId == type(IERC721).interfaceId ||
37+
interfaceId == type(IERC721Metadata).interfaceId ||
38+
super.supportsInterface(interfaceId);
39+
}
40+
```
41+
42+
可以看到,ERC721实现了`IERC721``IERC721Metadata``IERC165`的接口,查询的时候会返回`true`;否则返回`false`。我会在进阶内容中更详细的介绍`function selector``interfaceId`
43+
44+
### IERC721
45+
46+
`IERC721`是ERC721的接口合约,里面包括3个`event`和9个`function`
47+
48+
```Solidity
49+
interface IERC721 is IERC165 {
50+
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
51+
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
52+
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
53+
54+
function balanceOf(address owner) external view returns (uint256 balance);
55+
56+
function ownerOf(uint256 tokenId) external view returns (address owner);
57+
58+
function safeTransferFrom(address from, address to, uint256 tokenId) external;
59+
60+
function transferFrom(address from, address to, uint256 tokenId) external;
61+
62+
function approve(address to, uint256 tokenId) external;
63+
64+
function getApproved(uint256 tokenId) external view returns (address operator);
65+
66+
function setApprovalForAll(address operator, bool _approved) external;
67+
68+
function isApprovedForAll(address owner, address operator) external view returns (bool);
69+
70+
function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;
71+
}
72+
```
73+
74+
其中`event`包括:
75+
76+
1. `Transfer`事件:在转账时被释放,记录代币的发出地址`from`,接收地址`to``tokenid`
77+
2. `Approval`事件:在授权时释放,记录`approve`的发出地址`owner`
78+
3. `ApprovalForAll`事件:在批量授权时释放,记录`approve`的发出地址`owner`,被授权地址`operator`和是否被授权`approved。
79+
80+
其中`function`包括:
81+
82+
1. `balanceOf`:参数为要查询的`address`,返回该地址的`NFT`持有量`balance`
83+
2. `ownerOf`:参数为要查询的`tokenId`,返回这个`tokenId`的主人`owner`
84+
3. `safeTransferFrom`:安全转账(如果接收方是合约地址,会要求实现`ERC721`的接收接口)。参数为转出地址`from`,接收地址`to``tokenId`
85+
4. `transferFrom`:普通转账(不检查对方是否实现`ERC721`的接收接口),参数为转出地址`from`,接收地址`to``tokenId`
86+
5. `approve`:授权,批准另一个地址使用你的`NFT`。参数为被授权地址`to``tokenId`
87+
6. `getApproved`:查询`NFT`被批准给了哪个地址,参数为`tokenId`,返回被批准的地址`operator`
88+
7. `setApprovalForAll`:将自己持有的这类`NFT`批量授权给某个地址,参数为被授权的地址`operator`和是否授权`approved`
89+
8. `isApprovedForAll`:查询某人的`NFT`是否批量授权给了某个地址,参数为授权方`owner`和被授权地址`operator`,返回`bool`
90+
9. `safeTransferFrom`:安全转账,与`3.`不同的地方在于参数里面包含了`data`,可以做额外处理。
91+
92+
### IERC721Receiver
93+
94+
```Solidity
95+
interface IERC721Receiver {
96+
function onERC721Received(
97+
address operator,
98+
address from,
99+
uint256 tokenId,
100+
bytes calldata data
101+
) external returns (bytes4);
102+
}
103+
```
104+
105+
`IERC721Receiver`接口包含了一个函数`onERC721Received()`。这个函数会在`safeTransferFrom()`中被调用,代币的接收合约必须实现这个接口才能转账成功。
106+
107+
### IERC721Metadata
108+
109+
```Solidity
110+
interface IERC721Metadata is IERC721 {
111+
function name() external view returns (string memory);
112+
113+
function symbol() external view returns (string memory);
114+
115+
function tokenURI(uint256 tokenId) external view returns (string memory);
116+
}
117+
```
118+
119+
`IERC721Metadata``ERC721`的拓展接口,实现了`3`个查询`metadata`的常用函数:
120+
121+
1. `name()`:返回代币名称。
122+
2. `symbol()`:返回代币代号
123+
3. `tokenURI()`:通过`tokenId`查询`metadata`所在`url`
124+
125+
## 总结
126+
127+
本文是`ERC721`专题的第二讲,我们介绍了`ERC721`主合约调用的4个接口合约`IERC165``IERC721``IERC721Receiver``IERC721Metadata`。下一讲终于该介绍ERC721主合约了!LFG!
128+
129+
## 延伸阅读
130+
131+
- [EIP165](https://eips.ethereum.org/EIPS/eip-165)
132+
- [ERC721](https://eips.ethereum.org/EIPS/eip-721)
133+
- [中文分析EIP165](https://learnblockchain.cn/docs/eips/eip-165.html)

0 commit comments

Comments
 (0)