Michael.W基于Foundry精读Openzeppelin第15期——SignedMath.sol

news2024/11/17 17:29:35

Michael.W基于Foundry精读Openzeppelin第15期——SignedMath.sol

      • 0. 版本
        • 0.1 SignedMath.sol
      • 1. 目标合约
      • 2. 代码精读
        • 2.1 max(int256 a, int256 b) && min(int256 a, int256 b)
        • 2.2 average(int256 a, int256 b)
        • 2.3 abs(int256 n)

0. 版本

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

0.1 SignedMath.sol

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

SignedMath库提供了solidity中尚未内置的标准有符号数的数学运算方法。

1. 目标合约

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

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

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

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

contract MockSignedMath {
    using SignedMath for int;

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

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

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

    function abs(int n) external pure returns (uint) {
        return n.abs();
    }
}

全部foundry测试合约:

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

2. 代码精读

2.1 max(int256 a, int256 b) && min(int256 a, int256 b)

  • max(int256 a, int256 b):求两个有符号数中的最大值;
  • min(int256 a, int256 b):求两个有符号数中的最小值。
    function max(int256 a, int256 b) internal pure returns (int256) {
        // 通过三元运算符来求二者中的最大值
        return a > b ? a : b;
    }

    function min(int256 a, int256 b) internal pure returns (int256) {
        // 通过三元运算符来求二者中的最小值
        return a < b ? a : b;
    }

foundry代码验证

contract SignedMathTest is Test {
    MockSignedMath msm = new MockSignedMath();

    function test_Max() external {
        assertEq(msm.max(1, 2), 2);
        assertEq(msm.max(- 1, - 2), - 1);
        assertEq(msm.max(- 1, 1), 1);
        assertEq(msm.max(- 1, 0), 0);
        assertEq(msm.max(1, 0), 1);
    }

    function test_Min() external {
        assertEq(msm.min(1, 2), 1);
        assertEq(msm.min(- 1, - 2), - 2);
        assertEq(msm.min(- 1, 1), - 1);
        assertEq(msm.min(- 1, 0), - 1);
        assertEq(msm.min(1, 0), 0);
    }
}

2.2 average(int256 a, int256 b)

求两个有符号整数的平均值,结果向零取整。

注:对比传统解法(a+b)/2,本方法不会在a和b足够大或足够小时产生溢出。

    function average(int256 a, int256 b) internal pure returns (int256) {
        // 具体位运算的数学依据参见书籍《Hacker's Delight》:https://baike.baidu.com/item/Hacker%27s%20Delight/6927658?fr=ge_ala
        // x为a&b与(a^b)/2的和。为两个uint256求均值的方法。详情见:https://learnblockchain.cn/article/6191中的2.4——average(uint256, uint256)
        int256 x = (a & b) + ((a ^ b) >> 1);
        // uint256(x) >> 255:将前面计算得出的x转成uint256后右移255位得到符号位。即如果x为负数则为1,如果未非负数则为0。
        // 将上述符号位转换成int256,并与a^b的结果做与运算。返回x与上述运算结果的和(即两个有符号数的均值)
        return x + (int256(uint256(x) >> 255) & (a ^ b));
    }

foundry代码验证

contract SignedMathTest is Test {
    MockSignedMath msm = new MockSignedMath();

    function test_Average() external {
        assertEq(msm.average(2, 4), 3);
        assertEq(msm.average(2, 3), 2);
        assertEq(msm.average(type(int).max, type(int).max - 2), type(int).max - 1);
        assertEq(msm.average(type(int).min, type(int).min + 2), type(int).min + 1);
    }
}

2.3 abs(int256 n)

求一个int256的绝对值

    function abs(int256 n) internal pure returns (uint256) {
        // 关闭solidity 0.8的整数运算溢出检查。为了当n为type(int).min时不发生溢出错误
        unchecked {
            // 如果n不是负数,返回uint256(n)。否则返回uint256(-n)
            return uint256(n >= 0 ? n : -n);
        }
    }

foundry代码验证

