• Solidity - 算术运算的截断模式(unchecked)与检查模式(checked)- 0.8.0新特性


    0.8.0版本开始,算术运算有两个计算模式,一个是“wrapping”(截断)模式或为“unchecked”(不检查)模式,即在发生溢出的情况下会进行“截断”,不会触发失败异常,从而得靠引入额外的检查库来解决这个问题(如OpenZeppelin中的SafeMath库);另一个是"checked"(检查)模式。默认情况下,算术运算使用的是“checked”模式,会进行溢出检查,如果结果溢出,会出现失败异常回退。

    举个栗子:

    uint8最大值为255,255加上一个大于0的整数会溢出,加上unchecked{}会不检查是否溢出,否则默认使用截断模式检查溢出。

    测试0.8.0或以上版本 

    测试代码

    1. // SPDX-License-Identifier: MIT
    2. pragma solidity ^0.8.7;
    3. /// @dev 示例合约:uint8最大值为255,255加上一个大于0的整数会溢出,加上unchecked不会检查是否溢出
    4. contract TestUncheck {
    5. /// @dev 检查溢出(checked模式)
    6. function withoutUnchecked() external pure returns (uint8) {
    7. uint8 a = 255;
    8. uint8 b = 5;
    9. return (a + b);
    10. }
    11. /// @dev 不检查溢出(unchecked模式或称为截断模式)
    12. function withUnchecked() external pure returns (uint8) {
    13. uint8 a = 255;
    14. uint8 b = 5;
    15. // 不检查溢出,输出溢出结果
    16. unchecked {
    17. return (a + b);
    18. }
    19. }
    20. }

    测试检查模式(checked) 

    检查模式,由于数据溢出,发生异常回退。

    测试截断模式 (unchecked或wrapping)

    截断模式,虽然255+5溢出了,但输出了溢出结果4。

    unchecked 代码块可以在代码块中的任何位置使用,但不可以替代整个函数代码块,同样不可以嵌套。

    此设置仅影响语法上位于 unchecked 块内的语句。 在块中调用的函数不会此影响。

    测试0.8.0之前版本

    0.8.0之前版本为“wrapping”(截断)模式,即在发生溢出的情况下会进行“截断”,不会触发失败异常,从而得靠引入额外的检查库来解决这个问题(如OpenZeppelin中的SafeMath库)

    测试代码 

    测试一个离0.8.0最近版本0.7.6,合约代码如下:

    1. // SPDX-License-Identifier: MIT
    2. pragma solidity ^0.7.6;
    3. /// @dev 测试0.8.0以前版本,溢出为截断模式
    4. contract TestOverflow {
    5. /// @dev 不检查溢出(wrapping模式)
    6. function overflow() external pure returns (uint8) {
    7. uint8 a = 255;
    8. uint8 b = 5;
    9. return (a + b);
    10. }
    11. }

    测试结果(wrapping模式)

    输出截断数据,即为不检查模式 

  • 相关阅读:
    十 动手学深度学习v2 ——卷积神经网络之NiN + GoogLeNet
    k8s篇之一、环境搭建
    python之singledispatch单分派问题
    windows消息的处理过程 消息队列
    Linux学习
    卷积神经网络(CNN)——基础知识整理
    竞赛 深度学习 YOLO 实现车牌识别算法
    ES流、PES流和TS流介绍
    【JVM篇】什么是运行时数据区
    盘点Sui生态20个值得关注的项目,其中8个已进入测试阶段
  • 原文地址:https://blog.csdn.net/ling1998/article/details/125550140