SafeProxyFactory 创建 SafeProxy 并且 SafeProxy 继承 Safe

news/2025/3/4 22:53:13/文章来源:https://www.cnblogs.com/zhanchenjin/p/18751693

SafeProxyFactory 创建 SafeProxy 并且 SafeProxy 继承 Safe 所有方法的关键在于 代理合约(Proxy Pattern),特别是 SafeProxy 充当代理,并将调用委托给 Safe。让我们解析一下核心机制:


1. SafeProxy 是如何继承 Safe 方法的?

SafeProxy 其实并没有直接继承 Safe,而是通过 代理(Proxy)模式,利用 delegatecallSafeProxy 具备 Safe 的所有方法。

SafeProxy 的核心逻辑通常在其 fallback 函数内,通过 delegatecall 把调用转发给 _singleton(也就是 Safe),让 SafeProxy 看起来像是 Safe,但实际上只是一个空壳:

contract SafeProxy {address internal singleton;constructor(address _singleton) {require(_singleton != address(0), "Invalid singleton address");singleton = _singleton;}fallback() external payable {// 将调用代理到 singleton(Safe 合约)assembly {let _singleton := sload(0) // 读取 singleton 地址calldatacopy(0, 0, calldatasize()) // 复制 calldatalet result := delegatecall(gas(), _singleton, 0, calldatasize(), 0, 0)returndatacopy(0, 0, returndatasize()) // 复制返回数据switch resultcase 0 { revert(0, returndatasize()) }default { return(0, returndatasize()) }}}
}

2. deployProxy 是如何让 SafeProxy 具备 Safe 方法的?

deployProxy 方法中,我们关注以下关键点:

(1) 通过 CREATE2 创建 SafeProxy

bytes memory deploymentData = abi.encodePacked(type(SafeProxy).creationCode, uint256(uint160(_singleton)));
assembly {proxy := create2(0x0, add(0x20, deploymentData), mload(deploymentData), salt)
}
  • type(SafeProxy).creationCode:获取 SafeProxy 的合约代码。
  • abi.encodePacked(..., uint256(uint160(_singleton))):将 SafeProxy 代码和 _singleton 地址编码到一起。
  • create2(...):使用 CREATE2 部署 SafeProxy,确保地址可预测。

关键点:这里 _singleton 传入的是 Safe 的地址,意味着 SafeProxy 内部的 singleton 变量会被初始化为 Safe 的地址。

(2) SafeProxy 代理 Safe

SafeProxy 被创建后,它的 fallback 会将所有调用 delegatecall_singleton,即 Safe。因此:

  • 从外部调用 SafeProxy,会通过 fallback 进入 delegatecall,相当于直接调用 Safe 本体。
  • delegatecallSafeProxy 继承 Safe 的所有逻辑,但存储变量仍然在 SafeProxy 内部。

3. initializer 作用

 
if (initializer.length > 0) {assembly {if eq(call(gas(), proxy, 0, add(initializer, 0x20), mload(initializer), 0, 0), 0) {revert(0, 0)}}
}
  • initializer 允许在部署后立即执行初始化,通常用于 Safesetup 方法,以设置 owners、threshold、fallback handler 等信息。
  • 这避免了代理合约刚部署时处于未初始化状态,防止攻击者利用 delegatecall 进行恶意初始化(类似 EIP-1967 的安全风险)。
    •  
    • 使用 call 执行 initializer
      • initializer 是一个 bytes 类型的 calldata,它通常是 Safesetup 方法的 ABI 编码参数。
      • call 发送交易到 proxy(SafeProxy),执行 initializer 指定的初始化逻辑。
    • 如果 call 失败,则回滚整个交易

    各参数解析

    solidity
    call(gas(), proxy, 0, add(initializer, 0x20), mload(initializer), 0, 0)

    这是一个 call 低级操作,Solidity call 语法如下:

    solidity
    success := call(gas, to, value, inOffset, inSize, outOffset, outSize)

    参数解析:

    参数 作用
    gas() 传递当前剩余 Gas 让 proxy 运行 initializer
    proxy 目标合约地址,即 SafeProxy 实例
    0 发送的 ETH 数量,这里是 0
    add(initializer, 0x20) initializer 的数据指针,跳过前 32 字节长度信息
    mload(initializer) initializer 的数据长度
    0 返回数据存储的内存位置(这里忽略)
    0 返回数据的最大长度(这里忽略)

总结

  1. SafeProxy 只是一个壳,所有方法都通过 delegatecall 代理到 Safe
  2. deployProxy 通过 CREATE2 创建 SafeProxy,并设置 Safe 作为 singleton
  3. SafeProxyfallback 函数拦截所有调用,并 delegatecallSafe,让它表现得像 Safe
  4. initializer 允许部署时执行 Safesetup,确保合约立即可用。

最终结果: 通过 SafeProxy 交互,相当于直接调用 Safe,但存储数据仍然保留在 SafeProxy 自己的存储空间内,这就是 代理模式(Proxy Pattern) 的强大之处。 🚀

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ChromaDB

ChromaDB是一个开源的嵌入式向量数据库,专为存储和查询高维向量数据而设计,特别适用于与大型语言模型(LLMs)和嵌入模型(Embeddings)相关的应用场景 安装pip install chromadb启动服务chroma run --path ./chroma_data --host 0.0.0.0 --port 8000说明: --path ./chroma_…

如何为 Power Automate 配置 Azure Key Vault 权限

前言最近,在Power Automate中使用Azure Key Vault,然后,就需要配置一下AKV的权限。正文1.我们在Azure Portal里新建一个Key vault,如下图:2.进入Access policies,点击Create,如下图:3.如果只是为Power Automate使用,只需要勾选红框的权限就好,如下图:4.搜索需要的服…

P2671 [NOIP 2015 普及组] 求和

好题,思想很好。 首先看到这个题一个显然的思路是\(O(n^3)\)的暴力,直接枚举三个判断可行性计算贡献。 思考简单的优化,题目条件限制z-y=y-x变形可得\(y=\frac{z-x}{2}\),由于\(y\)一定是正整数,所以\(z\)与\(x\)正负性相同,考虑将原数组拆分为奇数和偶数两个集合,并在两…

web开发 辅助学习管理系统开发日记 day8

今日完成员工上传头像功能,删除员工功能,以及调试阿里云oss服务器。 Q1:如何配置阿里云服务器 1.创建阿里云服务器并且搭建好配置 2.引入依赖 在oss简介首页引入 3.从官网复制粘贴出上传文件这个功能所在工具类 4.在控制层里面进行上传 Q2 批量删除员工功能 1.在controller层…

pycharm添加conda环境的解释器时找不到python.exe

pycharm添加conda环境的解释器时找不到python.exe 先找到 anaconda 安装目录下的 condabin/conda ,然后加载环境, 加载之后下面就有了conda环境,可以进行选择

md5.exe WriteUp

WriteUp 题目信息 名称:md5.exe 分类:Reverse 描述:找到程序的flag题目链接: https://pan.baidu.com/s/1u8bGbKcUF6_gLaw63L3jyA?pwd=h8r5 提取码: h8r5解题思路 首先用DIE查看该文件,发现该文件没有壳,且是32位exe文件。所以可以直接用32位IDA打开该文件,并按F5对main函…

xor.exe WriteUp

WriteUp 题目信息 名称:xor.exe 分类:Reverse 描述:找到程序的flag题目链接: https://pan.baidu.com/s/1u8bGbKcUF6_gLaw63L3jyA?pwd=h8r5 提取码: h8r5解题思路 首先用DIE查看该文件,发现该文件没有壳,且是32位exe文件。所以可以直接用32位IDA打开该文件,并按F5对main函…

原型链图

啥都不说,先上图:上面展示了各个对象之间是怎样通过显式原型(prototype)及隐式原型([[prototype]],通过__proto__访问)来串联起来的。

【C++库函数】C++生成高质量随机数的方法

#include <iostream> #include <random>int main() {// 第一步:初始化真随机种子(使用硬件熵源)std::random_device rd; // 第二步:选择高性能引擎(推荐 mt19937)std::mt19937 gen(rd()); // 用 random_device 的输出来种子初始化引擎// 第三步:定义分布(…

20250305

1 烧碱的C浪回调后 开始布局中线多单。

玄机靶场通关(持续更新)

穷,没钱开靶场,全是看网上WP尝试自学。 你这应急响应,还真是高高在上呢……玄机靶场通关 全部要VIP,所以穷鬼我要看别人的WP来学 Windows应急-应急与研判训练计划一 服务器场景操作系统 Windows 服务器账号密码 administrator P@ssw0rd 题目来源公众号 ©州弟学安全 任…

代码在线运行工具网站神器——OneCompiler,程序员必备!

今天给大家分享一款功能强大的代码在线运行工具网站——OneCompiler,它可以让你轻松实现代码的编写、运行和分享。 网址 OneCompiler目前已经被收录在【3M万能在线工具箱】的【编程开发】工具中,这里也提供大家直接的网址: OneCompiler:https://onecompiler.com/ 支持70多种…