赞
踩
在数学运算过程中假如超过了长度则值会变成该类型的最小值,如果小于了该长度则变成最大值
- 数据上溢
uint8 numA = 255; numA++;uint8的定义域为[0,255],现在numA已经到顶了,numA++会使num变成0(由于256已经超过定义域,它会越过256,变成0),即数据发生上溢(越过上边界,叫上溢)。255 --> 256 -->0 上溢。
- 数据下溢
uint8 numB = 0; 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;}}
- import "./safemath.sol"; //1)引用库
- using SafeMath for uint256; //2)声明指定的类型
-
- uint256 a = 5;
- uint256 b = a.add(3); // 5 + 3 = 8 //3)用变量名来调用方法
- uint256 c = a.mul(2); // 5 * 2 = 10
- pragma solidity ^0.4.18;
-
- /**
- * @title SafeMath
- * @dev Math operations with safety checks that throw on error
- */
- library SafeMath {
-
- /**
- * @dev Multiplies two numbers, throws on overflow.
- */
- 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;
- }
-
- /**
- * @dev Integer division of two numbers, truncating the quotient.
- */
- 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;
- }
-
- /**
- * @dev Substracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend).
- */
- function sub(uint256 a, uint256 b) internal pure returns (uint256) {
- assert(b <= a);
- return a - b;
- }
-
- /**
- * @dev Adds two numbers, throws on overflow.
- */
- function add(uint256 a, uint256 b) internal pure returns (uint256) {
- uint256 c = a + b;
- assert(c >= a);
- return c;
- }
- }
-
- /**
- * @title SafeMath32
- * @dev SafeMath library implemented for uint32
- */
- library SafeMath32 {
-
- function mul(uint32 a, uint32 b) internal pure returns (uint32) {
- if (a == 0) {
- return 0;
- }
- uint32 c = a * b;
- assert(c / a == b);
- return c;
- }
-
- function div(uint32 a, uint32 b) internal pure returns (uint32) {
- // assert(b > 0); // Solidity automatically throws when dividing by 0
- uint32 c = a / b;
- // assert(a == b * c + a % b); // There is no case in which this doesn't hold
- return c;
- }
-
- function sub(uint32 a, uint32 b) internal pure returns (uint32) {
- assert(b <= a);
- return a - b;
- }
-
- function add(uint32 a, uint32 b) internal pure returns (uint32) {
- uint32 c = a + b;
- assert(c >= a);
- return c;
- }
- }
-
- /**
- * @title SafeMath16
- * @dev SafeMath library implemented for uint16
- */
- library SafeMath16 {
-
- function mul(uint16 a, uint16 b) internal pure returns (uint16) {
- if (a == 0) {
- return 0;
- }
- uint16 c = a * b;
- assert(c / a == b);
- return c;
- }
-
- function div(uint16 a, uint16 b) internal pure returns (uint16) {
- // assert(b > 0); // Solidity automatically throws when dividing by 0
- uint16 c = a / b;
- // assert(a == b * c + a % b); // There is no case in which this doesn't hold
- return c;
- }
-
- function sub(uint16 a, uint16 b) internal pure returns (uint16) {
- assert(b <= a);
- return a - b;
- }
-
- function add(uint16 a, uint16 b) internal pure returns (uint16) {
- uint16 c = a + b;
- assert(c >= a);
- return c;
- }
- }
-
- library SafeMath8 {
-
- function mul(uint8 a, uint8 b) internal pure returns (uint8) {
- if (a == 0) {
- return 0;
- }
- uint8 c = a * b;
- assert(c / a == b);
- return c;
- }
-
- function div(uint8 a, uint8 b) internal pure returns (uint8) {
- // assert(b > 0); // Solidity automatically throws when dividing by 0
- uint8 c = a / b;
- // assert(a == b * c + a % b); // There is no case in which this doesn't hold
- return c;
- }
-
- function sub(uint8 a, uint8 b) internal pure returns (uint8) {
- assert(b <= a);
- return a - b;
- }
-
- function add(uint8 a, uint8 b) internal pure returns (uint8) {
- uint8 c = a + b;
- assert(c >= a);
- return c;
- }
- }
-
- uint numA;
- numA++;
优化后
- import "./safemath.sol";
- using SafeMath for uint256;
-
- uint numA;
- //numA++;
- numA = numA.add(1);
- mapping(address => uint) ownerAppleCount;
- ownerAppleCount[msg.sender]++;
优化后
- import "./safemath.sol";
- using SafeMath for uint256;
-
- mapping(address => uint) ownerAppleCount;
- //ownerAppleCount[msg.sender]++;
- ownerAppleCount[msg.sender] = ownerAppleCount[msg.sender].add(1);
- struct Apple {
- uint32 id;
- uint weight;
- string color;
- }
- Apple zhaoApple = Apple(100,150,"red");
- zhaoApple.weight++;
优化后
- import "./safemath.sol";
- using SafeMath for uint256;
- using SafeMath32 for uint32;
-
- struct Apple {
- uint32 id;
- uint weight;
- string color;
- }
- Apple zhaoApple = Apple(100,150,"red");
- //zhaoApple.weight++;
- zhaoApple.weight = zhaoApple.weight.add(1);
- uint8 numB;
- numB--;
优化后
- import "./safemath.sol";
- using SafeMath8 for uint8;
-
- uint8 numB;
- //numB--;
- numB = numB.sub(1);
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。