初学指南: 使用 Risc0 创建你的第一个 ZK 项目

  • RISC0 Fans
  • 更新于 2024-06-22 22:22
  • 阅读 200

使用 Risc0 创建你的第一个 ZK 项目

原作者:Luffy Sama 于 2023/10/06

太长不看版

通过本文,你将拥有在 Risc0 中使用零知识证明的实际经验。不需要高级数学或密码学背景。我们将专注于编码基础,以开始构建现实世界的解决方案。本次动手介绍旨在使强大的隐私技术让任何开发人员都易于理解。

 Creating Your First ZK Project Using Risc0: A Guide for Beginners

介绍

零知识证明实现了私密、安全的交易。通过 zkSNARKs 和 zkSTARKs,证明者可以在不透露实际数据的情况下向验证者证明其拥有某些信息。

这对匿名性和保密性具有巨大潜力。但 zkSTARKs 和 zkSNARKs 很复杂。Risc0 使它们更易于访问。让我们看看它的基本实现:

本教程将涵盖:

  • 安装 Risc0

  • 使用 Rust 编写你的第一个零知识证明程序

先决条件:

  • 所需安装:

    • Rust 语言
    • Cargo crate
  • 一些基本的 Rust 编码知识

  • 代码编辑器(尽可能使用 VSCODE)

到最后,你将拥有在 Risc0 中使用零知识证明的实际经验。不需要高级数学或密码学背景。

我们将专注于编码基础,以开始构建现实世界的解决方案。本次动手介绍旨在使强大的隐私技术对任何开发人员都易于理解。

