news 2026/9/13 5:54:29

fhEVM JavaScript SDK 客户端(Client)完全指南:工厂选择、生命周期与配置

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
fhEVM JavaScript SDK 客户端(Client)完全指南:工厂选择、生命周期与配置

fhEVM JavaScript SDK 客户端(Client)完全指南:工厂选择、生命周期与配置

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

fhEVM JavaScript SDK 将「链上读取 + 本地加密/解密」抽象为一个统一的Client(客户端)对象,它是所有加密、解密、公钥读取与解密许可签名操作的入口。本文围绕 sdk/js-sdk/docs/clients.md 展开,深入讲解四个工厂函数的取舍、ethers / viem 两种接入方式、按调用(而非按客户端)签名的设计,以及ready/init()生命周期与可选项配置,并辅以 SDK 源码实现作为佐证,帮助你为页面选择最小、最快的客户端实例。

什么是 Client

一个 Client 是你调用加密解密操作的对象。它把一个 链定义(chain definition)(包含合约地址、Relayer URL 等 FHEVM 链信息)绑定到一个只读连接上,并在首次使用时懒加载所需的 WebAssembly 密码学模块。

关键点:

  • 只读连接:Client 只通过连接读取链上数据,从不代表你发送交易;
  • 懒加载 WASM:只有真正执行加密/解密时才下载并编译对应模块,普通读取不触发下载;
  • 适配器统一:所有 Client 都来自两个适配器入口之一——@fhevm/sdk/ethers@fhevm/sdk/viem。两者 API 完全一致,唯一的差别是原生连接对象不同(ethers 用provider,viem 用publicClient)。

选择哪种 Client:四个工厂

SDK 提供了四个工厂函数,它们的区别仅在于加载哪些 WASM 模块、从而暴露哪些方法。基本原则是:选择页面需求最窄的那个——例如一个只读取公开值的页面,绝不应该下载约 4.9 MB 的加密模块。

工厂加密解密加载的 WASM
createFhevmClientTFHE(约 4.9 MB)+ TKMS(约 600 KB)
createFhevmEncryptClientTFHE(约 4.9 MB)
createFhevmDecryptClientTKMS(约 600 KB)
createFhevmBaseClient

上表中的「解密」指私有解密decryptValue)。而读取公开值decryptPublicValue)以及签署解密许可(permit)每一种Client 上都可用——包括 Base Client——因为它们不需要密码学 WASM。两者的区别详见 Decryption。

从源码看,这一设计通过「装饰器(decorator)叠加」实现:createFhevmClient.ts 中createFhevmClientcreateFhevmBaseClient的基础上调用c.extend(decryptActions).extend(encryptActions);而 createFhevmEncryptClient.ts 只叠加encryptActions,createFhevmDecryptClient.ts 只叠加decryptActions。对应的类型定义在 fhevmClient.ts 中体现为BaseActions & DecryptActions & EncryptActions的排列组合,例如完整 Client 是Fhevm = Fhevm<chain, runtime, client> & BaseActions & DecryptActions & EncryptActions

Base Client 已内置的方法

base.ts 中的BaseActions是所有 Client 的公共子集,包括:

  • decryptPublicValue/decryptPublicValues:读取链上已被TFHE.allowForDecryption放开的密文的明文值,无需许可或私钥;
  • decryptPublicValuesWithSignatures:额外返回解密证明,可提交到链上由合约通过FHE.checkSignatures验证;
  • signDecryptionPermit(已标记 deprecated,见源码注释)、signLegacyDecryptionPermit(V1 许可形态,跨协议升级保持稳定)、signUnifiedDecryptionPermit(V2 统一许可,要求协议 API v0.14.0+);
  • parseTransportKeyPair/serializeTransportKeyPair:e2e 传输密钥对的序列化与反序列化;
  • serializeSignedDecryptionPermit/parseSignedDecryptionPermit:已签署许可的存储与校验;
  • fetchFheEncryptionKeyBytes:从 Relayer 拉取约 50 MB 的 FHE 公钥并缓存。

创建 Client:ethers 与 viem 两种写法

使用 ethers.js

provider可以是任意 ethers 的ContractRunner——JsonRpcProviderBrowserProvider,或者已连接的Wallet/Signer。Client 只通过它读取数据,绝不会代替你发送交易

