Solidity极简入门 ERC721专题:1. ERC721相关库
ERC721合约概览ERC721主合约一共引用了7个合约:import "./Address.sol"; import "./Context.sol"; import "./Strings.sol"; import "./IERC721.sol"; import "./IERC721Receiver.sol"; import "./IERC721Metadata.sol"; import "./ERC165.sol"; 他们分别是:3个库合约:Address.sol, Context.sol和Strings.sol3个接口合约:IERC721.sol, IERC721Receiver.sol, IERC721Metadata.sol1个EIP165合约:ERC165.sol所以在讲ERC721的主合约之前,我们会花两讲在引用的库合约和接口合约上。ERC721相关库Address库Address库是Address变量相关函数的合集,包括判断某地址是否为合约,更安全的function call。ERC721用到其中的isContract(): function isContract(...
Solidity极简入门 ERC721专题:1. ERC721相关库
ERC721合约概览ERC721主合约一共引用了7个合约:import "./Address.sol"; import "./Context.sol"; import "./Strings.sol"; import "./IERC721.sol"; import "./IERC721Receiver.sol"; import "./IERC721Metadata.sol"; import "./ERC165.sol"; 他们分别是:3个库合约:Address.sol, Context.sol和Strings.sol3个接口合约:IERC721.sol, IERC721Receiver.sol, IERC721Metadata.sol1个EIP165合约:ERC165.sol所以在讲ERC721的主合约之前,我们会花两讲在引用的库合约和接口合约上。ERC721相关库Address库Address库是Address变量相关函数的合集,包括判断某地址是否为合约,更安全的function call。ERC721用到其中的isContract(): function isContract(...
Solidity极简入门: 13.异常
这一讲,我们介绍solidity三种抛出异常的方法:error,require和assert,并比较三种方法的gas消耗。异常写智能合约经常会出bug,solidity中的异常命令帮助我们debug。ErrorError是solidity 0.8版本新加的内容,方便且高效(省gas)的向用户解释操作失败的原因。人们可以在contract之外定义异常。下面,我们定义一个TransferNotOwner异常,当用户不是代币owner的时候尝试转账,会抛出错误:error TransferNotOwner(); // 自定义error 在执行当中,error必须搭配revert(回退)命令使用。 function transferOwner1(uint256 tokenId, address newOwner) public { if(_owners[tokenId] != msg.sender){ revert TransferNotOwner(); } _owners[tokenId] = newOwner; } 我们定义了一个transferOwner1()函数,他会检查代币的o...
Solidity极简入门: 13.异常
这一讲,我们介绍solidity三种抛出异常的方法:error,require和assert,并比较三种方法的gas消耗。异常写智能合约经常会出bug,solidity中的异常命令帮助我们debug。ErrorError是solidity 0.8版本新加的内容,方便且高效(省gas)的向用户解释操作失败的原因。人们可以在contract之外定义异常。下面,我们定义一个TransferNotOwner异常,当用户不是代币owner的时候尝试转账,会抛出错误:error TransferNotOwner(); // 自定义error 在执行当中,error必须搭配revert(回退)命令使用。 function transferOwner1(uint256 tokenId, address newOwner) public { if(_owners[tokenId] != msg.sender){ revert TransferNotOwner(); } _owners[tokenId] = newOwner; } 我们定义了一个transferOwner1()函数,他会检查代币的o...
Solidity极简入门: 12. 库合约 站在巨人的肩膀上
这一讲,我们用ERC721的引用的库合约String为例介绍solidity中的库合约(library),并总结了常用的库函数。库函数库函数是一种特殊的合约,主要是为了提升solidity代码的复用性和减少gas fee而存在。库合约一般都是一些好用的函数合集(库函数),由大神或者项目方创作,咱们站在巨人的肩膀上,会用就行了。库合约:站在巨人的肩膀上库合约:站在巨人的肩膀上 他和普通合约主要有以下几点不同:不能存在状态变量不能够继承或被继承不能接收以太币不可以被销毁String库合约String库合约是将uint256类型转换为相应的string类型的代码库,样例代码如下:library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) public pure ret...
Solidity极简入门: 12. 库合约 站在巨人的肩膀上
这一讲,我们用ERC721的引用的库合约String为例介绍solidity中的库合约(library),并总结了常用的库函数。库函数库函数是一种特殊的合约,主要是为了提升solidity代码的复用性和减少gas fee而存在。库合约一般都是一些好用的函数合集(库函数),由大神或者项目方创作,咱们站在巨人的肩膀上,会用就行了。库合约:站在巨人的肩膀上库合约:站在巨人的肩膀上 他和普通合约主要有以下几点不同:不能存在状态变量不能够继承或被继承不能接收以太币不可以被销毁String库合约String库合约是将uint256类型转换为相应的string类型的代码库,样例代码如下:library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) public pure ret...
Solidity极简入门: 11. 抽象合约和接口
这一讲,我们用ERC721的接口合约为例介绍solidity中的抽象合约(abstact)和接口(interface),帮助大家更好的理解ERC721标准。抽象合约如果一个智能合约里至少有一个未实现的函数,即某个函数缺少{}中的内容,则必须将该合约标为abstract,不然编译会报错;另外,未实现的函数需要加virtual,以便子合约重写。拿我们之前的插入排序合约为例,如果我们还没想好具体怎么实现插入排序函数,那么可以把合约标为abstract,之后让别人补写上。abstract contract InsertionSort{ function insertionSort(uint[] memory a) public pure virtual returns(uint[] memory); }ERC 接口接口也是一种合约,跟抽象合约类似,都是为了设立标准和减少代码冗余,但是接口的要求更加严格:不能包含状态变量不能包含构造函数不能继承除接口外的其他合约所有函数都必须是external(接口与合约的ABI等价)我们看一个ERC721接口的例子,所有NFT都使用了这个接口:inter...
Solidity极简入门: 11. 抽象合约和接口
这一讲,我们用ERC721的接口合约为例介绍solidity中的抽象合约(abstact)和接口(interface),帮助大家更好的理解ERC721标准。抽象合约如果一个智能合约里至少有一个未实现的函数,即某个函数缺少{}中的内容,则必须将该合约标为abstract,不然编译会报错;另外,未实现的函数需要加virtual,以便子合约重写。拿我们之前的插入排序合约为例,如果我们还没想好具体怎么实现插入排序函数,那么可以把合约标为abstract,之后让别人补写上。abstract contract InsertionSort{ function insertionSort(uint[] memory a) public pure virtual returns(uint[] memory); }ERC 接口接口也是一种合约,跟抽象合约类似,都是为了设立标准和减少代码冗余,但是接口的要求更加严格:不能包含状态变量不能包含构造函数不能继承除接口外的其他合约所有函数都必须是external(接口与合约的ABI等价)我们看一个ERC721接口的例子,所有NFT都使用了这个接口:inter...
Solidity极简入门: 10. 继承 父与子
这一讲,我们介绍solidity中的继承(inheritance),包括简单继承,多重继承,以及修饰器(modifier)和构造函数(constructor)的继承。继承继承是面向对象编程很重要的组成部分,可以显著减少重复代码。如果把合约看作是对象的话,solidity也是面向对象的编程,也支持继承。规则virtual: 父合约中的函数,如果希望子合约重写,需要加上virtual关键字。 override:子合约重写了父合约中的函数,需要加上override关键。简单继承我们先写一个简单的爷爷合约Yeye,里面包含3个function: hip(), pop(), yeye(),返回值都是”Yeye”。contract Yeye { // 定义3个function: hip(), pop(), man(),返回值设为A。 function hip() public pure virtual returns (string memory){ return("Yeye"); } function pop() public pure virtual returns (string me...
Solidity极简入门: 10. 继承 父与子
这一讲,我们介绍solidity中的继承(inheritance),包括简单继承,多重继承,以及修饰器(modifier)和构造函数(constructor)的继承。继承继承是面向对象编程很重要的组成部分,可以显著减少重复代码。如果把合约看作是对象的话,solidity也是面向对象的编程,也支持继承。规则virtual: 父合约中的函数,如果希望子合约重写,需要加上virtual关键字。 override:子合约重写了父合约中的函数,需要加上override关键。简单继承我们先写一个简单的爷爷合约Yeye,里面包含3个function: hip(), pop(), yeye(),返回值都是”Yeye”。contract Yeye { // 定义3个function: hip(), pop(), man(),返回值设为A。 function hip() public pure virtual returns (string memory){ return("Yeye"); } function pop() public pure virtual returns (string me...