
fhEVMfhevm/sdk运行时兼容性完全指南多线程、单线程与边缘运行时支持矩阵【免费下载链接】fhevmFHEVM, a full-stack framework for integrating Fully Homomorphic Encryption (FHE) with blockchain applications项目地址: https://gitcode.com/GitHub_Trending/fh/fhevm本指南以 sdk/js-sdk/docs/runtime-compatibility.md 为核心系统讲解fhevm/sdk在浏览器、Node.js、Bun、Deno、Electron 与 Next.jsCSR/SSR/Edge等环境中的运行前提、线程能力判定与降级策略。读完你将掌握为什么“单线程在任何能编译 WASM 的环境都能跑”、多线程到底依赖哪些底层能力SharedArrayBuffer Worker 后端、以及为什么 Vercel Edge / Cloudflare Workers 无法在隔离区内直接运行 SDK——并能在自己的部署里做出正确的工程取舍。一、SDK 运行环境的三大能力前提fhevm/sdk内部会加载两个 WebAssembly 模块TFHE加密可多线程与TKMS解密始终轻量、单线程。因此一个环境是否支持 SDK最终取决于以下三项能力WASM 编译能力——运行时必须允许从字节构建 WebAssembly 模块WebAssembly.compile。如果 SDK 无法编译 WASM则完全无法运行这是硬性前提。解压能力——内嵌的 WASM 以 gzip 压缩存放。SDK 优先使用平台原生DecompressionStream否则回退到内置的纯 JS inflater兼容旧浏览器与部分运行时。因此解压永远不会成为硬性阻塞。线程能力仅 TFHE 多线程需要——多线程 TFHE 需要同时具备SharedArrayBuffer和 worker 后端WebWorker或node:worker_threads。二者缺一SDK 会优雅降级为单线程单线程永远可用它不需要 worker。核心结论凡是能编译 WASM 的环境单线程模式一定可用多线程只是需要额外线程能力支撑的性能优化。二、支持矩阵权威速查表下表是 runtime-compatibility.md 中支持矩阵的完整呈现。其中“when cross-origin isolated”指页面通过Cross-Origin-Opener-Policy: same-origin与Cross-Origin-Embedder-Policy: require-corp两个响应头服务使得crossOriginIsolated true且SharedArrayBuffer可用。环境SDK 运行ST多线程MTMT 在此需要什么备注Browser客户端✅✅ 跨源隔离时COOP/COEP 头 →SharedArrayBuffer Web Workers零配置。无 COOP/COEP → 降级为 ST。Browser — 旧版Firefox 113、Safari 16.4✅✅ 跨源隔离时同上无DecompressionStream→ SDK 使用纯 JS inflater。Electron沙箱化 renderer✅✅ 跨源隔离时Web Worker沙箱 renderer 中无worker_threadsSDK 自动选择 Web Worker 后端。Node.js脚本、后端、长驻服务✅✅node:worker_threadsSharedArrayBuffer始终可用无需 COOP/COEP——Node 中 SAB 恒存在。Bun✅✅worker_threads为与 Node 保持行为一致强制走 Node worker 后端。Deno✅✅ 隔离时Web Worker SharedArrayBufferWeb 标准后端。Next.js — CSR客户端组件任意 server runtime✅✅ 跨源隔离时浏览器SharedArrayBuffer Web WorkersSDK 运行在浏览器server runtime 只提供外壳。Next.js — SSRNode runtime服务端组件✅✅node:worker_threadsCOOP/COEP 服务端无关需要 bundler 的node:导入提示见“Bundlers”节。Next.js — SSREdge runtime服务端组件❌❌—不支持。见下文“Edge”。Next.js — Edge route CSRruntimeedge路由上的客户端组件✅✅ 跨源隔离时浏览器SharedArrayBuffer Web Workers支持——SDK 在客户端运行edge isolate 从不接触 WASM。Vercel Edge / Cloudflare Workers在 isolate内运行 SDK❌❌—不支持。见下文“Edge”。图例✅ 支持 · ❌ 不支持 · “when cross-origin isolated” 页面以Cross-Origin-Opener-Policy: same-originCross-Origin-Embedder-Policy: require-corp服务即crossOriginIsolated true且SharedArrayBuffer可用。从源码看这套矩阵正是 environment.ts 中基于能力探测而非 UA 字符串的环境判定的直接结果isNodeLike()检查process.versions.nodeisBrowserLike()要求存在location.href与addEventListener而 Vercel Edge、Cloudflare Workers、Next.js edge 既非 Node 也非浏览器探测返回安全值false/undefined调用方自然回退到 Web 标准 API。三、SSR 与 CSR 的本质区别元框架场景对于 Next.js 这类元框架SDK 代码在哪里执行比它位于哪条路由更重要CSR——SDK 运行在客户端组件中水合后在浏览器里执行。这是正常且完全受支持的路径。server runtimeNode或Edge只渲染 HTML 外壳从不编译 WASM因此即使是 edge 渲染的路由也可用只要 SDK 在客户端使用。SSR——SDK 运行在服务端组件中在服务端渲染期间执行。Node runtime 支持Edge runtime 不支持。因此“edge”并非一概不支持edge CSR 受支持edge SSR 不受支持。这是使用 Next.js 部署 fhEVM dApp 时最重要的工程判断之一。四、为什么 Edge 运行时服务端跑不了 SDK在 edge isolate 内部Vercel Edge、Cloudflare Workers、Next.jsruntimeedge服务端组件运行 SDK 会失败原因是三个相互独立的限制禁止动态 WASM 编译。Edge isolate 禁止运行时生成代码包括从字节调用WebAssembly.compile/instantiate。SDK 恰恰是从字节编译模块因此被拒绝。Next.jsdev模式在 Node 上模拟 Edge 且仅发出警告——DynamicWasmCodeGenerationWarning——所以本地看似能跑生产环境却会失败。没有SharedArrayBuffer。Edge isolate 不暴露 SAB因此supportsThreads为false→ 无论如何 MT 都不可能。代码体积限制。TFHE 模块有数 MB见下文通常超过 edge 的 bundle 大小上限。推荐方案在 edge 部署中从客户端组件CSR使用 SDK——edge runtime 负责服务页面浏览器负责运行 SDK。关于 TFHE 模块的体积可在 architecture.md 中找到佐证encrypt 模块的 TFHE WASMZK proof 生成约4.9 MB而 decrypt 模块的 TKMS WASM份额重建约600 KB。这也是 edge 环境代码体积限制被击穿的直接原因。五、Bundlers为什么消费者无需任何操作SDK 通过动态import()加载 Node 内置模块worker_threads、fs等并用环境检查做守卫。打包器必须被告知不要对这些导入做静态分析各自通过自己的 magic comment 实现——SDK 内置了全部三种// sdk/js-sdk/src/core/base/environment.ts 中的 _importNodeModule const id node:${name}; return (await import(/* vite-ignore */ /* webpackIgnore: true */ /* turbopackIgnore: true */ id)) as mod;vite-ignore—— VitewebpackIgnore: true—— webpackturbopackIgnore: true—— TurbopackNext.js。没有它Turbopack 无法分析由参数派生的模块说明符无法把node:内置模块当作候选打包会把调用替换成抛Cannot find module unknown的 stub——这曾静默禁用 Next 服务端组件中的 Nodeworker_threads后端→ TFHE 变为单线程。三个注释各自指示对应 bundler 发出原生import()由运行时解析在浏览器中该调用会抛错并被捕获返回undefined。SDK 消费者无需任何操作此处仅为完整说明。六、解压回退机制内嵌 WASM 是 gzip 压缩的。SDK 探测是否存在可用的DecompressionStream——注意它通过实际构造一个实例来探测因为仅做typeof检查不够部分运行时典型如 Next.js Edge Runtime暴露的是构造即抛错的 stub仅凭存在性判断是假阳性会在编译路径深处崩溃。相关实现在 environment.ts 的supportsDecompressionStream()export function supportsDecompressionStream(): boolean { if (_decompressionStreamSupported undefined) { if (typeof DecompressionStream ! function || typeof Blob ! function) { _decompressionStreamSupported false; } else { try { // 构造即探测——Next.js Edge stub 在这里抛错真实实现不会。 const probe new DecompressionStream(gzip); void probe; _decompressionStreamSupported true; } catch { _decompressionStreamSupported false; } } } return _decompressionStreamSupported; }当探测失败时SDK 回退到内置、零依赖的纯 JS inflater从而在旧浏览器Firefox 113、Safari 16.4及其他缺少可用DecompressionStream的运行时中依然能解压小体积的压缩载荷——无需消费者做任何事。七、线程降级源码级原理多线程并非“想开就开”。在 init-p.ts 的_resolveThreadConfig()中完整的降级逻辑如下线程数来源numberOfThreads未配置时取navigator.hardwareConcurrencynavigator缺失部分 edge 运行时、Node 21时降为 0单线程。numberOfThreads必须是非负整数否则直接抛错避免把调用者的错误静默抹平。SAB 探测线程数 0 时通过wasm-feature-detect的threads()探测SharedArrayBuffer浏览器中 SAB 依赖 COOP/COEP 头。探测失败则打印警告并降级单线程This browser does not support threads. Verify that your server returns correct headers: Cross-Origin-Opener-Policy: same-origin Cross-Origin-Embedder-Policy: require-corpworker 可用性auto模式下若线程可用但 blob/eval worker 不可用CSP 禁止blob:worker、Node 的--disallow-code-generation-from-strings等同样降级单线程。初始化非单线程时才调用tfheLib.initThreadPool(numberOfThreads)启动 worker 池单线程直接跳过。SDK 从不因线程问题抛错——缺少头或环境不支持线程时只记录警告并透明降级。这也印证了文档中的结论单线程总可用不需要 workerWASM 仍通过 URL 或内嵌 base64 加载。与之配套的 worker 后端选择在 isomorphicWorker.ts 的resolveWorkerApi()中运行时Web APINode API选中浏览器window / web worker有无web沙箱化 Electron renderer有无webNode.js无有nodejsdomVitest无有nodeDeno有有webBun有有node强制与 Node 保持一致注意沙箱化 Electron renderer 虽process.versions.node已设置但node:worker_threads不可用——由于 Web 优先策略它会自动走 Web Worker 后端这正是支持矩阵中“Electron 沙箱 renderer”一行的实现依据。八、实战配置建议1. 浏览器启用多线程设置 COOP/COEP 头由托管应用的服务器设置Cross-Origin-Opener-Policy: same-origin Cross-Origin-Embedder-Policy: require-corp缺头时浏览器禁用SharedArrayBufferSDK 自动回退单线程见 runtime-configuration.md。2. 强制单线程为最大化兼容性、或无法设置响应头时显式关闭线程import { setFhevmRuntimeConfig } from fhevm/sdk/ethers; // 或from fhevm/sdk/viem setFhevmRuntimeConfig({ singleThread: true });注意setFhevmRuntimeConfig按适配器隔离——fhevm/sdk/ethers与fhevm/sdk/viem各自持有独立配置必须从你创建 client 的同一适配器导入调用若同时使用两个适配器需分别配置。它在创建任何 client 之前调用一次重复调用相同配置为 no-op不同配置则抛错。3. 需要性能时显式指定线程数setFhevmRuntimeConfig({ numberOfThreads: 8 }); const client createFhevmClient({ chain: sepolia, provider }); await client.init(); // 现在编译 WASMnumberOfThreads: 0同样强制单线程。构造 client 不做任何 I/OWASM 编译的时机由你通过client.init()/client.ready掌控。4. Edge 部署的铁律若使用 Vercel Edge / Cloudflare Workers / Next.jsruntimeedgeSDK 只能从客户端组件CSR使用。edge 运行时服务页面浏览器运行 SDK——这是官方推荐且在矩阵中受支持的唯一 edge 姿势。5. 关注 WASM 体积与加载TFHE WASM 约 4.9 MB、TKMS 约 600 KB。加密客户端createFhevmEncryptClient只扩展 encrypt 模块bundler 不会打入 decrypt 的 WASM——按需选择 client 工厂即可控制打包体积。WASM/worker 资产的托管、locateFile、wasmAssetLoadMode与版本固定moduleVersions等加载细节详见 runtime-configuration.md。九、相关文档运行时配置 —— 线程、COOP/COEP 与 WASM 资产加载的完整配置项。Clients —— 加载这些 WASM 模块的 client 工厂。架构 —— loader 背后的运行时与模块设计。环境能力探测源码 —— 运行时识别、Node 内置模块动态导入与DecompressionStream探测。同构 Worker 源码 —— worker 后端选择矩阵与 blob/eval worker 冒烟测试。TFHE 模块初始化源码 —— 线程配置解析、SAB 探测与降级策略。【免费下载链接】fhevmFHEVM, a full-stack framework for integrating Fully Homomorphic Encryption (FHE) with blockchain applications项目地址: https://gitcode.com/GitHub_Trending/fh/fhevm创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考