Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Another round of suggestions for the new no-relay template #77

Merged
merged 4 commits into from
Feb 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 10 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ Verifiable results are sent to your Ethereum contract.

## Overview

The picture below shows a simplified overview of how users can integrate [Bonsai] into their Ethereum smart contracts:
Here is a simplified overview of how devs can integrate RISC Zero, with [Bonsai] proving, into their Ethereum smart contracts:

![Bonsai Foundry Template Diagram](images/bonsai-foundry-template.png)

1. Run your application logic in the [RISC Zero zkVM]. The provided Command Line Interface (CLI) sends an off-chain proof request to the Bonsai proving service.
2. Bonsai generates the computation result, written to the [journal], and a SNARK proof of its correctness.
1. Run your application logic in the [RISC Zero zkVM]. The provided Command Line Interface (CLI) sends an off-chain proof request to the [Bonsai] proving service.
2. [Bonsai] generates the program result, written to the [journal], and a SNARK proof of its correctness.
3. The CLI submits this proof and journal on-chain to your app contract for validation.
4. Your app contract calls the [RISC Zero Verifier] to validate the proof. If the verification is successful, the journal is deemed trustworthy and can be safely used.

Expand Down Expand Up @@ -51,7 +51,7 @@ Next we'll need to install the `risc0` toolchain with:
cargo risczero install
```

Now you have all the tools you need to develop and deploy an application with RISC Zero.
Now you have all the tools you need to develop and deploy an application with [RISC Zero].

[install Rust]: https://doc.rust-lang.org/cargo/getting-started/installation.html
[Foundry]: https://getfoundry.sh/
Expand All @@ -73,7 +73,7 @@ Your new project consists of:

- a [zkVM program] (written in Rust), which specifies a computation that will be proven;
- a [app contract] (written in Solidity), which receives the response;
- a [guest interface] (written in Rust), which lets you define how to parse and serialize the guest input and calldata so that the [RISC Zero zkVM] and Bonsai can interact with your contract.
- a [guest interface] (written in Rust), which lets you define how to parse and serialize the guest input and calldata so that the [RISC Zero zkVM] can integrate with your contract.

[instructions above]: #dependencies
[zkVM program]: ./methods/guest/src/bin
Expand All @@ -82,7 +82,7 @@ Your new project consists of:

### Run the Tests

- Use `cargo test` to run the tests in your zkVM program.
- Use `RISC0_DEV_MODE=true cargo test` to run the tests in your zkVM program.
- Use `RISC0_DEV_MODE=true forge test -vvv` to test your Solidity contracts and their interaction with your zkVM program.

## Develop Your Application
Expand All @@ -93,9 +93,9 @@ To build your application, you'll need to make changes in three folders:
- write the on-chain part of your project in the [contracts] folder
- write the guest interface in the [cli] folder

[methods]: ./methods
[cli]: ./cli
[contracts]: ./contracts
[methods]: ./methods/
[cli]: ./cli/
[contracts]: ./contracts/

### Configuring Bonsai

Expand All @@ -109,8 +109,7 @@ export BONSAI_API_KEY="YOUR_API_KEY" # see form linked above
export BONSAI_API_URL="BONSAI_URL" # provided with your api key
```

<!-- TODO(victor): Rename the RiscZeroGroth16VerifierTest -->
Now if you run `forge test` with `RISC0_DEV_MODE=false`, the test will run as before, but will additionally use the fully verifying `RiscZeroGroth16Verifier` contract instead of `RiscZeroGroth16VerifierTest` and will request a SNARK receipt from Bonsai.
Now if you run `forge test` with `RISC0_DEV_MODE=false`, the test will run as before, but will additionally use the fully verifying `RiscZeroGroth16Verifier` contract instead of `MockRiscZeroVerifier` and will request a SNARK receipt from Bonsai.

