Solidity 中 revert(), assert() 和 require()

函数assertrequire可以用于检查条件,如果条件不满足则抛出异常。

assert():

函数只能用于测试内部错误,检查不变量,正常的函数代码永远不会产生Panic, 甚至是基于一个无效的外部输入时。 如果发生了,那就说明出现了一个需要你修复的 bug。如果使用得当,语言分析工具可以识别出那些会导致 Panic 的 assert 条件和函数调用。

想象为一个过于自信的实现方式,即使有错误,也会执行并扣除 gas。

下列情况将会产生一个Panic异常: 提供的错误码编号,用来指示Panic的类型。

  1. 0x01: 如果你调用 assert 的参数(表达式)结果为 false 。
  2. 0x11: 在``unchecked { … }``外,如果算术运算结果向上或向下溢出。
  3. 0x12; 如果你用零当除数做除法或模运算(例如 5 / 0 或 23 % 0 )。
  4. 0x21: 如果你将一个太大的数或负数值转换为一个枚举类型。
  5. 0x22: 如果你访问一个没有正确编码的存储byte数组.
  6. 0x31: 如果在空数组上 .pop() 。
  7. 0x32: 如果你访问 bytesN 数组(或切片)的索引太大或为负数。(例如: x[i] 而 i >= x.length或 i < 0).
  8. 0x41: 如果你分配了太多的内内存或创建了太大的数组。
  9. 0x51: 如果你调用了零初始化内部函数类型变量。


require():

想象为一个更有礼貌些的实现方式,会发现错误,不扣除 gas。

函数要么创建一个 Error(string) 类型的错误,或者没有错误数据的错误并且 require函数应该用于确认条件有效性,例如输入变量,或合约状态变量是否满足条件,或验证外部合约调用返回的值。

 

下列情况将会产生一个 Error(string) (或没有数据)的错误:

  1. 如果你调用 require 的参数(表达式)最终结果为 false 。
  2. 如果你在不包含代码的合约上执行外部函数调用。
  3. 如果你通过合约接收以太币,而又没有 payable 修饰符的公有函数(包括构造函数和 fallback 函数)。
  4. 如果你的合约通过公有 getter 函数接收 Ether 。

在下面的情况下,来自外部调用的错误数据(如果提供的话)被转发,这意味可能 Error 或 Panic 都有可能触发。

  1. 如果 .transfer() 失败。
  2. 如果你通过消息调用调用某个函数,但该函数没有正确结束(例如, 它耗尽了 gas,没有匹配函数,或者本身抛出一个异常),不包括使用低级别 call , send , delegatecall , callcode或 staticcall 的函数调用。低级操作不会抛出异常,而通过返回 false 来指示失败。
  3. 如果你使用 new 关键字创建合约,但合约创建 没有正确结束 。

可以给 require 提供一个消息字符串,而 assert 不行。 在下例中,你可以看到如何轻松使用``require`` 检查输入条件以及如何使用 assert 检查内部错误.


revert():

revert 函数是另一个可以在代码块中处理异常的方法, 可以用来标记错误并回退当前的调用。revert 调用中还可以包含有关错误信息的参数,这个信息会被返回给调用者,并且产生一个 Error(string) 错误。

 

https://blog.csdn.net/tianlongtc/article/details/80261757

https://learnblockchain.cn/docs/solidity/control-structures.html#assert-require-revert

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值