假设我们有一个 uint8
, 只能存储8 bit数据。这意味着我们能存储的最大数字就是二进制 11111111
(或者说十进制的 2^8 - 1 = 255).
来看看下面的代码。最后 number
将会是什么值?
uint8 number = 255;
number++;
在这个例子中,我们导致了溢出 — 虽然我们加了1, 但是 number
出乎意料地等于 0
了。 (如果你给二进制 11111111
加1, 它将被重置为 00000000
,就像钟表从 23:59
走向 00:00
)。
下溢(underflow
)也类似,如果你从一个等于 0
的 uint8
减去 1
, 它将变成 255
(因为 uint
是无符号的,其不能等于负数)。
虽然我们在这里不使用 uint8
,而且每次给一个 uint256
加 1
也不太可能溢出 (2^256 真的是一个很大的数了),在我们的合约中添加一些保护机制依然是非常有必要的,以防我们的 DApp 以后出现什么异常情况。
然而,又是OpenZeppelin帮忙,它建立了一个叫做safeMath的库来帮忙,库是Solidity中一种特殊的合约,其中的一个功能是给原始数据类型增加方法。
比如使用SafeMath库的时候,使用using SafeMath for uint256这样的语法,SafeMath对于数据有add,sub(减法),mul(乘法)和div(除法)语法使用
如:using SafeMath for uint256; uint256 a = 5; uint256 b = a.add(3); // 5 + 3 = 8 uint256 c = a.mul(2); // 5 * 2 = 10
库与继承合约不同,库可以把自己的使用方法赋予某一个数据类型(有点类似类和包)
根据不同的uint字节数,有不同的SafeMath库来对应
SafeMath16
SafeMatn32等等