Michael.W基于Foundry精读Openzeppelin第16期——SignedSafeMath.sol

news2024/11/16 5:33:40

Michael.W基于Foundry精读Openzeppelin第16期——SignedSafeMath.sol

      • 0. 版本
        • 0.1 SignedSafeMath.sol
      • 1. 目标合约
      • 2. 代码精读
        • 2.1 mul(int256 a, int256 b)
        • 2.2 div(int256 a, int256 b)
        • 2.3 sub(int256 a, int256 b)
        • 2.4 add(int256 a, int256 b)

0. 版本

[openzeppelin]:v4.8.3,[forge-std]:v1.5.6

0.1 SignedSafeMath.sol

Github: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.8.3/contracts/utils/math/SignedSafeMath.sol

SignedSafeMath库就是直接对solidity内置的int256类型的加减乘除运算的函数封装。

注:从solidity 0.8版本开始,SignedSafeMath已经不再被广泛使用。因为从0.8版本开始,solidity编译器已经内置了运算符的溢出检查。

1. 目标合约

封装SignedSafeMath library成为一个可调用合约:

Github: https://github.com/RevelationOfTuring/foundry-openzeppelin-contracts/blob/master/src/utils/math/MockSignedSafeMath.sol

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

import "openzeppelin-contracts/contracts/utils/math/SignedSafeMath.sol";

contract MockSignedSafeMath {
    using SignedSafeMath for int;

    function mul(int a, int b) external pure returns (int) {
        return a.mul(b);
    }

    function div(int a, int b) external pure returns (int){
        return a.div(b);
    }

    function sub(int a, int b) external pure returns (int){
        return a.sub(b);
    }

    function add(int a, int b) external pure returns (int) {
        return a.add(b);
    }
}

全部foundry测试合约:

Github: https://github.com/RevelationOfTuring/foundry-openzeppelin-contracts/blob/master/test/utils/math/SignedSafeMath.t.sol

2. 代码精读

2.1 mul(int256 a, int256 b)

返回两个int256的乘积,如果产生溢出会revert。

    function mul(int256 a, int256 b) internal pure returns (int256) {
        // 是直接对a*b的函数封装,返回a与b的乘积
        return a * b;
    }

foundry代码验证

contract SignedSafeMathTest is Test {
    MockSignedSafeMath mssm = new MockSignedSafeMath();

    function test_Mul() external {
        assertEq(mssm.mul(3, 2), 6);
        assertEq(mssm.mul(3, - 2), - 6);
        assertEq(mssm.mul(- 3, 2), - 6);
        assertEq(mssm.mul(- 3, - 2), 6);
        // overflow
        vm.expectRevert();
        mssm.mul(type(int).max, 2);
        vm.expectRevert();
        mssm.mul(type(int).min, 2);
    }
}

2.2 div(int256 a, int256 b)

返回两个int256的商,如果除数为0会revert。

注:计算结果向0取整。

    function div(int256 a, int256 b) internal pure returns (int256) {
        // 是直接对a/b的函数封装,返回a与b的商
        return a / b;
    }

foundry代码验证

contract SignedSafeMathTest is Test {
    MockSignedSafeMath mssm = new MockSignedSafeMath();

    function test_Div() external {
        assertEq(mssm.div(3, 2), 1);
        assertEq(mssm.div(3, - 2), - 1);
        assertEq(mssm.div(- 3, 2), - 1);
        assertEq(mssm.div(- 3, - 2), 1);
        // overflow
        vm.expectRevert();
        mssm.div(1, 0);
    }
}

2.3 sub(int256 a, int256 b)

返回两个int256的差,如果产生溢出会revert

    function sub(int256 a, int256 b) internal pure returns (int256) {
        // 是直接对a-b的函数封装,返回a与b的差
        return a - b;
    }

foundry代码验证

contract SignedSafeMathTest is Test {
    MockSignedSafeMath mssm = new MockSignedSafeMath();

    function test_Sub() external {
        assertEq(mssm.sub(3, 2), 1);
        assertEq(mssm.sub(3, - 2), 5);
        assertEq(mssm.sub(- 3, 2), - 5);
        assertEq(mssm.sub(- 3, - 2), - 1);
        // overflow
        vm.expectRevert();
        mssm.sub(type(int).min, 1);
    }
}

2.4 add(int256 a, int256 b)

