整型溢出毛病(Integer Overflow/Underflow Vulnerability)是盘算机程序中因数值运算超出数据类型范围而导致的非常行为。可能导致的危害: 在智能合约中,这种毛病可能导致资产盘算错误、权限绕过, 合约逻辑失控,是区块链安全领域的高危风险之一。
在Solidity中, 当我们界说一个整型数据类型时通常需要声明这个整型的长度,在学习Solidity的过程中, 我们学习到整型有无符号整型uint与整型int类型 ,如果直接使用uint声明
uint a; // 这里等效于声明 uint256 a
焦点概念
数据类型的有限性 ,盘算机中所有数值类型都有固定的存储空间(例如 uint256 用 256 位二进制存储),其取值范围被严酷限制
uint8:0 ~ 255(2的8次方-1)
int8:-128 ~ 127 (-1 * 2的7次方 到 2的7次方-1)
溢出类型
上溢(Overflow):数值凌驾类型最大值 下溢(Underflow):数值低于类型最小值
上溢
原理
下面我们用uint8举例,uint8就是使用了8个比特位,其值的范围是0-2的八次方,也就是 0 - 255,255是uint8数据类型可以存储的最大值,那么如果我们设置一个uint8变量等于255,对其加1会发生什么呢,测试代码如下
// SPDX-License-Identifier: GPL-3.0
pragma solidity = 0.7.6;
contract Test {
function test() public pure returns(uint8) { uint8 a = 255; return a + 1; }
}
运行可以看到如下效果, 最后的值是0
img
此中运算过程是怎样的呢?
当我们界说了uint8 a = 255 之后,系统为我们分配了一个巨细为8bit的内存空间,随后设置其值为255, 换成2进制也就是 1111 1111(为了方便检察这里加上空格),不论是传统的系统还是区块链网络,其底层都是2进制,当我们执行a+1时,也就是二进制的 1111 1111 + 1
最后效果是
1 0000 0000
因为存储效果的变量只有 8 bit,最高位的1会被抛弃,最后只剩下
0000 0000
换算回10进制也就是0
同理, 如果是+2,那么就是
1 0000 0001
最高位被抛弃, 效果值为1
这就是整型上溢,上溢会使得原本很大的值变得很小
案例
假设我们有一个区块链网店业务,示例代码如下, 这种代码理论上是要用 uint256 的, 但是这里为了方便理解我将uint256都修改为了uint8, 现实利用中只需要增加对应的值使其凌驾2^256-1即可
这里当我们购买128个商品1时就会触发毛病
[code][/code] // SPDX-License-Identifier: MITpragma solidity = 0.7.6;
contract OnlineStore { // 商品布局体 struct Product { uint256 id; string name; uint8 price; // 单元 eth }
// 商品存储不定长数组 Product[] private products;
// 初始化函数 constructor() { // 创建三个示例商品 products.push(Product(1, " hone", 2)); // 1 ETH
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
|