当前位置: 首页 > news >正文

Michael.W基于Foundry精读Openzeppelin第32期——SignatureChecker.sol

Michael.W基于Foundry精读Openzeppelin第32期——SignatureChecker.sol

      • 0. 版本
        • 0.1 SignatureChecker.sol
      • 1. 目标合约
      • 2. 代码精读
        • 2.1 isValidSignatureNow(address signer, bytes32 hash, bytes memory signature)

0. 版本

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

0.1 SignatureChecker.sol

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

SignatureChecker库是一个用于链上签名验证的helper库。该库提供的验签函数既支持EOA账户地址的签名验证也支持IERC1271标准合约地址的签名验证。

IERC1271标准往往用于智能合约钱包的签名,例如Argent和Gnosis Safe。

注:关于IERC1271标准的详细解读参见:https://www.learnblockchain.cn/article/6443

1. 目标合约

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

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

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;import "openzeppelin-contracts/contracts/utils/cryptography/SignatureChecker.sol";contract MockSignatureChecker {using SignatureChecker for address;function isValidSignatureNow(address signer,bytes32 hash,bytes memory signature) external view returns (bool){return signer.isValidSignatureNow(hash, signature);}
}

全部foundry测试合约:

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

2. 代码精读

2.1 isValidSignatureNow(address signer, bytes32 hash, bytes memory signature)

凭借签名地址、签名内容以及签名本身来验证签名有效性。

