news 2026/9/13 3:22:11

fhevm Gateway 协议暂停机制(Pausing Mechanism)实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
fhevm Gateway 协议暂停机制(Pausing Mechanism)实战指南

fhevm Gateway 协议暂停机制(Pausing Mechanism)实战指南

【免费下载链接】fhevmFHEVM, a full-stack framework for integrating Fully Homomorphic Encryption (FHE) with blockchain applications项目地址: https://gitcode.com/GitHub_Trending/fh/fhevm

导读

本指南系统讲解 fhevm Gateway 协议的暂停(Pause)与恢复(Unpause)机制:当协议出现紧急状况(如安全事件、密钥泄露、升级过渡期)时,如何通过预授权的 pauser 账户快速冻结新的输入证明(input proof)与解密(decryption)请求,同时保证已提交请求的响应链路与链上 view 查询不受影响。阅读本文后,你将掌握PauserSet/Pausable合约的权限模型、被暂停的精确函数清单、GatewayConfig聚合暂停的实现原理,以及如何用仓库内置的 Hardhat 任务与PAUSER_PRIVATE_KEY/DEPLOYER_PRIVATE_KEY环境变量完成一轮完整的暂停—恢复操作。

1. 暂停机制概览:为什么需要"紧急刹车"

fhevm Gateway 协议对外承担两类关键职责:验证用户的输入证明(Input Verification)处理链上的解密请求(Decryption)。这两条链路一旦被恶意请求冲击,可能影响整个 Gateway 服务的可用性甚至资金安全。因此,协议设计了一套只允许人工触发的紧急暂停开关(The Gateway can only be paused and unpaused manually):

  • 暂停是"单向门":只有预注册的 pauser 账户可以暂停,且暂停后所有新的request类交易都会立即 revert;
  • 暂停不阻断存量请求:已经发送并上链的请求,其响应仍然会被接受,进行中的共识(on-going consensus)可以继续达成;
  • view 函数不受影响:只读查询依旧可调用,便于暂停期间排查问题;
  • 恢复权限更高:只有GatewayConfig合约的 owner(或GatewayConfig合约自身)能够解除暂停,避免 pauser 误操作导致协议无法恢复。

该机制由两个合约配合实现(详见 PauserSet 合约文档):

合约类型职责
PauserSet不可升级(immutable)合约管理"谁可以暂停"的账户白名单
Pausable抽象合约(abstract)提供pause()/unpause()核心逻辑,被各 Gateway 合约继承

2. 可暂停的合约与暂停后的行为语义

2.1 哪些合约可被暂停

pauser 账户可以暂停以下两个 Gateway 合约:

  • Decryption(解密请求入口)
  • InputVerification(输入证明验证入口)

其他 Gateway 合约(如CiphertextCommitsGatewayConfigKMSGeneration)在技术上也继承了Pausable,但当前版本没有对外暴露任何whenNotPaused修饰的请求函数,因此pauseAllGatewayContracts不会(也无需)暂停它们——这一设计取舍在 pauseContracts.ts 的注释中有明确说明。

2.2 暂停后的行为语义

一个合约被暂停意味着:任何触发其"请求(request)"类函数的交易都会 revert。同时保证:

  • 对已发送请求的响应交易仍被接受(网关后台仍可提交解密结果/证明响应);
  • 进行中的共识流程可以正常收敛;
  • 所有 view 函数(读取类)继续可调用。

该语义直接来自 OpenZeppelin 的PausableUpgradeable状态机:paused == true时,带whenNotPaused修饰符的函数全部回滚。

3. 被暂停的确切函数清单(源码级验证)

3.1 Decryption 合约

Decryption被暂停时,以下函数会 revert(在 Decryption.sol 中均带whenNotPaused修饰符):

函数源码位置功能
publicDecryptionRequestDecryption.sol#L332公钥公开解密请求
userDecryptionRequestDecryption.sol#L466用户私钥解密请求
delegatedUserDecryptionRequestDecryption.sol#L560委托式用户解密请求(如 委托解密指南 场景)

3.2 InputVerification 合约

