郴州網(wǎng)站建設服務騰訊企點注冊
?
?
在數(shù)學運算過程中假如超過了長度則值會變成該類型的最小值,如果小于了該長度則變成最大值
- 數(shù)據(jù)上溢
uint8 numA = 255; numA++;
?uint8的定義域為[0,255],現(xiàn)在numA已經(jīng)到頂了,numA++會使num變成0(由于256已經(jīng)超過定義域,它會越過256,變成0),即數(shù)據(jù)發(fā)生上溢(越過上邊界,叫上溢)。255 --> 256 -->0 上溢。
- 數(shù)據(jù)下溢
uint8 numB = 0; numB--;
numB本身是低水位線,現(xiàn)在numB-- 會使num變成255(由于-1已經(jīng)超過定義域,所以它會越過-1,變成255),即數(shù)據(jù)發(fā)生下溢(越過下邊界,叫下溢)。0–> -1 --> 255 下溢。??
?可以通過引用 OpenZeppelin的 SafeMath v2.5.x 庫,或者自定義一個SafeMath合約,來避免該問題。
????庫是 Solidity 中一種特殊的合約,它給原始數(shù)據(jù)類型增加了一些方法: add(), sub(), mul(), 以及 div()。
????先引用或者import SafeMath庫,然后聲明 using SafeMath for uint256 ,再通過變量名來調(diào)用這些方法。
?方法1:
導入庫import "SafeMath" ?
給變量使用庫 using SafeMath for 變量類型
傳遞參數(shù)給庫中add函數(shù)
uint e=255;
e=參數(shù)1.add(參數(shù)2)? ? ? ? ? ?底層是?參數(shù)1傳給a,參數(shù)2傳給b?
方法2:
也可以自己創(chuàng)建一個庫,用library聲明,而不是contract
library SafeMath {
func add(uint8 a,uint b) internal pure returns(uint 8){ 檢驗加法
? ? ? ?uint8 = a+b;
? ? ? ?assert(c>=a);
? ? ? ?assert()函數(shù)可以用來判斷參數(shù)是否成立,若不成立則彈出一個錯誤
? ? ? ?return c;}}
試例
import "./safemath.sol"; //1)引用庫
using SafeMath for uint256; //2)聲明指定的類型uint256 a = 5;
uint256 b = a.add(3); // 5 + 3 = 8 //3)用變量名來調(diào)用方法
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 0uint256 c = a / b;// assert(a == b * c + a % b); // There is no case in which this doesn't holdreturn 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 0uint32 c = a / b;// assert(a == b * c + a % b); // There is no case in which this doesn't holdreturn 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 0uint16 c = a / b;// assert(a == b * c + a % b); // There is no case in which this doesn't holdreturn 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 0uint8 c = a / b;// assert(a == b * c + a % b); // There is no case in which this doesn't holdreturn 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;}
}
1.自增修改
簡單變量
uint numA;
numA++;
優(yōu)化后?
import "./safemath.sol";
using SafeMath for uint256;uint numA;
//numA++;
numA = numA.add(1);
map
mapping(address => uint) ownerAppleCount;
ownerAppleCount[msg.sender]++;
優(yōu)化后?
import "./safemath.sol";
using SafeMath for uint256;mapping(address => uint) ownerAppleCount;
//ownerAppleCount[msg.sender]++;
ownerAppleCount[msg.sender] = ownerAppleCount[msg.sender].add(1);
結(jié)構(gòu)體?
struct Apple {uint32 id; uint weight;string color;
}
Apple zhaoApple = Apple(100,150,"red");
zhaoApple.weight++;
優(yōu)化后?
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);
2.自減修改
簡單變量
uint8 numB;
numB--;
優(yōu)化后?
import "./safemath.sol";
using SafeMath8 for uint8;uint8 numB;
//numB--;
numB = numB.sub(1);