Starknet 上的私密转账与 ZK 凭证

这篇文章介绍了一个在Starknet上实现实用隐私的工具包,它结合了Tongo进行加密余额管理以及Garaga和Noir实现零知识证明的选择性披露。文章详细阐述了如何利用这套基础设施构建各种隐私保护应用,并提供了技术原理、设置指南和代码示例。

2026年1月27日

完成时间:30分钟 (Codespaces) 或 1小时 (本地设置)

TLDR. Starknet 上的隐私终于变得实用。Tongo 提供加密余额。Garaga + Noir 让你可以通过大约10行电路代码来证明有关私人数据的任意事实。基础设施处理了困难的部分。分叉此存储库并构建缺失的部分。


存储库地址:https://github.com/starknet-edu/starknet-privacy-toolkit

区块链隐私已被打破。每一次转账,每一次余额——永久可见。这对于去信任化是好事,但对于实际应用来说却是灾难性的。接下来是一个改变这一现状的工作工具包:具有选择性披露的私人转账。

我将其构建为一个捐赠徽章系统。但这种模式是通用的。年龄验证、信用评分、代币持有量、薪资证明。基础设施相同,约束条件不同。

代码和实时应用程序

  1. 存储库
  2. 实时应用程序
  3. Web UI 代码
  4. 证明 API 服务器
  5. Tongo 客户端
  6. 快速启动模板
  7. 最小代码片段
  8. Noir 电路
  9. Cairo 徽章合约

如果这对你有帮助,请给此存储库点星。

Gemini_Generated_Image_mcq002mcq002mcq0

已部署合约

  1. Verifier: 0x022b20...2669 on Sepolia
  2. Badge: 0x077ca6...7010 on Sepolia
  3. Tongo mainnet: 0x00b921...0a16 USDC
  4. Tongo Sepolia: 0x00f34d...5f8a STRK

最快的使用方法

gh repo fork starknet-edu/starknet-privacy-toolkit
git clone https://github.com/starknet-edu/starknet-privacy-toolkit.git
cursor starknet-privacy-toolkit

然后告诉AI你想要什么:“将这个捐赠徽章更改为验证信用评分高于700”或“使其证明某人已满18岁,但不透露其出生日期”。

电路有10行。合约有30行。其余的都是连接管道。你修改小的部分,连接管道保持不变。

1. 隐私问题

每一次转账、每一个余额、每一次交互。永久公开。这对于去信任化是好事,但对于隐私来说却是灾难性的。你无法向政治敏感的事业捐款而不被追踪。你无法私下支付敏感服务。你的整个财务生活都是一本打开的书。

零知识证明解决了这个问题。正如 Eli Ben-Sasson (StarkWare 联合创始人) 所说:“ZK 有两个超级能力:隐私和可扩展性。” 精妙之处在于:你可以证明有关数据的事实,而不泄露数据本身。“我至少捐赠了100美元”是可以证明的,而无需显示你实际捐赠了847美元。

两部分使这成为可能:

  1. Tongo 处理私人转账。你存入代币,它们被加密。你转账时,金额保持隐藏。只有你和收款人知道。

  2. ZK Credentials 让你能够证明有关你私人数据的事实。使用 Noir (电路语言)、Barretenberg (证明生成器) 和 Garaga (Starknet 验证器) 构建。

2. 你可以构建什么

捐赠徽章只是一个例子。同样的模式适用于任何你想在不泄露Y的情况下证明X的情况:

  1. 捐赠徽章:证明你捐赠金额超过阈值,隐藏具体金额。
  2. 信用评分:证明评分高于700,隐藏实际评分。
  3. 年龄验证:证明已满18岁,隐藏出生日期。
  4. 合格投资者:证明净资产超过100万,隐藏实际财富。
  5. 代币持有者:证明你持有超过100个代币,隐藏确切余额。
  6. 薪资证明:证明你年收入超过5万,隐藏实际薪资。

对于捐赠徽章的例子,我设置了三个等级:

  1. 青铜:十美元
  2. 白银:一百美元
  3. 黄金:一千美元

但同样,这只是一个实例化。基础设施才是关键。

3. ZK 证明的实际工作原理

让我来分解一下,因为一旦你看到它,它实际上非常优雅。

步骤 1:提交

你使用一个随机秘密将你的私人数据哈希:

commitment = Poseidon(private_data, secret)