返回两个int256的和,如果产生溢出会revert。

    function add(int256 a, int256 b) internal pure returns (int256) {
        // 是直接对a+b的函数封装,返回a与b的和
        return a + b;
    }

foundry代码验证

contract SignedSafeMathTest is Test {
    MockSignedSafeMath mssm = new MockSignedSafeMath();

    function test_Add() external {
        assertEq(mssm.add(1, 2), 3);
        assertEq(mssm.add(- 1, 2), 1);
        assertEq(mssm.add(- 1, - 2), - 3);
        // overflow
        vm.expectRevert();
        mssm.add(type(int).max, 1);
    }
}

ps:
本人热爱图灵,热爱中本聪,热爱V神。
以下是我个人的公众号,如果有技术问题可以关注我的公众号来跟我交流。
同时我也会在这个公众号上每周更新我的原创文章,喜欢的小伙伴或者老伙计可以支持一下!
如果需要转发,麻烦注明作者。十分感谢!

在这里插入图片描述

公众号名称:后现代泼痞浪漫主义奠基人

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/815028.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

试试这三款音频转换格式软件,看看可不可以转换mp3?

你是不是不知道音频转换格式有什么用呢?为什么要音频转换呢? 其实音频转换格式的原因是: ①兼容性问题:不同的设备支持不同的音频格式,如果你想在不同设备之间共享音频文件的话,那么需要将文件转换另一种…

Android HTTP使用(详细版)

前言 在面试过程中,HTTP 被提问的概率还是比较高的。 小林我搜集了 5 大类 HTTP 面试常问的题目,同时这 5 大类题跟 HTTP 的发展和演变关联性是比较大的,通过问答 + 图解的形式由浅入深的方式帮助大家进一步的学习和理解 HTTP 协议。 HTTP 基本概念 Get 与 Post HTTP 特性…

Spring AOP 中的代理对象是怎么创建出来的?

文章目录 1. AOP 用法2. 原理分析2.1 doCreateBean2.2 postProcessAfterInitialization2.3 getAdvicesAndAdvisorsForBean2.3.1 findCandidateAdvisors2.3.2 findAdvisorsThatCanApply2.3.3 extendAdvisors 2.4 createProxy 今天和小伙伴们聊一聊 Spring AOP 中的代理对象是怎么…

将number输入框改写成只能输入数字的输入框

去掉 type”number” 末尾的箭头 场景代码 场景 在很多场景下,输入框是会被要求限制只能输入数字,不能输入文字或者符号的。通常我们会使用input事件 正则表达式 去实现这个功能,但今天提供另一种css的方法,将 type”number” 的…

面试总结-Redis篇章(九)——Redis主从复制、主从数据同步原理

Redis其他面试问题 主从复制单节点Redis的并发能力是有上限的,要进一步提高Redis的并发能力,就需要搭建主从集群,实现读写分离主节点主要进行客户端的写操作,从节点进行客户端的读操作,因为Redis一直都是读多写少&…

iTOP-RK3568开发板Windows 安装 RKTool 驱动

在烧写镜像之前首先需要安装 RKTool 驱动。 RKTool 驱动在网盘资料“iTOP-3568 开发板\01_【iTOP-RK3568 开发板】基础资料 \02_iTOP-RK3568 开发板烧写工具及驱动”路径下。 驱动如下图所示: 解压缩后,进入文件夹,如下图所示:…

品牌活动 | 阿里云云原生技术实践营:大模型+CloudOS,实现企业智能化

近日,由阿里云举办的“云原生技术实践营-应用和容器实践专场”在广州顺利开展。行云创新CEO马洪喜作为受邀嘉宾之一,参加了本次活动,分享了主题为“API大语言模型,以非侵入式实现企业业务智能化变革”的演讲,向参会者展…

【华秋干货铺】一文轻松搞定PCB叠层和阻抗设计

为了减少在高速信号传输过程中的反射现象,必须在信号源、接收端以及传输线上保持阻抗的匹配。单端信号线的具体阻抗取决于它的线宽尺寸以及与参考平面之间的相对位置。特定阻抗要求的差分对间的线宽/线距则取决于选择的PCB叠层结构。 由于最小线宽和最小线距是取决…

WRF替换GVF数据