InputVerification被暂停时,以下函数会 revert(见 InputVerification.sol#L190):

函数源码位置功能
verifyProofRequestInputVerification.sol#L190提交输入证明的验证请求

也就是说,暂停后任何新的加密输入(ciphertext input)都无法进入协议,同时任何新的解密请求都无法发起——这正是"冻结新请求"这一设计目标的精确落点。

4. 权限模型源码剖析:谁可以暂停、谁可以恢复

4.1Pausable抽象合约:双通道鉴权

Pausable.sol 基于 OpenZeppelinPausableUpgradeable实现,并通过硬编码的GATEWAY_CONFIG地址(来自 GatewayAddresses.sol)进行跨合约鉴权:

function pause() external virtual { if (!GATEWAY_CONFIG.isPauser(msg.sender) && msg.sender != gatewayConfigAddress) { revert NotPauserOrGatewayConfig(msg.sender); } _pause(); } function unpause() external virtual { // GatewayConfig owner(deployer 或多签)或 GatewayConfig 合约本身 if (msg.sender != Ownable2StepUpgradeable(gatewayConfigAddress).owner() && msg.sender != gatewayConfigAddress) { revert NotOwnerOrGatewayConfig(msg.sender); } _unpause(); }

关键点:

  • 暂停通道(pause)msg.sender必须是GatewayConfig.isPauser(addr) == true的已注册 pauser,或者是GatewayConfig合约地址本身(用于聚合暂停);
  • 恢复通道(unpause)msg.sender必须是GatewayConfig的 owner(由Ownable2StepUpgradeable管理,见 GatewayConfig),或者是GatewayConfig合约地址本身;
  • 源码中通过将GatewayConfig强转为Ownable2StepUpgradeable读取 owner,避免循环依赖,注释中对此有专门说明。

由此可得出结论(有源码依据):pauser 永远无法自行解除暂停,恢复权始终握在 owner 手中,形成"暂停快、恢复受控"的安全设计。

4.2PauserSet不可升级合约:pauser 名单管理

PauserSet.sol 是一个部署后不可升级的合约,其地址存储在GatewayConfig合约中,提供四个管理函数(接口定义见 IPauserSet.sol):

函数说明权限与校验(源码实现)
addPauser(address)添加 pauserGatewayConfigowner 可调用;拒绝零地址、拒绝重复添加(AccountAlreadyPauser),发出AddPauser事件
removePauser(address)移除 pauser仅 owner 可调用;目标必须是现有 pauser(AccountNotPauser),发出RemovePauser事件
swapPauser(old, new)原子替换 pauser仅 owner 可调用;校验旧地址是 pauser、新地址不是,发出SwapPauser事件
isPauser(address)查询是否 pauserview 函数,GatewayConfig内部pause()鉴权时调用

pauser 账户被设计为由 fhevm Gateway 协议 operators 控制的热钱包(见 gateway_config.md 中的 operators 说明),便于在紧急时刻快速响应。owner 添加/移除 pauser 的操作可通过仓库 tasks 目录下的 addPausers.ts、removePauser.ts、swapPauser.ts 执行,相关行为由测试 PauserSet.ts 覆盖验证。

5.GatewayConfig的聚合暂停:一次暂停全部

为了让 pauser 不需要逐个合约调用,GatewayConfig合约提供了聚合入口(源码见 GatewayConfig.sol#L535-L580,接口定义见 IGatewayConfig.sol):

function pauseAllGatewayContracts() external virtual onlyPauser { bool isDecryptionPaused = DECRYPTION.paused(); bool isInputVerificationPaused = INPUT_VERIFICATION.paused(); if (isDecryptionPaused && isInputVerificationPaused) { revert AllGatewayContractsAlreadyPaused(); } if (!isDecryptionPaused) DECRYPTION.pause(); if (!isInputVerificationPaused) INPUT_VERIFICATION.pause(); emit PauseAllGatewayContracts(); } function unpauseAllGatewayContracts() external virtual onlyOwner { bool isDecryptionPaused = DECRYPTION.paused(); bool isInputVerificationPaused = INPUT_VERIFICATION.paused(); if (!isDecryptionPaused && !isInputVerificationPaused) { revert AllGatewayContractsAlreadyUnpaused(); } if (isDecryptionPaused) DECRYPTION.unpause(); if (isInputVerificationPaused) INPUT_VERIFICATION.unpause(); emit UnpauseAllGatewayContracts(); }

实现要点:

  • pauseAllGatewayContractsonlyPauser修饰符——pauser 即可一键暂停DecryptionInputVerification
  • unpauseAllGatewayContractsonlyOwner修饰符——只有 owner 才能一键恢复
  • 两个聚合函数都是幂等且带全量状态检查的:全部已暂停时再暂停会 revert(AllGatewayContractsAlreadyPaused),全部未暂停时再恢复会 revert(AllGatewayContractsAlreadyUnpaused),避免了重复交易与 Gas 浪费;
  • 由于CiphertextCommitsGatewayConfig自身暂无whenNotPaused的请求函数,KMSGeneration尚未启用,聚合暂停只作用于上述两个合约(见 pauseContracts.ts#L104-L110 注释)。

6. Hardhat 任务:一键暂停与恢复

仓库在 tasks/pauseContracts.ts 中定义了完整的 Hardhat 任务。注意:源码中注册的任务名带task:前缀(文档中的简写名去掉前缀即为实际命令名)。

6.1 暂停任务(需要PAUSER_PRIVATE_KEY

文档中的任务名实际命令(npx hardhat ...作用
pauseAllGatewayContractstask:pauseAllGatewayContracts暂停全部可暂停的 Gateway 合约
pauseInputVerificationtask:pauseInputVerification仅暂停InputVerification
pauseDecryptiontask:pauseDecryption仅暂停Decryption

这些任务读取环境变量PAUSER_PRIVATE_KEY,用对应 pauser 钱包调用合约(见 pauseContracts.ts 中pauseSingleContractcontract.pause()的调用)。

# 仅暂停 Decryption 合约 PAUSER_PRIVATE_KEY="0x..." npx hardhat task:pauseDecryption --network <network>

6.2 恢复任务(需要DEPLOYER_PRIVATE_KEY

文档中的任务名实际命令(npx hardhat ...作用
unpauseAllGatewayContractstask:unpauseAllGatewayContracts恢复全部已暂停的 Gateway 合约
unpauseInputVerificationtask:unpauseInputVerification仅恢复InputVerification
unpauseDecryptiontask:unpauseDecryption仅恢复Decryption

恢复任务读取DEPLOYER_PRIVATE_KEY,因为只有GatewayConfigowner 才能调用unpause()(见 pauseContracts.ts#L43-L52 中unpauseSingleContract)。

所有任务还支持--use-internal-proxy-address可选参数:为true时使用/addresses目录中记录的内部代理地址,否则读取对应的地址环境变量(见 getGatewayContract)。

6.3 重要限制:多签接管后恢复任务的失效

GatewayConfig的所有权由部署者(deployer)转移给多签(multi-sig)之后,基于DEPLOYER_PRIVATE_KEY的恢复任务将无法再解除暂停。此时必须通过多签钱包调用GatewayConfigunpauseAllGatewayContracts(或对具体合约unpause)来完成恢复。部署与所有权转移的完整流程可参考 本地部署指南 与 ownership.ts。

7. 环境变量配置详解

暂停/恢复任务依赖两个环境变量(完整说明见 env_variables.md,示例值来自.env.example,用于本地测试):

环境变量描述Solidity 类型默认值
PAUSER_PRIVATE_KEY任一已注册 pauser 的私钥bytes32-
DEPLOYER_PRIVATE_KEY部署者账户私钥bytes32-
# pauser 私钥:用于执行暂停任务(含 pauseAllGatewayContracts) PAUSER_PRIVATE_KEY="0x3588ffb4f4d9bea785a012b895543fe68f2d580a9d449decc91a25878064079a" # (bytes32) # 部署者私钥:用于部署合约,以及在所有权未转移时执行恢复任务 DEPLOYER_PRIVATE_KEY="0x7136d8dc72f873124f4eded25f3525a20f6cee4296564c76b44f1d582c57640f" # (bytes32)

说明:

  • 每个 operator 都应将PAUSER_PRIVATE_KEY设为其热钱包(pauser)对应的私钥,以便在紧急时快速暂停;
  • 文档中给出的示例账户是通过make get-accounts生成的、已注资的 Hardhat 测试账户;
  • 部署相关环境变量的完整集合见 部署环境变量文档。

8. 端到端操作流程示例

结合上述机制,一次完整的"紧急暂停 → 排查 → 恢复"流程如下:

  1. 确认 pauser 已注册:owner 通过addPauser(或 addPausers.ts 任务)确保紧急响应账户在PauserSet白名单内;
  2. 设置环境变量:将 pauser 私钥填入PAUSER_PRIVATE_KEY
  3. 触发暂停
    PAUSER_PRIVATE_KEY="0x..." npx hardhat task:pauseAllGatewayContracts --network <network>

    此时Decryption.publicDecryptionRequest/userDecryptionRequest/delegatedUserDecryptionRequestInputVerification.verifyProofRequest全部开始 revert,新输入与新解密请求被冻结;

  4. 存量请求继续消化:后台对已提交请求的响应交易仍可正常上链,共识正常收敛;
  5. 排查并恢复:确认风险解除后,由 owner 侧执行恢复:
    DEPLOYER_PRIVATE_KEY="0x..." npx hardhat task:unpauseAllGatewayContracts --network <network>

    (若所有权已转移至多签,则改为通过多签发起GatewayConfig.unpauseAllGatewayContracts交易);

  6. 验证状态:可调用各合约的paused()视图函数确认状态已恢复正常。

9. 常见问题与边界情况

  • 暂停后还能提交请求吗?不能,带whenNotPaused的请求函数全部 revert;但响应类交易与 view 调用不受影响。
  • 重复暂停/恢复会怎样?聚合函数会因AllGatewayContractsAlreadyPaused/AllGatewayContractsAlreadyUnpausedrevert,天然防重复。
  • pauser 能恢复吗?不能。Pausable.unpause()仅允许GatewayConfigowner 或GatewayConfig合约本身调用。
  • GatewayConfig本身会被暂停吗?当前版本它虽继承Pausable,但未暴露任何whenNotPaused请求函数,聚合暂停不涉及它。
  • 多签接管后如何恢复?放弃 Hardhat 任务,改由多签钱包直接调用GatewayConfigunpauseAllGatewayContracts函数。

10. 延伸阅读

  • PauserSet 合约文档:pauser 名单管理接口与事件
  • Pausable 抽象合约源码:暂停/恢复鉴权实现
  • GatewayConfig 聚合暂停源码:pauseAllGatewayContracts/unpauseAllGatewayContracts
  • PauserSet 合约源码 与 IPauserSet 接口
  • 暂停任务实现 与 环境变量文档
  • GatewayConfig 合约文档:operators 与所有权模型

【免费下载链接】fhevmFHEVM, a full-stack framework for integrating Fully Homomorphic Encryption (FHE) with blockchain applications项目地址: https://gitcode.com/GitHub_Trending/fh/fhevm

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/13 3:22:05

Excel动态图表实战:构建数据驱动的交互式看板

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/13 3:17:40

YOLOv8裂缝检测实战:路面桥梁墙体小目标识别与边缘部署

简介&#xff1a;本资源是一套基于YOLOv8实现的路面、桥梁及墙体裂缝智能识别完整项目&#xff0c;面向计算机、人工智能、土木工程等相关专业本科生与研究生&#xff0c;专为毕业设计、课程设计及项目实战训练打造。项目代码经导师审核并获96.5分高分答辩评价&#xff0c;功能…

作者头像 李华
网站建设 2026/9/13 3:17:31

Comsol Chatbot:面向工程仿真的垂直领域AI协作者

1. 这不是另一个“AI客服”&#xff0c;而是Comsol工程师的实时协作者你有没有过这样的经历&#xff1a;在Comsol Multiphysics里建模到一半&#xff0c;突然卡在边界条件设置上——明明物理意义清晰&#xff0c;但软件里找不到对应的操作入口&#xff1b;或者导出的S参数矩阵想…

作者头像 李华
网站建设 2026/9/13 3:17:06

10个提示词工程实战技巧,让大模型输出质量立竿见影

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/13 3:16:13

fc命令详解:把bash历史命令变成可编辑重放的命令行工作台

开始之前先纠正一个容易混淆的点 很多人第一次看到“fc”这个词&#xff0c;脑子里蹦出来的可能是光纤通道&#xff08;Fibre Channel&#xff09;、可能是某个编程语言里的函数封装&#xff0c;甚至可能是网上那些和网络地址相关的八卦信息。但如果你正在敲 Linux 或 macOS 的…

作者头像 李华