```bash
RISC0_DEV_MODE=false forge test -vvv
Expand Down
4 changes: 2 additions & 2 deletions cli/src/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use std::str::FromStr;

use alloy_primitives::{FixedBytes, U256};
use alloy_sol_types::{sol, SolInterface, SolValue};
use anyhow::Result;
use anyhow::{Context, Result};
use risc0_ethereum_sdk::cli::GuestInterface;

// You can modify this file to implement the `GuestInterface` trait
Expand Down Expand Up @@ -53,7 +53,7 @@ impl GuestInterface for EvenNumberInterface {
seal: Vec<u8>,
) -> Result<Vec<u8>> {
// Decode the journal. Must match what was written in the guest with `env::commit_slice`
let x = U256::abi_decode(&journal, true)?;
let x = U256::abi_decode(&journal, true).context("decoding journal data")?;

// Encode the function call for `IEvenNumber.set(x)`
Ok(IEvenNumber::IEvenNumberCalls::set(IEvenNumber::setCall {
Expand Down
9 changes: 4 additions & 5 deletions contracts/README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
# Bonsai Solidity Contracts
# Solidity Contracts

This directory contains the Solidity contract for deploying a [Bonsai] application.
This directory contains the Solidity contract for deploying an application with [RISC Zero] on Ethereum.
There are two primary starter template contracts included.

<!-- TODO: Change this link once the new repo is live -->

The Solidity libraries for Bonsai can be found at [github.com/risc0/risc0](https://github.com/risc0/risc0/tree/main/bonsai/ethereum).

Contracts are built and tested with [forge], which is part of the [Foundry] toolkit.
Tests are defined in the `tests` directory in the root of this template.

[Foundry]: https://getfoundry.sh/
[forge]: https://github.com/foundry-rs/foundry#forge
[Bonsai]: https://dev.bonsai.xyz
[offloading the computation]: https://twitter.com/RiscZero/status/1677316664772132864
[RISC Zero]: https://risczero.com
[guest]: https://github.com/risc0/bonsai-foundry-template/tree/main/methods/guest/src/bin
93 changes: 65 additions & 28 deletions deployment-guide.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
# Bonsai Deployment Guide

> **Note: This software is not production ready. Do not use in production.**

Welcome to the [Bonsai] Deployment guide!
Welcome to the [RISC Zero] Ethereum Deployment guide!

Once you've written your [contracts] and your [methods], and [tested] your program, you're ready to deploy your contract.

You can either:

Once you've written your [contracts] and your [methods], and [tested] your program, you're ready to deploy your contract. You can either:
- Deploy your project to a local network
- Deploy to a testnet
- [Deploy your project to a local network]
- [Deploy to a testnet]

[methods]: ./methods/
[contracts]: ./contracts/
[tested]: ./README.md#run-the-tests
[Deploy your project to a local network]: #deploy-your-project-on-a-local-network
[Deploy to a testnet]: #deploy-your-project-on-a-testnet

## Deploy your project on a local network

Expand All @@ -19,21 +29,24 @@ You can deploy your contracts and run an end-to-end test or demo as follows:

Once anvil is started, keep it running in the terminal, and switch to a new terminal.

2. Set your private key:
2. Set your environment variables:
> ***Note:*** *This requires having access to a Bonsai API Key. To request an API key [complete the form here](https://bonsai.xyz/apply).*

```bash
# Anvil sets up a number of default wallets, and this private key is one of them.
export ETH_WALLET_PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
export BONSAI_API_KEY="YOUR_API_KEY" # see form linked in the previous section
export BONSAI_API_URL="BONSAI_API_URL" # provided with your api key
```

3. Deploy your contract by running:
> This requires that `ETH_WALLET_PRIVATE_KEY` be set.

```bash
forge script --rpc-url http://localhost:8545 --broadcast script/Deploy.s.sol
```

This command should output something similar to:

```bash
...
== Logs ==
Expand All @@ -42,30 +55,49 @@ You can deploy your contracts and run an end-to-end test or demo as follows:
...
```

### Interact with your deployment:
Save the `EvenNumber` contract address to an env variable:

```bash
export EVEN_NUMBER_ADDRESS=#COPY EVEN NUMBER ADDRESS FROM DEPLOY LOGS
```

You can also use the following command to set the contract address if you have `jq` installed:

```bash
export EVEN_NUMBER_ADDRESS=$(jq -re '.transactions[] | select(.contractName == "EvenNumber") | .contractAddress' ./broadcast/Deploy.s.sol/31337/run-latest.json)
```

### Interact with your local deployment

1. Query the state:

```bash
cast call --rpc-url http://localhost:8545 0xe7f1725e7734ce288f8367e1bb143e90bb3f0512 'get()(uint256)'
cast call --rpc-url http://localhost:8545 ${EVEN_NUMBER_ADDRESS:?} 'get()(uint256)'
```

2. Publish a new state
> ***Note:*** *This requires having access to a Bonsai API Key. To request an API key [complete the form here](https://bonsai.xyz/apply).*

```bash
RISC0_DEV_MODE=false BONSAI_API_URL="BONSAI_API_URL" BONSAI_API_KEY="BONSAI_API_KEY" cargo run --release -- publish \
cargo run --release -- publish \
--chain-id=31337 \
--rpc-url=http://localhost:8545 \
--contract=e7f1725E7734CE288F8367e1Bb143E90bb3F0512 \
--contract=${EVEN_NUMBER_ADDRESS:?} \
--guest-binary="IS_EVEN" \
--input=12345678
```

3. Query the state again to see the change:

```bash
cast call --rpc-url http://localhost:8545 ${EVEN_NUMBER_ADDRESS:?} 'get()(uint256)'
```

## Deploy your project on a testnet

You can deploy your contracts on a testnet such as `Sepolia` and run an end-to-end test or demo as follows:

1. Get access to Bonsai and an Ethereum node running on a given testnet, e.g., Sepolia (in this example, we will be using [alchemy](https://www.alchemy.com/) as our Ethereum node provider) and export the following environment variables:
1. Get access to Bonsai and an Ethereum node running on a given testnet, e.g., Sepolia (in this example, we will be using [Alchemy](https://www.alchemy.com/) as our Ethereum node provider) and export the following environment variables:
> ***Note:*** *This requires having access to a Bonsai API Key. To request an API key [complete the form here](https://bonsai.xyz/apply).*

```bash
export BONSAI_API_KEY="YOUR_API_KEY" # see form linked in the previous section
Expand All @@ -74,14 +106,14 @@ You can deploy your contracts on a testnet such as `Sepolia` and run an end-to-e
export ETH_WALLET_PRIVATE_KEY="YOUR_WALLET_PRIVATE_KEY" # the private key of your Ethereum testnet wallet e.g., Sepolia
```

2. Deploy your contract by running:
2. Deploy your contract by running:

```bash
forge script script/Deploy.s.sol --rpc-url https://eth-sepolia.g.alchemy.com/v2/$ALCHEMY_API_KEY --broadcast
forge script script/Deploy.s.sol --rpc-url https://eth-sepolia.g.alchemy.com/v2/${ALCHEMY_API_KEY:?} --broadcast
```

This command should output something similar to:

```bash
...
== Logs ==
Expand All @@ -93,31 +125,36 @@ You can deploy your contracts on a testnet such as `Sepolia` and run an end-to-e
Save the `EvenNumber` contract address to an env variable:

