fhevm-sdk CLI 实战:基于 @fhevm/sdk 与 FHETest 的 fhEVM 输入证明、解密与 ERC-7984 令牌工作流全指南
【免费下载链接】fhevmFHEVM, a full-stack framework for integrating Fully Homomorphic Encryption (FHE) with blockchain applications项目地址: https://gitcode.com/GitHub_Trending/fh/fhevm
导读
本文围绕当前仓库中sdk/cli-js-sdk子项目(代号cli-fhevm-sdk)展开,它是一套用 TypeScript/Node.js + pnpm workspace 构建的命令行工具,封装了@fhevm/sdk的 viem 工作流,面向FHETest合约提供输入证明(input proof)、公开解密(public decrypt)、用户解密(user decrypt)、委托用户解密(delegated user decrypt)以及 FHETest 初始化、检查与运算演示等能力。读完本文,你将掌握:如何安装并链接fhevm-sdk二进制、理解direct / fresh / stored / make-public四类解密子命令的语义差异、如何在多网络(testnet/devnet/mainnet/polygon)下配置 RPC 与密钥环境、如何对 ERC-7984 机密令牌执行转账与余额读取,以及如何按仓库既定的 toolkit/cli/load-test 边界进行二次开发与测试验证。
一、项目定位与 Workspace 结构
cli-fhevm-sdk是@fhevm/sdk的命令行示例与工程化封装,核心目标是把 fhEVM 的"加密输入 → 上链 → 解密"链路变成可复现、可管道化的 CLI 命令。它建立在 pnpm workspace 之上,根目录为 sdk/cli-js-sdk,包含三个包:
| 包 | 名称 | 职责 |
|---|---|---|
packages/toolkit | @cli-fhevm-sdk/toolkit | 可导入的库层:配置、加密、解密流程、FHETest 辅助函数。不依赖任何 CLI 包(commander、consola、tabtab) |
packages/cli | cli-fhevm-sdk | commander 命令装配层,产出fhevm-sdk二进制;通过workspace:*依赖 toolkit |
packages/load-test | @cli-fhevm-sdk/load-test | 私有的 relayer 负载测试应用(非可发布 SDK 库),持有负载模型、持久化 pool、原始 relayer 线协议校验、collector、报告与基线 |
从 docs/agents/ARCHITECTURE.md 可以看到更严格的边界约定:
- toolkit 的
exportsmap 直接指向 TypeScript 源码;CLI 构建(tsdown)通过deps.alwaysBundle把 toolkit 打进packages/cli/dist/,同时保持 npm 依赖外部化,因此 toolkit 的运行时依赖也必须同时声明在packages/cli/package.json(见 packages/cli/package.json,其中@fhevm/sdk固定为0.13.2)。 - CLI 消费 toolkit 时只能通过包名导入(根导出或深路径,如
@cli-fhevm-sdk/toolkit/flows/input-proof),禁止相对路径导入。 - SDK 集成只允许使用
@fhevm/sdk对外声明的入口点,不得解析其私有_esm、_cjs内部目录。 - 工具集 permit API 以秒为单位(与
@fhevm/sdk一致);面向用户的 CLI 选项可以用天(--duration-days),但必须在 CLI 边界完成换算。
二、快速开始:安装、构建与链接
官方 README(sdk/cli-js-sdk/README.md)给出的标准启动流程如下:
pnpm install cp .env.example .env pnpm run build cd packages/cli && pnpm add -g . fhevm-sdk --help要点说明:
- 项目要求Node.js >= 22(
@fhevm/sdk的硬性要求,见 docs/agents/ENGINE.md),包管理器为 pnpm(workspace 根声明packageManager: pnpm@11.9.0)。 pnpm run build用tsdown将 TypeScript 编译到packages/cli/dist/;被链接的fhevm-sdk二进制实际运行编译产物dist/index.mjs。链接或使用pnpm run cli之前必须先 build(见 docs/agents/CLI.md)。- 不全局链接时,用
pnpm --silent run cli等价替代fhevm-sdk;源码模式开发用pnpm --silent run cli:dev(无需重新构建)。 - 卸载全局链接:
pnpm remove --global cli-fhevm-sdk。 - 仓库根目录的
.env由packages/cli/src/env.ts以仓库相对路径自动加载(即使在别的目录运行 CLI 也会加载),Shell 环境变量优先于.env,显式的凭据 flag 又优先于环境变量。
安装完成后的推荐冒烟测试命令:
fhevm-sdk fhe-test info fhevm-sdk input-proof --type uint64 --value 42 fhevm-sdk fhe-test init --type uint32 fhevm-sdk public-decrypt fresh --type uint8 fhevm-sdk user-decrypt fresh --type uint16全局选项(如-n devnet、--rpc-url、--relayer-url)既可以放在子命令前也可以放在子命令后,在 command action 上下文中通过optsWithGlobals()读取。
三、命令地图:CLI 能做什么
完整命令能力见下表(来源:README.md 的 Command Map,并结合 docs/agents/CLI.md 的行为约束):
| 命令 | 作用 | 是否需要钱包 |
|---|---|---|
input-proof | 加密明文并请求已验证的输入证明,不写 FHETest | 否 |
public-decrypt direct | 公开解密任意合约的现有--handle(--contract指定 ACL 配对合约,默认 FHETest) | 仅当配对合约需要 caller 时 |
public-decrypt fresh | 加密值 → 以makePublic=true存入 FHETest → 公开解密 | 是 |
public-decrypt stored | 解密显式--account/--type槽位或钱包默认槽位中的 FHETest handle | 仅使用钱包默认时 |
public-decrypt make-public | 把调用者已存储的 FHETest handle 标记为公开,再公开解密 | 是 |
user-decrypt direct | 用户解密任意合约的现有 handle(--contract默认 FHETest) | 是 |
user-decrypt fresh | 加密值 → 以makePublic=false存入 FHETest → 作为 owner 解密 | 是 |
user-decrypt stored | 解密调用者在各--type槽位存储的 handle | 是 |
delegated-user-decrypt direct | 委托方解密任意合约的现有 handle | 委托方;仅创建 ACL 权限时需要被委托人 |
delegated-user-decrypt fresh | 被委托人创建私有 handle,委托方获得 ACL 权限后解密 | 委托方 + 被委托人 |
delegated-user-decrypt stored | 委托方解密被委托人存储的--type槽位 handle | 委托方;仅创建 ACL 权限时需要被委托人 |
verify-user-decrypt | 用保存的校验 artifact 解密并比对 relayer 的 user-decrypt GET 响应,URL 从 artifact 推导 | 否(需要 RPC) |
fhe-test info | 展示解析后的网络、宿主链、relayer 与 FHETest 元数据 | 否 |
fhe-test inspect | 读取原始 handle、显式 account/type 槽位或钱包默认槽位的 FHETest 状态 | 仅使用钱包默认时 |
fhe-test init | 为一个、多个或全部受支持类型创建公开 FHETest handle | 是 |
fhe-test op <operation> | 对调用者已存储的 handle 执行 FHETest 运算演示 | 是 |
token transfer | 加密金额并执行 ERC-7984 机密转账;--from走confidentialTransferFrom;--verify前后解密发送方余额确认 | 是 |
token balance | 读取钱包或显式 account 的机密 ERC-7984 余额 handle | 仅使用钱包默认时 |
completion install / uninstall | 安装/卸载 Shell 补全 | 否 |
用--help可查看任意命令的精确选项,例如:
fhevm-sdk public-decrypt stored --help fhevm-sdk delegated-user-decrypt fresh --help fhevm-sdk fhe-test op --help从源码看,命令注册位于 packages/cli/src/cli/commands(fhe-test.ts、input-proof.ts、public-decrypt.ts、user-decrypt.ts、delegated-user-decrypt.ts、token.ts、verify-user-decrypt.ts、completion.ts),与上表一一对应。
四、加密输入与输入证明(input-proof)
input-proof只与 SDK/relayer 通信,不会写任何交易。它把明文值加密为 fhEVM 可上链的密文,并请求经过验证的输入证明,供后续合约调用使用:
fhevm-sdk input-proof fhevm-sdk input-proof --type uint32 fhevm-sdk input-proof --type uint64 --value 42 --user 0x0000000000000000000000000000000000000002底层实现位于 packages/toolkit/src/flows/input-proof.ts,其流程编排层与@fhevm/sdk的适配层(packages/toolkit/src/fhevm)分离。输出结果类型定义在 packages/toolkit/src/types.ts:
export type InputProofResult = Readonly<{ contractAddress: Hex; userAddress: Hex; values: readonly EncryptValue[]; encryptedValues: readonly Hex[]; inputProof: Hex; }>;受支持的 FHETest 值类型(FHE_VALUE_TYPES)为:bool、uint8、uint16、uint32、uint64、uint128、uint256、address。同一文件中的FHE_TYPE_IDS给出了与 handle 末字节对应的类型标识(bool: 0, uint8: 2, uint16: 3, uint32: 4, uint64: 5, uint128: 6, address: 7, uint256: 8),解析器与补全选项均由该列表派生。
五、解密工作流:direct / fresh / stored / make-public 四类子命令
解密家族(public-decrypt、user-decrypt、delegated-user-decrypt)在 docs/agents/CLI.md 中被明确定义为纯分发器:家族根命令自身没有任何选项,不带子命令直接运行会打印帮助。每个家族包含三类子命令:
direct:直接解密任意合约的现有 handle。接受可重复的--handle,全部 handle 在一次 SDK 解密请求中发出。--contract是与 handle 配对的 ACL 合约,默认 FHETest;一次命令中的所有 handle 必须属于同一个配对合约,因此解密 token handle 时必须显式传--contract。fresh:先创建(存储)一个新的 FHETest handle 再解密,是刻意设计的单值流程。stored:读取指定 account/type 槽位中已有的 FHETest handle(默认bool槽位),接受可重复的--type,同样在一次请求中解密。
三个家族唯一的语义差异在fresh的存储方式上:
- 公开解密
fresh以makePublic=true存储; - 用户解密与委托用户解密
fresh以makePublic=false存储。
5.1 公开解密(public-decrypt)
# fresh:新建公开 handle 并立即解密 fhevm-sdk public-decrypt fresh --type uint8 fhevm-sdk public-decrypt fresh --type uint64 --value 42 # direct:解密已有公开 handle fhevm-sdk public-decrypt direct --handle 0x... --handle 0x... fhevm-sdk public-decrypt direct --handle 0x... --contract 0x<token or other contract> # stored:读取 FHETest 槽位 fhevm-sdk public-decrypt stored --type uint8 fhevm-sdk public-decrypt stored --account 0x... --type uint8 fhevm-sdk public-decrypt stored --type uint16 --type uint32 # make-public:把已存储 handle 标记为公开并解密 fhevm-sdk public-decrypt make-public --type uint64公开解密的结果包含可交给链上签名验证的证明材料,对应 types.ts 中的PublicDecryptResult:
export type PublicDecryptResult = Readonly<{ encryptedValues: readonly Hex[]; clearValues: readonly Readonly<{ type: string; value: string }>[]; abiEncodedCleartexts: Hex; decryptionProof: Hex; }>;5.2 用户解密(user-decrypt)
# fresh:新建私有 handle 并以 owner 身份解密 fhevm-sdk user-decrypt fresh --type uint8 fhevm-sdk user-decrypt fresh --type uint64 --value 42 --duration-days 7 fhevm-sdk user-decrypt fresh --type uint64 --value 42 --artifact ./artifacts/user-decrypt.json # direct:解密钱包拥有的已有私有 handle fhevm-sdk user-decrypt direct --handle 0x... --handle 0x... fhevm-sdk user-decrypt direct --handle 0x... --contract 0x<token or other contract> # stored:解密各类型槽位 fhevm-sdk user-decrypt stored --type uint8 fhevm-sdk user-decrypt stored --type uint16 --type uint32--duration-days是面向用户的便捷选项,CLI 会在调用 toolkit 前换算成秒;permit 摘要会报告 SDK 的version与durationSeconds。--artifact <path>会写出包含该解密请求传输私钥的敏感校验 artifact,仅用于排查重复的 relayer 响应,必须像密钥材料一样妥善保管。artifact 使用 schemaVersion 2,避免把@fhevm/sdk0.13.2 的协议版本化 permit 与旧请求材料混淆。
5.3 委托用户解密(delegated-user-decrypt)
委托解密的角色模型是:被委托人(delegator)拥有加密数据,委托方(delegate)签署解密 permit。凭据约定如下(docs/agents/CLI.md 与 README 均明确):
- 委托方凭据:
--private-key/--mnemonic或PRIVATE_KEY/MNEMONIC; - 被委托人凭据:
--delegator-private-key/--delegator-mnemonic或DELEGATOR_PRIVATE_KEY/DELEGATOR_MNEMONIC; --delegator <address>用于在不需要凭据或凭据另行提供时标识加密数据所有者。
# fresh:被委托人创建数据 → 必要时创建 ACL 委托 → 委托方解密 fhevm-sdk delegated-user-decrypt fresh --type uint8 fhevm-sdk delegated-user-decrypt fresh --type uint64 --value 42 --duration-days 7 --delegation-duration-days 30 fhevm-sdk delegated-user-decrypt fresh --type uint64 --artifact ./artifacts/delegated-user-decrypt.json # direct:解密原始 handle fhevm-sdk delegated-user-decrypt direct --delegator 0x... --handle 0x... --handle 0x... # stored:读取被委托人的 FHETest 槽位 fhevm-sdk delegated-user-decrypt stored --delegator 0x... --type uint8 fhevm-sdk delegated-user-decrypt stored --delegator 0x... --type uint16 --type uint32如果链上已存在有效的 ACL 委托,delegated-user-decrypt(根或stored)只需委托方凭据加--delegator;否则需要被委托人凭据,让 CLI 代为创建 ACL 委托。ACL 委托的底层读写位于 packages/toolkit/src/acl(abi.ts、delegation.ts)。
5.4 结果与 permit 摘要
用户解密/委托用户解密的统一结果类型(types.ts)包含permit摘要与可选的validationArtifact:
export type DecryptionPermitSummary = Readonly<{ version: 1 | 2; isDelegated: boolean; signerAddress: Hex; encryptedDataOwnerAddress: Hex; transportPublicKey: string; signature: Hex; contractAddresses: readonly string[]; startTimestamp: number; durationSeconds: number; // 以 SDK 规范秒为单位的签名 permit 生命周期 }>;permit 摘要有意省略传输私钥,避免敏感材料进入 stdout。
六、relayer 结果校验(verify-user-decrypt)
verify-user-decrypt把解密校验从"发起请求时"延后到"任意时刻":使用user-decrypt或delegated-user-decrypt保存的校验 artifact,对一个终态的 relayer GET 响应做密码学验证:
fhevm-sdk verify-user-decrypt --artifact ./artifacts/user-decrypt.jsonURL 推导规则(docs/agents/CLI.md 与 README 一致):
- relayer 基础 URL 来自 artifact 的
network; - 路径段来自其
flow(v2/user-decrypt或v2/delegated-user-decrypt); - job id 来自其
relayer.jobId; - 可用全局
--relayer-url覆盖基础 URL、--job-id <id>覆盖 job、--url <full-url>直接指定完整 URL; - 当设置
ZAMA_FHEVM_API_KEY时,作为x-api-keyGET 头发送(devnet 无密钥,mainnet 必须)。
验证器的工作内容:拉取 GET URL → 恢复传输密钥对 → 校验保存的 permit → 解密 KMS 签名封装的 shares → 在 artifact 含期望明文时比对明文。需要强调的是,结果的provenance字段区分了密码学验证与artifact 断言:KMS shares、请求 handle、传输密钥、permit 签名是密码学校验的;期望明文是本地 artifact 提供的调试值,并非独立认证的真值。协议 v2 委托 permit 中保存的 owner/委托标签同样属于 artifact 断言(序列化 permit 不保留历史 ACL 状态)。验证器会拒绝与可推导的签名 permit 材料相矛盾的 artifact 字段,并通过responseIdentity显式报告无法绑定的身份维度(unbound)。
实现上,保存响应的重建使用了针对@fhevm/sdk@0.13.2私有品牌对象的精确版本兼容接缝,仅在仓库未打包的 Node ESM 执行模型下受支持;打包或混用 CJS/ESM SDK 实例可能导致品牌检查失败。相关测试见 packages/cli/test/verify-user-decrypt.test.ts、verify-user-decrypt-artifact.test.ts与verify-user-decrypt-url.test.ts。
七、FHETest 工具:info / init / inspect / op
7.1 查看网络与合约信息
fhevm-sdk fhe-test info输出解析后的网络、宿主链、relayer 与 FHETest 合约元数据,是排查环境配置最快的命令。
7.2 初始化存储 handle
fhevm-sdk fhe-test init --type uint64 fhevm-sdk fhe-test init --type uint64 --type uint128 fhevm-sdk fhe-test init --bulk fhevm-sdk fhe-test init --type uint256 --forceinit --bulk调用合约级 all-types 初始化器,与--type互斥;--type可重复,用于非 bulk 模式下选择性地初始化指定类型;- init 的 JSON 输出包含
transactionHashes数组,因为非 bulk 初始化可能每个类型发送一笔交易; --force用于强制覆盖已存在的 handle。
7.3 检查 handle 状态
fhevm-sdk fhe-test inspect --type uint64 fhevm-sdk fhe-test inspect --account 0x... --type uint64 fhevm-sdk fhe-test inspect --handle 0x...fhe-test inspect是只读命令;原始--handle检查与 account/type 检查互斥;inspect --type <type>在未提供--account时,默认使用PRIVATE_KEY/MNEMONIC加载的钱包地址;FheTestHandle中的clearText是 FHETest 为 handle 保留的可检查明文镜像(如果存在),不是relayer 解密结果。
7.4 运算演示(op)
fhevm-sdk fhe-test op add-uint64 --value 42 fhevm-sdk fhe-test op xor-bool --value true --public fhevm-sdk fhe-test op eq-address --value 0x0000000000000000000000000000000000000001fhe-test op以显式子命令暴露 FHETest 运算演示,而非通用--type参数;运算名与底层行为对齐(docs/agents/CLI.md)。受支持运算定义在 packages/toolkit/src/types.ts 的FHE_TEST_OPERATIONS与FHE_TEST_OPERATION_CONFIG中,共 8 个:xor-bool、add-uint8、add-uint16、add-uint32、add-uint64、add-uint128、xor-uint256、eq-address,分别映射到 FHETest 合约的xorEbool、addEuint8、addEuint16、addEuint32、addEuint64、addEuint128、xorEuint256、eqEaddress(合约 ABI 见 packages/toolkit/src/fhe-test/abi.ts)。
八、ERC-7984 机密令牌工具:transfer 与 balance
token transfer与token balance的目标是ERC-7984 机密令牌而非 FHETest,且不存在按网络的默认令牌地址,因此每次调用都必须显式传--contract。
# 转账:金额为基础单位(0 < amount < 2^64),客户端加密为 euint64 并附带输入证明 fhevm-sdk token transfer --contract 0x... --to 0x... --amount 1000 # --from:通过 confidentialTransferFrom 花费已有 operator 授权额度 fhevm-sdk token transfer --contract 0x... --from 0x... --to 0x... --amount 1000 # --verify:前后解密发送方余额并报告 deltaMatches fhevm-sdk token transfer --contract 0x... --to 0x... --amount 1000 --verify几个关键行为(docs/agents/CLI.md 逐条明确):
ERC-7984 余额不足不会 revert,因此
transfer返回transferredHandle(实际移动的加密金额)。令牌 ACL 允许接收方(以及令牌授权账户)解密该 handle,而非发送方,所以接收方应这样解密:fhevm-sdk user-decrypt direct --handle <transferredHandle> --contract 0x<token address>这里
--contract必须指向令牌合约,因为默认配对是 FHETest,对令牌 handle 是错误的。--verify通过解密发送方转账前后的余额来确认结果,输出balanceBefore、balanceAfter以及布尔值deltaMatches(判断balanceBefore - balanceAfter === <请求金额>)。它增加两轮 user-decrypt。由于 ACL 下只有发送方本人能解密自己的余额,--verify与--from互斥(operator 钱包无法解密--from账户的余额)。
余额读取与管道化解密:
fhevm-sdk token balance --contract 0x... fhevm-sdk token balance --contract 0x... --account 0x... TOKEN=0x<token address> fhevm-sdk user-decrypt direct --contract "$TOKEN" --handle "$(fhevm-sdk token balance --contract "$TOKEN" | jq -r .balanceHandle)"token balance --account缺省时默认使用PRIVATE_KEY/MNEMONIC加载的钱包地址。令牌相关实现位于 packages/toolkit/src/token(ABI、reads、writes)与 packages/toolkit/src/flows/token(balance、transfer)。
九、网络、全局选项与环境变量
9.1 网络预设
-n, --network支持六个预设(README 给出的地址为当前仓库记录值):
| 网络 | FHETest 地址 | 宿主链 / relayer 说明 |
|---|---|---|
testnet(默认) | 0x94B9d3aF050687D1F76251aD7D09a1F216a19845 | Ethereum Sepolia |
testnet-amoy | 0xa66bCEd74D1Df0736d0eb8E52371b1b1AAA1F0F0 | Polygon Amoy + testnet relayer 配置 |
devnet | 0xf56a7990E63a63eC75aD9Aa07De8cB6bF7baa805 | Ethereum Sepolia + devnet relayer 配置 |
devnet-amoy | 0x7553CB9124f974Ee475E5cE45482F90d5B6076BC | Polygon Amoy + devnet relayer 配置 |
mainnet | 0xba4d707745689eD409d4Afac8722224f5FD78C63 | Ethereum Mainnet + mainnet relayer 配置 |
polygon | 0xFb10eda9e9b4f3f7dd928B6F32fBB94E2a20451d | Polygon PoS + mainnet relayer 配置 |
需要特别留意 docs/agents/CLI.md 的提醒:不同网络可能指向不同的宿主链,不要假设每个网络都是 Ethereum Sepolia。自定义 FHEVM 链必须包含 SDK 解析协议与兼容 WASM 版本所需的宿主链protocolConfig合约(见 ARCHITECTURE.md)。网络注册与解析代码在 packages/toolkit/src/config(networks.ts、resolve.ts、runtime.ts),网络名与默认值定义在 packages/toolkit/src/types.ts。
9.2 全局选项
| 选项 | 含义 |
|---|---|
--rpc-url <url> | 宿主链 RPC 覆盖;否则依次使用对应环境变量、公共兜底 |
--relayer-url <url> | relayer 基础 URL 覆盖;localhost:3000会被规范化为http://localhost:3000 |
--contract <address> | FHETest 合约覆盖(命令级选项,非全局选项) |
9.3 环境变量
| 变量 | 用途 |
|---|---|
MAINNET_RPC_URL | mainnet的 RPC |
POLYGON_RPC_URL | polygon的 RPC |
SEPOLIA_RPC_URL | testnet与devnet的 RPC |
POLYGON_AMOY_RPC_URL | testnet-amoy与devnet-amoy的 RPC |
ZAMA_FHEVM_API_KEY | 目标环境要求 API key 时的可选 SDK relayer 鉴权 |
PRIVATE_KEY | 默认钱包私钥;交易命令、用户解密、委托解密中的委托方凭据 |
MNEMONIC | 未设置PRIVATE_KEY时的默认钱包助记词 |
DELEGATOR_PRIVATE_KEY | 委托解密流程中加密数据所有者(被委托人)私钥 |
DELEGATOR_MNEMONIC | 未设置DELEGATOR_PRIVATE_KEY时的被委托人助记词 |
十、Shell 补全
fhevm-sdk completion install fhevm-sdk completion install --shell zsh fhevm-sdk completion uninstall支持bash、zsh、fish、pwsh,安装后需重启 Shell 或 source 配置文件。补全通过一个轻量静态解析器(packages/cli/bin/completion-server.mjs)实现——按 Tab 不会加载 SDK、连接网络或执行命令流程。架构上要求该解析器保持轻量,不得导入 TypeScript 运行时、SDK 客户端、配置或流程模块,且补全元数据必须与命令 help 保持同步。completion-server由 tabtab 的 Shell 模板调用,二进制将其路由到completion-server.mjs后再加载tsx或运行时流程模块,因此其 stdout 必须只输出补全项。
十一、架构边界与二次开发规范
从 docs/agents/ARCHITECTURE.md 可以看到三层明确边界:
toolkit 层(
packages/toolkit/src)按职责划分目录:flows:仅做编排,组合 config、SDK、合约、ACL、交易与值辅助函数;命令家族放入子目录(fhe-test、public-decrypt、user-decrypt、delegated-user-decrypt、token、relayer-result);fhevm:@fhevm/sdk适配与 SDK 响应归一化;fhe-test/token/acl:对应合约 ABI 与读写;config:网络注册表、运行时配置、账户加载与客户端上下文;values:明文解析、随机值、JSON 序列化;shared:跨切面辅助(进度、交易等待);types.ts与index.ts:公共类型与公共 API barrel,新公共函数必须从这里导出。
CLI 层(
packages/cli):src/cli只做命令注册、参数解析与 stdout/stderr 行为;bin/completion-server.mjs保持静态。新增命令遵循固定顺序:① CLI 模块放入packages/cli/src/cli/commands,② 流程模块放入对应的packages/toolkit/src/flows/<family>,③ 仅在跨越边界时才新增适配层。load-test 层(
packages/load-test/src):scenario/suite负责校验负载数据与流程分配;runner/flows负责调度器生命周期与每 relayer 流程一个 executor;relayer是受限的、运行时校验的原始 HTTP 协议适配器(禁止通过 TypeScript 断言信任线数据);pool负责持久化 pool 模式与链上/链下准备;collectors/report使用严格版本化报告模式,基线只能由显式的baseline bless命令在所有suite 报告通过后写入——缺失基线可以跳过比较,但损坏或不兼容的基线必须失败。
命令行层的关键开发约束(docs/agents/CLI.md):
- 进度与状态日志走stderr,最终机器可读结果走stdout 且为 JSON(命令可管道化);
- CLI 命令模块禁止顶层流程导入,运行时流程模块必须在
.action()内动态导入,以保持 help 与补全启动快速; - 修改命令行为、选项、输出、默认值或支持的流程时,必须同步更新 README 示例与本指南。
十二、开发与测试
项目统一用 pnpm 脚本驱动(docs/agents/TESTING.md 与 docs/agents/ENGINE.md):
pnpm run typecheck # tsc --noEmit pnpm run test # 各包 vitest run pnpm run build # tsdown 构建 CLI 产物CLI 改动后应补跑 help/解析相关检查:
pnpm --silent run cli --help pnpm --silent run cli user-decrypt --help pnpm --silent run cli delegated-user-decrypt --helpload-test 改动后验证其完整私有包并检查受影响命令组:
pnpm --filter @cli-fhevm-sdk/load-test run typecheck pnpm --filter @cli-fhevm-sdk/load-test run test pnpm load-test --help pnpm load-test pool --help pnpm load-test report --help pnpm load-test baseline --help除非用户要求或已有凭据/RPC 可用,避免网络相关检查。单元测试必须覆盖单位换算与 SDK 适配器请求形状,尤其是断言 permit 时长以durationSeconds传给@fhevm/sdk——仅靠类型检查无法发现语义性的单位回归(这正是 CLI 在边界把--duration-days换算为秒的原因)。现有测试见 packages/cli/test(parsers.test.ts、user-decrypt.test.ts、verify-user-decrypt*.test.ts)。
工具链约定:依赖安装用pnpm install;包脚本用pnpm run <script>;本地二进制用pnpm exec <binary>;一次性执行用pnpm dlx <package> <command>;开发期用tsx运行 TS 入口;构建产物用tsdown;类型检查用tsc --noEmit。项目面向 Node.js 22+,优先使用 Node 内置 API 处理文件系统、路径、URL 与进程行为。
十三、尚未暴露的 FHETest 能力
当前 CLI 聚焦 SDK 演示流程(输入证明、公开/用户/委托解密、FHETest 初始化、检查与精选运算演示),README 明确列出FHETest.sol中暂未做成一级 CLI 命令的能力:
| FHETest 能力 | 可能的 CLI 扩展方向 |
|---|---|
verify(handles, cleartexts, decryptionProof) | 链上验证公开解密证明材料 |
createPublicHandle(inputHandle, inputProof) | 验证外部创建的加密输入,并无需按 account/type 存储即可公开可解密 |
类型化 getter(getEuint64()、getEuint64Of(account)) | 直接读取类型化加密 handle,替代通用 account/type 检查 |
getHandle(type) | 不传 account 读取调用者原始 handle |
这些能力提示了该 CLI 未来的扩展空间,也说明当前版本对 FHETest 合约能力的覆盖是"聚焦 SDK 演示"而非"穷尽全部 ABI"。
结语
cli-fhevm-sdk把@fhevm/sdk最常用的 fhEVM 工作流沉淀为可脚本化、可管道化的命令行界面:一条input-proof即可完成加密与证明,public-decrypt/user-decrypt/delegated-user-decrypt三个家族以direct(任意合约 handle)、fresh(新值全流程)、stored(FHETest 槽位)覆盖了解密的所有使用形态,verify-user-decrypt则提供了事后重放的密码学校验手段。配合三层 workspace 架构(toolkit/cli/load-test)与严格的 stdout-JSON 约定,它既是一个开箱即用的 fhEVM 演示与调试工具,也是一份"如何工程化封装@fhevm/sdk"的参考实现。深入阅读 README.md 与 docs/agents 下的 CLI、ARCHITECTURE、TESTING、ENGINE 四份指南,可进一步掌握其全部命令语义与扩展规范。
【免费下载链接】fhevmFHEVM, a full-stack framework for integrating Fully Homomorphic Encryption (FHE) with blockchain applications项目地址: https://gitcode.com/GitHub_Trending/fh/fhevm
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考