WRF替换GVF数据 GVF(Green Vegetation Fraction) 是决定WRF模拟局地/区域气候研究的关键参数。研究表明GVF对模式模拟温度、湿度和潜热误差校正贡献率分别为62%,87%和92%。因此本文提供对WRF中的GVF进行替换的具体方法。 1.GVF获取   目前还没有现成的GVF产品可以…

Java代码连接RabbitMQ服务器

目录 1.添加依赖 2.生产者代码 3.消费者代码 4.效果 1.发送消息 2.消费消息 5.注意 1.添加依赖 <dependency><groupId>com.rabbitmq</groupId><artifactId>amqp-client</artifactId><version>5.12.0</version></dependenc…

12、springboot自定义banner

springboot自定义banner ▲ 控制Banner信息是否显示及在哪里显示&#xff1a; 在application.properties这个配置文件里面进行以下的属性设置&#xff1a;spring.main.banner-mode 属性进行设置&#xff0c;该属性支持如下3个属性值&#xff1a;- console&#xff1a;在Spring…

JavaWeb+jsp+Tomcat的教务查询系统

点击以下链接获取源码&#xff1a; https://download.csdn.net/download/qq_64505944/88134601?spm1001.2014.3001.5503 jsp/tomcat7.05/MySQL5.7或8版本/ssm框架/spring/ Web框架&#xff1a;SpringBoot/ORM框架&#xff1a;Mybatis/安全框架&#xff1a;Shiro/分页插件&am…

指针进阶详解---C语言

❤博主CSDN:啊苏要学习 ▶专栏分类&#xff1a;C语言◀ C语言的学习&#xff0c;是为我们今后学习其它语言打好基础&#xff0c;C生万物&#xff01; 开始我们的C语言之旅吧&#xff01;✈ 目录 前言&#xff1a; 一.字符指针 二.指针数组 三.数组指针 四.数组、指针参数 …

html富文本编辑器

接了个单子&#xff0c;需要添加一个文章模块&#xff0c;一看用到的技术这么老&#xff0c;人傻了&#xff0c;纯html css js 。 在普通页面中 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"…

word xls有用小技巧

不少office、代码编辑等软件&#xff0c;很简单高效小技巧。Word xlsx 某一行或列不动&#xff1a; 视图》冻结窗格》冻结首行 eclispe 全局搜索 CtrlH 制定变量、名称搜索 鼠标左键点中CtrlAltG

Promethus(普罗米修斯)监控系统

一、普罗米修斯概述 Prometheus(由go语言(golang)开发)是一套开源的监控&报警&时间序列数据库的组合。适合监控docker容器。因为kubernetes(俗称k8s)的流行带动了prometheus的发展。 Overview | Prometheus 二、时间序列数据 1、什么是序列数据 时间序列数据(TimeSer…

Docker安装es以及ik分词器

1、拉取镜像 docker pull elasticsearch:7.10.12、下载对应版本的ik分词、并将它们解压到ik文件夹下&#xff0c;如图 https://github.com/medcl/elasticsearch-analysis-ik/releases 3、在服务器上创建文件夹 mkdir /usr/elklog/elk/es mkdir /usr/elklog/elk/es/data mkdi…

Android 架构模式如何选择

作者&#xff1a;vivo 互联网客户端团队-Xu Jie Android架构模式飞速演进&#xff0c;目前已经有MVC、MVP、MVVM、MVI。到底哪一个才是自己业务场景最需要的&#xff0c;不深入理解的话是无法进行选择的。这篇文章就针对这些架构模式逐一解读。重点会介绍Compose为什么要结合MV…

脑电信号处理与特征提取——6.运用机器学习技术和脑电进行大脑解码(涂毅恒)

目录 六、运用机器学习技术和脑电进行大脑解码 6.1 前言 6.2 基于脑电数据的机器学习基础分析 6.3 基于脑电数据的机器学习进阶分析 6.4 代码解读 六、运用机器学习技术和脑电进行大脑解码 6.1 前言 6.2 基于脑电数据的机器学习基础分析 6.3 基于脑电数据的机器学习进阶分…

反射简述

什么是反射反射在java中起到什么样的作用获取class对象的三种方式反射的优缺点图 什么是反射 JAVA反射机制是在运行状态中&#xff0c;对于任意一个类&#xff0c;都能够知道这个类的所有属性和方法&#xff1b;对于任意一个对象&#xff0c;都能够调用它的任意一个方法和属性&…