```bash
export EVEN_NUMBER_ADDRESS=0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512
export EVEN_NUMBER_ADDRESS=#COPY EVEN NUMBER ADDRESS FROM DEPLOY LOGS
```

You can also use the following command to set the contract address if you have `jq` installed:

## Interact with your deployment:
```bash
export EVEN_NUMBER_ADDRESS=$(jq -re '.transactions[] | select(.contractName == "EvenNumber") | .contractAddress' ./broadcast/Deploy.s.sol/11155111/run-latest.json)
```

### Interact with your testnet deployment

1. Query the state:

```bash
cast call --rpc-url https://eth-sepolia.g.alchemy.com/v2/$ALCHEMY_API_KEY $EVEN_NUMBER_ADDRESS 'get()(uint256)'
cast call --rpc-url https://eth-sepolia.g.alchemy.com/v2/${ALCHEMY_API_KEY:?} ${EVEN_NUMBER_ADDRESS:?} 'get()(uint256)'
```

2. Publish a new state
> ***Note:*** *This requires having access to a Bonsai API Key. To request an API key [complete the form here](https://bonsai.xyz/apply).*

```bash
RISC0_DEV_MODE=false cargo run --release -- publish \
cargo run --release -- publish \
--chain-id=11155111 \
--rpc-url=https://eth-sepolia.g.alchemy.com/v2/$ALCHEMY_API_KEY \
--contract=$EVEN_NUMBER_ADDRESS \
--rpc-url=https://eth-sepolia.g.alchemy.com/v2/${ALCHEMY_API_KEY:?} \
--contract=${EVEN_NUMBER_ADDRESS:?} \
--guest-binary="IS_EVEN" \
--input=12345678
```

[Bonsai]: https://risczero.com/bonsai
[contracts]: https://github.com/risc0/bonsai-foundry-template/tree/main/contracts
[methods]: https://github.com/risc0/bonsai-foundry-template/tree/main/methods
[tested]: https://github.com/risc0/bonsai-foundry-template/tree/main#test-your-project
[Groth16 SNARK proof]: https://www.risczero.com/news/on-chain-verification
3. Query the state again to see the change:

```bash
cast call --rpc-url https://eth-sepolia.g.alchemy.com/v2/${ALCHEMY_API_KEY:?} ${EVEN_NUMBER_ADDRESS:?} 'get()(uint256)'
```
33 changes: 19 additions & 14 deletions methods/README.md
Original file line number Diff line number Diff line change
@@ -1,33 +1,38 @@
## zkVM Methods
# zkVM Methods

This directory contains the [zkVM] portion of your [Bonsai] application.
This directory contains the [zkVM] portion of your [RISC Zero] application.
This is where you will define one or more [guest programs] to act as a coprocessor to your [on-chain logic].

> In typical use cases, the only code in this directory that you will need to edit is inside [`guest/src/bin`].
> In typical use cases, the only code in this directory that you will need to edit is inside [`guest/src/bin`].

[zkVM]: https://dev.risczero.com/zkvm
[RISC Zero]: https://www.risczero.com/
[guest programs]: https://dev.risczero.com/terminology#guest-program
[on-chain logic]: ../contracts/
[`guest/src/bin`]: ./guest/src/bin/

### Writing Guest Code
To learn to write code for the zkVM, we recommend [Guest Code 101].

To learn to write code for the zkVM, we recommend [Guest Code 101].

Examples of what you can do in the guest can be found in the [RISC Zero examples].

[Guest Code 101]: https://dev.risczero.com/zkvm/developer-guide/guest-code-101
[RISC Zero examples]: https://github.com/risc0/tree/v0.18.0/examples

### From Guest Code to Binary File

Code in the `methods/guest` directory will be compiled into one or more [RISC-V] binaries.
Code in the `methods/guest` directory will be compiled into one or more binaries.

Build configuration for the methods is included in `methods/build.rs`.

Each will have a corresponding image ID, which is a hash identifying the program.

### Uploading Binary to Bonsai

<!-- TODO: This should have practical instructions on how to actually upload to Bonsai -->

When [deploying] your application, you will upload your binary to Bonsai where the guest will run when requested.
The image ID will be included in the deployment of the smart contracts to reference your guest program living in Bonsai.

[deploying]: ../deployment-guide
[RISC Zero examples]: https://github.com/risc0/tree/v0.18.0/examples
[Guest Code 101]: https://dev.risczero.com/zkvm/developer-guide/guest-code-101
[on-chain logic]: ../contracts/readme
[`guest/src/bin`]: ./guest/src/bin/
[guest program]: https://dev.risczero.com/terminology#guest-program
[guest programs]: https://dev.risczero.com/terminology#guest-program
[developer documentation]: https://dev.risczero.com
[zkVM]: https://dev.risczero.com/zkvm
[Bonsai]: https://dev.risczero.com/bonsai/
5 changes: 4 additions & 1 deletion script/Deploy.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,12 @@ import {EvenNumber} from "../contracts/EvenNumber.sol";
/// @notice Deployment script for the BonsaiStarter project.
/// @dev Use the following environment variable to control the deployment:
/// * ETH_WALLET_PRIVATE_KEY private key of the wallet to be used for deployment.
///
/// See the Foundry documentation for more information about Solidity scripts.
/// https://book.getfoundry.sh/tutorials/solidity-scripting
contract EvenNumberDeploy is Script, BonsaiCheats {
function run() external {
uint256 deployerKey = vm.envOr("ETH_WALLET_PRIVATE_KEY", uint256(0));
uint256 deployerKey = uint256(vm.envBytes32("ETH_WALLET_PRIVATE_KEY"));

vm.startBroadcast(deployerKey);

Expand Down
8 changes: 3 additions & 5 deletions sdk/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ pub fn query(
// No input. Return the Ethereum ABI encoded bytes32 image ID.
None => format!("0x{}", hex::encode(image_id)),
};
// Forge test FFI calls expect hex encoded bytes sent to stdout
print!("{output}");
std::io::stdout()
.flush()
Expand Down Expand Up @@ -130,11 +131,8 @@ pub fn publish(
post_state_digest,
seal,
} = prover::generate_proof(&elf, input)?;
let calldata = guest_interface.encode_calldata(
risc0_zkvm::serde::from_slice(journal.as_slice())?,
post_state_digest,
seal,
)?;

let calldata = guest_interface.encode_calldata(journal, post_state_digest, seal)?;

let runtime = tokio::runtime::Runtime::new()?;
runtime.block_on(tx_sender.send(calldata))?;
Expand Down
5 changes: 3 additions & 2 deletions sdk/src/eth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,12 @@ impl TxSender {
.from(self.client.address())
.data(calldata);

eprintln!("Transaction request: {:?}", &tx);
// TODO: Add these back as proper log lines istead of print statements
//eprintln!("Transaction request: {:?}", &tx);

let tx = self.client.send_transaction(tx, None).await?.await?;

eprintln!("Transaction receipt: {:?}", &tx);
//eprintln!("Transaction receipt: {:?}", &tx);

Ok(tx)
}
Expand Down
Loading