? ? Solidity是一種類似于JavaScript的語言,它面向物件,支持多繼承,可以一次回傳多個值,在開發智能合約的程序中,對應++、–這類操作要考慮變數的定義域,即要考慮變數的上溢與下溢問題,
- 資料上溢
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 ,再通過變數名來呼叫這些方法,
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
1、庫合約
//safemath.sol
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;
}
}
2、自增修改
2.1 案例A 簡單變數
//原文1
uint numA;
numA++;
//修改1
import "./safemath.sol";
using SafeMath for uint256;
uint numA;
//numA++;
numA = numA.add(1);
2.2 案例B map變數
//原文2
mapping(address => uint) ownerAppleCount;
ownerAppleCount[msg.sender]++;
//修改2
import "./safemath.sol";
using SafeMath for uint256;
mapping(address => uint) ownerAppleCount;
//ownerAppleCount[msg.sender]++;
ownerAppleCount[msg.sender] = ownerAppleCount[msg.sender].add(1);
2.3 案例C 結構體變數
//原文3
struct Apple {
uint32 id;
uint weight;
string color;
}
Apple zhaoApple = Apple(100,150,"red");
zhaoApple.weight++;
//修改3
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);
3、自減修改
3.1 案例D
//原文4
uint8 numB;
numB--;
//修改4
import "./safemath.sol";
using SafeMath8 for uint8;
uint8 numB;
numB--;
numB = numB.sub(1);
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/303112.html
標籤:區塊鏈
