当前位置: 首页 > 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代码示例以及它们的性能分析和比较。 比较排…...

反向工程与模型迁移:打造未来商品详情API的可持续创新体系

在电商行业蓬勃发展的当下,商品详情API作为连接电商平台与开发者、商家及用户的关键纽带,其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息(如名称、价格、库存等)的获取与展示,已难以满足市场对个性化、智能…...

使用分级同态加密防御梯度泄漏

抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...

PL0语法,分析器实现!

简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

MySQL JOIN 表过多的优化思路

当 MySQL 查询涉及大量表 JOIN 时,性能会显著下降。以下是优化思路和简易实现方法: 一、核心优化思路 减少 JOIN 数量 数据冗余:添加必要的冗余字段(如订单表直接存储用户名)合并表:将频繁关联的小表合并成…...

Python 实现 Web 静态服务器(HTTP 协议)

目录 一、在本地启动 HTTP 服务器1. Windows 下安装 node.js1)下载安装包2)配置环境变量3)安装镜像4)node.js 的常用命令 2. 安装 http-server 服务3. 使用 http-server 开启服务1)使用 http-server2)详解 …...

【学习笔记】erase 删除顺序迭代器后迭代器失效的解决方案

目录 使用 erase 返回值继续迭代使用索引进行遍历 我们知道类似 vector 的顺序迭代器被删除后,迭代器会失效,因为顺序迭代器在内存中是连续存储的,元素删除后,后续元素会前移。 但一些场景中,我们又需要在执行删除操作…...

提升移动端网页调试效率:WebDebugX 与常见工具组合实践

在日常移动端开发中,网页调试始终是一个高频但又极具挑战的环节。尤其在面对 iOS 与 Android 的混合技术栈、各种设备差异化行为时,开发者迫切需要一套高效、可靠且跨平台的调试方案。过去,我们或多或少使用过 Chrome DevTools、Remote Debug…...

第八部分:阶段项目 6:构建 React 前端应用

现在,是时候将你学到的 React 基础知识付诸实践,构建一个简单的前端应用来模拟与后端 API 的交互了。在这个阶段,你可以先使用模拟数据,或者如果你的后端 API(阶段项目 5)已经搭建好,可以直接连…...

CppCon 2015 学习:Reactive Stream Processing in Industrial IoT using DDS and Rx

“Reactive Stream Processing in Industrial IoT using DDS and Rx” 是指在工业物联网(IIoT)场景中,结合 DDS(Data Distribution Service) 和 Rx(Reactive Extensions) 技术,实现 …...

【Zephyr 系列 16】构建 BLE + LoRa 协同通信系统:网关转发与混合调度实战

🧠关键词:Zephyr、BLE、LoRa、混合通信、事件驱动、网关中继、低功耗调度 📌面向读者:希望将 BLE 和 LoRa 结合应用于资产追踪、环境监测、远程数据采集等场景的开发者 📊篇幅预计:5300+ 字 🧭 背景与需求 在许多 IoT 项目中,单一通信方式往往难以兼顾近场数据采集…...