Skip to main content

Write and deploy an LEZ program with logos-scaffold

Use logos-scaffold to create, build, and deploy a guest program on the Logos Execution Zone testnet.

logos-scaffold is a project scaffold and CLI tool that manages the full lifecycle of a LEZ guest program — from project creation to deployment. It pins LEZ and SPEL dependencies, builds a project-local sequencer, and handles wallet interactions, so you can focus on writing your program logic.

Before you begin, ensure you have:

  • Linux x86_64 or macOS
  • git, curl, and Rust/Cargo (latest stable)
  • Docker or Podman — required for the RISC0 guest method build
  • The RISC Zero toolchain installed via rzup: run rzup install rust (needed by logos-scaffold build) and rzup install r0vm (needed by the sequencer to execute transactions)
  • Nixlogos-scaffold setup builds the basecamp and lgpm dependencies as Nix flakes (build = "nix-flake" in scaffold.toml); logos-scaffold doctor flags a missing nix with Install nix

What to expect

  • You can create a new LEZ program project with logos-scaffold.
  • You can write a guest program that runs inside the RISC0 zkVM.
  • You can build and deploy your program to the LEZ testnet.
  • You can interact with your deployed program using the wallet CLI.

Step 1: Install logos-scaffold

  1. Clone the logos-scaffold repository and install the CLI:

    git clone https://github.com/logos-co/scaffold.git
    cd scaffold
    cargo install --path .

    This installs two binaries on your PATH: logos-scaffold and the shorter alias lgs. They are functionally identical.

  2. Verify the installation:

    logos-scaffold --version

Step 2: Create a new project

  1. Create a new LEZ program project. Replace my-program with your project name:

    logos-scaffold new my-program
    cd my-program

    This generates a project with the default template, which includes a sample guest program and runner scripts.

  2. Inspect the project layout:

    my-program/
    ├── scaffold.toml # Project configuration and dependency pins
    ├── methods/
    │ └── guest/
    │ └── src/bin/ # Guest programs run inside the RISC0 zkVM
    ├── src/
    │ └── bin/ # Runner scripts that submit transactions
    └── .scaffold/ # Local state, wallet home, and build artifacts

Step 3: Set up the project

  1. Run setup to sync the LEZ and SPEL repositories to their pinned commits, build the project-local sequencer and wallet binaries, and seed the default wallet:

    logos-scaffold setup

    This step can take several minutes on a cold cache as it builds the sequencer from source.

Step 4: Write your guest program

Guest programs run inside the RISC0 zkVM and define the on-chain logic of your LEZ program. Each guest program in methods/guest/src/bin/ becomes a deployable program with its own program_id.

  1. Open the sample guest program:

    $EDITOR methods/guest/src/bin/hello_world.rs
  2. The program receives a ProgramInput struct via the zkVM environment, applies your logic, and writes a ProgramOutput struct to the journal. The sequencer verifies the proof and updates the on-chain account state.

    Key concepts:

    • Instructions are encoded as Vec<u8> (opcode byte followed by payload).
    • Account data is stored in AccountWithMetadata structs.
    • Use RISC0_DEV_MODE=1 during development to skip ZK proof generation for faster iteration.

Step 5: Build the project

  1. Build the workspace. In development, use RISC0_DEV_MODE=1 to skip proof generation:

    RISC0_DEV_MODE=1 logos-scaffold build

    The build compiles your guest programs and produces .bin artifacts under target/riscv-guest/…/riscv32im-risc0-zkvm-elf/release/.

Step 6: Start a local sequencer

  1. Start a project-local sequencer to test your program before deploying to the testnet:

    RISC0_DEV_MODE=1 logos-scaffold localnet start

    The sequencer is daemonised and survives terminal or tmux session closure. Use logos-scaffold localnet status to check that it is running and logos-scaffold localnet stop to stop it.

Step 7: Deploy your program

  1. Deploy all guest programs to the running sequencer:

    RISC0_DEV_MODE=1 logos-scaffold deploy

    After a successful deployment, logos-scaffold prints a per-program summary; when the vendored spel tooling is available it also prints a program_id — a hex-encoded RISC0 image ID computed from the submitted ELF. The example runner scripts in Step 8 load the program from its embedded ELF, so you do not need to copy a program_id to complete this guide.

  2. To deploy a specific program by name:

    RISC0_DEV_MODE=1 logos-scaffold deploy hello_world

Step 8: Interact with your program

Use the project-local wallet CLI to submit transactions to your deployed program. The wallet is available at logos-scaffold wallet.

  1. With the sequencer from Step 6 running, top up the default wallet from the faucet, then list your accounts (wallet list shows accounts, not a balance):

    logos-scaffold wallet topup
    logos-scaffold wallet list
  2. Run one of the example runner scripts that submit transactions to your program:

    export NSSA_WALLET_HOME_DIR="$(pwd)/.scaffold/wallet"
    RISC0_DEV_MODE=1 cargo run --bin run_hello_world -- <PUBLIC_ACCOUNT_ID>

    The runner scripts in src/bin/ demonstrate how to construct and sign a PublicTransaction, set the program_id, encode an instruction, and submit the transaction via the sequencer RPC.

Deploy to the testnet

To deploy to the LEZ public testnet instead of a local sequencer, ensure your wallet has test tokens (use logos-scaffold wallet topup to request from the faucet) and remove the RISC0_DEV_MODE=1 prefix from the build and deploy commands. Full ZK proof generation can take significantly longer than dev mode.

logos-scaffold build
logos-scaffold deploy