这篇文章介绍了一个在Starknet上实现实用隐私的工具包,它结合了Tongo进行加密余额管理以及Garaga和Noir实现零知识证明的选择性披露。文章详细阐述了如何利用这套基础设施构建各种隐私保护应用,并提供了技术原理、设置指南和代码示例。
2026年1月27日
完成时间:30分钟 (Codespaces) 或 1小时 (本地设置)
TLDR. Starknet 上的隐私终于变得实用。Tongo 提供加密余额。Garaga + Noir 让你可以通过大约10行电路代码来证明有关私人数据的任意事实。基础设施处理了困难的部分。分叉此存储库并构建缺失的部分。
存储库地址:https://github.com/starknet-edu/starknet-privacy-toolkit
区块链隐私已被打破。每一次转账,每一次余额——永久可见。这对于去信任化是好事,但对于实际应用来说却是灾难性的。接下来是一个改变这一现状的工作工具包:具有选择性披露的私人转账。
我将其构建为一个捐赠徽章系统。但这种模式是通用的。年龄验证、信用评分、代币持有量、薪资证明。基础设施相同,约束条件不同。
如果这对你有帮助,请给此存储库点星。

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行。其余的都是连接管道。你修改小的部分,连接管道保持不变。
每一次转账、每一个余额、每一次交互。永久公开。这对于去信任化是好事,但对于隐私来说却是灾难性的。你无法向政治敏感的事业捐款而不被追踪。你无法私下支付敏感服务。你的整个财务生活都是一本打开的书。
零知识证明解决了这个问题。正如 Eli Ben-Sasson (StarkWare 联合创始人) 所说:“ZK 有两个超级能力:隐私和可扩展性。” 精妙之处在于:你可以证明有关数据的事实,而不泄露数据本身。“我至少捐赠了100美元”是可以证明的,而无需显示你实际捐赠了847美元。
两部分使这成为可能:
Tongo 处理私人转账。你存入代币,它们被加密。你转账时,金额保持隐藏。只有你和收款人知道。
ZK Credentials 让你能够证明有关你私人数据的事实。使用 Noir (电路语言)、Barretenberg (证明生成器) 和 Garaga (Starknet 验证器) 构建。
捐赠徽章只是一个例子。同样的模式适用于任何你想在不泄露Y的情况下证明X的情况:
对于捐赠徽章的例子,我设置了三个等级:
但同样,这只是一个实例化。基础设施才是关键。
让我来分解一下,因为一旦你看到它,它实际上非常优雅。
你使用一个随机秘密将你的私人数据哈希:
commitment = Poseidon(private_data, secret)
这就像把一封信装进信封。每个人都能看到信封的存在,但没人能读到里面的内容。
这个承诺会记录在链上。它是公开的。但关键在于:哈希函数是单向的。没有人能从承诺中逆向工程出你的数据。如果你稍后揭示输入,他们可以验证承诺,但他们无法仅仅通过看到承诺就找出输入。
现在是巧妙的部分。你在本地运行一个Prover。这需要大约30到60秒,并生成大约八KB的数据。这个证明说明:
美妙之处在于:证明丝毫没有揭示实际值。甚至没有一点暗示。它不是加密数据,理论上可以解密。它是一个完全不同的对象,它证明了知识,但没有传递知识。
如果承诺是密封的信封,那么证明就像是向保安出示腕带。你可以证明你被允许进入,而无需透露你的身份。
智能合约检查证明。如果有效,你将获得凭证。合约得知该声明为真。它从不了解底层数据。
这是核心循环。其他一切都是实现细节。

三个工具,各司其职。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
一个陷阱:版本非常重要。这些工具紧密耦合。请务必使用这些特定版本,否则证明将失败:
这不是一个错误。这是密码学。验证器是为特定的证明格式编译的。不同版本 = 不同格式 = 验证失败。
为什么选择 Codespaces:
分步说明:
在存储库上创建一个 GitHub Codespace。

安装工具链 ( setup-codespace.sh):
chmod +x setup-codespace.sh
./setup-codespace.sh

