Toccata Dev Guide

A developer guide to Kaspa's Toccata programmability stack: covenants, transaction v1, script pricing, inline ZK, based ZK apps, and Silverscript.

Toccata makes Kaspa UTXOs expressive enough to carry real application state. It is active on mainnet as of June 30, 2026, at DAA score 474_165_565.

Before listing opcodes, it is better to look at the smallest stateful object Toccata can express: a UTXO that requires its spend to create a valid successor.

The first example is one stateful coin.

pragma silverscript ^0.1.0;

contract Counter(int init_count, int max_step) {
    int count = init_count;

    #[covenant.singleton(mode = transition)]
    function increment(State prev_state, int step) : (State) {
        require(step > 0);
        require(step <= max_step);
        return({ count: prev_state.count + step });
    }
}

There is no mutable Counter object stored inside a Kaspa node. There is a UTXO whose script public key commits to a script preimage. That preimage contains both the contract and the current state. When the UTXO is spent, the transaction reveals the preimage, the script computes the next state, and the script refuses to pass unless the transaction creates the next committed UTXO.

flowchart LR
    classDef chain fill:#eef6ff,stroke:#4b82c3,color:#172033
    classDef tx fill:#fff7e8,stroke:#c58b2a,color:#1f1b12
    classDef script fill:#eef9ef,stroke:#4d9f5b,color:#132016

    U0["live UTXO<br/>P2SH(contract + state_0)"]:::chain
    W["spend reveals<br/>contract + state_0 + args"]:::tx
    C["script checks<br/>state_1 = transition(state_0, args)"]:::script
    U1["next UTXO<br/>P2SH(contract + state_1)"]:::chain

    U0 --> W --> C --> U1

That is the core covenant move: compress, open, validate, recompress.

The rest of Toccata exists around that loop: transaction fields for covenant outputs, opcodes for inspecting the current transaction, consensus lineage for covenant families, pricing for expensive work, and proof hooks for applications that should not run fully on L1.

Important

The consensus features described here are mainnet features. The developer tooling is younger. Silverscript is the main covenant authoring path and is approaching the interface developers should expect, but release and audit status still need attention. Argent and vprogs are earlier reference stacks. Expect periodic guide updates as those repos move.

What Toccata adds

Before Toccata, a Kaspa script could protect a UTXO, but it could not easily require the spending transaction to create a valid successor.

Toccata adds the pieces needed for that check.

PieceWhat it is for
Transaction v1compute_budget, covenant output bindings, user lanes, gas, and the v1 BLAKE3 txid model
Covenant IDsa consensus-tracked lineage label for covenant UTXOs, independent of changing P2SH hashes
Introspection opcodesaccess to inputs, outputs, covenant groups, auth groups, hashes, and byte slices
Script pricinga runtime meter for stack growth, hashing, signatures, and ZK verification
ZK precompilesdirect verification of Groth16 and RISC Zero Succinct proofs inside script
Seqcommit lanesapp-specific L1 activity commitments for based apps, without proving the whole DAG

The result is still UTXO-native. Toccata does not turn Kaspa into an account-chain smart contract system. Instead it makes UTXOs able to carry state, split into lanes, merge when necessary, and prove the next step.

Two roads

Most Toccata designs start on one of two roads.

flowchart TB
    classDef base fill:#f4f7fb,stroke:#8794a8,color:#172033
    classDef cov fill:#edf8f2,stroke:#55a66b,color:#102015
    classDef zk fill:#f7f1ff,stroke:#8b68ca,color:#1d162b
    classDef tool fill:#fff6e8,stroke:#bd8d37,color:#21180c

    L1["Kaspa L1<br/>tx v1, covenant IDs, script pricing"]:::base

    C["L1 covenant apps<br/>state transitions run in script"]:::cov
    Z["based ZK apps<br/>state transitions run off-chain, settle by proof"]:::zk

    S["Silverscript"]:::tool
    A["Argent-style lowering"]:::tool
    V["vprogs runtime"]:::tool

    L1 --> C
    L1 --> Z
    S --> C
    A -. "multi-contract source lowering" .-> S
    V --> Z

Road 1: L1 covenants

Use L1 covenants when the state transition is small enough, public enough, and local enough to run directly in script.

This road is more expressive than it first looks. A single global state UTXO is sequential, but Kaspa's high-frequency DAG makes many covenant families viable when state is split into independent lanes. A token system, market, game league, vault set, or routing family can have many live UTXOs advancing in parallel, with occasional merge or leader/delegate transitions when shared coordination is needed.

