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

业务系统对接大模型的基础方案:架构设计与关键步骤

业务系统对接大模型:架构设计与关键步骤 在当今数字化转型的浪潮中,大语言模型(LLM)已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中,不仅可以优化用户体验,还能为业务决策提供…...

【网络】每天掌握一个Linux命令 - iftop

在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...

深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录

ASP.NET Core 是一个跨平台的开源框架,用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录,以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...

【WiFi帧结构】

文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...

IGP(Interior Gateway Protocol,内部网关协议)

IGP(Interior Gateway Protocol,内部网关协议) 是一种用于在一个自治系统(AS)内部传递路由信息的路由协议,主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...

1.3 VSCode安装与环境配置

进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件,然后打开终端,进入下载文件夹,键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...

ETLCloud可能遇到的问题有哪些?常见坑位解析

数据集成平台ETLCloud,主要用于支持数据的抽取(Extract)、转换(Transform)和加载(Load)过程。提供了一个简洁直观的界面,以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...

Linux云原生安全:零信任架构与机密计算

Linux云原生安全:零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言:云原生安全的范式革命 随着云原生技术的普及,安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测,到2025年,零信任架构将成为超…...

Spring AI与Spring Modulith核心技术解析

Spring AI核心架构解析 Spring AI(https://spring.io/projects/spring-ai)作为Spring生态中的AI集成框架,其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似,但特别为多语…...

IP如何挑?2025年海外专线IP如何购买?

你花了时间和预算买了IP,结果IP质量不佳,项目效率低下不说,还可能带来莫名的网络问题,是不是太闹心了?尤其是在面对海外专线IP时,到底怎么才能买到适合自己的呢?所以,挑IP绝对是个技…...