solidity学习(四)-- Require(), Assert(), Revert()的用法和区别
在0.4.1之前,if....throw用于判断一个条件是否满足条件,如不满足则终断运行。但如果上面的函数,被其他拥有者调用,会显示出:“返回无效操作代码错误”,它会撤回所有的状态转变,用光你所有的gas。
之后,assert(), require(), and revert() 三个函数代替了if...throw的功能,并对gas有了更好的处理。原文章中提到的例子:
if(msg.sender != owner) { revert(); }
assert(msg.sender == owner);
require(msg.sender == owner);
这三个函数在功能上是与if(msg.sender != owner) { throw; }是等价的。下面具体说说这三个函数的区别。
- revert
revert的用法和throw很像,也会撤回所有的状态转变。但是它有两点不同
1.它允许你返回一个值;
2.它会把所有剩下的gas退回给caller
调用起来就像这样子:
revert(‘Something bad happened’);
require(condition, ‘Something bad happened’);
- require
- 验证一个用户的输入是否合法:require(input<20);
- 验证一个外部协议的响应:require(external.send(amount));
- 判断执行一段语句的前置条件,验证合约执行前的状态: require(block.number > SOME_BLOCK_NUMBER) or require(balance[msg.sender]>=amount);
- require应该被最常使用到;一般用于函数的开头处。
- assert
- 检查有没有上溢overflow或者是下溢underflow: ie. c = a+b; assert(c > b)
- 检查常数非变量(invariants):assert(this.balance >= totalSupply);在完成变化后检查状态,避免本不应该发生的情况出现,如程序的bug;assert不应该被经常利用到,一般用于函数结尾处。
- 验证改变后的状态;预防不应该发生的条件。
基本上,require()
应该被用于函数中检查条件,assert()
用于预防不应该发生的情况,但不应该使条件错误。另外,除非认为之前的检查(用 require
)会导致无法验证 overflow
,否则不应该盲目使用 assert
来检查 overflow。
资料:
https://ethfans.org/posts/when-to-use-revert-assert-and-require-in-solidity
https://www.jianshu.com/p/4560cf887f71
珍惜时间,只错一次