这就像把一封信装进信封。每个人都能看到信封的存在,但没人能读到里面的内容。

这个承诺会记录在链上。它是公开的。但关键在于:哈希函数是单向的。没有人能从承诺中逆向工程出你的数据。如果你稍后揭示输入,他们可以验证承诺,但他们无法仅仅通过看到承诺就找出输入。

步骤 2:证明

现在是巧妙的部分。你在本地运行一个Prover。这需要大约30到60秒,并生成大约八KB的数据。这个证明说明:

  1. 我知道能哈希到那个承诺的值。
  2. 这些值满足一个约束,例如金额高于阈值。

美妙之处在于:证明丝毫没有揭示实际值。甚至没有一点暗示。它不是加密数据,理论上可以解密。它是一个完全不同的对象,它证明了知识,但没有传递知识。

如果承诺是密封的信封,那么证明就像是向保安出示腕带。你可以证明你被允许进入,而无需透露你的身份。

步骤 3:验证

智能合约检查证明。如果有效,你将获得凭证。合约得知该声明为真。它从不了解底层数据。

这是核心循环。其他一切都是实现细节。

4. ZK 流程

diagram-zk-pipeline

三个工具,各司其职。Noir 将约束编译成算术电路。Barretenberg 接收电路和私人输入并生成证明。Garaga 将证明转换为 Starknet calldata。正如 Starknet 博客 所解释的:“使用 Garaga,Noir 开发者可以将其程序编译为自动生成 Cairo 验证器,将其部署到 Starknet 上,并验证证明而无需编写任何 Cairo 代码。”

OpenZeppelin 简洁地指出:

“Noir 抽象了底层加密复杂性,允许开发者专注于逻辑而非电路优化。与 Circom 或 ZoKrates 等早期框架不同,Noir 利用类似 Rust 的语法和工具来减少样板代码和人为错误。”

OpenZeppelin, A Developer’s Guide to Building Safe Noir Circuits

一个陷阱:版本非常重要。这些工具紧密耦合。请务必使用这些特定版本,否则证明将失败:

  1. Noir: 1.0.0 beta 1
  2. Barretenberg: 0.67.0
  3. Garaga: 0.15.5

这不是一个错误。这是密码学。验证器是为特定的证明格式编译的。不同版本 = 不同格式 = 验证失败。

5. 设置

为什么选择 Codespaces:

  1. Noir、BB 和 Garaga 对操作系统版本和系统库很敏感。
  2. Codespaces 提供了一个与工具链匹配的干净 Linux 环境。
  3. 更少的本地设置意外意味着黑客更快上手。

分步说明:

  1. 在存储库上创建一个 GitHub Codespace。 codespace

  2. 安装工具链 ( setup-codespace.sh):

    chmod +x setup-codespace.sh
    ./setup-codespace.sh

codespaces-install

  1. 启动证明 API:

    source garaga-env/bin/activate
    bun run api

    你应该看到:Proof API running on http://localhost:3001

  2. 暴露 API 端口:

    1. 在 Codespaces 中,将端口 3001 设置为 Public,以便 Web UI 可以调用它。
  3. (可选) 在另一个终端启动 Web UI:

    bun run dev:web

    在浏览器中打开 5173 端口的 URL。

就是这样。一切都已安装。 如果脚本失败,请使用下面的手动安装步骤。

