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

oracle与MySQL数据库之间数据同步的技术要点

Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异,它们的数据同步要求既要保持数据的准确性和一致性,又要处理好性能问题。以下是一些主要的技术要点: 数据结构差异 数据类型差异&#xff…...

在Ubuntu中设置开机自动运行(sudo)指令的指南

在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...

用docker来安装部署freeswitch记录

今天刚才测试一个callcenter的项目,所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...

招商蛇口 | 执笔CID,启幕低密生活新境

作为中国城市生长的力量,招商蛇口以“美好生活承载者”为使命,深耕全球111座城市,以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子,招商蛇口始终与城市发展同频共振,以建筑诠释对土地与生活的…...

JS手写代码篇----使用Promise封装AJAX请求

15、使用Promise封装AJAX请求 promise就有reject和resolve了,就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...

scikit-learn机器学习

# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...

作为测试我们应该关注redis哪些方面

1、功能测试 数据结构操作:验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化:测试aof和aof持久化机制,确保数据在开启后正确恢复。 事务:检查事务的原子性和回滚机制。 发布订阅:确保消息正确传递。 2、性…...

Caliper 配置文件解析:fisco-bcos.json

config.yaml 文件 config.yaml 是 Caliper 的主配置文件,通常包含以下内容: test:name: fisco-bcos-test # 测试名称description: Performance test of FISCO-BCOS # 测试描述workers:type: local # 工作进程类型number: 5 # 工作进程数量monitor:type: - docker- pro…...

C语言中提供的第三方库之哈希表实现

一. 简介 前面一篇文章简单学习了C语言中第三方库(uthash库)提供对哈希表的操作,文章如下: C语言中提供的第三方库uthash常用接口-CSDN博客 本文简单学习一下第三方库 uthash库对哈希表的操作。 二. uthash库哈希表操作示例 u…...

日常一水C

多态 言简意赅:就是一个对象面对同一事件时做出的不同反应 而之前的继承中说过,当子类和父类的函数名相同时,会隐藏父类的同名函数转而调用子类的同名函数,如果要调用父类的同名函数,那么就需要对父类进行引用&#…...