import { createFhevmClient } from '@fhevm/sdk/ethers'; import { sepolia } from '@fhevm/sdk/chains'; import { ethers } from 'ethers'; const provider = new ethers.JsonRpcProvider('https://ethereum-sepolia-rpc.publicnode.com'); const client = createFhevmClient({ chain: sepolia, provider });

使用 viem

import { createFhevmClient } from '@fhevm/sdk/viem'; import { sepolia } from '@fhevm/sdk/chains'; import { createPublicClient, http } from 'viem'; import { sepolia as viemSepolia } from 'viem/chains'; const publicClient = createPublicClient({ chain: viemSepolia, transport: http('https://ethereum-sepolia-rpc.publicnode.com'), }); const client = createFhevmClient({ chain: sepolia, publicClient });

注意 viem 示例中出现了两个sepolia导入@fhevm/sdk/chains提供的是FHEVM 链定义(合约地址、Relayer URL),而viem/chains提供的是 viem 自己的传输链。它们是不同的对象,两者都需要。

签名是「按调用」而不是「按客户端」

四个工厂都不接受signerwalletClient参数——Client 是只读的。当某个操作需要签名时(目前只有签署解密许可需要),把 signer 传给那个具体方法:

await client.signLegacyDecryptionPermit({ /* … */ signerAddress: await signer.getAddress(), signer, // ethers Signer,或 viem 的 Account / WalletClient });

这保证了加密与公开读取完全无需钱包(wallet-free)。从类型定义看,Client 的只读性在 coreFhevmClient.ts 中被固化为readonly client字段(原生连接对象),配合FhevmBase接口中的readonly chainreadonly uid等不可变成员。

可选项(Options)

每个工厂都接受一个可选的options对象:

const client = createFhevmClient({ chain: sepolia, provider, options: { batchRpcCalls: true, // 把客户端的链上读取批量合并为 multicall }, });
选项类型适用范围作用
batchRpcCallsboolean所有 Client把客户端的合约读取合并为批量 RPC 调用(multicall)
fheEncryptionKeyFheEncryptionKeyBytesencrypt / full提供预取的 FHE 公钥,跳过网络拉取
moduleVersionsFhevmModuleVersions因 Client 而异固定 TFHE/TKMS WASM 的具体版本,而非使用默认值

从源码看,选项类型在 coreFhevmClient.ts 中被定义为分层结构:FhevmBaseOptions(仅batchRpcCalls)是所有 Client 的基础;FhevmEncryptOptions = FhevmBaseOptions & { fheEncryptionKey?, moduleVersions? }FhevmDecryptOptions = FhevmBaseOptions & { moduleVersions? };完整版FhevmOptions则同时包含前两者。

moduleVersions的取值定义在 moduleVersions.ts:可以是'auto',也可以显式指定tfhe/kms版本,并配合checkCompatibility: 'throw' | 'warn' | 'off'控制版本与协议兼容表的校验行为。模块版本固定与加密密钥缓存详见 Runtime configuration。

加载与生命周期

构造 Client 是瞬时操作,不产生任何 I/O。在加密或解密之前,需要await client.ready(或client.init())一次——它会解析协议版本,并下载、编译该 Client 所需的 WASM。encryptValuesdecryptValuegenerateTransportKeyPair都依赖这一步,未完成会直接抛错;唯一的例外是decryptPublicValues——它从 Relayer 解析所需内容,无需事先init()即可工作

建议把await client.ready放在你能控制的时机——例如启动画面(splash screen)或路由切换时:

const client = createFhevmClient({ chain: sepolia, provider }); await client.ready; // 解析版本,下载 + 编译 WASM,仅一次

每个 Client 暴露一组精简的生命周期成员:

成员类型说明
init()() => Promise<void>预加载并编译该 Client 的 WASM 模块
readyPromise<void>在 Client 可使用时 resolve
uidstring该 Client 实例的稳定标识符
chainFhevmChain创建 Client 时使用的链定义
protocolVersion解析结果对象该链已解析的 FHEVM 协议版本
extend(actions)函数附加额外 action 方法(高级/内部用途)

重复调用init()是安全的——模块初始化按 WASM 版本缓存。某个 WASM 版本被一个 Client 实例独占;如果创建第二个尝试加载同一版本的 Client 会抛错。实践中建议:每个页面创建一个 Client 并复用

从源码看,init()ready的定义位于 coreFhevmClient.ts 的Fhevm接口(readonly init: () => Promise<void>readonly ready: Promise<void>);基础初始化会调用ensureFrozenContext(见 base.ts 的_initBase),先解析并缓存冻结的版本基座;加密初始化则由 encrypt.ts 中的_initEncrypt负责。extend的类型签名也明确要求返回this & actions,印证了「装饰器叠加出能力」的架构。

实践中只加密 / 只解密的用法

一个常见模式是按路由拆分 dApp。例如一个只负责加密的「提交」页面:

import { createFhevmEncryptClient } from '@fhevm/sdk/ethers'; const client = createFhevmEncryptClient({ chain: sepolia, provider }); // 暴露 encryptValue / encryptValues(+ 公开解密 + 许可辅助方法)

一个只回读私有值的「结果」页面:

import { createFhevmDecryptClient } from '@fhevm/sdk/ethers'; const client = createFhevmDecryptClient({ chain: sepolia, provider }); // 暴露 decryptValue / decryptValues / generateTransportKeyPair(+ 公开解密 + 许可辅助方法)

每个页面只下载自己需要的 WASM。具体方法细节参见 Encryption 与 Decryption。

进一步阅读

  • Encryption —— 加密值并构造输入证明;
  • Decryption —— 私有解密、公开值、委托;
  • Runtime configuration —— 线程、WASM 加载、版本固定;
  • Chains —— FHEVM 链定义与内置链;
  • API reference —— 完整的工厂与方法签名;
  • Architecture —— 客户端与运行时架构;
  • SDK 源码目录 sdk/js-sdk/src,其中ethers/clients/viem/clients/为两套适配器实现,core/clients/decorators/为共享的 actions 装饰器,core/types/为类型定义。

【免费下载链接】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:54:19

C#/VB与三菱FX5U PLC通过SLMP协议实现以太网通讯交互

简介&#xff1a;这套源码采用C#与VB.NET编写&#xff0c;面向三菱FX5U可编程控制器的上位机通讯交互&#xff0c;专为需要将个人电脑与控制器对接的开发者打造&#xff0c;尤其适用于自动化设备的调试与数据采集场景。方案基于TCP协议&#xff0c;支持整数、双整数与浮点数的读…

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

OSG中Mipmap纹理技术的原理与优化实践

1. Mipmap纹理技术概述在三维图形渲染领域&#xff0c;纹理质量直接影响最终视觉效果。当观察者与纹理表面的距离变化时&#xff0c;传统单级纹理会导致明显的视觉瑕疵——近处出现锯齿&#xff08;Aliasing&#xff09;&#xff0c;远处产生闪烁&#xff08;Flickering&#x…

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

S7-200 PLC与组态王在自动洗车控制系统中的应用实践

前阵子朋友盘下一个小型洗车店&#xff0c;设备是二手市场淘来的“残血版”自动洗车机&#xff0c;原控制柜里的继电器东倒西歪&#xff0c;动作时序全靠时间继电器硬凑&#xff0c;三天两头卡壳。让我过去看看能不能救活&#xff0c;我一看柜子里的走线&#xff0c;头就大了—…

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

磁控U位资产管理系统:机房资产全链路智能管控实践

1. 机房资产管理的痛点&#xff1a;为什么传统U位管理越来越跟不上我做机房运维这些年&#xff0c;最怕的不是服务器宕机&#xff0c;而是年底资产盘点。几百上千个机柜&#xff0c;上万台设备&#xff0c;底账和现场普遍对不上。仓库里明明显示有空U位&#xff0c;到了现场一查…

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

双馈风机低电压穿越技术与MATLAB仿真实践

1. 双馈风机DFIG与低电压穿越技术背景双馈异步风力发电机&#xff08;Doubly-Fed Induction Generator, DFIG&#xff09;作为现代风力发电系统的核心部件&#xff0c;其独特之处在于转子绕组通过背靠背变流器与电网连接。这种结构使得DFIG能够在同步转速30%的范围内实现变速运…

作者头像 李华