WTF Solidity极简入门第十四讲:抽象合约和接口

This article is not available in the current language yet. Showing the original version.
这一讲,我们用 ERC721 的接口合约为例介绍 solidity 中的抽象合约(abstract)和接口(interface),帮助大家更好的理解 ERC721 标准。

原文:《Solidity 极简入门: 14.抽象合约和接口》

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

所有代码和教程开源在 github: github.com/AmazingAng/WTFSolidity

这一讲,我们用 ERC721 的接口合约为例介绍 solidity 中的抽象合约(abstract)和接口(interface),帮助大家更好的理解 ERC721 标准。

抽象合约

如果一个智能合约里至少有一个未实现的函数,即某个函数缺少 {} 中的内容,则必须将该合约标为 abstract,不然编译会报错;另外,未实现的函数需要加 virtual,以便子合约重写。拿我们之前的插入排序合约为例,如果我们还没想好具体怎么实现插入排序函数,那么可以把合约标为 abstract,之后让别人补写上。

Solidity极简入门第十四讲:抽象合约和接口

接口

接口类似于抽象合约,但它不实现任何功能。接口的规则:

- 不能包含状态变量

- 不能包含构造函数

- 不能继承除接口外的其他合约

- 所有函数都必须是 external 且不能有函数体

- 继承接口的合约必须实现接口定义的所有功能

虽然接口不实现任何功能,但它非常重要。接口是智能合约的骨架,定义了合约的功能以及如何触发它们:如果智能合约实现了某种接口(比如 ERC20 或 ERC721),其他 Dapps 和智能合约就知道如何与它交互。因为接口提供了两个重要的信息:

- 合约里每个函数的 bytes4 选择器,以及基于它们的函数签名函数名 (每个参数类型)。

- 接口 id(更多信息见EIP165)

另外,接口与合约 ABI(Application Binary Interface)等价,可以相互转换:编译接口可以得到合约的 ABI,利用abi-to-sol 工具也可以将 ABI json 文件转换为接口 sol 文件。

我们以 ERC721 接口合约 IERC721 为例,它定义了 3 个 event 和 9 个 function,所有 ERC721 标准的 NFT 都实现了这些函数。我们可以看到,接口和常规合约的区别在于每个函数都以;代替函数体 { } 结尾。

Solidity极简入门第十四讲:抽象合约和接口

IERC721 事件

IERC721 包含 3 个事件,其中 Transfer 和 Approval 事件在 ERC20 中也有。

- Transfer 事件:在转账时被释放,记录Token的发出地址 from,接收地址 to 和 tokenid。

- Approval 事件:在授权时释放,记录授权地址 owner,被授权地址 approved 和 tokenid`。

- ApprovalForAll 事件:在批量授权时释放,记录批量授权的发出地址 owner,被授权地址 operator 和授权与否的 approved。

IERC721 函数

balanceOf:返回某地址的 NFT 持有量 balance。

ownerOf:返回某 tokenId 的主人 owner。

transferFrom:普通转账,参数为转出地址 from,接收地址 to 和 tokenId。

safeTransferFrom:安全转账(如果接收方是合约地址,会要求实现 ERC721Receiver 接口)。参数为转出地址 from,接收地址 to 和 tokenId。

approve:授权另一个地址使用你的 NFT。参数为被授权地址 approve 和 tokenId。

getApproved:查询 tokenId 被批准给了哪个地址。

setApprovalForAll:将自己持有的该系列 NFT 批量授权给某个地址 operator。

isApprovedForAll:查询某地址的 NFT 是否批量授权给了另一个 operator 地址。

safeTransferFrom:安全转账的重载函数,参数里面包含了 data。

什么时候使用接口?

如果我们知道一个合约实现了 IERC721 接口,我们不需要知道它具体代码实现,就可以与它交互。

无聊猿 BAYC 属于 ERC721 Token,实现了 IERC721 接口的功能。我们不需要知道它的源代码,只需知道它的合约地址,用 IERC721 接口就可以与它交互,比如用 balanceOf() 来查询某个地址的 BAYC 余额,用 safeTransferFrom() 来转账 BAYC。

Solidity极简入门第十四讲:抽象合约和接口

总结

这一讲,我介绍了`solidity`中的抽象合约(`abstract`)和接口(`interface`),他们都可以写模版并且减少代码冗余。我们还讲了`ERC721`接口合约`IERC721`,以及如何利用它与无聊猿`BAYC`合约进行交互。

Share to:

Author: 0xAA

Opinions belong to the column author and do not represent PANews.

This content is not investment advice.

Image source: 0xAA. If there is any infringement, please contact the author for removal.

Follow PANews official accounts, navigate bull and bear markets together
PANews APP
It is suspected that the Dragonfly address transferred 137 million SKY tokens to Coinbase, a decrease in value of more than half compared to when the tokens were withdrawn.
PANews Newsflash