contract SignedMathTest is Test {
    MockSignedMath msm = new MockSignedMath();

    function test_Abs() external {
        assertEq(msm.abs(0), 0);
        assertEq(msm.abs(- 1), 1);
        assertEq(msm.abs(1), 1);
        // int256的最大正数的二进制为0+255个1
        assertEq(msm.abs(type(int).max), (1 << 255) - 1);
        // int256的最小负数的二进制为其最大正数+1,即1+255个0
        assertEq(msm.abs(type(int).min), 1 << 255);
    }
}

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

在这里插入图片描述

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

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

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

相关文章

final的使用以及权限修饰符

final表示最终的、不可改变的 final跟abstract不可以同时使用&#xff0c;因为二者是冲突的。final表示不可变&#xff0c;abstrac表示必须要重写、必须要变。 常见的四种用法 修饰一个类 格式&#xff1a; public final class 类名称{ }final修饰之后&#xff0c;这个类不能…

杂谈项——关于我在bw上的见闻,以及个人对二次元游戏行业方面的前瞻

君兮_的个人主页 勤时当勉励 岁月不待人 C/C 游戏开发 Hello,米娜桑们&#xff0c;这里是君兮_&#xff0c;今天为大家带来一点不一样的&#xff0c;首先先光速叠一下甲&#xff1a; 在此说明博主并不是一个什么都知道的大佬&#xff0c;只是一个普通的老二次元以及期望以后能…

大数据-Spark批处理实用广播Broadcast构建一个全局缓存Cache

1、broadcast广播 在Spark中&#xff0c;broadcast是一种优化技术&#xff0c;它可以将一个只读变量缓存到每个节点上&#xff0c;以便在执行任务时使用。这样可以避免在每个任务中重复传输数据。 2、构建缓存 import org.apache.spark.sql.SparkSession import org.apache.s…

Xshell配置ssh免密码登录-公钥与私钥登录linux服务器

目录 简介 提示 方法步骤 步骤1&#xff1a;生成密钥公钥&#xff08;Public key&#xff09;与私钥(Private Key) 方法1&#xff1a;使用xshell工具 方法2&#xff1a;使用命令行 步骤2&#xff1a;放置公钥(Public Key)到服务器 方法1&#xff1a;&#xff08;我使用的是…

LeetCode551.Student-Attendance-Record-i<学生出勤记录 I>

题目&#xff1a; 思路&#xff1a; 遍历就完事了.连续三天不来return false; 超过两次缺勤 fasle; 代码是&#xff1a; //codeclass Solution { public:bool checkRecord(string s) {int n s.length();int abtimes0,latimes0;for(int i0;i<n;i){switch(s[i]){case(A):l…

总结942

5:40起床 6:00~7:00单词复习300个&#xff0c;记100个 7:15~8:00早读&#xff0c;《love is as strong as death》第一第二段 8:10~9:10三大计算回顾 9:15~10:06 习题880第一章基础选择纠错 10:10~10&#xff1a;30单词默写 10:30~11:40强化第一讲习题 11:40~12:30继续…

【雕爷学编程】MicroPython动手做(16)——掌控板之图片图像显示3

知识点&#xff1a;什么是掌控板&#xff1f; 掌控板是一块普及STEAM创客教育、人工智能教育、机器人编程教育的开源智能硬件。它集成ESP-32高性能双核芯片&#xff0c;支持WiFi和蓝牙双模通信&#xff0c;可作为物联网节点&#xff0c;实现物联网应用。同时掌控板上集成了OLED…

Android 设备兼容性使用详解

和你一起终身学习&#xff0c;这里是程序员Android 经典好文推荐&#xff0c;通过阅读本文&#xff0c;您将收获以下知识点: 一、设备兼容性分类二、硬件设备兼容三、软件 APP 兼容四、兼容不同语言五、兼容不同分辨率六、兼容不同屏幕方向布局七、兼容不同硬件 Feature八、兼容…

TortoiseGit安装与配置

注&#xff1a;在安装TortoiseGit之前我已经安装了git工具。 二、Git的诞生及环境配置_tortoisegit安装包_朱嘉鼎的博客-CSDN博客 1、TortoiseGit简介 TortoiseGit是基于TortoiseSVN的Git版本的Windows Shell界面。它是开源的&#xff0c;可以完全免费使用。 TortoiseGit 支持…

redis突然变慢问题定位

