ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

fhevm Host Contracts 实战指南:在宿主链上部署 FHEVM、DAO 升级与跨链 KMS 状态镜像

fhevm Host Contracts 实战指南:在宿主链上部署 FHEVM、DAO 升级与跨链 KMS 状态镜像 fhevm Host Contracts 实战指南在宿主链上部署 FHEVM、DAO 升级与跨链 KMS 状态镜像【免费下载链接】fhevmFHEVM, a full-stack framework for integrating Fully Homomorphic Encryption (FHE) with blockchain applications项目地址: https://gitcode.com/GitHub_Trending/fh/fhevm本篇指南围绕开源仓库 fhevm 中host-contracts这一 Node 包展开它承载了在任意宿主 EVM 区块链Host EVM Blockchain上部署一套完整 FHEVM 实例所需的全部核心 Solidity 合约。读者将掌握三件事如何初始化依赖并通过 Forge 运行合约测试如何以“仅准备不生效”的方式为FHEVMExecutor做 DAO 驱动升级以及如何理解并操作 Ethereumcanonical 链与 Polygon 等非 canonical 宿主链之间共享的ProtocolConfig状态——包括镜像方法、导出/审核/应用三步初始化流程。读完本文你可以独立完成一条非 canonical 宿主链从零初始化、以及后续 KMS 上下文/epoch 轮转的镜像操作。背景host-contracts 在 FHEVM 架构中的位置fhevm 是一个将全同态加密FHE能力与区块链应用集成的全栈框架。其中host-contracts位于仓库根目录下的 host-contracts 目录专门提供“宿主链侧”的后端合约其核心职责是管理 FHE 密文的访问控制ACL与密文输入验证InputVerifier校验 KMS 签名与节点信息KMSVerifier并在 canonical 链上执行 KMS 上下文/epoch 的生成与确认KMSGeneration记录协议级配置与 KMS 上下文状态ProtocolConfig并负责将该状态跨链同步到非 canonical 宿主链承载用户合约执行入口FHEVMExecutor与 HCU 资源限制HCULimit。与面向应用开发者的 library-solidity提供FHE.sol等用户侧库不同host-contracts 面向的是链的运营者谁要部署一条新的 FHEVM 宿主链、谁要升级链上组件、谁要管理多链 KMS 状态都需要直接与这一层打交道。快速开始安装依赖与运行测试host-contracts同时使用 HardhatTypeScript 任务与 FoundryForge 测试。从仓库根目录进入该包后npm install安装完成后如果之前未拉取 Soldeer 依赖如 OpenZeppelin 合约需要先执行npm run forge:soldeer npm run test:forge对应脚本定义在 host-contracts/package.json 中forge:soldeer执行forge soldeer installtest:forge执行forge test。包内还提供了常用的 Hardhat 辅助脚本例如npm run compile先部署空的 UUPS 代理含--with-kms-generation true路径与PauserSet再执行 hardhat compilenpm run test运行hardhat testnpm run test:gas仅运行名字匹配Gas的测试用例npm run mock:daemon/mock:query/mock:encrypt启动本地 mock coprocessor 守护进程用于本地链路联调。合约清单总览host-contracts/contracts目录contracts下按职责划分为多个子目录与顶层合约文件 / 目录职责ACL.sol、ACLEvents.sol密文访问控制列表及其事件定义管理谁能对密文执行操作FHEVMExecutor.sol用户合约执行入口负责将 FHE 操作调度到 coprocessor 网络InputVerifier.sol验证 coprocessor 签名的密文输入KMSVerifier.sol校验 KMS 签名、节点与上下文生命周期信息KMSGeneration.sol仅在 canonical 宿主链部署驱动 KMS 上下文/epoch 的生成与确认ProtocolConfig.sol协议级配置与 KMS 上下文/epoch 状态的唯一事实来源并提供跨链镜像入口HCULimit.sol宿主链 HCUHomomorphic Computation Unit用量限制bridge/跨链桥ConfidentialBridge相关合约基于 LayerZeroemptyProxy/、immutable/供首次部署与不可变参数使用的辅助代理与不可变合约interfaces/各合约的接口与事件定义如IProtocolConfig.sol本文后续聚焦 README 重点阐述的两个运维主题FHEVMExecutor 的 DAO 驱动升级与ProtocolConfig 的多链状态镜像。Prepare-only executor 升级DAO 驱动的 FHEVMExecutor 升级为什么需要“仅准备”模式FHEVMExecutor是 UUPS 可升级合约其代理proxy地址对用户合约固定不变。常规的task:upgradeFHEVMExecutor会一次性完成“导入代理 → 部署新实现 → 原地升级”。但治理驱动的升级尤其是 DAO 提案需要把“部署新实现”和“切换代理”两个动作解耦先离线准备好实现地址与reinitializeV*调用数据供多签/DAO 审核签名再由治理提案最终执行。task:prepareUpgradeFHEVMExecutor正是为此设计其行为定义见 host-contracts/tasks/upgradeContracts.ts包括将现有代理forceImport进 OpenZeppelin 的升级 manifest使升级校验基于真实部署状态通过prepareUpgradekind: uups部署新的实现合约但不触碰代理打印新实现地址、reinitializeV*函数签名与 calldata以及外层upgradeToAndCall(address,bytes)的完整 calldata可选地等待 2 分钟后对实现合约执行区块浏览器源码验证。执行前置条件地址文件必须与目标环境一致contracts/FHEVMExecutor.sol会importaddresses/FHEVMHostAddresses.sol把 ACL、KMSVerifier 等兄弟合约地址编译进实现字节码。因此运行升级任务前磁盘上的地址生成文件必须与当前正在升级的环境一致。若从零生成或切换环境应按顺序执行以下 setter 任务顺序很重要setACLAddress会重写两份文件其余任务在其基础上追加npx hardhat task:setACLAddress --address acl npx hardhat task:setFHEVMExecutorAddress --address executor-proxy npx hardhat task:setKMSVerifierAddress --address kms npx hardhat task:setInputVerifierAddress --address input-verifier npx hardhat task:setHCULimitAddress --address hcu-limit npx hardhat task:setPauserSetAddress --address pauser-set这些命令生成两份文件host-contracts/addresses/.env.hosthost-contracts/addresses/FHEVMHostAddresses.sol喂给 setter 的地址值应来自当前线上环境的真实部署。一个实用的权威来源是代理背后现有实现合约的已验证源码包verified source bundle中的addresses/FHEVMHostAddresses.sol。运行 prepare 任务npx hardhat task:prepareUpgradeFHEVMExecutor \ --network sepolia \ --current-implementation previous-contracts/FHEVMExecutor.sol:FHEVMExecutor \ --new-implementation contracts/FHEVMExecutor.sol:FHEVMExecutor \ --verify-contract true参数说明--network选择实现合约部署交易发往的链如 sepolia--current-implementation磁盘上保存的旧实现源码路径与合约名路径:合约名格式--new-implementation当前 checkout 中的新实现源码--use-internal-proxy-address true可选代理地址改为从addresses/.env.host读取而不是从环境变量读取--verify-contract默认true部署完成后等待 2 分钟并对实现执行 Etherscan 类区块浏览器验证。一个关键实现细节任务在重新编译前会先执行hardhat clean见 host-contracts/tasks/upgradeContracts.ts 中compileImplementations对compile:specific的调用及 README 的说明确保实现不是针对另一环境编译出的过期 artifact 构建的。源码中还会校验新旧实现 artifact 的contractName与预期一致且新实现必须包含reinitializeV*前缀的重初始化函数否则直接报错拒绝执行。与常规升级任务的对比任务是否修改代理用途task:upgradeFHEVMExecutor是立即生效私钥直接持有者快速升级task:prepareUpgradeFHEVMExecutor否仅打印 calldataDAO 提案先部署实现、打印upgradeToAndCall载荷供签名同模式的任务还覆盖ACL、KMSVerifier、ProtocolConfig、KMSGeneration、InputVerifier、HCULimit等全部可升级组件task:prepareUpgrade*系列其中ProtocolConfig升级时还会带上由环境变量构建的reinitializeV*参数buildProtocolConfigReinitializeArgs。另外首次部署ConfidentialBridge走task:prepareUpgradeConfidentialBridge其内部调用initializeFromEmptyProxy并校验LZ_ENDPOINT_ADDRESS与--dst-eids/--dst-chain-ids配对。事件消费者注意KMSVerifier 生命周期事件已迁移迁移到 canonical 的ProtocolConfig状态之后KMSVerifier不再发射上下文生命周期事件。链下消费者如 relayer、listener、KMS-connector应改从ProtocolConfig合约订阅事件地址见host-contracts/addresses/FHEVMHostAddresses.sol中的protocolConfigAdd条目旧KMSVerifier.NewContextSet(uint256,address[],uint256)新ProtocolConfig.NewKmsContext(uint256,uint256,KmsNodeParams[],KmsThresholds,string,PcrValues[])旧KMSVerifier.KMSContextDestroyed(uint256)新ProtocolConfig.KmsContextDestroyed(uint256)新事件签名与 host-contracts/contracts/interfaces/IProtocolConfig.sol 中定义一致额外携带 epochId、节点参数、阈值、软件版本与 PCR 值信息量比旧事件更完整。宿主部署角色canonical 与非 canonicaltask:deployAllHostContracts强制要求显式传入--with-kms-generation取值以明确本次部署的宿主链角色npx hardhat task:deployAllHostContracts --with-kms-generation true # canonical 宿主链 npx hardhat task:deployAllHostContracts --with-kms-generation false # 非 canonical 宿主链同一份合约多条链canonical 是唯一事实来源Ethereum 是 canonical 宿主链——KMS 上下文/epoch 状态的唯一事实来源完整的生命周期只在其上运行治理方开启一个上下文/epochdefineNewKmsContextAndEpoch/defineNewEpochForCurrentKmsContextKMS 签名者达成法定人数confirmKmsContextCreation/confirmEpochActivation后状态才激活。KMSGeneration只部署在 Ethereum 上。其他每条宿主链上部署的是同一份ProtocolConfig合约不存在单独的多链合约但这些非 canonical 宿主链如 Polygon是只读副本read-replica它们不运行生命周期/法定人数路径因为 KMS 重分片与远程证明只在 Ethereum 上发生一次。它们没有KMSGeneration唯一的写入路径就是下文介绍的镜像方法。镜像方法非 canonical 链的写入路径mirrorKmsContextAndEpoch与mirrorKmsEpoch是副本replica追踪 Ethereum 状态的方式。两者都是onlyACLOwner且绕过确认法定人数——副本无法重跑 MPC 远程证明因此信任运营者导入 Ethereum 已最终确定的状态并使其立即变为Active。合约侧实现host-contracts/contracts/ProtocolConfig.solmirrorKmsContextAndEpoch(contextId, epochId, kmsNodeParams, thresholds, softwareVersion, pcrValues)——导入一个上下文及其首个 epoch 为 active 状态发射MirrorKmsContextAndEpoch事件。内部先校验contextId latestActiveKmsContextId否则 revertNonIncreasingKmsContextId、epochId epochCounter否则 revertNonIncreasingEpochId再_storeAndActivateKmsContextAndEpoch落库。mirrorKmsEpoch(contextId, epochId)——推进已镜像上下文的 active epoch发射MirrorKmsEpoch事件。要求contextId等于当前 active 上下文且该上下文仍存活epoch 同样必须严格递增。严格递增唯一的链上防回滚守卫ID 必须严格递增——这是唯一的链上守卫防止状态回滚。间隔gap是允许的在 Ethereum 上被中止或从未激活的上下文/epoch 只是永远不会被镜像而已。但没有任何机制阻止副本漂移如果一次镜像调用被跳过或乱序应用副本状态就会落后。按序将 Ethereum 的每次轮转回放到每个副本是运营者的责任。任务层定义在 host-contracts/tasks/mirrorKmsContext.ts提供了两组镜像任务均遵循“build calldataDAO 路径从不广播/ broadcastdevnet / test-suite 无 DAO 路径”的约定上下文切换task:buildMirrorKmsContextAndEpochCalldata/task:mirrorKmsContextAndEpoch同节点集 epoch 轮转task:buildMirrorKmsEpochCalldata/task:mirrorKmsEpoch这四者共享同一组 CLI 参数--canonical-rpc-urlcanonical 链 RPC、--canonical-protocol-config-address、可选的--block-number默认读取 latest finalized 区块与可选的--use-internal-proxy-address。上下文切换路径有一个额外的安全校验它从 canonical 读取 active 上下文锚getKmsContextAnchor定位NewKmsContext事件的发射区块读取该事件中的节点/软件版本/PCR 数据后用 ABI 编码重新计算contextInfoHash并与链上锚比对不一致直接抛错tasks/mirrorKmsContext.ts中readCanonicalContextSwitch的computeContextInfoHash与哈希比对。事件数据在 ETH 上不存在MPC 字段不在存储内因此节点数据只能从事件取回这个哈希交叉校验保证了事件数据与链上锚一致。广播前还会断言副本确实需要切换/推进assertReplicaNeedsContextSwitch/assertReplicaNeedsEpochMirror给出明确的错误信息而不是裸 revert。从 canonical 链初始化非 canonical 的 ProtocolConfigEthereum 的ProtocolConfig是协议状态的唯一事实来源因此新的宿主链要从它播种副本。整个流程是 artifact 驱动的——每个环境都走同样的三步。第 1 步导出 canonical KMS 上下文为可审核的 JSON artifact该步骤只需 RPC 访问可从干净的 checkout 直接运行npx hardhat task:exportCanonicalProtocolConfig \ --canonical-rpc-url https://mainnet.example \ --canonical-protocol-config-address 0x... \ --out canonical-protocol-config-snapshot.jsonartifact 持有一个export对象它是将快照展开为扁平KEYvalue映射bigint 序列化为十进制字符串。每个 key 会成为第 3 步 apply 任务读取的环境变量。其底层实现在 host-contracts/tasks/protocolConfigMirror.ts 的readCanonicalSnapshot先做 RPC 握手getNetworkgetBlock默认钉在finalized区块再做合约身份/版本前缀校验随后一次性读取 active 上下文/epoch、节点集与四个阈值。第 2 步审核所有读取都发生在同一个区块上因此审核者如 DAO 签名者可以通过重新运行带--block-number N的导出并 diff 输出逐字节复现artifact——即使之后发生了defineNewKmsContextAndEpoch轮转也不受影响。第 3 步应用将审核通过的 artifact 应用到本地的ProtocolConfig代理上。两种环境运行相同的 prepare 步骤——部署实现并构建upgradeToAndCall(initializeFromCanonical(contextId, epochId, …))载荷让副本落在 canonical 的 active 上下文/epoch 上而不是从本地新计数器开始。两者的差异仅在谁执行该载荷环境任务签名者devnet / localtask:deployProtocolConfigFromCanonicalDEPLOYER_PRIVATE_KEYtestnet / mainnettask:prepareDeployProtocolConfigFromCanonicalDAO 执行打印出的upgradeToAndCall载荷# devnet用部署者私钥直接升级 npx hardhat task:deployProtocolConfigFromCanonical # testnet/mainnet部署实现并打印 DAO 载荷不触碰代理 npx hardhat task:prepareDeployProtocolConfigFromCanonical导出 key 对照表两个 apply 任务都从环境变量读取配置不接受任何命令行 flag传入 canonical 状态——由部署平台把值注入部署容器。任务会在部署任何东西之前拒绝坏值因此配置错误的环境不会动到代理。导出 key 如下Variable类型含义CANONICAL_CHAIN_IDdecimal stringcanonical 宿主链的 chain id。CANONICAL_PROTOCOL_CONFIG_ADDRESSaddress快照读取自的 canonicalProtocolConfig地址。CANONICAL_BLOCK_NUMBERdecimal string快照钉住的区块号。CANONICAL_BLOCK_HASH32-byte hex该区块的哈希。CANONICAL_KMS_CONTEXT_IDdecimal string要镜像的 active KMS context id。CANONICAL_EPOCH_IDdecimal string要镜像的 active KMS epoch id。CANONICAL_KMS_NODESJSON arrayKMS 节点集每个节点一个 JSON 对象。CANONICAL_KMS_THRESHOLDSJSON object四个阈值每个为 decimal string。context id、epoch id、节点集与阈值会成为initializeFromCanonical的 calldata因此任务会对它们完整校验。chain id 与区块号属于溯源信息任务按十进制字符串解析。区块哈希与地址同样是溯源信息任务只检查存在性并打印。合约侧的initializeFromCanonicalhost-contracts/contracts/ProtocolConfig.sol带有onlyFromEmptyProxy与reinitializer守卫并校验canonicalContextId KMS_CONTEXT_COUNTER_BASE 1、canonicalEpochId EPOCH_COUNTER_BASE 1随后_storeAndActivateKmsContextAndEpoch一次性落库并激活。注意该函数只接收四个入参contextId、epochId、节点、阈值MPC 元数据partyId、mpcIdentity、caCert、storagePrefix不会被存储因此镜像路径用确定性占位符填充partyId从 0 编号、mpcIdentity为空串、caCert为0x、storagePrefix为空串见buildCanonicalUpgradeProposal中的注释说明——副本存储的节点集仍与 canonical 完全一致。职责边界任务只校验“环境给了什么”只有第 1 步会访问 canonical 链。任务只检查环境变量给它们的值不会证明这些值与审核过的 artifact 一致——这个绑定关系由部署平台负责。两个 apply 任务都会打印decodedArgs载荷编码的 context id、epoch id、节点集与阈值以及 chain id、区块号、区块哈希与 canonicalProtocolConfig地址。运营者需要把每个溯源值与 artifact 逐一比对由于打印的节点集带占位 MPC 字段需逐字段比对。全栈部署与后续轮转部署一整套非 canonical 宿主栈时task:deployAllHostContracts --protocol-config-source canonical会把镜像与其余宿主合约串行执行使用相同的环境变量fhevm-cli 多链栈正是如此因此 e2e 测试用与生产完全相同的方式播种非 canonical 链。后续的 canonical 轮转则分别用task:buildMirrorKmsContextAndEpochCalldata/task:mirrorKmsContextAndEpoch——上下文切换更换签名者集合task:buildMirrorKmsEpochCalldata/task:mirrorKmsEpoch——同节点集 epoch 轮转。两者都通过--canonical-rpc-url/--canonical-protocol-config-address读取 canonical 的 active KMS 上下文/epoch上下文切换对还会用恢复出的NewKmsContext事件数据与 canonical 的contextInfoHash锚交叉校验然后调用副本的mirrorKmsContextAndEpoch/mirrorKmsEpoch定义于 host-contracts/tasks/mirrorKmsContext.ts。小结一张图看懂状态流Ethereumcanonical侧治理defineNewKmsContextAndEpoch→ KMS 签名者confirmKmsContextCreation/confirmEpochActivation→ 状态ActiveNewKmsContext/KmsContextDestroyed事件由ProtocolConfig发射。非 canonical 侧mirrorKmsContextAndEpoch/mirrorKmsEpochonlyACLOwner、严格递增、跳过法定人数直接把 Ethereum 已确定的状态导入为Active发射MirrorKmsContextAndEpoch/MirrorKmsEpoch。新增宿主链则通过“导出 → 审核 → 应用”三步以initializeFromCanonical直接播种 canonical 的 active 状态。这套设计把多签共识集中到一条链上MPC 重分片与远程证明只跑一次其余宿主链只消费结果代价是副本的最终一致性完全依赖运营者按序回放每一次轮转。理解“canonical 是唯一事实来源、副本是受信任的镜像”这一心智模型是正确运维多链 FHEVM 的关键。【免费下载链接】fhevmFHEVM, a full-stack framework for integrating Fully Homomorphic Encryption (FHE) with blockchain applications项目地址: https://gitcode.com/GitHub_Trending/fh/fhevm创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表