当前位置:   article > 正文

Solidity拓展:数学运算过程中数据长度溢出的问题_solidity溢出库

solidity溢出库

在数学运算过程中假如超过了长度则值会变成该类型的最小值,如果小于了该长度则变成最大值

  • 数据上溢
  1. uint8 numA = 255;
  2. numA++;

 uint8的定义域为[0,255],现在numA已经到顶了,numA++会使num变成0(由于256已经超过定义域,它会越过256,变成0),即数据发生上溢(越过上边界,叫上溢)。255 --> 256 -->0 上溢。

  • 数据下溢
  1. uint8 numB = 0;
  2. numB--;

numB本身是低水位线,现在numB-- 会使num变成255(由于-1已经超过定义域,所以它会越过-1,变成255),即数据发生下溢(越过下边界,叫下溢)。0–> -1 --> 255 下溢。  

 可以通过引用 OpenZeppelin的 SafeMath v2.5.x 库,或者自定义一个SafeMath合约,来避免该问题。
    库是 Solidity 中一种特殊的合约,它给原始数据类型增加了一些方法: add(), sub(), mul(), 以及 div()。
    先引用或者import SafeMath库,然后声明 using SafeMath for uint256 ,再通过变量名来调用这些方法。
 

方法1:

导入库import "SafeMath"  

给变量使用库 using SafeMath for 变量类型

传递参数给库中add函数

uint e=255;

e=参数1.add(参数2)           底层是 参数1传给a,参数2传给b 

方法2:

也可以自己创建一个库,用library声明,而不是contract

library SafeMath {

func add(uint8 a,uint b) internal pure returns(uint 8){ 检验加法

       uint8 = a+b;

       assert(c>=a);

       assert()函数可以用来判断参数是否成立,若不成立则弹出一个错误

       return c;}}

试例

  1. import "./safemath.sol"; //1)引用库
  2. using SafeMath for uint256; //2)声明指定的类型
  3. uint256 a = 5;
  4. uint256 b = a.add(3); // 5 + 3 = 8 //3)用变量名来调用方法
  5. uint256 c = a.mul(2); // 5 * 2 = 10