启动证明 API:
source garaga-env/bin/activate
bun run api
你应该看到:Proof API running on http://localhost:3001
暴露 API 端口:
3001 设置为 Public,以便 Web UI 可以调用它。(可选) 在另一个终端启动 Web UI:
bun run dev:web
在浏览器中打开 5173 端口的 URL。
就是这样。一切都已安装。 如果脚本失败,请使用下面的手动安装步骤。
如果UI显示“Proof Server: Offline”:
3001 是 Public。https://your-codespace-3001.app.github.dev/) 粘贴到 UI 中的 Proof API URL 字段,然后点击 Save。source garaga-env/bin/activate 然后 bun run apibun run dev:web 并打开 5173 URL。150,秘密 12345678)生成一个证明。
其他有用的脚本: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
这是捐赠徽章的完整 电路:
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 关键字表示“公开输入”。这些值对验证者可见。threshold 和 commitment 是公开的。donation_amount 和 donor_secret 是私有的。它们用于生成证明,但永不透露。
两个断言:
如果两者都通过,你将获得一个有效证明。如果任何一个失败,则没有证明。
这就是你针对不同用例进行修改的地方。 想要年龄验证?将 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
让我们来看看实际的命令。
cd zk-badges
node computecommitment.js 15000 "mysecret123"
## Output: 0x1abc...def (your commitment)
用你在步骤1中实际的承诺替换占位符值:
threshold = "1000"
commitment = "0x..." # paste your commitment from step 1
donation_amount = "15000"
donor_secret = "0x..." # paste the hex of your secret
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秒,具体取决于你的硬件。它正在进行真正的密码学,生成一个通过某些数学特性而不泄露输入的证明。
garaga calldata \
--system ultra_keccak_honk \
--vk ./target/vk \
--proof ./target/proof \
--format starkli \
> ../calldata.txt
./generate-proof.sh --amount 15000 --threshold 1000 --donor-secret "mysecret123" --tier 1
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
}
}
这里发生的关键事情:
使用 Scarb 构建:scarb build
审计可以降低风险,但不能消除风险。始终检查版本并理解你所依赖的密码学假设。
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
运行 健康检查 以诊断问题:bun run scripts/health-check.ts
could not satisfy constraint:你的金额低于阈值。使用更高的金额或更低的阈值。Invalid proof:版本不匹配。运行 bb 并确认输出显示 0.67.0。Commitment already used:此承诺之前已被领取。使用不同的秘密生成新的承诺。nargo: command not found:Noir 未安装。运行 noirup 并确认它安装了 1.0.0 beta 1 版本。bb: libc++.so.1 not found:缺少 C++ 运行时。安装 libc++ dev 包,然后重试。Garaga: Requires Python <3.11:Python 版本错误。使用带有 venv 模块的 python3.10。徽章证明你捐赠了足够的金额。但存在一个问题:如果捐赠本身是公开转账,那么你的隐私只得到了一半的保护。每个人仍然能看到你发送的确切金额。
Tongo 解决了这个问题。它是一个针对 Starknet 的私有转账协议。请参阅 tongo-client.ts 和 tongo-service.ts 中的完整集成。
一个重要的细节是:Tongo 无需设置。该协议的密码学依赖于 Stark 曲线上的离散对数假设,不需要可信设置或有毒废物。这与依赖 CRS 的 SNARK 系统有很大不同。在此处阅读更多关于 Tongo 密码学的信息。
四个操作:

请参阅 tongo-key-manager.ts 以获取完整实现:
const key = '0x' + crypto.randomBytes(32).toString('hex');
将其安全存储。这是访问你的 Tongo 资金的唯一方式。
理解这一点很重要:
Fund 是公开的。每个人都看到你存入了多少。这是不可避免的,因为代币必须来自某个地方。
Transfer 是私有的。金额和收款人隐藏。只有你和收款人知道。
Rollover 是私有的。你正在领取你的待定余额。金额保持隐藏。
Withdraw 是公开的。金额再次变得可见。
模式:公开 → 私有 → 私有 → 公开。你的隐私窗口在 fund 和 withdraw 之间。

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


完整流程:
世界看到的是:你存入了一定金额,你拥有一个徽章。他们看不到的是:你转账的确切金额,以及谁收到了它。
让我明确威胁模型。
受保护:
不受保护:
如果你需要更强的隐私,请使用新的钱包,不要重复使用秘密,并在操作之间增加延迟。
这个工具包是构建在 Starknet 上的更大隐私堆栈的一部分:
工具:
Tongo:
Starknet:
钱包:
这是一个模板。分叉它。将其提供给你的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:
电路有10行。合约有30行。基础设施处理了困难的部分。
想法:
原语已在此处。私人转账可行。ZK 凭证可行。现在用它们构建一些有用的东西。系好安全带。
2
- 原文链接: espejel.bearblog.dev/sta...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!