如果UI显示“Proof Server: Offline”:

  1. 确保在 Codespaces 中端口 3001Public
  2. 将你的 Codespaces URL (例如 https://your-codespace-3001.app.github.dev/) 粘贴到 UI 中的 Proof API URL 字段,然后点击 Save

5分钟内接下来要做什么

  1. 启动 API:运行 source garaga-env/bin/activate 然后 bun run api
  2. 启动 UI:bun run dev:web 并打开 5173 URL。
  3. 在步骤6中,粘贴你的 Codespaces URL,点击 Save,然后使用默认值(金额 150,秘密 12345678)生成一个证明。

proof

其他有用的脚本:bun run check:health (验证设置),bun run template:quickstart (运行最小示例),bun run tongo:init (初始化 Tongo 客户端)。

手动安装

如果你想在本地运行:

## Noir
curl -L https://noirup.dev | bash
source ~/.bashrc
noirup --version 1.0.0-beta.1

## Barretenberg
curl -L https://bbup.dev | bash
source ~/.bashrc
bbup --version 0.67.0
sudo apt-get install -y libc++-dev libc++abi-dev

## Garaga (needs Python 3.10 specifically)
sudo add-apt-repository ppa:deadsnakes/ppa -y
sudo apt-get install -y python3.10 python3.10-venv python3.10-dev
python3.10 -m venv garaga-env
source garaga-env/bin/activate
pip install garaga==0.15.5

## Bun
curl -fsSL https://bun.sh/install | bash

如果 noirup.dev 或 bbup.dev 失败,请改用这些镜像:

curl -fsSL https://raw.githubusercontent.com/noir-lang/noirup/main/install | bash
curl -fsSL https://raw.githubusercontent.com/AztecProtocol/aztec-packages/master/barretenberg/bbup/install | bash

验证你的版本:

nargo --version  # should say 1.0.0-beta.1
bb --version     # should say 0.67.0

6. 电路

这是捐赠徽章的完整 电路

use std::hash::poseidon::bn254::hash_2;

fn main(
    threshold: pub u64,
    commitment: pub Field,
    donation_amount: u64,
    donor_secret: Field
) {
    let computed = hash_2([donation_amount as Field, donor_secret]);
    assert(computed == commitment);
    assert(donation_amount >= threshold);
}

就是这样。10行。

pub 关键字表示“公开输入”。这些值对验证者可见。thresholdcommitment 是公开的。donation_amountdonor_secret 是私有的。它们用于生成证明,但永不透露。

两个断言:

  1. (金额, 秘密) 的哈希必须等于承诺
  2. 金额必须至少达到阈值

如果两者都通过,你将获得一个有效证明。如果任何一个失败,则没有证明。

这就是你针对不同用例进行修改的地方。 想要年龄验证?将 donation_amount >= threshold 更改为 birth_year <= current_year - 18。想要信用评分检查?将其更改为 credit_score >= 700。流程保持不变。

测试电路

cd zk-badges/donation_badge
nargo test

编译电路

电路配置在 Nargo.toml 中:

nargo compile

输出:target/donation_badge.json


7. 生成证明

让我们来看看实际的命令。

1. 计算你的承诺

使用 computecommitment.js

cd zk-badges
node computecommitment.js 15000 "mysecret123"
## Output: 0x1abc...def (your commitment)

2. 创建 prover.toml

用你在步骤1中实际的承诺替换占位符值:

threshold = "1000"
commitment = "0x..."  # paste your commitment from step 1
donation_amount = "15000"
donor_secret = "0x..."  # paste the hex of your secret

3. 生成证明

nargo execute witness

bb prove_ultra_keccak_honk \
  -b ./target/donation_badge.json \
  -w ./target/witness.gz \
  -o ./target/proof

bb write_vk_ultra_keccak_honk \
  -b ./target/donation_badge.json \
  -o ./target/vk

这需要30到60秒,具体取决于你的硬件。它正在进行真正的密码学,生成一个通过某些数学特性而不泄露输入的证明。

4. 转换为 calldata

garaga calldata \
  --system ultra_keccak_honk \
  --vk ./target/vk \
  --proof ./target/proof \
  --format starkli \
  > ../calldata.txt

或者直接使用 generate-proof.sh

./generate-proof.sh --amount 15000 --threshold 1000 --donor-secret "mysecret123" --tier 1

8. 智能合约

Garaga 会根据你的电路自动生成验证器合约。你可以在存储库中看到生成的 honk_verifier.cairo。你围绕它编写应用程序逻辑。

这是 徽章合约

##[starknet::contract]
mod DonationBadge {
    use starknet::ContractAddress;
    use starknet::get_caller_address;

    #[storage]
    struct Storage {
        verifier_address: ContractAddress,
        user_badges: LegacyMap<(ContractAddress, u8), bool>,
        user_max_tier: LegacyMap<ContractAddress, u8>,
        used_commitments: LegacyMap<u256, bool>,
    }

    #[external(v0)]
    fn claim_badge(
        ref self: ContractState,
        full_proof_with_hints: Span<felt252>,
        threshold: u256,
        donation_commitment: u256,
        badge_tier: u8
    ) -> bool {
        let caller = get_caller_address();

        // Prevent replay attacks
        assert(!self.used_commitments.read(donation_commitment), 'Used');

        // Can only upgrade, not downgrade
        assert(badge_tier > self.user_max_tier.read(caller), 'No upgrade');

        // Verify the proof
        let verifier = IUltraKeccakHonkVerifierDispatcher {
            contract_address: self.verifier_address.read()
        };
        assert(verifier.verify_ultra_keccak_honk_proof(full_proof_with_hints), 'Invalid');

        // Record the badge
        self.used_commitments.write(donation_commitment, true);
        self.user_badges.write((caller, badge_tier), true);
        self.user_max_tier.write(caller, badge_tier);

        true
    }
}

这里发生的关键事情:

  1. 重放保护:每个承诺只能使用一次。
  2. 仅可升级:你可以从青铜升级到白银再到黄金,但不能降级。
  3. 证明验证:委托给 Garaga 生成的验证器。

使用 Scarb 构建:scarb build


安全和审计

  1. Garaga 发布了一份 CryptoExperts 于 2025 年 6 月进行的审计报告,涵盖了核心密码原语和验证器逻辑。阅读安全页面和审计报告
  2. Barretenberg 是证明后端,已由 Veridise 审计。查看 Bigfield 审计
  3. Poseidon 哈希,用于电路中的承诺,是为 ZK 效率而设计的。原始论文报告称,其每消息位约束比 Pedersen 哈希在电路形式中少 8 倍。阅读论文

审计可以降低风险,但不能消除风险。始终检查版本并理解你所依赖的密码学假设。


9. 领取你的徽章

sncast --profile sepolia invoke \
  --contract-address 0x077ca6f2ee4624e51ed6ea6d5ca292889ca7437a0c887bf0d63f055f42ad7010 \
  --function claim_badge \
  --calldata $(cat calldata.txt) 1000 0xCOMMITMENT 1

检查你的徽章:

sncast --profile sepolia call \
  --contract-address 0x077ca6f2ee4624e51ed6ea6d5ca292889ca7437a0c887bf0d63f055f42ad7010 \
  --function get_badge_tier \
  --calldata 0xYOUR_ADDRESS

10. 常见错误

运行 健康检查 以诊断问题:bun run scripts/health-check.ts

  1. could not satisfy constraint:你的金额低于阈值。使用更高的金额或更低的阈值。
  2. Invalid proof:版本不匹配。运行 bb 并确认输出显示 0.67.0
  3. Commitment already used:此承诺之前已被领取。使用不同的秘密生成新的承诺。
  4. nargo: command not found:Noir 未安装。运行 noirup 并确认它安装了 1.0.0 beta 1 版本。
  5. bb: libc++.so.1 not found:缺少 C++ 运行时。安装 libc++ dev 包,然后重试。
  6. Garaga: Requires Python <3.11:Python 版本错误。使用带有 venv 模块的 python3.10。

11. Tongo:私有传输层

徽章证明你捐赠了足够的金额。但存在一个问题:如果捐赠本身是公开转账,那么你的隐私只得到了一半的保护。每个人仍然能看到你发送的确切金额。

Tongo 解决了这个问题。它是一个针对 Starknet 的私有转账协议。请参阅 tongo-client.tstongo-service.ts 中的完整集成。

一个重要的细节是:Tongo 无需设置。该协议的密码学依赖于 Stark 曲线上的离散对数假设,不需要可信设置有毒废物。这与依赖 CRS 的 SNARK 系统有很大不同。在此处阅读更多关于 Tongo 密码学的信息

工作原理

四个操作:

  1. Fund(存入)。将公共代币转换为加密余额。此步骤是公开的,人们会看到你存入了多少。
  2. Transfer(转账)。发送加密金额。金额和收款人对除收款人以外的所有人隐藏。
  3. Rollover(转存)。领取传入的转账。你的余额增加,但金额保持隐藏。
  4. Withdraw(提现)。转换回公共代币。此步骤也是公开的。

diagram-tongo-architecture

核心概念

  1. Tongo 私钥。一个256位的秘密。这并非你的钱包密钥。它是 Tongo 的一个单独密钥。丢失它,你就失去了你的资金。
  2. Tongo 公钥。从私钥派生。分享此密钥以接收转账。
  3. 加密余额。你的余额存储在链上但已加密。只有你可以阅读。
  4. 待定余额。传入的转账首先到达此处。你使用 Rollover 来领取它们。

生成密钥

请参阅 tongo-key-manager.ts 以获取完整实现:

const key = '0x' + crypto.randomBytes(32).toString('hex');

将其安全存储。这是访问你的 Tongo 资金的唯一方式。

隐私保障

理解这一点很重要:

Fund 是公开的。每个人都看到你存入了多少。这是不可避免的,因为代币必须来自某个地方。

Transfer 是私有的。金额和收款人隐藏。只有你和收款人知道。

Rollover 是私有的。你正在领取你的待定余额。金额保持隐藏。

Withdraw 是公开的。金额再次变得可见。

模式:公开 → 私有 → 私有 → 公开。你的隐私窗口在 fund 和 withdraw 之间。


12. 网页界面

Screenshot 2026-01-18 at 10

如果你不想使用命令行:

  1. 连接钱包 ( BraavosArgentX)
  2. 选择网络 (主网或 Sepolia)
  3. 资助你的 Tongo 余额
  4. 私密转账
  5. 领取你的徽章

证明生成发生在 后端服务器 上。确保它正在运行,UI 将显示连接状态。前端调用 badge-service.ts 来协调一切。 如果徽章面板显示“Proof Server: Offline”,请检查 Codespaces 中端口 3001 是否为公共,并将你的 Codespaces URL 粘贴到 UI 中的 Proof API URL 字段。

proof


13. 整合

Untitled-2025-02-24-1516

完整流程:

  1. Fund(存入):将代币存入 Tongo(公开入口,所有人可见)
  2. Transfer(转账):私密发送给收款人(金额隐藏)
  3. Prove(证明):生成 ZK 证明显示金额 > 阈值
  4. Claim(领取):在链上铸造徽章

世界看到的是:你存入了一定金额,你拥有一个徽章。他们看不到的是:你转账的确切金额,以及谁收到了它。


14. 实际受保护的内容

让我明确威胁模型。

受保护:

  1. 转账金额,在链上加密。
  2. 确切的捐赠金额,只透露阈值。
  3. 承诺绑定,你不能重复使用证明。

不受保护:

  1. 钱包地址,仍然公开。
  2. 交易时间,在链上可见。
  3. 徽章所有权,徽章本身是公开的。

如果你需要更强的隐私,请使用新的钱包,不要重复使用秘密,并在操作之间增加延迟。


15. 更广阔的图景

这个工具包是构建在 Starknet 上的更大隐私堆栈的一部分:

  1. 私有余额:Tongo,已上线。
  2. ZK 凭证:Garaga,已上线。
  3. 不可关联地址:隐形地址 (stealth addresses),即将推出。
  4. 交易混合:MIST.cash,正在开发中。

16. 资源

工具:

  1. Noir:电路语言
  2. Barretenberg:证明后端
  3. Garaga:Starknet 验证器
  4. 我们的电路:此存储库中的 Noir 代码

Tongo:

  1. Tongo:协议文档
  2. Tongo SDK:TypeScript 集成
  3. tongo-config.ts:此存储库中的网络配置

Starknet:

  1. Starknet:L2
  2. Cairo Book:合约语言
  3. Starknet Foundry:开发工具
  4. Voyager:区块浏览器

钱包:

  1. Braavos
  2. ArgentX

17. 构建你自己的应用

这是一个模板。分叉它。将其提供给你的LLM。构建你自己的东西。从包含最小示例的 模板文件夹 开始。 捐赠徽章只是一个实例。你应该分叉它并构建其他东西。

gh repo fork starknet-edu/starknet-privacy-toolkit
git clone https://github.com/starknet-edu/starknet-privacy-toolkit.git
cursor starknet-privacy-toolkit

告诉 AI:

  1. “将此更改为验证用户已满18岁”
  2. “调整电路以进行信用评分验证”
  3. “创建一个代币门控会员证明”
  4. “为贷款申请构建薪资验证”

电路有10行。合约有30行。基础设施处理了困难的部分。

想法:

  1. 受年龄限制内容的年龄验证
  2. DeFi 借贷的信用评分证明
  3. 代币销售的合格投资者验证
  4. 不泄露持有量的代币门控访问
  5. 公寓租赁的薪资验证
  6. DAO 会员证明
  7. 私有投票系统
  8. 匿名举报人凭证

原语已在此处。私人转账可行。ZK 凭证可行。现在用它们构建一些有用的东西。系好安全带。

Omar Espejel · X · GitHub

2

  • 原文链接: espejel.bearblog.dev/sta...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
espejel.beardev
espejel.beardev
江湖只有他的大名,没有他的介绍。