paint-brush
使用 Risc0 创建您的第一个 ZK 项目:初学者指南经过@luffysama
529 讀數
529 讀數

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

经过 Luffy Sama13m2023/10/05
Read on Terminal Reader

太長; 讀書

最后,您将获得 Risc0 中零知识证明的实践经验。无需高级数学或密码学背景。 我们将重点关注开始构建实际解决方案的编码要点。本实践介绍旨在让任何开发人员都能理解强大的隐私技术。
featured image - 使用 Risc0 创建您的第一个 ZK 项目:初学者指南
Luffy Sama HackerNoon profile picture

介绍

零知识证明可实现私密、安全的交易。通过 zkSNARKs 和 zkSTARKs,证明者可以向验证者证明拥有某些信息,而无需透露实际数据。


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


本教程将涵盖:

  • Risc0的安装

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


先决条件:

  • 复制粘贴快捷方式

  • 所需安装:

    • Rust 语言
    • 货箱
  • 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


这就是我们所需要的。那么,让我们转到代码编辑器。

写一些神奇的线条:

现在我们已经完成安装,您可以阅读并按照以下 abra kadabra 🪄 步骤进行操作:


  1. 打开代码编辑器并前往要在编辑器终端中创建项目的位置。


  2. 在终端中使用以下命令创建项目的新实例: cargo risczero new multiply


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

  3. 您应该会看到创建了一个名为“multiply”的文件夹。 cd 进入其中。 cd multiply


  4. 文件夹结构非常简单。


    1. 我们有一个主机文件夹和一个方法文件夹。


    2. 主机文件夹包含我们称为访客程序的主机程序。它还具有验证您是否愿意的能力。


    3. 方法文件夹包含来宾程序,其中包含经过验证的 zkvm 应用程序部分。它从主机接收输入参数,然后根据逻辑生成结果,将结果提交到日志,并将它们作为收据发送到主机。


    4. 其余文件将根据需要随时解释。

  5. 让我们从嘉宾节目开始吧。


    1. 让我们更改文件的名称main.rs —> multiply.rs

    2. src文件夹中创建一个名为bin的文件夹,并将mutiply.rs移至其中。您的文件夹结构应如下所示:

    3. 打开Cargo.toml并将更新更改为name = "method_name” —> name = "multiply”

    4. Cargo.toml中添加以下代码。

       [[bin]] name = "multiply" path = "src/bin/multiply.rs"
    5. 所以你的最终Cargo.toml将如下所示:

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


      1. 在下面的代码中,我们从主机程序获取输入。然后我们确保输入不是 1 的微不足道的因子。然后我们计算乘积,最后将其提交回程序主机。

         // We will get the values for these variables from host program let a:u64 = env::read(); let b:u64 = env::read(); // To avoid trivial factors like multiplication by 1 if a == 1 || b == 1 { panic!("Trivial factors !!") // The panic! macro in Rust is used to intentionally crash a program when an unrecoverable error occurs } // Caculate the product of the two numbers let product = a.checked_mul(b).expect("Integer Overflow"); // Commit back the output to the host to save it as receipt env::commit(&product);
      2. 完成上述更改后,您的multiply.rs应该如下所示。

    7. methods文件夹的Cargo.toml中还有最后一项更改。

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


    9. 您的最终Cargo.toml如下所示。

    10. 我们这里的工作已经完成了。

    11. 现在,让我们进入主机程序。

      1. 您的主机文件夹现在一定是这样的。

      2. 我们希望将main.rs拆分为两个文件: prover.rsverify.rs


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


      4. 删除main.rs 。创建文件并将其命名为verify.rs & prove.rs


      5. 您的文件夹结构现在应该如下所示。

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


      7. 添加以下代码。这些是我们需要的进口。

         use multiply_methods::MULTIPLY_ELF; // It is a binary file of multiply_method use risc0_zkvm::{ default_prover, serde::{from_slice, to_vec}, ExecutorEnv, };


      8. 让我们对 main 函数进行更改。

         fn main() { // Declaring our secret input params let a: u64 = 17; let b: u64 = 23; // First, we construct an executor environment let env = ExecutorEnv::builder() .add_input(&to_vec(&a).unwrap()) // Passing the input params to environment so it can be used by gues proggram .add_input(&to_vec(&b).unwrap()) .build() .unwrap(); // Obtain the default prover. let prover = default_prover(); // Produce a receipt by proving the specified ELF binary. let receipt = prover.prove_elf(env, MULTIPLY_ELF).unwrap(); // Extract journal of receipt (ie output c, where c = a * b) let c: u64 = from_slice(&receipt.journal).unwrap(); // Print an assertion println!("Hello, world! I know the factors of {}, and I can prove it!", c); // Let's serialize the receipt so we can save it to an file for verifier program to verify. let serialized = bincode::serialize(&receipt).unwrap(); // Writing the serialized contect to receipt.bin file let _saved_file = match std::fs::write("./receipt.bin", serialized){ Ok(()) => println!("Receipt saved and serialized as receipt.bin"), Err(_) => println!("Something went wrong !!"), }; }


      9. 你的最终的prove.rs应该看起来像这样。

      10. 让我们打开verify.rs并将代码添加到其中。


      11. 在这里,我们将导入访客程序映像 ID 和一些基本导入。

         use multiply_methods::MULTIPLY_ID; use risc0_zkvm::Receipt;


      12. 让我们对 main 函数进行更改。

         fn main(){ // Let's impor the receipt that was generated by prove let receipt_path ="./receipt.bin".to_string(); let receipt_file = std::fs::read(receipt_path).unwrap(); // As we has serialized the receipt we need to desrialize it let receipt = bincode::deserialize::<Receipt>(&receipt_file).unwrap(); // Let's verify if the receipt that was generated was not created tampered with let _verification = match receipt.verify(MULTIPLY_ID){ Ok(()) => println!("Proof is Valid"), Err(_) => println!("Something went wrong !!"), }; }


      13. 您的最终verify.rs应该看起来像这样。

      14. 我保证这些是最终的改变。现在,我们快完成了。


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

         multiply-methods = { path = "../methods" }
      16. 您的 Cargo.toml 将如下所示。

    12. 终于到了看看我们的代码是否有效的时候了。


    13. 在项目的根目录中启动控制台,然后在console cargo run --release --bin prove


    14. 该命令将为验证者生成证明和收据。


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


    15. 完成此操作后,如果您愿意,您可以验证您生成的收据。为此,运行此命令cargo run --release --bin verify


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


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