恒美微站 Logo 恒美微站
  • 首页
  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心
  • 联系我们

fhEVM 加密加法实战:FHEAdd 合约从加密输入到密文计算与用户解密全流程解析

  • 首页
  • 资讯中心
  • /
  • fhEVM 加密加法实战:FHEAdd 合约从加密输入到密文计算与用户解密全流程解析

相关资讯

Django多角色就业系统:权限控制、双前端协同与生产部署 2026/9/12 4:04:07
电-热综合能源系统优化与需求响应技术解析 2026/9/12 4:04:07
从文本到CAD模型:text-to-cad技术原理与工程实践 2026/9/12 4:04:07

最新资讯

Zettlr:本地优先的学术写作编辑器
Polars 如何编写并注册一个 Rust 表达式插件(pyo3-polars)?
Dapr 1.10.1 修复解析:CloudEvent 信封 `id` 与 `source` 字段回归问题与发布链路源码剖析
DolphinScheduler 数据源配置:元数据库与数据源中心一次配通的实操路径
永磁直流电机四象限控制与PID协同设计
Seko替代工具实测:四款AI视觉工具选型指南

今日推荐

MATLAB仿生优化框架:长鼻浣熊算法多策略融合实现
【JAVA毕设源码分享】基于 JavaWeb 的校园一卡通管理系统的设计与实现 基于 JavaWeb 的校园卡业务管理系统(程序+文档+代码讲解+一条龙定制)
【JAVA毕设源码分享】基于 Java 的图书馆借阅管理平台的搭建与实现 基于 Java 的图书馆综合管理系统(程序+文档+代码讲解+一条龙定制)

本周热门

超人会飞不算本事:系统稳定依赖清晰规则与边界设计
超人VS蜘蛛侠:拆解超级IP的影响力与传播方法论
基于CNN的调制信号识别:MATLAB实现时频图分类实战

本月精选

自研推理加速器Redwood:两周内实现PyTorch模型高效部署的实战教程
V4L2摄像头采集实战:从camera_client.rar到出图全流程解析
从“谁发明了钢琴键”到知识问答智能体:RAG与记忆工程实践

fhEVM 加密加法实战:FHEAdd 合约从加密输入到密文计算与用户解密全流程解析

