Aztec 与隐私 L2
Aztec 架构、private/public state 双模型、note encryption、PXE
日期: 2026-12-23 方向: ZK工程 / 电路开发 阶段: Phase 4 - ZK电路开发实战 (Day 223-243) 标签: #ZK #Aztec #Noir #privacy-L2 #UltraPlonk
今日目标
| 类型 | 内容 |
|---|---|
| 学习 | Aztec 架构、private/public state 双模型、note encryption、PXE |
| 实操 | 研究 Aztec mainnet 设计,对比 Tornado/zkSync |
| 产出 | aztec.md(架构 + 编程模型 + 真实数据) |
背景
Aztec 是什么?/ What is Aztec?
由 Aztec Labs(Joe Andrews, Zac Williamson 等,前身是 zk.money / Aztec Connect)开发的 隐私 L2。
- 与 zkSync/Scroll 不同:Aztec 不是 zkEVM,是全新隐私优先 VM (AVM)
- 编程语言:Noir(Rust-like,今天复习)
- proof system:UltraPlonk(Barretenberg backend)+ Honk(新一代)
- 主网代号 "Aztec Network" 计划 2025 上线(截至 2026 已稳定运行)
关键创新:
- 每个合约可以同时有 private state 和 public state
- 用户可以 prove 状态变化(private functions)而不暴露具体值
- public state 类似 EVM (sequencer 处理)
- private state 是 note-based(类似 Zcash UTXO + 智能合约)
Aztec 架构图
USER (Browser)
│
│ executes private functions LOCALLY
│ - reads encrypted notes from PXE
│ - generates proof
│ - emits encrypted log + nullifier
│
▼
┌────────────────────┐
│ PXE (Private eXec │
│ Environment) │
│ - per-user wallet │
│ - note storage │
│ - prover │
└─────────┬──────────┘
│
│ tx = (
│ privateProof,
│ publicCallStack,
│ nullifiers[],
│ newNoteHashes[],
│ encryptedLogs[]
│ )
▼
┌────────────────────┐
│ Sequencer (L2) │
│ - aggregates txs │
│ - executes pub fn │
│ - generates rollup│
│ proof │
└─────────┬──────────┘
│
▼
┌────────────────────┐
│ L1 (Ethereum) │
│ - verifies rollup │
│ - state trees │
│ - DA via blob │
└────────────────────┘
Private/Public Dual State Model
Private state — Notes (UTXO model)
// Aztec 合约示例
contract PrivateToken {
use dep::aztec::prelude::*;
storage {
balances: Map<AztecAddress, PrivateMutable<BalanceNote>>,
// ↑ 每个地址的 balance 是一组私有 notes
total_supply: PublicMutable<Field>, // 公开总量
}
#[private]
fn transfer(to: AztecAddress, amount: Field) {
let from = context.msg_sender();
// read existing notes (sum)
let mut from_balance = storage.balances.at(from).read();
assert(from_balance >= amount);
// create new note for `to` with amount
let new_note_to = BalanceNote::new(amount, to);
storage.balances.at(to).insert(new_note_to);
// burn old notes (nullifier emitted)
// create change note for `from`
let change_note = BalanceNote::new(from_balance - amount, from);
storage.balances.at(from).replace(change_note);
}
#[public]
fn mint(amount: Field) {
storage.total_supply.write(storage.total_supply.read() + amount);
}
}
关键概念:
#[private]函数在 PXE(用户浏览器)中执行 + ZK prove#[public]函数在 sequencer 上执行(类似 EVM)Note是私有 state 的最小单元,每次 transfer 销毁旧 note + 创建新 note(UTXO-style)- 只有 nullifier 和 new note hash 上链,amount/from/to 加密
Note 数据结构
struct BalanceNote {
amount: Field,
owner: AztecAddress,
randomness: Field, // for hiding
}
note_hash = Poseidon(amount, owner, randomness, ...)
nullifier = Poseidon(note_hash, ownerSecret)
note_hash 进入全局 note merkle tree(深度 ~32)。 spent 时 emit nullifier,进入 nullifier set 防双花。
PXE:Private eXecution Environment
PXE 是用户私钥 + note storage + prover 的本地环境,类似「ZK 钱包」:
┌─────────── PXE ──────────────┐
│ │
│ ┌─────────┐ ┌─────────┐ │
│ │ Account │ │ Notes │ │
│ │ Keys │ │ DB │ │
│ └─────────┘ └─────────┘ │
│ │
│ ┌────────────────────┐ │
│ │ ACIR Simulator │ │
│ │ (run private fn) │ │
│ └────────────────────┘ │
│ │
│ ┌────────────────────┐ │
│ │ Prover │ │
│ │ (Barretenberg) │ │
│ └────────────────────┘ │
└────────────────────────────────┘
PXE 与 Aztec 节点同步:
- 订阅每个 block 的 encryptedLogs
- 用用户的 view key 解密自己的 notes
- 把解密后的 notes 存本地 DB
- 用户发起 private fn 时,从 DB 找 notes、生成 proof
类比 Tornado Cash 但更通用:
- Tornado: 全局只有 1 种 note (1 ETH),所有人共享 tree
- Aztec: 任何合约可以定义任何 note schema,每个用户私有的 notes
tx 生命周期 / Tx Lifecycle
1. User clicks "transfer 10 tokens to Bob"
↓
2. PXE simulates the private function call locally
- reads notes for Alice's balance
- calculates new state
- prepares: { nullifiers, newNotes, publicCalls, encryptedLogs }
↓
3. PXE generates ZK proof (UltraPlonk)
- proves: "I correctly executed this Aztec contract's private fn,
given valid input notes, producing these nullifiers and new notes"
↓
4. Tx submitted to Aztec sequencer
- sequencer adds to mempool
- aggregates with other txs
↓
5. Sequencer builds rollup
- executes #[public] functions sequentially (like EVM)
- aggregates private proofs into rollup proof (recursion)
↓
6. L1 commitment
- rollup proof verified on L1
- state trees (note tree, nullifier tree, public tree) updated
Aztec vs 其他隐私方案
| 维度 | Tornado Cash | Aztec | zkSync Era | Solana SPL |
|---|---|---|---|---|
| 隐私范围 | 单一 mixer | 全部 state | 无(公开) | 无 |
| 编程模型 | 单一合约 | 智能合约 + private fn | 智能合约(公开) | 智能合约(公开) |
| 用户钱包 | 普通 | PXE(重) | 普通 | 普通 |
| 监管接口 | 无 | View keys 可披露 | 链上公开 | 链上公开 |
| 性能(tps) | 单 tx ~10 sec | TBD(~10 tps 私有 fn) | 30+ | 50+ |
真实数据(计划/早期)
| 指标 | 数值 |
|---|---|
| L1 Rollup contract | Aztec L1 contract(mainnet 上线后公布) |
| Test net (Sandbox) | aztec-sandbox docker image |
| Single private fn proof | ~5-30 sec on consumer hardware |
| Recursion depth | 多层(private → tx → block → root rollup) |
| Final L1 proof | UltraHonk wrapped, ~3-5 KB |
| Verify gas | ~600k |
关键合约 / Aztec Connect 历史
Aztec Connect(2022-2023)是 Aztec 的前身,基于 Aztec V2:
- L1 合约:
0xff1F2B4ADb9dF6FC8eAFe4D9088dB73E50EaD81f(RollupProcessor) - 累计 TVL:~$50M
- 关键 bridge: zkETH, AAVE-stETH, Element fixed yield
- 2023-03 关闭(团队转向 Aztec V3 主网)
V3("Aztec Network")从零重构,使用 Noir + UltraPlonk + AVM(取代 V2 的固定电路)。
安全考虑 / Security Considerations
View Keys 与监管接口
每个 Aztec 账户可以生成 view key(subkey):
- 持有 view key 可以解密 notes(但不能花)
- 可披露给:自己、税务、机构托管、监管者
- 这是 Aztec 区别于 Tornado 的关键合规特性
Nullifier 唯一性
如同 Tornado,nullifier 防双花。Aztec 维护全局 nullifier merkle tree。
- nullifier 派生自 note + secret
- 每个 note 至多一次 nullifier 提交
Private fn underconstrained 风险
合约开发者写 Noir 时容易出错(同 Day 228)。Aztec 标准库提供 helper macros 减少错误,但 audit 仍重要。
PXE 信任假设
PXE 持有用户私钥 + note 数据。如果 PXE 被入侵:
- 私钥泄露 → 资产可被盗
- note 数据泄露 → 历史隐私丢失
- mitigations: hardware wallet、Apple Secure Enclave 集成
真实开发体验 / DX Notes
# 启动 sandbox
npx @aztec/aztec-sandbox
# 写合约
mkdir my_contract && cd my_contract
aztec-cli new my-contract
# 写 src/main.nr
aztec-cli compile
# 部署
aztec-cli deploy --rpc-url http://localhost:8080 my_contract.json
# 调用 private fn
aztec-cli send transfer --args "$BOB" 100 --contract $ADDR
约束统计:
$ aztec-cli compile --info
PrivateToken::transfer
acir_size: 12,500
brillig_size: 5,200
expected_prove_time: ~3 sec
Aztec 适合什么场景?
✅ 合适:
- 私有 DEX(隐藏订单 + size)
- 隐私支付(工资、补贴)
- 隐私身份(KYC 后选择性披露)
- 私有 voting / governance
- 私有 lending(不暴露借贷头寸)
❌ 不适合:
- 高频公开交易(DEX 公开 orderbook)
- 必须公开的应用(透明拍卖、公开 NFT 市场)
- 状态依赖大量公开数据的(如 oracle 重应用)
关键速查
[Aztec contract anatomy]
storage — Map<key, PrivateMutable | PublicMutable>
#[private] fn — runs in PXE, generates proof
#[public] fn — runs in sequencer, like EVM
notes — UTXO-style private state units
nullifier — derived from note, prevents double-spend
[Comparing Cs]
Confidentiality (state): Aztec ✓, zkSync ✗
Compatibility (Solidity): Aztec ✗, zkSync ✓ (with zksolc)
Cost (gas): similar (~30× cheaper than L1)
Composability (cross-fn): Aztec async, zkSync sync
面试题
-
Q: Aztec 和 Tornado Cash 的核心区别? A: Tornado 是单一应用(混币器),所有用户共享 1 棵 Merkle tree。Aztec 是通用隐私 VM:任何 dApp 可以定义自己的 private state(note schema)、private fn,并组合调用其他合约。Aztec 是 Tornado 的「智能合约化 + 通用化」。
-
Q: 为什么 Aztec 用 Noir + UltraPlonk 而不是 EVM + Halo2? A: 隐私要求 user-side prove,需要简洁、类型安全的 DSL(Noir 比 Solidity + Halo2 简单 10×)。UltraPlonk 提供 lookup + recursion,且 universal setup 适合用户频繁生成 proof。EVM bytecode 在 ZK 中代价高,Aztec 用自定义 AVM 性能更好。
-
Q: PXE 是什么?为什么需要它? A: PXE = Private eXecution Environment。每个用户本地运行一个 PXE:存私钥、解密的 notes、运行 private fn 模拟器、生成 ZK proof。需要它是因为:(a) 私有 state 不能公开存(必须用户本地);(b) 私有 fn 必须在 user-side prove(不能让 sequencer 看明文)。
-
Q: Aztec 的合规接口(view keys)如何工作? A: 每个账户有 master key 派生 spend key + view key。view key 解密 notes(看到 amount/from/to)但不能 sign tx。用户可主动披露 view key 给:审计、监管、税务、机构。这让 Aztec 不被简单划为「全黑」隐私协议。
明日预告
Day 237 — Week 35 复习:ZK 应用全景。把身份、投票、游戏、隐私 L2 等全部应用整合成一张 map。