part 30:
在Solidity
中,try-catch
只能被用于external
函数或public
函数或创建合约时constructor
(被视为external
函数)的调用。基本语法如下:
try externalContract.f() { // call成功的情况下 运行一些代码 } catch { // call失败的情况下 运行一些代码 }
其中externalContract.f()
是某个外部合约的函数调用,try
模块在调用成功的情况下运行,而catch
模块则在调用失败时运行。
同样可以使用this.f()
来替代externalContract.f()
,this.f()
也被视作为外部调用,但不可在构造函数中使用,因为此时合约还未创建。
如果调用的函数有返回值,那么必须在try
之后声明returns(returnType val)
,并且在try
模块中可以使用返回的变量;如果是创建合约,那么返回值是新创建的合约变量。
part 31 :
这一讲,我们将介绍以太坊上的ERC20
代币标准,并发行自己的测试代币。
ERC20
ERC20
是以太坊上的代币标准,来自2015年11月V神参与的EIP20。它实现了代币转账的基本逻辑:
- 账户余额(balanceOf())
- 转账(transfer())
- 授权转账(transferFrom())
- 授权(approve())
- 代币总供给(totalSupply())
- 授权转账额度(allowance())
- 代币信息(可选):名称(name()),代号(symbol()),小数位数(decimals())
IERC20
IERC20
是ERC20
代币标准的接口合约,规定了ERC20
代币需要实现的函数和事件。 之所以需要定义接口,是因为有了规范后,就存在所有的ERC20
代币都通用的函数名称,输入参数,输出参数。 在接口函数中,只需要定义函数名称,输入参数,输出参数,并不关心函数内部如何实现。 由此,函数就分为内部和外部两个内容,一个重点是实现,另一个是对外接口,约定共同数据。 这就是为什么需要ERC20.sol
和IERC20.sol
两个文件实现一个合约。
事件
IERC20
定义了2
个事件:Transfer
事件和Approval
事件,分别在转账和授权时被释放
/** * @dev 释放条件:当 `value` 单位的货币从账户 (`from`) 转账到另一账户 (`to`)时. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev 释放条件:当 `value` 单位的货币从账户 (`owner`) 授权给另一账户 (`spender`)时. */ event Approval(address indexed owner, address indexed spender, uint256 value);
函数
IERC20
定义了6
个函数,提供了转移代币的基本功能,并允许代币获得批准,以便其他链上第三方使用。
part 32:
代币水龙头
当人渴的时候,就要去水龙头接水;当人想要免费代币的时候,就要去代币水龙头领。代币水龙头就是让用户免费领代币的网站/应用。
最早的代币水龙头是比特币(BTC)水龙头:现在BTC一枚要$30,000,但是在2010年,BTC的价格只有不到$0.1,并且持有人很少。为了扩大影响力,比特币社区的Gavin Andresen开发了BTC水龙头,让别人可以免费领BTC。撸羊毛大家都喜欢,当时就有很多人去撸,一部分变为了BTC的信徒。BTC水龙头一共送出了超过19,700枚BTC,现在价值约6亿美元!
ERC20水龙头合约
这里,我们实现一个简版的ERC20
水龙头,逻辑非常简单:我们将一些ERC20
代币转到水龙头合约里,用户可以通过合约的requestToken()
函数来领取100
单位的代币,每个地址只能领一次。
状态变量
我们在水龙头合约中定义3个状态变量
amountAllowed
设定每次能领取代币数量(默认为100
,不是一百枚,因为代币有小数位数)。tokenContract
记录发放的ERC20
代币合约地址。requestedAddress
记录领取过代币的地址。