发布时间:2026/9/12 4:09:08
fhEVM 加密加法实战:FHEAdd 合约从加密输入到密文计算与用户解密全流程解析 fhEVM 加密加法实战FHEAdd 合约从加密输入到密文计算与用户解密全流程解析【免费下载链接】fhevmFHEVM, a full-stack framework for integrating Fully Homomorphic Encryption (FHE) with blockchain applications项目地址: https://gitcode.com/GitHub_Trending/fh/fhevm本指南以 fhEVM 仓库中的FHEAdd示例为核心演示如何对全同态加密FHE值执行加法运算用户以密文形式提交a与b合约在不解密的情况下计算出a b再交由指定用户解密得到明文结果。读完本文你将掌握 fhEVM 中euint8加密类型的输入提交、FHE.add密文运算、FHE 权限allow/allowThis语义以及用 Hardhat 插件完成端到端测试的完整链路。示例概览一次完整的加密加法闭环docs/examples/fheadd.md提供的FHEAdd示例完整覆盖了 fhEVM 应用的四个核心环节加密输入Alice 通过fhevm.createEncryptedInput(...)将明文80和123加密并连同输入证明inputProof提交给合约密文存储合约通过FHE.fromExternal验证并接管外部传入的密文句柄handle存入状态变量密文计算computeAPlusB()调用FHE.add(_a, _b)全程不暴露任何明文授权解密通过FHE.allow/FHE.allowThis授予合约与调用者的 FHE 权限再由 Bob 通过fhevm.userDecryptEuint解密出结果203。该示例在 docs/examples/SUMMARY.md 中被归入 FHE Operations → Add 章节与fheifthenelse.md、fhe-counter.md等构成 fhEVM 入门操作序列适合作为第一个 FHE 运算合约来学习。运行前置条件文件目录摆放原文档特别强调为了让 Hardhat 能正确编译与测试合约必须将文件放置到指定目录.sol文件 →your-project-root-dir/contracts/.ts文件 →your-project-root-dir/test/这符合 Hardhat 的默认约定contracts/目录下的 Solidity 源码会被自动识别编译test/目录下的 Mocha 测试文件会被自动加载执行。示例中FHEAdd.ts从../../../types导入生成的类型定义FHEAdd__factory对应测试文件位于test/下两级目录的场景因此需保持该目录层级结构。合约实现FHEAdd.sol 逐段解读以下为完整合约代码docs/examples/fheadd.md中 FHEAdd.sol 标签页内容// SPDX-License-Identifier: BSD-3-Clause-Clear pragma solidity ^0.8.24; import { FHE, euint8, externalEuint8 } from fhevm/solidity/lib/FHE.sol; import { ZamaEthereumConfig } from fhevm/solidity/config/ZamaConfig.sol; contract FHEAdd is ZamaEthereumConfig { euint8 private _a; euint8 private _b; // solhint-disable-next-line var-name-mixedcase euint8 private _a_plus_b; // solhint-disable-next-line no-empty-blocks constructor() {} function setA(externalEuint8 inputA, bytes calldata inputProof) external { _a FHE.fromExternal(inputA, inputProof); FHE.allowThis(_a); } function setB(externalEuint8 inputB, bytes calldata inputProof) external { _b FHE.fromExternal(inputB, inputProof); FHE.allowThis(_b); } function computeAPlusB() external { // The sum a b is computed by the contract itself (address(this)). // Since the contract has FHE permissions over both a and b, // it is authorized to perform the FHE.add operation on these values. // It does not matter if the contract caller (msg.sender) has FHE permission or not. _a_plus_b FHE.add(_a, _b); // At this point the contract itself (address(this)) has been granted ephemeral FHE permission // over _a_plus_b. This FHE permission will be revoked when the function exits. // // Now, to make sure _a_plus_b can be decrypted by the contract caller (msg.sender), // we need to grant permanent FHE permissions to both the contract itself (address(this)) // and the contract caller (msg.sender) FHE.allowThis(_a_plus_b); FHE.allow(_a_plus_b, msg.sender); } function result() public view returns (euint8) { return _a_plus_b; } }导入与继承FHE、euint8、externalEuint8均来自fhevm/solidity/lib/FHE.sol。euint8是 8 位无符号整数的加密类型externalEuint8是外部传入的密文句柄类型本质上是bytes32的包装二者属于不同的 Solidity 类型必须通过FHE.fromExternal转换才能参与运算。合约继承ZamaEthereumConfig。该抽象合约定义在 library-solidity/config/ZamaConfig.sol其构造函数会调用FHE.setCoprocessor(ZamaConfig.getEthereumCoprocessorConfig())为合约注入 ACL、Coprocessor 与 KMSVerifier 三个核心合约地址。从源码可以看到Ethereum 配置分支支持chainid 1以太坊主网、chainid 11155111Sepolia 测试网和chainid 31337本地 Hardhat/Anvil 网络若在其他链上部署会触发ZamaProtocolUnsupported回退。因此本示例既可在本地 mock 环境运行也可面向 Ethereum 主网/Sepolia 部署。setA / setB接收加密输入function setA(externalEuint8 inputA, bytes calldata inputProof) external { _a FHE.fromExternal(inputA, inputProof); FHE.allowThis(_a); }FHE.fromExternal(externalEuint8, bytes)在 library-solidity/lib/FHE.sol 中的实现逻辑是当inputProof非空时调用Impl.verify(inputHandle, inputProof, FheType.Uint8)对客户端生成的零知识证明进行链上校验验证通过后返回可用的euint8当inputProof为空时跳过证明校验但要求调用者msg.sender已被 ACL 授权使用该句柄否则回退SenderNotAllowedToUseHandle。这一分支可用于智能合约账户smart contract accounts场景将已校验并授权的句柄直接复用。紧接着的FHE.allowThis(_a)是关键一步它调用Impl.allow(handle, address(this))把对密文_a的使用权限授予合约自身。没有这一步合约后续无法对_a执行FHE.add。computeAPlusB密文加法与权限授予function computeAPlusB() external { _a_plus_b FHE.add(_a, _b); FHE.allowThis(_a_plus_b); FHE.allow(_a_plus_b, msg.sender); }该函数演示了 fhEVM 权限模型的三个重要事实运算权限只看合约自身FHE.add(_a, _b)由合约执行只要合约address(this)对_a、_b拥有 FHE 权限即可与msg.sender这里测试中由 Bob 调用是否拥有权限无关。注释中特意说明 It does not matter if the contract caller (msg.sender) has FHE permission or not.临时权限与永久权限运算产生的_a_plus_b会在执行期间被自动授予合约临时ephemeral权限函数退出后即失效。为了让它能被持久使用必须显式调用FHE.allowThis(_a_plus_b)将永久权限授予合约自身显式授权给用户FHE.allow(_a_plus_b, msg.sender)将永久权限授予本次调用的发送者Bob这样 Bob 才能解密结果。从源码看FHE.allow/FHE.allowThis的euint8重载library-solidity/lib/FHE.sol都会先调用isInitialized检查句柄是否有效未初始化则替换为加密的 0然后调用Impl.allow完成 ACL 注册并返回原值。result读取加密结果function result() public view returns (euint8) { return _a_plus_b; }view函数直接返回密文句柄合约本身不暴露任何明文信息安全性由 FHE 保证。FHE.add 底层实现类型支持与零值处理FHE.add是重载函数族。以add(euint8 a, euint8 b)为例library-solidity/lib/FHE.solfunction add(euint8 a, euint8 b) internal returns (euint8) { if (!isInitialized(a)) { a asEuint8(0); } if (!isInitialized(b)) { b asEuint8(0); } return euint8.wrap(Impl.add(euint8.unwrap(a), euint8.unwrap(b), false)); }实现细节值得注意对未初始化句柄自动替换为加密的 0isInitialized检查句柄是否为空空句柄在参与运算前会被asEuint8(0)替换避免产生无效运算最终调用Impl.add生成加密运算请求交由 Coprocessor 在密文域内完成加法返回新的密文句柄从源码结构看add覆盖euint8/16/32/64/128/256全部整数加密类型且支持跨类型混合运算如add(euint8, euint16) → euint16结果类型自动提升为较宽的宽度。因此本示例虽以euint8演示同一套模式可直接推广到更大位宽。测试实现FHEAdd.ts 端到端验证以下为完整测试代码docs/examples/fheadd.md中 FHEAdd.ts 标签页内容import { FhevmType, HardhatFhevmRuntimeEnvironment } from fhevm/hardhat-plugin; import { HardhatEthersSigner } from nomicfoundation/hardhat-ethers/signers; import { expect } from chai; import { ethers } from hardhat; import * as hre from hardhat; import { FHEAdd, FHEAdd__factory } from ../../../types; import type { Signers } from ../../types; async function deployFixture() { // Contracts are deployed using the first signer/account by default const factory (await ethers.getContractFactory(FHEAdd)) as FHEAdd__factory; const fheAdd (await factory.deploy()) as FHEAdd; const fheAdd_address await fheAdd.getAddress(); return { fheAdd, fheAdd_address }; } /** * This trivial example demonstrates the FHE encryption mechanism * and highlights a common pitfall developers may encounter. */ describe(FHEAdd, function () { let contract: FHEAdd; let contractAddress: string; let signers: Signers; let bob: HardhatEthersSigner; before(async function () { // Check whether the tests are running against an FHEVM mock environment if (!hre.fhevm.isMock) { throw new Error(This hardhat test suite cannot run on Sepolia Testnet); } const ethSigners: HardhatEthersSigner[] await ethers.getSigners(); signers { owner: ethSigners[0], alice: ethSigners[1] }; bob ethSigners[2]; }); beforeEach(async function () { // Deploy a new contract each time we run a new test const deployment await deployFixture(); contractAddress deployment.fheAdd_address; contract deployment.fheAdd; }); it(a b should succeed, async function () { const fhevm: HardhatFhevmRuntimeEnvironment hre.fhevm; let tx; // Lets compute 80 123 203 const a 80; const b 123; // Alice encrypts and sets a as 80 const inputA await fhevm.createEncryptedInput(contractAddress, signers.alice.address).add8(a).encrypt(); tx await contract.connect(signers.alice).setA(inputA.handles[0], inputA.inputProof); await tx.wait(); // Alice encrypts and sets b as 203 const inputB await fhevm.createEncryptedInput(contractAddress, signers.alice.address).add8(b).encrypt(); tx await contract.connect(signers.alice).setB(inputB.handles[0], inputB.inputProof); await tx.wait(); // Why Bob has FHE permissions to execute the operation in this case ? // See computeAPlusB() in FHEAdd.sol for a detailed answer tx await contract.connect(bob).computeAPlusB(); await tx.wait(); const encryptedAplusB await contract.result(); const clearAplusB await fhevm.userDecryptEuint( FhevmType.euint8, // Specify the encrypted type encryptedAplusB, contractAddress, // The contract address bob, // The user wallet ); expect(clearAplusB).to.equal(a b); }); });测试要点拆解Mock 环境强制校验before钩子中检查hre.fhevm.isMock若非 mock 环境直接抛错。这是因为本测试用例依赖本地 FHEVM mock 插件的即时加密/解密能力不适用于真实 Sepolia 网络真实网络需要等待链下协处理器异步执行解密请求。加密输入的三段式 APIconst inputA await fhevm.createEncryptedInput(contractAddress, signers.alice.address).add8(a).encrypt();createEncryptedInput(contractAddress, account)声明密文的归属合约与用户地址.add8(a)加入一个 8 位整数.encrypt()完成加密并返回{ handles, inputProof }。handles[0]是对应的密文句柄inputProof是供链上fromExternal校验的零知识证明——两者分别对应合约setA的inputA与inputProof参数。权限与调用者分离的演示a、b由 Alice 加密并提交但加法运算computeAPlusB()由 Bob 调用。测试注释直接提问 Why Bob has FHE permissions to execute the operation in this case?——答案就在合约的computeAPlusB()中运算只需合约自身有权限与调用者无关。这正体现了 FHE 场景下数据的加密者、运算的发起者、结果的解密者可以是不同主体的特点。用户解密fhevm.userDecryptEuint(FhevmType.euint8, encryptedAplusB, contractAddress, bob)以 Bob 的钱包发起解密。由于computeAPlusB中已执行FHE.allow(_a_plus_b, msg.sender)即授予 Bob 永久权限Bob 才能成功解密出明文203断言expect(clearAplusB).to.equal(a b)通过。常见误区与设计要点总结综合合约注释与测试用例这个看似简单的示例集中呈现了几个 fhEVM 开发的高频知识点外部句柄必须先验证再使用任何externalEuint8都必须经过FHE.fromExternal携带非空inputProof或已被 ACL 验证否则无法进入euint8运算域合约运算不依赖调用者权限FHE.add等运算要求的是合约自身address(this)对操作数的权限msg.sender是否有权限不影响运算执行临时权限不等于永久权限运算结果的临时权限在函数退出即失效如需后续解密或再次运算必须显式FHE.allowThis/FHE.allow解密需要显式授权想要让某个用户解密某个密文必须把该密文的 FHE 权限授予该用户这是 ACL 模型library-solidity/lib/FHE.sol 中Impl.isAllowed/Impl.allow对应实现的强制要求。延伸阅读加密与解密完整入门fhe-encrypt-single-value.md、fhe-user-decrypt-single-value.md条件运算fheifthenelse.md状态保持型应用fhe-counter.md链上公开解密无需用户交互heads-or-tails.md、highest-die-roll.md完整操作类型参考FHE.sol的add/sub/mul/lt/select等重载族定义于 library-solidity/lib/FHE.sol可按加密类型检索对应实现掌握本示例后你可以将同样的加密输入 → 密文运算 → 权限授予 → 用户解密模式扩展到euint16、euint256乃至地址加密类型构建如隐私余额相加、密文聚合统计等更复杂的应用。【免费下载链接】fhevmFHEVM, a full-stack framework for integrating Fully Homomorphic Encryption (FHE) with blockchain applications项目地址: https://gitcode.com/GitHub_Trending/fh/fhevm创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于恒美微站

恒美微站专注于为个体商户、工作室提供极简自助建站服务,让每个人都能轻松拥有专业网站。

快速链接

  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心

服务项目

  • 可视化建站
  • 拖拽编辑
  • 主题定制
  • SEO 优化
  • 网站托管

联系方式

  • 📍 地址:北京市朝阳区建国路 88 号
  • 📞 电话:400-888-8888
  • ✉️ 邮箱:info@hmyw.cn
  • 🕐 时间:周一至周日 9:00-18:00

© 2024 恒美微站 hmyw.cn 版权所有 | 京 ICP 备 12345678 号