news 2026/9/13 5:51:56

fhevm 网关暂停机制环境变量完全指南:PAUSER_PRIVATE_KEY 与 DEPLOYER_PRIVATE_KEY 的配置与使用

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
fhevm 网关暂停机制环境变量完全指南:PAUSER_PRIVATE_KEY 与 DEPLOYER_PRIVATE_KEY 的配置与使用

fhevm 网关暂停机制环境变量完全指南:PAUSER_PRIVATE_KEY 与 DEPLOYER_PRIVATE_KEY 的配置与使用

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

本文是 fhevm 开源仓库中 Gateway 网关合约「暂停机制」的环境变量配置指南。文章以 gateway-contracts/docs/getting-started/pausing/env_variables.md 为骨架,结合 pauseContracts.ts、Pausable.sol、GatewayConfig.sol 及 .env.example 等仓库源码与配置,系统讲解暂停/恢复网关所需的两个核心环境变量、它们的来源、被哪些 Hardhat 任务消费,以及底层合约如何校验调用者身份。读完本文,你将能够正确配置本地与生产环境的暂停相关变量,并理解暂停权限与所有权转移之间的安全边界。

为什么暂停机制需要专门的环境变量

fhevm Gateway 协议允许「暂停者(pauser)」在紧急情况下暂停网关合约,阻止新的请求(输入证明、解密请求)被处理;网关只能被手动暂停和恢复。暂停能力由PauserSet(管理暂停者地址)与抽象合约Pausable(提供暂停/恢复功能)共同支撑,详见 暂停机制文档 与 PauserSet 合约文档。

暂停操作由 Hardhat 任务驱动(见下文),而任务执行时需要签名账户,因此仓库约定通过两个环境变量注入密钥:

环境变量说明Solidity 类型默认值备注
PAUSER_PRIVATE_KEY某个暂停者的私钥bytes32--
DEPLOYER_PRIVATE_KEY部署者的私钥bytes32--

这两个变量的取值示例均来自 .env.example,用于本地测试;其中列出的账户都是通过以下命令生成的、已注资的 Hardhat 账户:

make get-accounts

该命令定义在 Makefile 中,实际执行的是DOTENV_CONFIG_PATH=$(ENV_PATH) npx hardhat get-accounts,即以.env中的助记词批量推导账户地址与私钥。

PAUSER_PRIVATE_KEY:暂停者私钥

PAUSER_PRIVATE_KEY="0x3588ffb4f4d9bea785a012b895543fe68f2d580a9d449decc91a25878064079a" # (bytes32)

暂停者私钥是注册在PauserSet合约中的某个暂停者地址所对应的私钥。它被用于通过暂停类 Hardhat 任务暂停合约,包括pauseAllGatewayContracts。每个运营商(operator)都应将该环境变量设置为自己的热钱包(hot wallet)中用作暂停者的账户私钥。

在 .env.example 中的来源与对应关系

在 .env.example 中,暂停者相关配置如下:

# Pausers # The number of pausers must be lower or equal to the number of pausers' address defined below NUM_PAUSERS="2" # Pauser 1 PAUSER_ADDRESS_0="0x6591319B97979Acc59b7191A8B4Ec381375bFc92" # accounts[23] (address) # Pauser 2 PAUSER_ADDRESS_1="0xb19e21437c47A541842bB84b018d3955462B35De" # accounts[24] (address) # The first pauser's private key # This is required for local tests and running the pausing task. It must correspond to one of the pauser's private key PAUSER_PRIVATE_KEY="0x3588ffb4f4d9bea785a012b895543fe68f2d580a9d449decc91a25878064079a" # accounts[23], private key (bytes32)

关键对应关系:PAUSER_PRIVATE_KEY必须与PAUSER_ADDRESS_0(即accounts[23])匹配。注释明确说明它"必须对应于某个暂停者的私钥"。本地测试时,.env.example 还提供了NUM_PAUSERSPAUSER_ADDRESS_{i}等注册信息,用于把暂停者地址写入PauserSet合约。

暂停者数量与运营商的关系

按照 部署环境变量文档 的说明,NUM_PAUSERS(注册的暂停者数量)应等于协议中注册的运营商总数(KMS 节点数量 + 协处理器数量)。每个暂停者预期是协议运营商控制的热钱包,PauserSet合约提供addPauserremovePauserswapPauserisPauser四个函数来管理这些地址(见 PauserSet 合约文档)。

DEPLOYER_PRIVATE_KEY:部署者私钥

DEPLOYER_PRIVATE_KEY="0x7136d8dc72f873124f4eded25f3525a20f6cee4296564c76b44f1d582c57640f" # (bytes32)

这是部署者账户的私钥,用于部署合约(详见 部署环境变量文档)。如果GatewayConfig合约的所有权由部署者持有,则它还可用于恢复(unpause)被暂停的合约(详见 暂停机制文档)。

