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
  1. 验证一个用户的输入是否合法:require(input<20);
  2. 验证一个外部协议的响应:require(external.send(amount));
  3. 判断执行一段语句的前置条件,验证合约执行前的状态:  require(block.number > SOME_BLOCK_NUMBER) or require(balance[msg.sender]>=amount);
  4. require应该被最常使用到;一般用于函数的开头处
  • assert
  1. 检查有没有上溢overflow或者是下溢underflow: ie. c = a+b; assert(c > b)
  2. 检查常数非变量(invariants):assert(this.balance >= totalSupply);在完成变化后检查状态,避免本不应该发生的情况出现,如程序的bug;assert不应该被经常利用到,一般用于函数结尾处
  3. 验证改变后的状态;预防不应该发生的条件。

基本上,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
posted @ 2021-07-05 15:11  这醋好甜  阅读(854)  评论(0编辑  收藏  举报