Skip to content
•5 分钟阅读•0次浏览

基于fhEVM构建支持隐私交易的加密货币钱包

fhEVM隐私区块链协议
TLDR

本文的项目代码开源在这里。

全同态加密在区块链的应用

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
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
fhEVM的Hardhat插件不支持在Sepolia测试网络测试

直接运行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等钱包后会弹出登录的签名页。

主要的流程如下:

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