在 .env.example 中,DEPLOYER_PRIVATE_KEY对应accounts[1]

# Private keys DEPLOYER_PRIVATE_KEY="0x7136d8dc72f873124f4eded25f3525a20f6cee4296564c76b44f1d582c57640f" # accounts[1], private key (bytes32) NEW_OWNER_PRIVATE_KEY="0x7ae52cf0d3011ef7fecbe22d9537aeda1a9e42a0596e8def5d49970eb59e7a40" # accounts[2], private key (bytes32)

两个变量如何驱动暂停/恢复任务

暂停与恢复操作通过 pauseContracts.ts 中定义的 Hardhat 任务完成。该文件是理解这两个环境变量如何被消费的最佳源码入口。

暂停类任务

  • task:pauseAllGatewayContracts:暂停全部网关合约
  • task:pauseInputVerification:仅暂停InputVerification合约
  • task:pauseDecryption:仅暂停Decryption合约

这些任务需要本地设置PAUSER_PRIVATE_KEY环境变量。

恢复类任务

  • task:unpauseAllGatewayContracts:恢复全部网关合约
  • task:unpauseInputVerification:仅恢复InputVerification合约
  • task:unpauseDecryption:仅恢复Decryption合约

重要限制:这些恢复任务只有在GatewayConfig合约的所有权由部署者持有时才能执行,因此要求本地设置DEPLOYER_PRIVATE_KEY。一旦GatewayConfig的所有权转移到多签(multi-sig)所有者,这些任务将无法再恢复合约;届时必须通过多签合约调用GatewayConfigunpause函数来恢复。

源码层面的密钥注入逻辑

在 pauseContracts.ts 中,getGatewayContract辅助函数通过getRequiredEnvVar(envVarPrivateKeyName)读取对应的环境变量,并用它构造签名钱包:

