我最近在重新学solidity,巩固一下细节,也写一个“Solidity极简入门”,供小白们使用(编程大佬可以另找教程),每周更新1-3讲。
欢迎关注我的推特:@0xAA_Science
所有代码开源在github(64个star开微信交流群,已开填表加入;128个star录教学视频): github.com/AmazingAng/WTFSolidity
这一讲,我们用ERC721
的接口合约为例介绍solidity
中的抽象合约(abstract
)和接口(interface
),帮助大家更好的理解ERC721
标准。
如果一个智能合约里至少有一个未实现的函数,即某个函数缺少主体{}
中的内容,则必须将该合约标为abstract
,不然编译会报错;另外,未实现的函数需要加virtual
,以便子合约重写。拿我们之前的插入排序合约为例,如果我们还没想好具体怎么实现插入排序函数,那么可以把合约标为abstract
,之后让别人补写上。
abstract contract InsertionSort{
function insertionSort(uint[] memory a) public pure virtual returns(uint[] memory);
}
接口也是一种合约,跟抽象合约类似,都是为了设立标准和减少代码冗余,但是接口的要求更加严格:
- 不能包含状态变量
- 不能包含构造函数
- 不能继承除接口外的其他合约
- 所有函数都必须是external(接口与合约的
ABI
等价)
我们看一个ERC721
接口的例子,所有NFT都使用了这个接口:
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;
}
这个接口里面共定义了3个event
和9个function
,为所有ERC721
函数设立了标准:所有ERC721
合约都要实现这些function
。
接口中事件的定义和正常合约里一样。ERC721
接口里面的event
包括:
Transfer
(转账事件):记录发起地址
,接收地址
,和tokenId
Approve
(批准事件):记录持有地址
,批准地址
,和tokenId
ApproveForAll
(批量批准事件):记录持有地址
,批准地址
,和一个代表批准与否的bool
值。可以看到,接口中的事件和正常合约里的事件一样。
接口中所有function
都必须带有external
标签(不需要写virtual
标签,因为默认为virtual
)。ERC721
接口里面的function
包括:
balanceOf
:查询某个地址的NFT
持有量ownerOf
:查询某个tokenId
的持有人safeTransferFrom
:安全转账(如果接收方是合约地址,会要求实现ERC721
的接收接口)。transferFrom
:普通转账approve
:批准另一个地址使用你的NFT
getApproved
:查询NFT
被批准给了哪个地址setApprovalForAll
:将全部NFT
批量批准给某个地址isApprovedForAll
:查询全部NFT
是否批准给了某个地址safeTransferFrom
:安全转账,与3.
不同的地方在于参数里面包含了data
- 写大工程的时候打草稿用
- 大神写标准的时候
这一讲,我介绍了solidity
中的抽象合约(abstract
)和接口(interface
),他们都可以写模版并且减少代码冗余。我们还讲了ERC721
接口合约,以后会更详细的讲一下ERC721
代币标准。