Silverscript is the intended authoring surface for L1 covenant apps. Argent is best understood as the next layer up: actor-style, multi-contract source that can lower into Silverscript the way async lowers into a more mechanical runtime representation.

Start with Covenant State.

Road 2: Based ZK apps

Use a based app when the state is too shared, too private, or too expensive to execute directly on L1.

The user operation is intentionally ordinary: a v1 L1 transaction in an app-specific user lane, carrying the operation in the transaction payload. The app state machine runs off-chain. A settlement covenant on L1 verifies that the executor consumed the right lane activity, started from the previous state commitment, ended at the new one, and honored any exits or permissions the protocol requires.

sequenceDiagram
    participant User
    participant Lane as Kaspa user lane
    participant Exec as App executor
    participant Prover
    participant Cov as Settlement covenant

    User->>Lane: v1 tx with app payload + gas
    Lane-->>Exec: ordered app activity
    Exec->>Exec: apply operations to app state
    Exec->>Prover: state diff + lane witness
    Prover->>Cov: proof + next state commitment
    Cov->>Cov: verify proof, lane anchor, exits

KIP-21 is what makes this practical. Without partitioned sequencing commitments, every app would need to prove not only which transactions targeted it, but also which transactions did not. With lanes, the proof can focus on the app's own L1 activity.

Start with Based Apps.

Transaction v1 is the shared floor

Do not treat transaction v1 as a later chapter for protocol implementers. Every serious Toccata developer eventually touches it.

Version 1 changes three things that show up immediately in application design:

  • an input carries compute_budget instead of v0 sig_op_count;
  • an output may carry CovenantBinding { authorizing_input, covenant_id };
  • non-native user lanes and non-zero gas become available for based app activity.

It also separates three hash contexts:

flowchart LR
    classDef id fill:#eef6ff,stroke:#4b82c3,color:#172033
    classDef block fill:#eef9ef,stroke:#4d9f5b,color:#132016
    classDef sig fill:#fff7e8,stroke:#c58b2a,color:#1f1b12

    TX["transaction v1"]
    ID["txid<br/>identity"]:::id
    H["tx::hash<br/>block commitment"]:::block
    S["sighash<br/>spender intent"]:::sig

    TX --> ID
    TX --> H
    TX --> S

    ID --> IDR["excludes signatures,<br/>mass, compute budget"]
    H --> HR["includes full encoding,<br/>mass, compute budget"]
    S --> SR["signs covered outputs,<br/>not compute budget"]

That separation affects wallets, indexers, relayers, ZK guests, and anyone debugging why two hashes that "should be the same" are not.

Continue with Transaction V1.

How to read this book

The book is arranged as a reading sequence rather than a protocol spec.

If you are using coding agents, read Agent Brief early and attach it to implementation tasks. It tells an agent which mental model not to miss: validate the next output, respect covenant IDs, do not invent account-state assumptions, and check the exact repo behavior before making protocol claims.

If you are making an architecture call, read Decision Guide after the first three chapters. The core decision is usually about shared state: whether the app can be split into many UTXO lanes, whether it needs occasional coordinated transitions, or whether it really wants an off-chain state machine with proof-based settlement.

Status notes

This guide uses present-tense language for Toccata consensus features because they are mainnet-active. Tooling status is different:

  • Silverscript is the primary higher-level covenant language. Treat it as the recommended covenant authoring direction while checking release and audit status.
  • Argent is an experimental actor-style frontend for multi-contract covenant apps. The likely long-term framing is that Argent-like constructs become the multi-contract precompilation layer of the Silverscript toolchain.
  • vprogs is an evolving Rust runtime for based computation and RISC Zero proving. Its repo is a source of patterns, not yet a stable external developer API.

Terms you will keep seeing

TermMeaning
Covenanta script-controlled UTXO whose spend validates the next output layout and state transition
Covenant IDa 32-byte consensus-tracked lineage identifier carried by covenant UTXOs
P2SH state patternencoding state in the redeem script preimage and committing to it through a P2SH hash
Compute budgetversion 1 per-input execution budget, priced into script units
Script unitthe runtime meter for script execution
User lanea version 1 subnetwork ID with a 4-byte namespace and 16 zero bytes; reserved [x, 19 zero bytes] system IDs are not user lanes
Gasa version 1 lane gas commitment for user-lane admission
Seqcommitthe chain-block sequencing commitment exposed to script
Inline ZKa covenant that verifies a proof directly as part of its spend
Based appan off-chain app state machine whose user operations are ordered on Kaspa L1 and whose state transitions settle through a covenant proof