CPU 相关&#xff1a;使用复杂度过高命令、数据的持久化&#xff0c;都与耗费过多的 CPU 资源有关 内存相关&#xff1a;bigkey 内存的申请和释放、数据过期、数据淘汰、碎片整理、内存大页、内存写时复制都与内存息息相关 磁盘相关&#xff1a;数据持久化、AOF 刷盘策略&…

v.sqlflow.cn 上线试用

马哈鱼数据血缘工具从2023年8月开始开通国内云版本的服务&#xff0c;相比国外版本&#xff0c;访问速度有很大的提升&#xff0c;访问域名为 https://v.sqlflow.cn. 2023年8月和9月注册的用户可免费获得价值 3000 元的一年高级帐户&#xff0c;可以使用马哈鱼数据血缘工具全部…

DCGAN对抗网络用于生成动漫卡通人物(Python代码)

DCGAN全称Deep Convolutional Generative Adversarial Networks&#xff0c;中文名深度卷积对抗网络。 1.1 DCGAN的特点 DCGAN除了G网络与CNN不同之外&#xff0c;它还有以下的不同&#xff1a; 1.取消所有pooling层。G网络中使用转置卷积&#xff08;transposed convolutiona…

集合中的数据结构

栈 先进后出入口跟出口在同一侧 队列 先进先出入口跟出口在不同的一层 数组 查询快、增删慢查询快是因为数组的地址是连续的&#xff0c;我们通过数组的首地址就可以找到数组&#xff0c;之后通过数组的下标就可以访问数组的每一个元素。增删慢是因为数组的长度是固定的&…

计算机论文中名词翻译和解释笔记

看论文中一些英文的简写不知道中文啥意思&#xff0c;或者一个名词不知道啥意思。 于是自己做了一个个人总结。 持续更新 目录 SoftmaxDeep Learning(深度学习)循环神经网络(Recurrent Neural Network简称 RNN)损失函数/代价函数(Loss Function)基于手绘草图的三维模型检索(Ske…

区块链 2.0笔记

区块链 2.0 以太坊概述 相对于比特币的几点改进 缩短出块时间至10多秒ghost共识机制mining puzzle BTC:计算密集型ETH&#xff1a;memory-hard(限制ASIC) proof of work->proof of stake对智能合约的支持 BTC&#xff1a;decentralized currencyETH&#xff1a;decentral…

一篇文章搞定克拉美罗界(CRB)

起因&#xff1a; 二郎最近在研究LBL&#xff08;长基线&#xff09;定位&#xff0c;大部分论文都提到了文中算法获得的方差接近CRB&#xff0c;所以自己的算法性能较好。于是二郎就想知道克拉美罗界是什么意思&#xff0c;以及能应用的场景。 经过&#xff1a; 1&#xff…

python整理

Python 整理&#xff08;更新中&#xff09; 一、环境搭建 1- 下载python解析器 下载地址&#xff1a;https://www.python.org/ 2- 安装解析器: 3.pycharm 安装操作 1- 下载pycharm 下载地址: https://www.jetbrains.com/pycharm/ pycharm开发第一个Python程序 在这…

20.0 HTTP 通信

1. web开发 1.1 web开发介绍 Web指的是World Wide Web(万维网), 是一种基于互联网的信息系统. 万维网由一系列通过超文本链接相互连接的页面组成, 这些页面中包含了文本, 图像, 音频, 视频等多媒体内容. 用户可以通过浏览器访问万维网上的网页, 并通过超链接在不同页面之间导…

Flowable-中间事件-消息中间捕获事件

定义 消息中间事件指在流程中将一个消息事件作为独立的节点来运行。它是一种捕获事件&#xff0c;当流程 执行到消息中间事件时就会中断在这里&#xff0c;一直等待被触发&#xff0c;直接到该事件接收到相应的消息后&#xff0c;流 程沿后继路线继续执行。消息事件是一种引用…

网络编程(10) : 从connect到三次握手建立连接,再从close到四次挥手断开连接

1、TCP前置知识 1.1什么是TCP TCP 是面向连接的、可靠的、基于字节流的传输层通信协议。 面向连接&#xff1a;必须是一对一建立连接后才能通信可靠的&#xff1a;无论网络链路出现怎么样的变化&#xff0c;TCP可以保证报文一定能被对端收到字节流&#xff1a;流式协议&#…