Skip to content

Commit

Permalink
[docs] update to writing program (#1049)
Browse files Browse the repository at this point in the history
* update to writing program

* address comments

* add compile

* address comments
  • Loading branch information
luffykai authored Dec 15, 2024
1 parent 47c6499 commit a26c3de
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 5 deletions.
1 change: 1 addition & 0 deletions book/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,4 @@
# Advanced Usage

- [Overview](./advanced-usage/overview.md)
- [Testing the program](./advanced-usage/testing-program.md)
2 changes: 1 addition & 1 deletion book/src/getting-started/quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ First, create a new Rust project.
cargo init fibonacci
```

Since we are using some nightly features, we need to specify the Rust version. Create a `rust-toolchain.toml` file with the following content:
Since we are using some nightly features, we need to specify the Rust version. Run `rustup component add rust-src --toolchain nightly-2024-10-30` and create a `rust-toolchain.toml` file with the following content:

```toml
[toolchain]
Expand Down
8 changes: 8 additions & 0 deletions book/src/writing-apps/compile.md
Original file line number Diff line number Diff line change
@@ -1 +1,9 @@
# Cross-Compilation

First let's define some key terms used in cross-compilation:
- **host** - the machine you're compiling and/or proving on. Note that one can compile and prove on different machines, but they are both called *host* as they are traditional machine architectures.
- **guest** - the executable to be run in a different VM architecture (e.g. the OpenVM runtime, or Android app).

There are multiple things happening in the `cargo openvm build` command as in the section [here](./write-program.md). In short, this command compiles on host to an executable for guest target.
It first compiles the program normally on your *host* platform with RISC-V and then transpiles it to a different target. See here for some explanation of [cross-compilation](https://rust-lang.github.io/rustup/cross-compilation.html).
Right now we use `riscv32im-risc0-zkvm-elf` target which is available in the [Rust toolchain](https://doc.rust-lang.org/rustc/platform-support/riscv32im-risc0-zkvm-elf.html), but we will contribute an OpenVM target to Rust in the future.
44 changes: 40 additions & 4 deletions book/src/writing-apps/write-program.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,51 @@ std = ["openvm/std"]

*TODO*: point to CLI installation instructions

First we need to build the program targeting the OpenVM runtime, and that requires some configuration. Put the following in `openvm.toml`:
```toml
[app_fri_params]
log_blowup = 2
num_queries = 42
proof_of_work_bits = 16

[app_vm_config.io]
[app_vm_config.rv32i]
[app_vm_config.rv32m]
range_tuple_checker_sizes = [256, 2048]
```

And run the following command to build the program:

```bash
cargo openvm build --transpile --transpiler-config openvm.toml --transpile-to outputs/fibonacci.vmexe
```

Next we can keygen the generate the proving and verifying keys:

```bash
cargo openvm keygen --config app_config.toml --output outputs/pk --vk-output outputs/vk
```

Now, to prove the program some input is needed. The input parameter is either a hex string or a file path. So for example if we want to compute the 10th fibonacci number, we can run:

```bash
cargo openvm prove app --app-pk outputs/pk --exe outputs/fibonacci.vmexe --input "0x000000000000000A" --output outputs/proof
cargo openvm verify app --app-vk outputs/vk --proof outputs/proof
```

No errors should be returned, and the proof should be correctly verified.

## Handling I/O

`openvm::io` provides a few functions to read and write data.
The program can take input from stdin, with some functions provided by `openvm::io`.

`read` takes from stdin the next vec and deserialize it into a generic type `T`, so one should specify the type when calling it:
`openvm::io::read` takes from stdin and deserializes it into a generic type `T`, so one should specify the type when calling it:
```rust
let n: u64 = read();
```

`read_vec` will just read a vector and return `Vec<u8>`.
`openvm::io::read_vec` will just read a vector and return `Vec<u8>`.

`openvm::io::reveal` sends public values to the final proof (to be read by the smart contract).

`reveal`
For debugging purposes, `openvm::io::print` and `openvm::io::println` can be used normally, but `println!` will only work if `std` is enabled.

0 comments on commit a26c3de

Please sign in to comment.