使用 @zama-fhe/relayer-sdk 构建 fhEVM Web 应用:从 CDN 引入到实例初始化的完整指南
【免费下载链接】fhevmFHEVM, a full-stack framework for integrating Fully Homomorphic Encryption (FHE) with blockchain applications项目地址: https://gitcode.com/GitHub_Trending/fh/fhevm
导读
本文基于 fhevm 仓库的 Web 应用开发指南 展开,系统讲解如何在浏览器端使用@zama-fhe/relayer-sdk构建基于 fhEVM(全同态加密虚拟机)的 dApp。你将掌握三种引入 SDK 的方式(UMD CDN、ESM CDN、npm 包)、WASM 初始化initSDK与实例创建createInstance的完整流程,并理解FhevmInstance与 SepoliaConfig 在加密输入、用户解密、公开解密三大核心场景中的承接关系,从而直接上手开发可加密、可解密的前端应用。
为什么选择 Relayer SDK 构建 Web 应用
fhEVM 的完整架构包含 FHEVM Host Chain(承载 ACL、KMSVerifier、InputVerifier 等合约的链)与 Gateway Chain(执行解密与输入验证的链)。如果前端直接与 Gateway Chain 交互,客户端必须同时拥有两条链上的钱包与代币,这对普通用户与开发者都极为繁琐。
@zama-fhe/relayer-sdk正是为了解决这一问题而设计:借助 SDK 总览 中描述的 Relayer 架构,FHEVM 客户端只需要在 FHEVM Host Chain 上持有钱包,所有与 Gateway Chain 的交互都由 SDK 通过 HTTP 调用 Zama 维护的 Relayer 完成,Relayer 在 Gateway Chain 上代为支付相关费用。因此在前端集成时,你只需关注浏览器环境下的加密、签名与调用,复杂的跨链交互被完全屏蔽在 SDK 内部。
在开始编码前,建议先阅读 初始化(Setup)指南,理解FhevmInstance对象承载的全部配置与方法。
Step 1:以正确的方式引入 SDK
@zama-fhe/relayer-sdk由多个文件组成,包括 WASM 文件与 Web Workers,如果手动配置打包器(Webpack、Vite、Rollup 等)将这些组件正确打进构建产物,过程会相当繁琐——尤其是开发带服务端渲染(SSR)的 dApp 时。官方文档为此提供了三种引入方式,按场景任选其一。
方式一:UMD CDN(推荐用于快速上手)
在你的项目入口 HTML 顶部引入 UMD 构建产物:
<script src="https://cdn.zama.ai/relayer-sdk-js/0.2.0/relayer-sdk-js.umd.cjs" type="text/javascript"></script>引入后,SDK 会以全局对象(window.fhevm)的形式暴露。如果你同时通过 npm 安装了@zama-fhe/relayer-sdk包,也可以直接使用 bundle 导入:
import { initSDK, createInstance, SepoliaConfig } from "@zama-fhe/relayer-sdk/bundle";UMD 方式的最大价值在于彻底绕开打包器对 WASM 与 Worker 的处理问题。关于这一点,常见 Webpack 错误指南 中专门提到:当使用 SSR 框架打包库失败时,官方推荐直接使用 bundle 预打包版本,以<script>标签嵌入库并按如下方式初始化:
const start = async () => { await window.fhevm.initSDK(); // load wasm needed const config = { ...SepoliaConfig, network: window.ethereum }; config.network = window.ethereum; const instance = window.fhevm.createInstance(config).then((instance) => { console.log(instance); }); };方式二:ESM CDN(零构建体验)
如果你更喜欢 ES Module 语法,可以直接从 CDN 以模块方式加载:
<script type="module"> import { initSDK, createInstance, SepoliaConfig } from "https://cdn.zama.ai/relayer-sdk-js/0.2.0/relayer-sdk-js.js"; await initSDK(); const config = { ...SepoliaConfig, network: window.ethereum }; config.network = window.ethereum; const instance = await createInstance(config); </script>这种方式适合原型验证或不需要打包器的轻量页面:initSDK()负责加载 TFHE 相关的 WASM,createInstance(config)负责构造实例,两步都完成后即可使用实例的加密与解密能力。
方式三:npm 包(正式项目集成)
在正式项目中使用 npm / Yarn / pnpm 安装:
# Using npm npm install @zama-fhe/relayer-sdk # Using Yarn yarn add @zama-fhe/relayer-sdk # Using pnpm pnpm add @zama-fhe/relayer-sdk@zama-fhe/relayer-sdk使用ESM 格式,因此你的package.json需要设置"type": "module"(参见 Node.js 官方对package.jsontype 字段的说明)。如果你的 Node 项目使用"type": "commonjs"或未声明 type,可以通过强制加载 Web 版本解决:
import { createInstance } from '@zama-fhe/relayer-sdk/web';正常 ESM 场景下的导入方式为:
import { initSDK, createInstance, SepoliaConfig } from "@zama-fhe/relayer-sdk";从仓库结构看,@zama-fhe/relayer-sdk的源码位于 sdk/js-sdk/src,其中 index.ts 为包的统一入口,wasm/目录下分别维护了tfhe与tkms两套 WASM 模块(sdk/js-sdk/src/wasm),这也解释了为何 SDK 必须通过initSDK()显式加载 WASM 后才能工作。
Step 2:用 initSDK 加载 TFHE WASM
TFHE 加密运算依赖 WebAssembly。使用库内任何加密功能之前,必须先调用initSDK()加载 WASM:
import { initSDK } from "@zama-fhe/relayer-sdk/bundle"; const init = async () => { await initSDK(); // Load needed WASM };注意:若跳过此步骤直接调用加密相关 API,通常会因为 WASM 尚未就绪而抛出与 TFHE 运行时相关的错误。
initSDK()是异步函数,务必await完成后再进入后续流程。
Step 3:创建 FhevmInstance 实例
WASM 加载完成后,即可创建实例。FhevmInstance是 SDK 的核心对象,它持有与 fhEVM 交互所需的全部配置与方法。最小示例:
import { initSDK, createInstance, SepoliaConfig } from "@zama-fhe/relayer-sdk/bundle"; const init = async () => { await initSDK(); // Load FHE const config = { ...SepoliaConfig, network: window.ethereum }; return createInstance(config); }; init().then((instance) => { console.log(instance); });其中SepoliaConfig是 SDK 为 Zama 维护的 Sepolia 测试网 FHEVM 与 Relayer 预置的配置对象,可直接使用;network: window.ethereum覆盖为浏览器钱包注入的 Provider(如 MetaMask),这样实例即可用用户钱包发起签名请求。
SepoliaConfig 背后的完整配置项
如果你不依赖预设配置,也可以参考 初始化(Setup)指南 手动传入全部参数。createInstance接受的核心配置如下:
import { createInstance } from "@zama-fhe/relayer-sdk"; const instance = await createInstance({ // ACL_CONTRACT_ADDRESS (FHEVM Host chain) aclContractAddress: "0x687820221192C5B662b25367F70076A37bc79b6c", // KMS_VERIFIER_CONTRACT_ADDRESS (FHEVM Host chain) kmsContractAddress: "0x1364cBBf2cDF5032C47d8226a6f6FBD2AFCDacAC", // INPUT_VERIFIER_CONTRACT_ADDRESS (FHEVM Host chain) inputVerifierContractAddress: "0xbc91f3daD1A5F19F8390c400196e58073B6a0BC4", // DECRYPTION_ADDRESS (Gateway chain) verifyingContractAddressDecryption: "0xb6E160B1ff80D67Bfe90A85eE06Ce0A2613607D1", // INPUT_VERIFICATION_ADDRESS (Gateway chain) verifyingContractAddressInputVerification: "0x7048C39f048125eDa9d678AEbaDfB22F7900a29F", // FHEVM Host chain id chainId: 11155111, // Gateway chain id gatewayChainId: 55815, // Optional RPC provider to host chain network: "https://eth-sepolia.public.blastapi.io", // Relayer URL relayerUrl: "https://relayer.testnet.zama.cloud", });这些参数的含义:
| 配置项 | 作用 | 备注 |
|---|---|---|
aclContractAddress | FHEVM Host Chain 上的 ACL(访问控制列表)合约地址 | 控制谁可以解密 / 操作特定 ciphertext |
kmsContractAddress | Host Chain 上的 KMSVerifier 合约地址 | 用于验证 KMS 签名与密钥材料 |
inputVerifierContractAddress | Host Chain 上的 InputVerifier 合约地址 | 验证新加密输入及其零知识证明 |
verifyingContractAddressDecryption | Gateway Chain 上的解密验证合约地址 | 供 Relayer 侧做解密请求的 EIP-712 签名验证 |
verifyingContractAddressInputVerification | Gateway Chain 上的输入验证合约地址 | 供 Relayer 侧做输入注册的 EIP-712 签名验证 |
chainId | FHEVM Host Chain 的 chain id | Sepolia 为11155111 |
gatewayChainId | Gateway Chain 的 chain id | 固定为55815 |
network | Host Chain 的 RPC Provider 或 RPC URL | 可选;浏览器中通常传window.ethereum |
relayerUrl | Relayer 服务的 HTTP 地址 | 测试网为https://relayer.testnet.zama.cloud |
简化写法等价于:
import { createInstance, SepoliaConfig } from "@zama-fhe/relayer-sdk"; const instance = await createInstance(SepoliaConfig);Sepolia 相关合约地址、chain id 等信息都封装在SepoliaConfig对象中,无需记忆。
实例就绪之后:三大核心能力
创建好FhevmInstance后,实例即可用于以下三类操作,均已有独立指南,本文只做承接说明:
- 加密输入(Input registration):使用
instance.createEncryptedInput(contractAddress, userAddress)创建加密缓冲区,通过add8/add16/add32/add64/add128/add256/addBool/addAddress等类型化方法填充明文,最后buffer.encrypt()得到 ciphertext handles 与 inputProof,可传给链上合约的FHE.fromExternal使用。完整流程见 输入注册指南。 - 用户解密(User decryption):当需要让某个用户用自己的密钥查看自己的私有数据(如余额、计数)而不暴露明文时,通过
instance.generateKeypair()、instance.createEIP712(...)配合钱包signTypedData签名,最后instance.userDecrypt(...)在客户端完成"用用户 NaCl 公钥重新加密"的流程,只有该用户能解密。前置条件是合约中已通过FHE.allow(ciphertext, address)正确设置 ACL 权限。详见 用户解密指南。 - 公开解密(Public decryption):当需要让所有人看到某个 ciphertext 的明文(如拍卖结果)时,调用
instance.publicDecrypt(handles)通过 Relayer 的 HTTP 端点请求解密,返回明文值及可在链上验证的密码学证明;链上可用FHE.checkSignatures()验证。详见 公开解密指南。
常见问题排查与打包器注意事项
在前端集成@zama-fhe/relayer-sdk时,最常遇到的问题集中在打包环节,官方 常见 Webpack 错误指南 给出了四类典型场景的解决方案:
Can't resolve 'tfhe_bg.wasm':SDK 内部使用new URL('tfhe_bg.wasm')触发 Webpack 解析,需在webpack.config.js中添加 fallback:resolve: { fallback: { 'tfhe_bg.wasm': require.resolve('tfhe/tfhe_bg.wasm'), }, },Buffer is not defined:浏览器环境缺少 Node.js 核心模块,需安装并配置 browserify 版 fallback:resolve: { fallback: { buffer: require.resolve('buffer/'), crypto: require.resolve('crypto-browserify'), stream: require.resolve('stream-browserify'), path: require.resolve('path-browserify'), }, },- ESM 版本导入的 typing 问题:打包器会依据
package.json的"browser"字段替换导入版本,若出现类型问题可强制导入浏览器包,或参考 React 模板的tsconfig.json(TypeScript 5)配置。 - SSR 框架打包失败:直接改用 bundle 预打包版本(
@zama-fhe/relayer-sdk/bundle)并以<script>标签嵌入,初始化时通过window.fhevm.initSDK()与window.fhevm.createInstance(...)调用(示例见上文"方式一")。
小结与推荐阅读路径
在 Web 应用中集成 fhEVM 的核心链路可以概括为三步:引入 SDK(CDN 或 npm)→await initSDK()加载 WASM →createInstance(config)创建实例。之后所有加密、解密能力都由该实例统一提供。
建议按以下顺序继续深入:
- SDK 总览:理解 Relayer 架构与 SDK 定位
- 初始化指南:完整的配置项与 SepoliaConfig 说明
- 输入注册:将明文加密注册为链上 ciphertext
- 用户解密 与 公开解密:两类解密场景的完整代码
- Webpack 调试指南:打包与 SSR 场景排障
- CLI 指南:命令行方式使用 SDK
如果希望在浏览器环境中提前调试 SDK 的加密与解密行为,还可以结合仓库中的 JS SDK 测试用例 与 SDK 示例 进行本地验证。
【免费下载链接】fhevmFHEVM, a full-stack framework for integrating Fully Homomorphic Encryption (FHE) with blockchain applications项目地址: https://gitcode.com/GitHub_Trending/fh/fhevm
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考