async function getGatewayContract( name: string, ethers: HardhatEthersHelpers, useInternalAddress: boolean, envVarPrivateKeyName: string, ) { // Get the account (pauser for pausing OR deployer for unpausing) wallet const accountPrivateKey = getRequiredEnvVar(envVarPrivateKeyName); const account = new Wallet(accountPrivateKey).connect(ethers.provider); ... }

暂停单个合约时传入'PAUSER_PRIVATE_KEY',恢复单个合约时传入'DEPLOYER_PRIVATE_KEY'

async function pauseSingleContract(name: string, ethers: HardhatEthersHelpers, useInternalAddress: boolean) { const { contract, proxyAddress } = await getGatewayContract(name, ethers, useInternalAddress, 'PAUSER_PRIVATE_KEY'); await contract.pause(); console.log(`${name} contract successfully paused at address: ${proxyAddress}\n`); } async function unpauseSingleContract(name: string, ethers: HardhatEthersHelpers, useInternalAddress: boolean) { // NOTE: this task won't work once ownership will be transferred from initial deployer to the multisig const { contract, proxyAddress } = await getGatewayContract(name, ethers, useInternalAddress, 'DEPLOYER_PRIVATE_KEY'); await contract.unpause(); console.log(`${name} contract successfully unpaused at address: ${proxyAddress}\n`); }

getRequiredEnvVar定义于 loadVariables.ts,若对应环境变量缺失会直接抛错,从而保证任务不会被错误地静默执行。

批量任务task:pauseAllGatewayContracts/task:unpauseAllGatewayContracts则经由GatewayConfig合约的pauseAllGatewayContracts()/unpauseAllGatewayContracts()函数间接操作全部可暂停合约,签名账户的选择逻辑与上述一致(暂停用PAUSER_PRIVATE_KEY,恢复用DEPLOYER_PRIVATE_KEY)。

所有任务还支持一个可选参数useInternalProxyAddress,为false(默认)时从.env中的GATEWAY_CONFIG_ADDRESS等变量读取代理地址,为true时改用/addresses目录下的内部代理地址。

底层合约如何校验密钥对应的身份

环境变量只是把私钥交给任务脚本,真正的权限校验发生在链上合约中。

Pausable 抽象合约:暂停/恢复的双重准入

Pausable.sol 继承 OpenZeppelin 的PausableUpgradeable,并定义了pause()unpause()

  • pause():仅允许「注册在PauserSet中的暂停者」或GatewayConfig合约本身调用,否则 revertNotPauserOrGatewayConfig
  • unpause():仅允许「GatewayConfig的所有者」或GatewayConfig合约本身调用,否则 revertNotOwnerOrGatewayConfig

这解释了为什么暂停用PAUSER_PRIVATE_KEY、恢复用DEPLOYER_PRIVATE_KEY:两者分别对应isPauser校验与owner校验。当GatewayConfig所有权转移给多签后,DEPLOYER_PRIVATE_KEY不再等于owner,恢复任务自然失效。

GatewayConfig:批量暂停/恢复的编排与幂等保护

GatewayConfig.sol 中:

  • pauseAllGatewayContracts()onlyPauser修饰符(内部调用PAUSER_SET.isPauser(msg.sender)校验),会读取DecryptionInputVerificationpaused()状态,仅暂停当前未暂停的合约;若两者都已暂停,则 revertAllGatewayContractsAlreadyPaused
  • unpauseAllGatewayContracts()onlyOwner修饰符,仅恢复当前处于暂停状态的合约;若两者都未暂停,则 revertAllGatewayContractsAlreadyUnpaused

从源码结构看,代码注释还指出:CiphertextCommitsGatewayConfig目前技术上可暂停但尚无可暂停函数,因此pauseAllGatewayContracts()不会暂停它们;KMSGeneration合约目前未被使用,也无需暂停。

暂停后哪些函数会被阻断

当合约处于暂停状态时,触发其"请求类"函数的交易会被 revert,而已发送请求的响应仍会被接受(进行中的共识可以继续达成),其余 view 函数也仍然可调用:

  • Decryption合约(见 Decryption.sol):publicDecryptionRequestuserDecryptionRequestdelegatedUserDecryptionRequest均带whenNotPaused修饰符,暂停时被阻断。
  • InputVerification合约(见 InputVerification.sol):verifyProofRequestwhenNotPaused修饰符(该文件第 190 行附近),暂停时被阻断。

也就是说,暂停保护的是"新请求入口",而非"已在进行中的请求流程",这与 暂停机制文档 的描述完全一致。

配置与使用的完整步骤

本地测试环境

  1. 从 .env.example 复制生成.env文件;
  2. 确认PAUSER_PRIVATE_KEYPAUSER_ADDRESS_0accounts[23])对应;
  3. 确认DEPLOYER_PRIVATE_KEY对应accounts[1]
  4. 运行make get-accounts生成并查看已注资的 Hardhat 账户;
  5. 在已部署网关合约的本地网络上执行暂停/恢复任务,例如:
npx hardhat task:pauseAllGatewayContracts npx hardhat task:unpauseAllGatewayContracts npx hardhat task:pauseDecryption npx hardhat task:unpauseDecryption npx hardhat task:pauseInputVerification npx hardhat task:unpauseInputVerification

生产环境

  • 每个运营商将PAUSER_PRIVATE_KEY设置为自己的热钱包(暂停者)私钥;
  • 只要GatewayConfig仍由部署者(或由部署者私钥控制)持有所有权,DEPLOYER_PRIVATE_KEY即可用于恢复;
  • 所有权一旦移交多签,恢复必须改走多签调用GatewayConfig.unpause的治理流程,DEPLOYER_PRIVATE_KEY将不再具备恢复权限。

安全要点总结

  • 暂停者预期是运营商控制的热钱包,私钥泄露风险由运营商自行管理;
  • PAUSER_PRIVATE_KEYDEPLOYER_PRIVATE_KEY权限不对称:前者只能暂停,后者(作为所有者)既能恢复,也掌握GatewayConfig的全部管理职能;
  • 所有权移交多签是安全模型的一部分:此后即使持有部署者私钥也无法单独恢复合约,防止单点故障;
  • 两个变量的 Solidity 类型均为bytes32,与账户私钥的 32 字节格式一致,配置时必须带上0x前缀。

如需深入了解暂停的完整工作流、PauserSet的暂停者管理函数,或部署时其他环境变量的说明,可继续阅读 暂停机制文档、PauserSet 合约文档、部署环境变量文档 与 本地部署指南。

【免费下载链接】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 5:51:12

RAG技术解析:检索增强生成的核心架构与实战应用

/* 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 5:50:49

COMSOL三维多孔介质建模技术与工程应用

/* 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 5:49:42

基于CNN的动物疲劳识别系统设计与实现

1. 项目背景与核心价值动物疲劳识别是一个在畜牧养殖、动物保护、宠物健康监测等领域具有重要应用价值的技术方向。传统的人工观察方法存在效率低、主观性强、难以规模化等问题。基于深度学习的解决方案能够实现自动化、全天候的动物状态监测,为养殖场管理、野生动物…

作者头像 李华
网站建设 2026/9/13 5:48:15

信噪比提升实战:从噪声溯源到PCB物理层优化

1. 为什么“信噪比”不是参数表里的一个数字,而是芯片落地的生死线“噪声中的‘火眼金睛’:传感芯片的信噪比提升策略”——这个标题里,“火眼金睛”不是修辞,是工程现场的真实压力。我做过七款不同原理的传感器模组(光…

作者头像 李华
网站建设 2026/9/13 5:47:52

工业异常检测:AutoIAD框架与多Agent协同技术解析

1. 工业异常检测的现状与挑战在半导体、汽车制造等精密工业领域,生产线上一个微小的缺陷可能导致数百万的损失。传统的人工检测方式每小时最多处理200-300个工件,而现代高速产线的生产速度可达每分钟上百件。这种速度与精度的双重需求,催生了…

作者头像 李华