Solidity拓展:数学运算过程中数据长度溢出的问题
在数学运算过程中假如超过了长度则值会变成该类型的最小值,如果小于了该长度则变成最大值
- 数据上溢
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);
相关文章:
Solidity拓展:数学运算过程中数据长度溢出的问题
在数学运算过程中假如超过了长度则值会变成该类型的最小值,如果小于了该长度则变成最大值 数据上溢 uint8 numA 255; numA;uint8的定义域为[0,255],现在numA已经到顶了,numA会使num变成0(由于256已经超过定义域,它会越过256&…...
【C语言】经典题目(一)
【C语言】字符串刷题篇在这里哦! 【C语言】字符串—刷题篇 【C】语言经典题目,五个摘录为一篇,将会持续更新啦!💞 C语言经典题目 三位数水仙花数完数求利润三个数数字排序 三位数 💫题目 已知有1、2、3、4…...
Linux 设备树文件手动编译的 shell 脚本
前言 前面通过 Makefile 实现手动编译 Linux 设备树 dts 源文件及其 设备树依赖 dtsi、.h 头文件,如何写成一个 shell 脚本,直接编译呢? 其实就是 把 Makefile 重新编写为 shell 脚本即可 编译设备树 shell 脚本 脚本内容如下:…...
C++核心编程——初识STL——STL的基本概念和六大组件
文章目录💬 一.前言二.STL基本概念和组成①容器②算法③迭代器④空间配置器⑤适配器⑥仿函数 三.STL工作机制 一.前言 长久以来,软件界一直希望建立一种可重复利用的东西,以及一种得以制造出“可重复运用的东西”的方法,让程序员的心血不止于…...
5.2图的BFS与DFS遍历
一.BFS遍历 1.图的广度优先遍历代码实现 说明: 1.广度优先遍历,类比树的层次遍历(树属于特殊的图) 2.对应算法想象图的物理结构存储: 邻接矩阵表示唯一时间复杂度:O(|V|^2); 邻接表不唯一:O(|V|2|E|)&…...
JSP+SQL网上选课系统(源代码+论文+答辩PPT)
随着科学技术的不断提高,计算机科学日渐成熟,其强大的功能已为人们深刻认识,它已进入人类社会的各个领域并发挥着越来越重要的作用。学生选课系统作为一种现代化的教学技术,以越来越受到人民的重视,是一个学校不可缺少的部分, 学生选课系统就是为了管理好选课信息而设计的。学…...
C语言数据结构——树、堆(堆排序)、TOPK问题
🐶博主主页:ᰔᩚ. 一怀明月ꦿ ❤️🔥专栏系列:线性代数,C初学者入门训练,题解C,C的使用文章,「初学」C,数据结构 🔥座右铭:“不要等到什么都没…...
springboot+vue 刘老师
课程内容 前端:vue elementui 后端:springboot mybatisplus 公共云部署 ------boot-------- 热部署 不用devtools,交给jrebel工具 RequestMapping 参数 value 路径 method 方法consumes 请求媒体类型 如 application/jsonproduces …...
学生网上考试报名系统的设计与实现
技术栈: MySQL、Maven、SpringBoot、Spring、SpringMVC、MyBatis、HikariCP、fastjson、slf4j系统功能:用户角色: (1)登录:用户在登录界面输入正确的账户名和密码,点击登录,系统将与…...
Jmeter实现分布式并发
Jmeter实现分布式并发,即使用远程机执行用例。 环境: VMware Fusion Windows系统是win7。 操作过程 1、Master在jmeter.properties添加remote_hosts 2、Slave在jmeter.properties添加server_port 同时把remote_hosts修改为和主机(Master…...
动态xml文件配置 hibernate validator 约束校验
父文章 入参校验产品化 schema_个人渣记录仅为自己搜索用的博客-CSDN博客 一般都是通过 注解进行校验, 很少看到 通过配置来进行校验. 自己再通过谷歌找到了官网文档hibernate validator constraint from xml Hibernate Validator 8.0.0.Final - Jakarta Bean Validation Re…...
Vue绑定class样式与style样式
1,回顾HTML的class属性 答:任何一个HTML标签都能够具有class属性,这个属性可能只有一个值,如class"happs",也有可能存在多个属性值,如class"happs good blue",js的原生DOM针…...
集权攻击系列:如何利用PAC新特性对抗黄金票据?
黄金票据简介 黄金票据是一种常见的域内权限维持手段,这种攻击主要是利用了Kerberos认证过程中TGT票据由KRBTGT用户的hash加密的特性,在掌握KRBTGT用户密码之后可以通过签发一张高权限用户的TGT票据,再利用这个TGT向KDC获取域内服务的ST来实…...
同程面试(部分)(未完全解析)
一面 Java直接内存有了解吗?为什么Java NIO的效率更高?Netty用到很多NIO,来了一个请求后Netty是怎么分发的,它里面有哪些角色?粘包、拆包怎么解决?为什么建立TCP连接是三次握手,而不是四次&…...
讯飞星火_VS_文心一言
获得讯飞星火认知大模型体验授权,第一时间来测试一下效果,使用申请手机号登录后,需要同意讯飞SparkDesk体验规则,如下图所示: 同意之后就可以进行体验了,界面如下: 讯飞星火效果体验 以下Promp…...
Java的集合
1. HashMap排序题,上机题。 已知一个HashMap<Integer,User>集合, User有name(String)和age(int)属性。请写一个方法实现对HashMap 的排序功能,该方法接收 HashMap<Intege…...
addr2line 使用,定位kernel panic 代码位置
在kernel崩溃时,方便定位代码。 需要打开kernel配置CONFIG_DEBUG_INFO。 需要有System.map和vmlinux文件,一般在out目录。 一般panic的时候会有给出panic的指针,如下down_write。 el1_data说明发生异常了,进入和entry.S文件&a…...
OpenAI目前所有模型介绍
目录 概述 GPT-4 (limted beta) GPT-3.5 GPT-3 各类模型介绍 DALLE Beta Whisper Beta Embeddings Moderation Codex (deprecated) 概述 模型描述GPT-4 Limited beta 一组在 GPT-3.5 上改进的模型,可以理解并生成自然语言或代码GPT-3.5一组在 GPT-3 上改…...
【P43】JMeter 吞吐量控制器(Throughput Controller)
文章目录 一、吞吐量控制器(Throughput Controller)参数说明二、测试计划设计2.1、Total Executions2.2、Percent Executions2.3、Per User 一、吞吐量控制器(Throughput Controller)参数说明 允许用户控制后代元素的执行的次数。…...
方正书版命令详解
方正书版常用的排版符包括: 空格:表示文字之间的间距,不同字号的文字需要适当调整空格大小。 省略号:用于省略一段文字,通常用三个点表示(…)。 破折号:用于表示强调或者断句&…...
铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以? 在 Golang 的面试中,map 类型的使用是一个常见的考点,其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...
多场景 OkHttpClient 管理器 - Android 网络通信解决方案
下面是一个完整的 Android 实现,展示如何创建和管理多个 OkHttpClient 实例,分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...
视频字幕质量评估的大规模细粒度基准
大家读完觉得有帮助记得关注和点赞!!! 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用,因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型(VLMs)在字幕生成方面…...
C++ 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...
AspectJ 在 Android 中的完整使用指南
一、环境配置(Gradle 7.0 适配) 1. 项目级 build.gradle // 注意:沪江插件已停更,推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...
稳定币的深度剖析与展望
一、引言 在当今数字化浪潮席卷全球的时代,加密货币作为一种新兴的金融现象,正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而,加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下,稳定…...
关于uniapp展示PDF的解决方案
在 UniApp 的 H5 环境中使用 pdf-vue3 组件可以实现完整的 PDF 预览功能。以下是详细实现步骤和注意事项: 一、安装依赖 安装 pdf-vue3 和 PDF.js 核心库: npm install pdf-vue3 pdfjs-dist二、基本使用示例 <template><view class"con…...
日常一水C
多态 言简意赅:就是一个对象面对同一事件时做出的不同反应 而之前的继承中说过,当子类和父类的函数名相同时,会隐藏父类的同名函数转而调用子类的同名函数,如果要调用父类的同名函数,那么就需要对父类进行引用&#…...