需要注意的是:与ECDSA的EOA地址验签不同,基于IERC1271标准的合约地址验签结果是可以改变的。可能在区块高度N和N+1上,IERC1271的验签结果是相反的。

    function isValidSignatureNow(address signer,bytes32 hash,bytes memory signature) internal view returns (bool) {// 将输入的signer当做EOA账户地址,使用ECDSA.tryRecover()以及签名内容和签名还原出signer地址(address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);if (error == ECDSA.RecoverError.NoError && recovered == signer) {// 如果ECDSA.tryRecover返回的错误类型为ECDSA.RecoverError.NoError且还原出的signer地址与输入signer地址相同,说明signer地址确实为EOA地址,并且通过验签。返回truereturn true;}// 如果没有通过EOA地址验签,那么再假定signer为IERC1271标准的合约地址。使用IERC1271标准的isValidSignature()函数进行验签// 本库使用直接staticcall的方式来调用signer合约的isValidSignature()方法(bool success, bytes memory result) = signer.staticcall(abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature));// 如果staticcall调用成功且返回值只占32字节,同时返回值为IERC1271.isValidSignature的selector,表明通过IERC1271标准的验签——即返回true// 如果不满足以上条件,说明本次既不通过EOA地址验签也不通过IERC1271合约地址验签。可认作是无效的签名,返回falsereturn (success &&result.length == 32 &&abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));}

foundry代码验证

contract SignatureCheckerTest is Test {using ECDSA for bytes;MockSignatureChecker msc = new MockSignatureChecker();uint eoaSignerPrivateKeyInERC1271 = 1024;MockERC1271 me = new MockERC1271(vm.addr(eoaSignerPrivateKeyInERC1271));uint signerPrivateKey = 2048;address signerAddress = vm.addr(signerPrivateKey);function test_IsValidSignatureNow_AsEOAAddress() external {// case 1: return true with correct eoa signaturebytes32 digestHash = bytes("Michael.W").toEthSignedMessageHash();(uint8 v, bytes32 r, bytes32 s) = vm.sign(signerPrivateKey, digestHash);bytes memory signature = bytes.concat(r, s, bytes1(v));assertTrue(msc.isValidSignatureNow(signerAddress,digestHash,signature));// case 2: return false with incorrect eoa signaturebytes memory incorrectSignature = bytes.concat(r, s, bytes1(v + 1));assertFalse(msc.isValidSignatureNow(signerAddress,digestHash,incorrectSignature));}function test_IsValidSignatureNow_AsIERC1271Address() external {// case 1: return true with valid signature of ERC1271bytes32 digestHash = bytes("Michael.W").toEthSignedMessageHash();(uint8 v, bytes32 r, bytes32 s) = vm.sign(eoaSignerPrivateKeyInERC1271, digestHash);bytes memory signature = bytes.concat(r, s, bytes1(v));assertTrue(msc.isValidSignatureNow(address(me),digestHash,signature));// case 2: return true with invalid signature of ERC1271bytes memory incorrectSignature = bytes.concat(r, s, bytes1(v + 1));assertFalse(msc.isValidSignatureNow(address(me),digestHash,incorrectSignature));// case 3: return false when the signer contract address is not the implementor of IERC1271(v, r, s) = vm.sign(eoaSignerPrivateKeyInERC1271, digestHash);signature = bytes.concat(r, s, bytes1(v));assertFalse(msc.isValidSignatureNow(address(new NotImplementIERC1271()),digestHash,signature));}
}contract MockERC1271 is IERC1271 {using ECDSA for bytes32;address _signerEOA;constructor(address signerEOA){_signerEOA = signerEOA;}function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue){return hash.recover(signature) == _signerEOA ? IERC1271.isValidSignature.selector : bytes4(0);}
}contract NotImplementIERC1271 {}

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

在这里插入图片描述

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

相关文章:

Michael.W基于Foundry精读Openzeppelin第32期——SignatureChecker.sol

Michael.W基于Foundry精读Openzeppelin第32期——SignatureChecker.sol 0. 版本0.1 SignatureChecker.sol 1. 目标合约2. 代码精读2.1 isValidSignatureNow(address signer, bytes32 hash, bytes memory signature) 0. 版本 [openzeppelin]:v4.8.3,[for…...

如何修改字符串内容?

⭐ 作者:小胡_不糊涂 🌱 作者主页:小胡_不糊涂的个人主页 📀 收录专栏:浅谈Java 💖 持续更文,关注博主少走弯路,谢谢大家支持 💖 String 1. 修改字符串2. StringBuilder和…...

pgadmin4中的备份与恢复

一,postgresql 数据的备份与恢复 (一)数据库备份与恢复 1,备份 windows环境 1> dump 逻辑备份 1,用管理员身份打开power shell 2,切换到本机 postgresql 安装目录下的 bin 目录: PS C…...

内网穿透——搭建私人影音媒体平台

文章目录 1. 前言2. Jellyfin服务网站搭建2.1. Jellyfin下载和安装2.2. Jellyfin网页测试 3.本地网页发布3.1 cpolar的安装和注册3.2 Cpolar云端设置3.3 Cpolar本地设置 4.公网访问测试5. 结语 1. 前言 随着移动智能设备的普及,各种各样的使用需求也被开发出来&…...

使用psql操作PostgreSQL数据库

postgresql的操作和mysql差别较大。。 可以使用 psql 命令行工具或者其他的 PostgreSQL 客户端工具来查看表。如下是使用 psql 命令行工具查看表的方法: 连接到 PostgreSQL 数据库: 如果一个PostgreSQL的连接为 postgresql://用户名:密码127.0.0.1:5432/…...

什么是网络取证(Network Forensics)

企业采用新技术来检查其网络安全是否存在零日漏洞,与立即指示问题的物理层不同,黑客攻击尝试可能会被忽视并变得严重,直到对网络流量有一个整体的可见性。通过实时监控来跟踪其源和目标的流量,以查明问题或潜在问题的根源。 什么…...

农村农产品信息展示网站的设计与实现(论文+源码)_kaic

摘 要 随着软件技术的迅速发展,农产品信息展示的平台越来越多,传统的农产品显示方法将被计算机图形技术取代。这种网站技术主要把农产品的描述、农产品价格、农产品图片等内容,通过计算机网络的开发技术,在互联网上进行展示,然后通过计算机网…...

keepalived+lvs(DR)(四十六)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 目录 前言 一、作用 二、调度器配置 三、web节点配置 一、作用 使用keepalived解决lvs的单点故障 高可用集群 二、调度器配置 安装keepalived yum install -y k…...

从数据孤岛到企业xPA的演化

“数据孤岛”一直以来是企业在信息化进程中面临的比较头疼的问题,由于数据独立存在于不同部门之中,无法进行相互联动,致使数据库无法兼容,这无形中加大了跨部门合作的沟通成本。在此背景下,一种新兴的规划方法——扩展…...

视觉注意力收集

参考博文:神经网络学习小记录64——Pytorch 图像处理中注意力机制的解析与代码详解_pynq 注意力机制_Bubbliiiing的博客-CSDN博客 【计算机视觉】详解 自注意力:Non-local 模块与 Self-attention (视觉注意力机制 (一))_自注意力模块_何处闻韶的博客-CS…...

StableVideo:使用Stable Diffusion生成连续无闪烁的视频

使用Stable Diffusion生成视频一直是人们的研究目标,但是我们遇到的最大问题是视频帧和帧之间的闪烁,但是最新的论文则着力解决这个问题。 本文总结了Chai等人的论文《StableVideo: Text-driven consistency -aware Diffusion Video Editing》&#xff…...

「快学Docker」Docker容器安全性探析

「快学Docker」Docker容器安全性探析 引言容器安全性威胁Docker容器安全性目录容器镜像安全性主机与容器隔离访问控制运行时监控与防御网络安全性Docker容器安全性最佳实践 总结 引言 在当今快速发展的软件开发和部署领域,容器化技术已经成为一种不可或缺的工具。然…...

鲍威尔“放鹰”,美联储或将再加息?

KlipC报道:美联储主席鲍威尔8月25日举行的杰克逊霍尔全球央行年会上表示,尽管过去一年通胀总体持续下行,但住房和服务通胀仍处于高位,鲍威尔也表达了通胀上行风险的担忧,多次表示可能会在适当的情形进一步加息。演讲结…...

docker go安装库失败

在 Docker 容器中使用 Go 获取包时超时,可能是由于网络问题或者是由于特定的网络限制。以下是一些建议和解决方法: 更改下载源: Go 默认使用 proxy.golang.org 作为模块代理。在某些地区或网络环境中,这可能会导致超时。你可以尝试更改 Go 的…...

利用python进行键盘模拟输入

记一次利用python模拟键盘输入,由于键盘中英文切换较为麻烦,所以写了两个小程序分别进行英文字符模拟或中文字符模拟。 #用于键盘英文字符输入模拟 import pyautogui import timedef simulate_typing(text):# Give some time to switch to the desired …...

2024年java面试(二)--spring篇

文章目录 1.spring事务传播机制2.spring事务失效原因3.Bean的生命周期4.Bean作用域5.依赖注入三种方式(Ioc的三种实现方式)6.实例化bean的三种方式7.IOC容器初始化加载Bean流程 1.spring事务传播机制 声明式事务虽然优于编程式事务,但也有不…...

cyclictest stress 工具 使用

工具介绍 1. Cyclictest 准确且重复地测量线程的预期唤醒时间与它实际唤醒的时间之间的差异,以提供有关系统延迟的统计数据。 它可以测量由硬件、固件和操作系统引起的实时系统延迟 2.stress是Linux的一个压力测试工具,可以对CPU、Memory、IO、磁盘进行…...

天合翔宇荣获 HICOOL 2023 全球创业者大赛决赛二等奖

8 月 25 日晚,主题为“聚势创新 向光而行”的 HICOOL2023 全球创业者峰会开幕式,在中国国际展览中心(顺义馆)举行。北京市委书记尹力宣布开幕,市委副书记、市长殷勇致辞,市委副书记刘伟出席。 开幕式之后&…...

【LeetCode75】第三十五题 统计二叉树中好节点的数目

目录 题目: 示例: 分析: 代码: 题目: 示例: 分析: 给我们一棵二叉树,让我们统计这棵二叉树中好节点的数目。 那么什么是好节点,题目中给出定义,从根节点…...

探究排序算法:比较与非比较排序算法及性能分析

探究排序算法:比较与非比较排序算法及性能分析 排序算法是计算机科学中的基本问题,它涉及将一组元素按照特定的顺序排列。本文将深入介绍比较排序算法和非比较排序算法,包括每个算法的原理、Java代码示例以及它们的性能分析和比较。 比较排…...

超短脉冲激光自聚焦效应

前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...

stm32G473的flash模式是单bank还是双bank?

今天突然有人stm32G473的flash模式是单bank还是双bank?由于时间太久,我真忘记了。搜搜发现,还真有人和我一样。见下面的链接:https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...

Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件

今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...

基于当前项目通过npm包形式暴露公共组件

1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹,并新增内容 3.创建package文件夹...

linux 下常用变更-8

1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...

css的定位(position)详解:相对定位 绝对定位 固定定位

在 CSS 中,元素的定位通过 position 属性控制,共有 5 种定位模式:static(静态定位)、relative(相对定位)、absolute(绝对定位)、fixed(固定定位)和…...

unix/linux,sudo,其发展历程详细时间线、由来、历史背景

sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...

BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践

6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...

今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存

文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...

C# 求圆面积的程序(Program to find area of a circle)

给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...