库合约源码

  1. pragma solidity ^0.4.18;
  2. /**
  3. * @title SafeMath
  4. * @dev Math operations with safety checks that throw on error
  5. */
  6. library SafeMath {
  7. /**
  8. * @dev Multiplies two numbers, throws on overflow.
  9. */
  10. function mul(uint256 a, uint256 b) internal pure returns (uint256) {
  11. if (a == 0) {
  12. return 0;
  13. }
  14. uint256 c = a * b;
  15. assert(c / a == b);
  16. return c;
  17. }
  18. /**
  19. * @dev Integer division of two numbers, truncating the quotient.
  20. */
  21. function div(uint256 a, uint256 b) internal pure returns (uint256) {
  22. // assert(b > 0); // Solidity automatically throws when dividing by 0
  23. uint256 c = a / b;
  24. // assert(a == b * c + a % b); // There is no case in which this doesn't hold
  25. return c;
  26. }
  27. /**
  28. * @dev Substracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend).
  29. */
  30. function sub(uint256 a, uint256 b) internal pure returns (uint256) {
  31. assert(b <= a);
  32. return a - b;
  33. }
  34. /**
  35. * @dev Adds two numbers, throws on overflow.
  36. */
  37. function add(uint256 a, uint256 b) internal pure returns (uint256) {
  38. uint256 c = a + b;
  39. assert(c >= a);
  40. return c;
  41. }
  42. }
  43. /**
  44. * @title SafeMath32
  45. * @dev SafeMath library implemented for uint32
  46. */
  47. library SafeMath32 {
  48. function mul(uint32 a, uint32 b) internal pure returns (uint32) {
  49. if (a == 0) {
  50. return 0;
  51. }
  52. uint32 c = a * b;
  53. assert(c / a == b);
  54. return c;
  55. }
  56. function div(uint32 a, uint32 b) internal pure returns (uint32) {
  57. // assert(b > 0); // Solidity automatically throws when dividing by 0
  58. uint32 c = a / b;
  59. // assert(a == b * c + a % b); // There is no case in which this doesn't hold
  60. return c;
  61. }
  62. function sub(uint32 a, uint32 b) internal pure returns (uint32) {
  63. assert(b <= a);
  64. return a - b;
  65. }
  66. function add(uint32 a, uint32 b) internal pure returns (uint32) {
  67. uint32 c = a + b;
  68. assert(c >= a);
  69. return c;
  70. }
  71. }
  72. /**
  73. * @title SafeMath16
  74. * @dev SafeMath library implemented for uint16
  75. */
  76. library SafeMath16 {
  77. function mul(uint16 a, uint16 b) internal pure returns (uint16) {
  78. if (a == 0) {
  79. return 0;
  80. }
  81. uint16 c = a * b;
  82. assert(c / a == b);
  83. return c;
  84. }
  85. function div(uint16 a, uint16 b) internal pure returns (uint16) {
  86. // assert(b > 0); // Solidity automatically throws when dividing by 0
  87. uint16 c = a / b;
  88. // assert(a == b * c + a % b); // There is no case in which this doesn't hold
  89. return c;
  90. }
  91. function sub(uint16 a, uint16 b) internal pure returns (uint16) {
  92. assert(b <= a);
  93. return a - b;
  94. }
  95. function add(uint16 a, uint16 b) internal pure returns (uint16) {
  96. uint16 c = a + b;
  97. assert(c >= a);
  98. return c;
  99. }
  100. }
  101. library SafeMath8 {
  102. function mul(uint8 a, uint8 b) internal pure returns (uint8) {
  103. if (a == 0) {
  104. return 0;
  105. }
  106. uint8 c = a * b;
  107. assert(c / a == b);
  108. return c;
  109. }
  110. function div(uint8 a, uint8 b) internal pure returns (uint8) {
  111. // assert(b > 0); // Solidity automatically throws when dividing by 0
  112. uint8 c = a / b;
  113. // assert(a == b * c + a % b); // There is no case in which this doesn't hold
  114. return c;
  115. }
  116. function sub(uint8 a, uint8 b) internal pure returns (uint8) {
  117. assert(b <= a);
  118. return a - b;
  119. }
  120. function add(uint8 a, uint8 b) internal pure returns (uint8) {
  121. uint8 c = a + b;
  122. assert(c >= a);
  123. return c;
  124. }
  125. }

1.自增修改

简单变量

  1. uint numA;
  2. numA++;

优化后 

  1. import "./safemath.sol";
  2. using SafeMath for uint256;
  3. uint numA;
  4. //numA++;
  5. numA = numA.add(1);

map

  1. mapping(address => uint) ownerAppleCount;
  2. ownerAppleCount[msg.sender]++;

优化后 

  1. import "./safemath.sol";
  2. using SafeMath for uint256;
  3. mapping(address => uint) ownerAppleCount;
  4. //ownerAppleCount[msg.sender]++;
  5. ownerAppleCount[msg.sender] = ownerAppleCount[msg.sender].add(1);

结构体 

  1. struct Apple {
  2. uint32 id;
  3. uint weight;
  4. string color;
  5. }
  6. Apple zhaoApple = Apple(100,150,"red");
  7. zhaoApple.weight++;

优化后 

  1. import "./safemath.sol";
  2. using SafeMath for uint256;
  3. using SafeMath32 for uint32;
  4. struct Apple {
  5. uint32 id;
  6. uint weight;
  7. string color;
  8. }
  9. Apple zhaoApple = Apple(100,150,"red");
  10. //zhaoApple.weight++;
  11. zhaoApple.weight = zhaoApple.weight.add(1);

2.自减修改

简单变量

  1. uint8 numB;
  2. numB--;

优化后 

  1. import "./safemath.sol";
  2. using SafeMath8 for uint8;
  3. uint8 numB;
  4. //numB--;
  5. numB = numB.sub(1);
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/607345
推荐阅读
相关标签
  

闽ICP备14008679号