Solidity拓展:数学运算过程中数据长度溢出的问题

news/2024/10/21 10:02:59/

 

 

在数学运算过程中假如超过了长度则值会变成该类型的最小值,如果小于了该长度则变成最大值

  • 数据上溢
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 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++;

优化后 

import "./safemath.sol";
using SafeMath for uint256;uint numA;
//numA++;
numA = numA.add(1);

map

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);

2.自减修改

简单变量

uint8 numB;
numB--;

优化后 

import "./safemath.sol";
using SafeMath8 for uint8;uint8 numB;
//numB--;
numB = numB.sub(1);

http://www.ppmy.cn/news/96524.html

相关文章

Linux-0.11 文件系统open.c详解

Linux-0.11 文件系统open.c详解 模块简介 对于一个文件系统&#xff0c;需要提供一些封装好的系统调用提供给应用层调用。例如打开一个文件&#xff0c;对于应用层而言&#xff0c;其并不关心底层的inode和buffer_cache的操作。 open.c便是提供这样的一个功能。 同样是文件系…

IOC理解

1. Java反射 Java反射机制存在于运行时&#xff0c;对于任意一个类&#xff0c;都能获取这个类的所有属性和方法&#xff0c;对于任意一个对象&#xff0c;都能通过反射机制去调用它的属性和方法&#xff0c;这种动态获取类信息及动态调用对象方法的功能称为Java反射机制&#…

驱动开发——嵌入式(驱动)软开基础(九)

1 系统调用的作用? (1)为应用程序提供访问硬件资源的统一接口,以至于应用程序不必关心具体的硬件操作细节。 (2)对系统内核进行保护,保证系统的稳定和安全,因为系统调用规定了用户进程进入内核的具体方式以及所能访问的数据范围。 2 BootLoader、Linux内核、根文件系…

Java并发常见面试题

参考:javauide、程序员大斌、面试宝典 1.并发与并行的区别 并发:两个及两个以上的作业在同一 时间段 内执行。并行:两个及两个以上的作业在同一 时刻 执行。2.同步和异步的区别 同步:发出一个调用之后,在没有得到结果之前, 该调用就不可以返回,一直等待。异步:调用在发…

WPF界面设计

目录 1.设计一个优美的注册界面1.实现效果2.代码展示 2.简易登录按钮设计1.实现效果2.代码展示 3.设计一个优美的注册登录界面&#xff08;连接数据库&#xff09;1.实现效果2.代码展示 4.设计一个简单的在线教育系统界面1.实现效果2.代码展示 5. 设计一个Dashboard1.实现效果2…

医院管理系统详细设计说明书

详细设计说明书 1.引言 1.1编写目的 在完成了针对北京工商大学校医院的前期调查&#xff0c;同时与多位学生进行了全面深入的探讨和分析的基础上&#xff0c;提出了这份概要设计说明书。 此概要设计说明书对北京工商大学校医院管理系统网站做了全面细致的概要设计&#xff0c;…

低代码平台

aims https://aisuda.bce.baidu.com/amis/zh-CN/docs/start/getting-started

AntV X6结合Vue组件渲染节点,并与节点组件进行双向的数据交互

项目使用 Vue2.0 Element-ui 框架&#xff0c;在开发流程功能时自定义节点&#xff0c;为实现稍复杂的样式以及操作交互&#xff0c;使用 markup attrs的方式的话&#xff0c;比较麻烦&#xff0c;且难以结合使用 Element-ui的交互组件&#xff0c;因此换成结合 Vue组件渲染方…