# 在 Starknet 上隐私验证 zk-SNARK:零知识的低成本魔法 **Published by:** [Starknet 中文](https://paragraph.com/@starknet-zh/) **Published on:** 2024-12-05 **URL:** https://paragraph.com/@starknet-zh/starknet-zk-snark ## Content 原文:Zero-Knowledge Magic for Cheap 翻译及校对:Starknet 中文社区 📑 转载请注明出处 🕹️ 你来到了俱乐部,但忘带了身份证,安保人员们正盯着你看。 如果你能在不透露太多信息的情况下证明自己的年龄就好了。 这正是零知识证明的作用所在。 精选速览 现在,你可以通过 Starknet 来验证 zk-SNARK 了。 Starknet 是发布零知识证明的最经济的方式¹。 赚取收益?这个「消息」由本文独家提供。 零知识入门包 🎒 我们需要三种关键成分。 Starknet 就像一条超级强大的高速公路,复杂的智能合约可以在这里以低成本的价格快速运行。你们可以把 Starknet 看作是以太坊的一个速度飞快的「亲戚」。 Circom² 是你所在社区的证明生成器。它允许开发者编写程序,隐藏部分输入信息。 Garaga 是 Starknet 的证明检查器。就像一个非常精密的安保人员,能够直接在 Starknet 上验证数学证明。 整个过程是如何协同工作的 🔄 首先,我们需要用一种支持零知识证明的编程语言编写我们想要检查的计算。这类语言允许指定私密输入,并能够编译成我们所称之为 zk 电路的形式。 作为黑匣子的 ZK 电路 接下来,我们需要选择一个框架来生成和验证证明,具体取决于你是只需要本地验证,还是希望将证明发布到链上,供所有人查看。 整个流程如下: 🧑‍💻 编写代码并编译你的 zk 电路 🧮 证明:生成一个证明 🏗️ 在链上部署验证器 ✅ 验证:在链上发布并验证证明 如果你想保持神秘感,请不要继续往下读。🙈 一步一步来 (Cairo) ✨ 第一步:创建你的电路 pragma circom 2.0.7; include "../../node_modules/circomlib/circuits/comparators.circom"; include "../../node_modules/circomlib/circuits/poseidon.circom"; template Auth() { signal input password; signal input hash; signal output out; component hasher = Poseidon(1); hasher.inputs[0] <== password; // Add the hash to output for testing out <== hasher.out; component eq = IsEqual(); eq.in[0] <== hasher.out; eq.in[1] <== hash; 1 === eq.out; } component main {public [hash]}= Auth(); 这个 Circom 程序通过将密码与其 Poseidon 哈希值进行比对来验证某人是否知道密码。 额外加分:尝试在 zkrepl.dev 上实现,点击此处生成 Poseidon 哈希值。 编译完成后,你将获得一个私有证明密钥和一个验证密钥。 现在,给定一个私密输入, { "password": "0x476172616761526f636b73", "hash": "137293068078....58724960716461" } 你可以使用证明密钥在你的机器上生成一个证明: 格式为 groth16 的证明文件 proof.json 文件中包含的所有公共输入 public.json 技术细节:*也可使用 zkrepl.dev 生成证明。此外,你还可以通过 Git 复制此仓库,使用 *snarkjs 框架在本地生成证明。 现在,零知识魔法确保了两件事: 任何人都可以验证这个证明,并确信你知道密码 任何人都无法通过查看该证明得知密码⁴。 第二步:使用 Garaga 编写验证器 现在我们已经有了 proof.json,让我们在 Starknet 上部署一个验证器,发布证明供所有人查看。 1. 首先,Garaga 可以自动生成一个适用于你电路的 Starknet 验证器合约。我们只需要与编译电路绑定的验证密钥: garaga gen --system groth16 -vk verification_key.json 2. 声明验证器,暂时无需部署,你可以使用: starkli declare target/dev/verifier.contract_class.json 3. 使用合约中的验证器来处理证明。 fn verify_login(proof: Span<felt252>) { // Get the caller let caller = get_contract_address(); // Get the verifier implementation let class_hash = self.verifier_class.read(); let garaga_verifier = IVerifierLibraryDispatcher { class_hash }; // Check the proof let result = garaga_verifier.verify_groth16_proof_bn254(proof); assert!(result.is_some(), "invalid proof"); let expected_hash = *result.unwrap()[0]; assert(self.hash.read(caller) == expected_hash, "Wrong authentication") } 4. 使用 Garaga CLI 发布证明,生成交易数据并通过 starkli 发送交易。 garaga calldata --system groth16 \ --vk verification_key.json \ --proof proof.json \ --public-inputs public.json 等一下?!🫴 我们并没有解决最初的「我已经超过21岁了」这个问题,对吧? 确实如此,但我们证明了两件事: 零知识应用的难点在于编写验证电路。 一切皆有可能。你可以使用 OpenPassport 私密地访问公民的出生日期,或者直接使用它们的 API 来创建证明,免去繁琐步骤。 Starknet 的费用和 Garaga 的先进优化技术使得这一切的成本变得很低。 费用表如下: 部署:约 5 美元 链上证明验证:小于 1 美元 来挑战吗,兄弟?🤺 准备好练习了吗?证明你的能力并获得奖励。 通过将你的 Starknet 地址的因式分解 ZK 证明发送到这个合约,证明你能够分解整数:挑战合约 你必须提供一组包含 32 个整数的列表,这些整数相乘等于你的地址。 例如,如果你的地址是 0x31337,即十进制的 201527, 可能的因子包括 1、137、1471、201527。 一个有效的输入示例是:[201527, 1, 1, 1, 1, …, 1](31 个 1) 因子越多,得分和奖励就越高。 1 的因子不算在内,请将你的输入格式化为一个包含 32 个整数的数组。 查看 zk-mint 仓库,获取更多关于如何生成和发布证明的线索。 如果你成功解决了,记得来 https://x .com/tek_kac 发推分享哦 :) 脚注: [¹] 这里的「最便宜的」的意思是指,这是据我所知,请不要引用我这句话。 [²] 我们使用 Circom,但其他 zk-DSL³ 也能通过 Garaga 处理:如 Gnark 或 Risc0。 [³] zk-DSL:零知识领域特定语言。 [⁴] 相信我,现在数学证明不适合放在这个脚注里。 ## Publication Information - [Starknet 中文](https://paragraph.com/@starknet-zh/): Publication homepage - [All Posts](https://paragraph.com/@starknet-zh/): More posts from this publication - [RSS Feed](https://api.paragraph.com/blogs/rss/@starknet-zh): Subscribe to updates - [Twitter](https://twitter.com/StarkNet_ZH): Follow on Twitter