本文的项目代码开源在这里。
全同态加密在区块链的应用
Zama的fhEVM近来正式在以太坊主网发布,并完成了第一笔机密USDT转账。这是一个标志性的事件,从此全同态加密在区块链有了新的应用。与EVM的整合意味着隐私保护是可编程控制,这可能会开启新的应用。
Zama官方提供了Relayer SDK,允许第三方dApp集成fhEVM的功能。所以有了这篇文章,尝试在以太坊Sepolia测试网络使用fhEVM构建一个转账金额和收款人保密的钱包。
创建项目
项目分为两部分:链上智能合约和前端。几乎所有的操作都在链上完成,所以目前没有后端服务。各部分代码以monorepo方式管理。其中:
frontend,dApp前端,与用户钱包和链上部署的智能合约交互,使用Relayer SDK;contracts,智能合约,使用fhEVM的Solidity库完成全同态密码操作,如金额加密、解密、扣减、增加等。
前端
前端页面部署在免费层级的Cloudflare Workers平台上。为保持简单,只使用了React和Vite框架,使用官方提供的模版创建项目:
$ pnpm create cloudflare@latest frontend --framework=react
.../19b9c386a6b-abd0 | +1 +
.../19b9c386a6b-abd0 | Progress: resolved 1, reused 0, downloaded 1, added 1, done
──────────────────────────────────────────────────────────────────────────────────────────────────────────
👋 Welcome to create-cloudflare v2.62.0!
🧡 Let's get started.
📊 Cloudflare collects telemetry about your usage of Create-Cloudflare.
Learn more at: https://github.com/cloudflare/workers-sdk/blob/main/packages/create-cloudflare/telemetry.md
──────────────────────────────────────────────────────────────────────────────────────────────────────────
╭ Create an application with Cloudflare Step 1 of 3
│
├ In which directory do you want to create your application?
│ dir ./frontend
│
├ What would you like to start with?
│ category Framework Starter
│
├ Which development framework do you want to use?
│ framework React
│
├ Select your deployment platform
│ platform Workers with Assets
│
├ Select a variant:
│ variant TypeScript + SWC
...
引入RainbowKit预构建的UI组件,通过Wagmi链接用户钱包,Sepolia链上操作通过Viem完成。
$ pnpm add @rainbow-me/rainbowkit wagmi viem引入Zama的Relayer SDK,并初始化。
$ pnpm add @zama-fhe/relayer-sdk智能合约
智能合约与fhEVM已经部署在Sepolia的合约交互,核心功能有:
- 符合ERC-7984标准的机密同质化代币,封装Sepolia上的USDC代币成机密代币;
- 支付网关合约,调用fhEVM的同态加密功能完成账户余额扣减、增加等操作。
fhEVM提供了Hardhat的项目模版(zama-ai/fhevm-hardhat-template)),可以直接点击“Use this template”创建新的项目。但在这里,我直接拉取项目模版的代码到本地,并放在contracts目录下。
如果使用了国内的npm镜像如npmmirrors,可能遇到报错“No matching version found for @nomicfoundation/slang@1.3.1 while fetching it from https://registry.npmmirror.com/”。此时需要临时切换成npm官方站:
$ pnpm i --registry https://registry.npmjs.org/编译合约代码:
$ pnpm compile
> fhevm-hardhat-template@0.3.0-3 compile /Users/chuck/Projects/astra-hetu/contracts
> cross-env TS_NODE_TRANSPILE_ONLY=true hardhat compile
Generating typings for: 30 artifacts in dir: types for target: ethers-v6
Successfully generated 106 typings!
Compiled 28 Solidity files successfully (evm target: cancun).
> fhevm-hardhat-template@0.3.0-3 postcompile /Users/chuck/Projects/astra-hetu/contracts
> npm run typechain
> fhevm-hardhat-template@0.3.0-3 typechain
> cross-env TS_NODE_TRANSPILE_ONLY=true hardhat typechain运行测试:
$ pnpm test
> fhevm-hardhat-template@0.3.0-3 test /Users/chuck/Projects/astra-hetu/contracts
> hardhat test
Compiled 1 Solidity file successfully (evm target: cancun).
Hetu Protocol
ConfidentialUSDCWrapper
Deployment
✔ should have correct name
✔ should have correct symbol
✔ should have correct underlying token
✔ should have 6 decimals matching USDC
✔ should have 1:1 conversion rate
Wrapping USDC → cUSDC
✔ should wrap USDC into cUSDC
✔ should create encrypted balance after wrap
✔ should decrypt to correct wrapped amount
✔ should allow wrapping to different recipient
✔ should revert on insufficient allowance
Confidential Transfers
✔ should transfer encrypted tokens between users (51ms)
HetuPaymentGateway
Deployment
✔ should set correct owner
...Hardhat默认的测试网络在内存中保存状态。也可以启动本地网络,更接近测试网络的运行情况。启动本地网络:
$ pnpm chain
> fhevm-hardhat-template@0.3.0-3 chain /Users/chuck/Projects/astra-hetu/contracts
> hardhat node --network hardhat --no-deploy
Started HTTP and WebSocket JSON-RPC server at http://127.0.0.1:8545/
Accounts
========
Account #0: 0xD8C83D1C163aF2A69d77deeba0FD97FDA1C3b041 (10000 ETH)
Account #1: 0x92bE91002Eb44086CCee18cAD8e112c5c0dE6baA (10000 ETH)
Account #2: 0x47749FC0E32D821451f433b4E1Bff951eE371473 (10000 ETH)
Account #3: 0x479BE9b5Db5eBc457C6C01bC42a74c1DfBEebf0F (10000 ETH)
Account #4: 0x74EcD30B4a054800c029449110Cf9aA389753E7F (10000 ETH)
Account #5: 0x3d896DFea5Bf023111e0d3469C3BF608a57668E6 (10000 ETH)
...本地网络启动后,打开另一个终端,并部署合约到本地网络:
$ pnpm deploy:localhost
> fhevm-hardhat-template@0.3.0-3 deploy:localhost /Users/chuck/Projects/astra-hetu/contracts
> hardhat deploy --network localhost
Nothing to compile
No need to generate any newer typings.
🌊 Hetu Deployment
Network: localhost
Deployer: 0xD8C83D1C163aF2A69d77deeba0FD97FDA1C3b041
📦 Deploying ConfidentialUSDCWrapper...
deploying "ConfidentialUSDCWrapper" (tx: 0x5de517bb16e55b2ff9e5a275ff5b9a799661f8536326f9b9785fa1bcafb3f238)...: deployed at 0x32103E46a0edb5F5F3509A532308755D0F6F3149 with 2102227 gas
✅ ConfidentialUSDCWrapper deployed at: 0x32103E46a0edb5F5F3509A532308755D0F6F3149
🚀 Deploying HetuPaymentGateway...
deploying "HetuPaymentGateway" (tx: 0x8d29e2542165bbac56bec708cfff15e37edf361ef364a0ef7d98faf62aa2ece9)...: deployed at 0xa3509686e6104DDf899CD06814109BbA573Bd2c3 with 2159134 gas
✅ Deployment Complete!
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
ConfidentialUSDCWrapper: 0x32103E46a0edb5F5F3509A532308755D0F6F3149
HetuPaymentGateway: 0xa3509686e6104DDf899CD06814109BbA573Bd2c3
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🔑 Update frontend/src/lib/contracts.ts with these addresses在本地网络上运行测试:
$ pnpm hardhat test --network localhost
Hetu Protocol
ConfidentialUSDCWrapper
Deployment
✔ should have correct name
✔ should have correct symbol
✔ should have correct underlying token
✔ should have 6 decimals matching USDC
✔ should have 1:1 conversion rate
Wrapping USDC → cUSDC
✔ should wrap USDC into cUSDC
✔ should create encrypted balance after wrap
✔ should decrypt to correct wrapped amount (47ms)
✔ should allow wrapping to different recipient
✔ should revert on insufficient allowance
Confidential Transfers
✔ should transfer encrypted tokens between users (59ms)
HetuPaymentGateway
Deployment
✔ should set correct owner
✔ should set correct default token
Send Payment
✔ should send encrypted payment
✔ should update payment count
✔ should revert when sending to self
✔ should revert when sending to zero address
...部署
部署分为两部分,其中智能合约需要实现部署,并记录部署的合约地址。在合约地址更新到前端代码后,在Cloudflare平台部署前端dApp。
智能合约
部署到Sepolia测试网络:
$ pnpm deploy:sepolia
> fhevm-hardhat-template@0.3.0-3 deploy:sepolia /Users/chuck/Projects/astra-hetu/contracts
> hardhat deploy --network sepolia
Generating typings for: 4 artifacts in dir: types for target: ethers-v6
Successfully generated 62 typings!
Compiled 3 Solidity files successfully (evm target: cancun).
🌊 Hetu Deployment
Network: sepolia
Deployer: 0xD8C83D1C163aF2A69d77deeba0FD97FDA1C3b041
📦 Deploying ConfidentialUSDCWrapper...
deploying "ConfidentialUSDCWrapper" (tx: 0x7a7432eab37a3b4afc255ec3bc2d8ca7706221dafa8e8be37d3f6675dd6738b3)...: deployed at 0xe6832A06dE93088Cd637ea35602075aEcD0f9998 with 2111934 gas
✅ ConfidentialUSDCWrapper deployed at: 0xe6832A06dE93088Cd637ea35602075aEcD0f9998
🚀 Deploying HetuPaymentGateway...
deploying "HetuPaymentGateway" (tx: 0x8837fe56694953a400a0a88684867f6561d56f06cd4363c18e49663da37c860a)...: deployed at 0xb49712B3BA9042168b2C35E84c9F5B2b561426CC with 2159112 gas
✅ Deployment Complete!
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
ConfidentialUSDCWrapper: 0xe6832A06dE93088Cd637ea35602075aEcD0f9998
HetuPaymentGateway: 0xb49712B3BA9042168b2C35E84c9F5B2b561426CC
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━直接运行pnpm test:sepolia会报错:“Cannot find a value for the configuration variable ‘ZAMA_FHEVM_API_KEY’”。这是因为fhEVM的Hardhat插件提供了Mock实现,并没有与Sepolia测试网络相关的代码。
验证合约代码:
$ pnpm verify:sepolia 0xe6832A06dE93088Cd637ea35602075aEcD0f9998 0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238 "Confidential USDC" "cUSDC" ""
> contracts@0.1.0 verify:sepolia /Users/chuck/Projects/astra-hetu/contracts
> hardhat verify --network sepolia 0xe6832A06dE93088Cd637ea35602075aEcD0f9998 0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238 'Confidential USDC' cUSDC ''
Successfully submitted source code for contract
contracts/ConfidentialUSDCWrapper.sol:ConfidentialUSDCWrapper at 0xe6832A06dE93088Cd637ea35602075aEcD0f9998
for verification on the block explorer. Waiting for verification result...
Successfully verified contract ConfidentialUSDCWrapper on the block explorer.
https://sepolia.etherscan.io/address/0xe6832A06dE93088Cd637ea35602075aEcD0f9998#code
The contract 0xe6832A06dE93088Cd637ea35602075aEcD0f9998 has already been verified on Sourcify.
https://repo.sourcify.dev/contracts/partial_match/11155111/0xe6832A06dE93088Cd637ea35602075aEcD0f9998/
$ pnpm verify:sepolia 0xb49712B3BA9042168b2C35E84c9F5B2b561426CC 0xe6832A06dE93088Cd637ea35602075aEcD0f9998
> contracts@0.1.0 verify:sepolia /Users/chuck/Projects/astra-hetu/contracts
> hardhat verify --network sepolia 0xb49712B3BA9042168b2C35E84c9F5B2b561426CC 0xe6832A06dE93088Cd637ea35602075aEcD0f9998
Successfully submitted source code for contract
contracts/HetuPaymentGateway.sol:HetuPaymentGateway at 0xb49712B3BA9042168b2C35E84c9F5B2b561426CC
for verification on the block explorer. Waiting for verification result...
Successfully verified contract HetuPaymentGateway on the block explorer.
https://sepolia.etherscan.io/address/0xb49712B3BA9042168b2C35E84c9F5B2b561426CC#code
The contract 0xb49712B3BA9042168b2C35E84c9F5B2b561426CC has already been verified on Sourcify.
https://repo.sourcify.dev/contracts/partial_match/11155111/0xb49712B3BA9042168b2C35E84c9F5B2b561426CC/dApp
记录下上面的两个地址:cUSDC代币合约地址0xe6832A06dE93088Cd637ea35602075aEcD0f9998和支付网关合约地址0xb49712B3BA9042168b2C35E84c9F5B2b561426CC。更新到frontend目录下的src/lib/contracts.ts中。
如果还没有Cloudflare账户,注册一个免费账户。创建新的Worker,并选择从GitHub代码库部署。相关的部署配置:
- 构建命令:
pnpm build - 部署命令:
pnpm dlx wrangler deploy - 目录:
/改成/frontend
如果遇到问题,寻找React+Vite在Cloudflare Workers上部署的方法。
测试项目
连接钱包
如果上面部署成功,登录Cloudflare Worker的页面,点击“login”后,选择Metamask等钱包后会弹出登录的签名页。

主要的流程如下:
- 把账户里的USDC封装成cUSDC代币,封装后的金额不再公开可见(如果没有USDC,需要找Sepolia水龙头获取测试USDC);
- 将cUSDC转账给任意地址,转账交易数据在区块上不公开;
- 接收到cUSDC后,可以选择解密,或继续持有待后续使用。