zoukankan      html  css  js  c++  java
  • Solidity知识点集 — 溢出和下溢

    合约安全增强: 溢出和下溢

    什么是 溢出 (overflow)?

    假设我们有一个 uint8, 只能存储8 bit数据。这意味着我们能存储的最大数字就是二进制 11111111 (或者说十进制的 2^8 - 1 = 255).

    来看看下面的代码。最后 number 将会是什么值?

    uint8 number = 255;
    number++;
    

    在这个例子中,我们导致了溢出 — 虽然我们加了1, 但是number 出乎意料地等于 0了。

    下溢(underflow)也类似,如果你从一个等于 0uint8 减去 1, 它将变成 255 (因为 uint 是无符号的,其不能等于负数)。

    使用 SafeMath

    为了防止这些情况,OpenZeppelin 建立了一个叫做 SafeMath库(library),默认情况下可以防止这些问题。

    一个Solidity 中一种特殊的合约。其中一个有用的功能是给原始数据类型增加一些方法。

    比如,使用 SafeMath 库的时候,我们将使用 using SafeMath for uint256 这样的语法。 SafeMath 库有四个方法 — addsubmul, 以及 div。现在我们可以这样来让 uint256 调用这些方法:

    using SafeMath for uint256;
    
    uint256 a = 5;
    uint256 b = a.add(3); // 5 + 3 = 8
    uint256 c = a.mul(2); // 5 * 2 = 10
    

    来看看 SafeMath 的部分代码:

    library SafeMath {
    
      function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        if (a == 0) {
          return 0;
        }
        uint256 c = a * b;
        assert(c / a == b);
        return c;
      }
    
      function div(uint256 a, uint256 b) internal pure returns (uint256) {
        // assert(b > 0); // Solidity automatically throws when dividing by 0
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold
        return c;
      }
    
      function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        assert(b <= a);
        return a - b;
      }
    
      function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        assert(c >= a);
        return c;
      }
    }
    

    首先我们有了 library 关键字, 库允许我们使用 using 关键字,它可以自动把库的所有方法添加给一个数据类型

    using SafeMath for uint;
    // 这下我们可以为任何 uint 调用这些方法了
    uint test = 2;
    test = test.mul(3); // test 等于 6 了
    test = test.add(5); // test 等于 11 了
    

    assert 和 require

    assertrequire 相似,若结果为否它就会抛出错误。 assertrequire 区别在于,require 若失败则会返还给用户剩下的 gasassert则不会。所以大部分情况下,你写代码的时候会比较喜欢 requireassert 只在代码可能出现严重错误的时候使用,比如 uint 溢出。


     
  • 相关阅读:
    Spring 中众多的的Initializer
    Spring Factories
    spring 的各种context
    @import和@Bean的区别,以及ImportSelector和ImportBeanDefinitionRegistrar两个接口的简单实用
    Spring 配置的方式
    记一次JAVA FULL GC问题处理【3】
    关于String, StringBuilder,StringBuffer 的一些测试数据
    记一次JAVA FULL GC问题处理【2】
    ThreadLocal 结构
    记一次JAVA FULL GC问题处理【1】
  • 原文地址:https://www.cnblogs.com/x-poior/p/10579973.html
Copyright © 2011-2022 走看看