安装

  • (对于 MacOS)要安装 rust 和 cargo,可以在终端中运行以下命令:

    curl [https://sh.rustup.rs](https://sh.rustup.rs/) -sSf | sh

  • 要安装 Risc0,在安装 rust 并重启终端后运行以下命令:

    cargo install cargo-risczero

  • 为了成功构建上述命令,你需要安装所需的依赖项。brew install openssl brew install pkgconf

  • 接下来,我们需要安装 risc0 工具链:cargo risczero install

这就是我们所需要的。所以,让我们进入代码编辑器。

写一些神奇的代码:

现在我们已经完成了安装,你可以阅读并按照这些魔法步骤进行操作:

一. 打开代码编辑器并进入你想要在编辑器终端中创建项目的位置。 二. 使用以下命令在终端中创建项目的新实例:cargo risczero new multiply

该命令为我们创建了一个名为 multiply 的基本模板

三. 你应该会看到一个名为 multiply 的文件夹。进入该文件夹。cd multiply 四. 文件夹结构非常简单。 a. 我们有一个 host 文件夹和一个 methods 文件夹。 b. host 文件夹包含我们称之为 guest 程序的主程序。它还具有验证功能。 c. methods 文件夹包含 guest 程序,其中包含 zkvm 应用程序中被证明的部分。它从 host 接收输入参数,然后根据逻辑生成结果,将其提交到日志,并将其作为收据发送给 host。 d. 其余文件将在需要时逐步解释。

备注:Host 是运行 zkVM 的Host,Host 程序会加载 guest 程序 ,你并在需要时为 guest 提供输入。

Gust 程序

让我们从 guest 程序开始。

a. 让我们将文件名更改为 main.rs —> multiply.rs

b. 在 src 文件夹中创建一个名为 bin 的文件夹,并将 mutiply.rs 移动到其中。你的文件夹结构应如下所示:

c. 打开 Cargo.toml 并将 name = "method_name” —> name = "multiply” 更新。

d. 在 Cargo.toml 中添加以下代码。

    [[bin]]
    name = "multiply"
    path = "src/bin/multiply.rs"

e. 所以你的最终 Cargo.toml 应该是这样的:

f. 现在,打开 multiply.rs。在这里我们将编辑主函数。这是将在 zkvm 中执行的函数。

i. 在下面的代码中,我们从Host程序获取输入。然后我们确保输入不是 1 这样的平凡因子。然后我们计算乘积并最终将其提交回程序的Host。

        // 我们将从Host程序获取这些变量的值
        let a:u64 = env::read();
        let b:u64 = env::read();

        // 避免像乘以 1 这样的平凡因子
        if a == 1 || b == 1 {
        panic!("Trivial factors !!")  // Rust 中的 panic! 宏用于在发生不可恢复的错误时故意使程序崩溃
        }

        // 计算两个数字的乘积
        let product = a.checked_mul(b).expect("Integer Overflow");

        // 将输出提交回Host以将其保存为收据
        env::commit(&product);

ii. 经过上述更改后,你的 multiply.rs 应该是这样的。

g. 在 methods 文件夹的 Cargo.toml 中还有一个更改。

h. 打开并更新 name = "multiply-methods" 的值。

i. 你的最终 Cargo.toml 应该如下所示。

j. 我们的工作到此结束。

Host 程序

现在,让我们转到 Host 程序。

  1. 你的 Host 文件夹现在应该是这样的。

  1. 我们想将 main.rs 拆分为两个文件,即 prover.rsverify.rs

  2. src 下创建一个新文件夹并命名为 bin

  3. 删除 main.rs。创建文件并命名为 verify.rsprove.rs

  4. 你的文件夹结构现在应该是这样的:

  1. 打开 prove.rs,让我们开始编码:

  2. 添加以下代码。这些是我们需要的导入。

    use multiply_methods::MULTIPLY_ELF; // 它是 multiply_method 的二进制文件
    use risc0_zkvm::{
        default_prover,
        serde::{from_slice, to_vec},
        ExecutorEnv,
      };
  1. 让我们对主函数进行更改。
    fn main() {
            // 声明我们的秘密输入参数
        let a: u64 = 17;
        let b: u64 = 23;

        // 首先,我们构建一个执行环境
        let env = ExecutorEnv::builder()
        .add_input(&to_vec(&a).unwrap())  // 将输入参数传递给环境,以便Guest程序可以使用
        .add_input(&to_vec(&b).unwrap())
        .build()
        .unwrap();

        // 获取默认的 prover。
        let prover = default_prover();

        // 通过证明指定的 ELF 二进制文件生成收据。
        let receipt = prover.prove_elf(env, MULTIPLY_ELF).unwrap();

        // 提取收据的日志(即输出 c,其中 c = a * b)
        let c: u64 = from_slice(&receipt.journal).unwrap();

        // 打印断言
        println!("Hello, world! I know the factors of {}, and I can prove it!", c);

            // 让我们序列化收据,以便我们可以将其保存到文件中供验证程序验证。
        let serialized = bincode::serialize(&receipt).unwrap();

            // 将序列化内容写入 receipt.bin 文件
        let _saved_file = match std::fs::write("./receipt.bin", serialized){
         Ok(()) => println!("Receipt saved and serialized as receipt.bin"),
         Err(_) => println!("Something went wrong !!"),
        };

    }
  1. 你的最终 prove.rs 应该是这样的。

  1. 让我们打开并向我们的 verify.rs 添加代码。

  2. 在这里,我们将导入Guest程序 镜像 ID 和一些基本导入。

    use multiply_methods::MULTIPLY_ID;
    use risc0_zkvm::Receipt;
  3. 让我们对主函数进行更改。

fn main(){
    // 让我们导入由 prove 生成的 receipt
    let receipt_path ="./receipt.bin".to_string();
    let receipt_file = std::fs::read(receipt_path).unwrap();

    // 因为我们已经序列化了 receipt,所以需要反序列化它
    let receipt = bincode::deserialize::<Receipt>(&receipt_file).unwrap();

    // 让我们验证生成的 receipt 是否未被篡改
    let _verification = match receipt.verify(MULTIPLY_ID){
    Ok(()) => println!("Proof is Valid"),
    Err(_) => println!("Something went wrong !!"),
    };
}
  1. 你的最终 verify.rs 应该看起来像这样。

  1. 我保证这些是最后的更改。现在,我们几乎完成了。

  2. 打开 host 文件夹中的 Cargo.toml,并在依赖项下进行以下更改。

multiply-methods = { path = "../methods" }
  1. 你的 Cargo.toml 将看起来像这样。

运行

终于到了看看我们的代码是否工作的时间了。

在项目的根目录中启动控制台,并在 console cargo run --release --bin prove 中运行以下命令

此命令将为验证者生成证明和 receipt。

第一次运行时会花费很多时间。所以不要担心,喝杯咖啡直到完成。

完成后,如果你愿意,可以验证你生成的 receipt。为此,运行此命令 cargo run --release --bin verify

第一次运行时会花费很多时间。所以不要担心,喝杯咖啡直到完成。

恭喜!!!你已经使用 Risc0 编写了你的第一个 ZK 应用。如果你需要任何帮助,请给我留言,我会回复你。

关于作者

Luffy Sama@luffysama

Web3 探索者,致力于帮助用户进入 Web3。喜欢阅读和撰写关于最新技术的博客。

本文由 AI 翻译,欢迎小伙伴们来校对

点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

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