FHEVM项目快速入门:测试全同态加密智能合约
2025-07-08 08:20:31作者:戚魁泉Nursing
前言
本文将详细介绍如何使用Zama的FHEVM库测试支持全同态加密(FHE)的智能合约。我们将从基础测试环境搭建开始,逐步实现加密状态变量的测试验证,帮助开发者掌握FHEVM的核心测试方法。
测试环境搭建
创建测试脚本
在项目test目录下创建FHECounter.ts
文件,内容如下:
import { FHECounter, FHECounter__factory } from "../types";
import { FhevmType } from "@fhevm/hardhat-plugin";
import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers";
import { expect } from "chai";
import { ethers, fhevm } from "hardhat";
type Signers = {
deployer: HardhatEthersSigner;
alice: HardhatEthersSigner;
bob: HardhatEthersSigner;
};
async function deployFixture() {
const factory = (await ethers.getContractFactory("FHECounter")) as FHECounter__factory;
const fheCounterContract = (await factory.deploy()) as FHECounter;
const fheCounterContractAddress = await fheCounterContract.getAddress();
return { fheCounterContract, fheCounterContractAddress };
}
describe("FHECounter", function () {
let signers: Signers;
let fheCounterContract: FHECounter;
let fheCounterContractAddress: string;
before(async function () {
const ethSigners: HardhatEthersSigner[] = await ethers.getSigners();
signers = { deployer: ethSigners[0], alice: ethSigners[1], bob: ethSigners[2] };
});
beforeEach(async () => {
({ fheCounterContract, fheCounterContractAddress } = await deployFixture());
});
it("should be deployed", async function () {
console.log(`FHECounter has been deployed at address ${fheCounterContractAddress}`);
expect(ethers.isAddress(fheCounterContractAddress)).to.eq(true);
});
});
与传统测试的区别
- 使用FHEVM兼容的智能合约
FHECounter
而非普通Counter
- 测试逻辑相同但支持加密计算
- 状态变量以加密形式存储和操作
基础测试验证
部署验证测试
运行测试命令:
npx hardhat test
预期输出:
FHECounter
FHECounter has been deployed at address 0x7553CB9124f974Ee475E5cE45482F90d5B6076BC
✔ should be deployed
1 passing (1ms)
加密状态变量测试
初始状态验证
it("encrypted count should be uninitialized after deployment", async function () {
const encryptedCount = await fheCounterContract.getCount();
expect(encryptedCount).to.eq(ethers.ZeroHash);
});
关键点:
encryptedCount
是十六进制字符串表示的FHEVM句柄- 初始值为
0x000...000
表示未初始化状态 - 底层逻辑上等同于明文0
加密操作测试
增量操作测试
it("increment the counter by 1", async function () {
// 验证初始状态
const encryptedCountBeforeInc = await fheCounterContract.getCount();
expect(encryptedCountBeforeInc).to.eq(ethers.ZeroHash);
const clearCountBeforeInc = 0;
// 加密操作数1
const clearOne = 1;
const encryptedOne = await fhevm
.createEncryptedInput(fheCounterContractAddress, signers.alice.address)
.add32(clearOne)
.encrypt();
// 执行增量操作
const tx = await fheCounterContract
.connect(signers.alice)
.increment(encryptedOne.handles[0], encryptedOne.inputProof);
await tx.wait();
// 验证结果
const encryptedCountAfterInc = await fheCounterContract.getCount();
const clearCountAfterInc = await fhevm.userDecryptEuint(
FhevmType.euint32,
encryptedCountAfterInc,
fheCounterContractAddress,
signers.alice,
);
expect(clearCountAfterInc).to.eq(clearCountBeforeInc + clearOne);
});
技术要点:
- 使用
createEncryptedInput
创建绑定到特定合约和用户的加密输入 - 增量操作需要提供加密值和零知识证明
- 使用
userDecryptEuint
解密结果验证
减量操作测试
it("decrement the counter by 1", async function () {
// 加密操作数1
const clearOne = 1;
const encryptedOne = await fhevm
.createEncryptedInput(fheCounterContractAddress, signers.alice.address)
.add32(clearOne)
.encrypt();
// 先增1
let tx = await fheCounterContract
.connect(signers.alice)
.increment(encryptedOne.handles[0], encryptedOne.inputProof);
await tx.wait();
// 再减1
tx = await fheCounterContract
.connect(signers.alice)
.decrement(encryptedOne.handles[0], encryptedOne.inputProof);
await tx.wait();
// 验证结果
const encryptedCountAfterDec = await fheCounterContract.getCount();
const clearCountAfterDec = await fhevm.userDecryptEuint(
FhevmType.euint32,
encryptedCountAfterDec,
fheCounterContractAddress,
signers.alice,
);
expect(clearCountAfterDec).to.eq(0);
});
安全机制解析
- 上下文绑定加密:加密值绑定到特定合约和用户,防止重用
- 零知识证明:验证加密输入的完整性和真实性
- 权限控制:通过
FHE.allow()
实现加密数据的访问控制
总结
通过本教程,您已经掌握了:
- FHEVM测试环境搭建方法
- 加密状态变量的初始化和验证
- 加密操作的执行和结果验证
- FHEVM的核心安全机制
这些知识为您开发更复杂的全同态加密智能合约奠定了坚实基础。下一步可以尝试部署到测试网络或探索更复杂的FHEVM功能。