Technical writing

How Starknet contract source verification works

Starknet source verification rebuilds a submitted Cairo workspace with the pinned Scarb and compiler context, locates the intended contract artifact, and compares its Sierra class hash—and, where applicable, compiled class hash—with the declared class. A match shows that the submitted source reproduces the onchain class identity. It does not verify the STARK proof that secures Starknet state transitions. Sources: Starknet state and class hashes, Scarb Starknet contract artifacts.

Blockchain systems

A practical explanation of how a verifier reconstructs a Cairo build, compares the resulting Starknet class, and publishes source without confusing source verification with proof verification.

Validation scope
CLI flags, workspace resolution, artifact comparison, and failure stages were checked against the tagged verifier release and official Scarb/Starknet documentation.

This guide answers

  • How does Starknet contract source verification work?
  • Why does a Cairo contract fail verification even when the source looks correct?
  • What are Sierra, CASM, class hash, and compiled class hash in a verifier?

When to use this / when not to use this

Use this when

  • You are building, operating, or debugging a Cairo contract source-verification workflow.
  • A class-hash mismatch needs to be traced to workspace resolution, compiler inputs, artifacts, or comparison logic.

Do not use this when

  • You are trying to validate Starknet block proofs, contract behavior, or application security.
  • You do not have the exact manifest, lockfile, source tree, target, profile, and compiler context used for declaration.

Separate source verification from proof verification

Starknet uses validity proofs to prove correct state transitions, but block-explorer source verification answers a narrower question: can the submitted Cairo workspace and build configuration reproduce the class declared on Starknet? A verified source helps humans inspect code; it does not create or validate the network's STARK proof.

The onchain identity starts with a class hash. A deployed contract address resolves to a class hash, and a class can be declared without being deployed. For Cairo 1 and later contracts, the declared Sierra class also has a compiled class hash that commits to the CASM form used for execution. The verifier must select the correct identity before it compiles anything. Sources: Starknet state and compiled class hashes, Starknet JSON-RPC specification.

Request identity

  • Network and either a contract address or class hash.
  • Contract module name and package when a workspace contains multiple candidates.
  • Scarb manifest, lockfile, source tree, and target configuration.
  • Cairo/Scarb versions and build profile.
  • Verifier schema, endpoint, and comparison-rule version.

Reconstruct the original Scarb compilation unit

Scarb compiles a target from a main package, its dependencies, the selected profile, compiler configuration, and conditional attributes. The visible contract file is therefore not a sufficient build input. Dependency versions, lockfile state, feature flags, source paths, and settings such as Sierra ID replacement can alter the emitted artifact. Sources: Scarb compilation model, Scarb.lock reference.

A verification client should resolve the workspace locally and submit an explicit file set with build metadata. A verification service should compile in an isolated, resource-bounded environment using a pinned toolchain. Inferred values must be labeled because inference makes the result easier to obtain but weaker as provenance.

Inputs commonly missed

  • Scarb.lock or another exact dependency-resolution record.
  • The package name when multiple workspace members define contracts.
  • The full module path when contract module names collide.
  • Profile-specific Cairo settings and target options.
  • Generated or external contract sources included by the original build.
System diagramStarknet source-verification pipeline

The service reconstructs a build and compares class identities before an explorer publishes the submitted source.

Source: Voyager Verifier repository
  1. 01ResolveAddress → class hash on one network
  2. 02CollectWorkspace + manifest + lockfile
  3. 03CompilePinned Scarb/Cairo profile
  4. 04CompareSierra and compiled class hashes
  5. 05PublishSource + build evidence + status

Compare the right artifact at the right boundary

After compilation, locate the target contract through Scarb's Starknet artifact index rather than guessing a filename. Compute the Sierra class hash from the reproduced contract class and compare it with the declared class. Where the workflow validates compilation to CASM, compute and compare the compiled class hash as a separate result. Sources: Scarb Sierra and CASM target documentation, Starknet class-trie specification.

Keep raw artifacts and computed hashes in the job record. If normalization is necessary for a legacy format, name and version the rule and preserve the pre-normalized bytes. A verifier that silently edits artifacts until they match produces a publication result that cannot be audited later.

Useful mismatch categories

  • Wrong network, address, or class hash before build starts.
  • Workspace resolution or source-collection failure.
  • Compiler version, allowed-libfunc, or target incompatibility.
  • Sierra class-hash mismatch after a successful build.
  • Compiled class-hash mismatch between the reproduced CASM and declaration.

Publish a result that survives operational reality

Compilation can be slow and explorer APIs can be unavailable, so verification is naturally asynchronous. Expose queued, resolving, compiling, comparing, verified, mismatched, invalid, and failed as distinct states. A retry after a transport failure should reuse the immutable request; changing inputs creates a new request identity. Sources: Voyager verifier implementation, Voyager verifier v2.3.0 release.

When a match succeeds, publish the exact source set, manifest and lockfile metadata, compiler versions, class identity, comparison result, and timestamp. Do not overwrite a historical result when the verifier changes. Append a new evaluation or correction so the explorer can explain which logic produced each status.

Operational safeguards

  • Extract archives with path confinement and reject symlink escapes.
  • Run compilers without credentials or unrestricted network access.
  • Bound CPU, memory, disk, process count, and wall time.
  • Cache only by the complete canonical request identity.
  • Report queue age, compiler failures by version, and mismatch categories separately.

The verification pipeline, with a failure owner at every stage

This is the operational pipeline I use to explain Voyager Verifier. Each stage produces a named artifact and fails before submission when its own invariant cannot be established.

  1. 01Resolve
    Input
    workspace root + contract name
    Assertion
    one package and one contract target
    Output
    resolved package manifest
    Failure
    ambiguous or missing target
  2. 02Compile
    Input
    Scarb profile + source tree
    Assertion
    Sierra and CASM artifacts exist
    Output
    compiler artifacts + metadata
    Failure
    profile or compiler mismatch
  3. 03Normalize
    Input
    local artifacts
    Assertion
    comparison ignores no semantic field
    Output
    normalized Sierra/CASM pair
    Failure
    unsupported artifact schema
  4. 04Compare
    Input
    normalized local + on-chain class
    Assertion
    program and entry points match
    Output
    class-hash comparison report
    Failure
    compiled class hash differs
  5. 05Submit
    Input
    source bundle + exact class hash
    Assertion
    request is idempotently identified
    Output
    Voyager verification result
    Failure
    network or explorer rejection

Implementation examples

Concrete commands and data shapes you can adapt.

Verify a workspace contract through Voyagershell
voyager verify --network mainnet \
  --class-hash <CLASS_HASH> \
  --contract-name <CONTRACT_MODULE>

# Starknet Foundry can use Voyager as its verification provider.
sncast verify --network mainnet \
  --class-hash <CLASS_HASH> \
  --contract-name <CONTRACT_MODULE> \
  --verifier voyager
Make Scarb emit both Sierra and CASM artifactstoml
[[target.starknet-contract]]
sierra = true
casm = true

Decision log

The choices that shape the design—and what each choice costs.

  1. Resolve workspaces before submission

    The client can identify package, target, lockfile, and source-path errors close to the developer.

    Tradeoff: The client must track Scarb metadata changes and still cannot prove the submitted workspace is the original one.
  2. Expose the verifier as a Rust library and a CLI

    Foundry and other tools can reuse source collection and payload logic without parsing terminal output.

    Tradeoff: Library compatibility becomes a public contract alongside CLI behavior.
  3. Keep comparison stages explicit

    A successful compilation with the wrong class hash is a different developer problem from an invalid workspace.

    Tradeoff: The status model and job storage are more detailed than a single verified boolean.

Failure cases

What breaks, how it presents, and the recovery boundary.

The source compiles locally but the class hash differs
Signal

Compilation succeeds and emits the selected contract, but the reproduced Sierra class hash does not match.

Response

Compare Scarb/Cairo versions, lockfile, build profile, target settings, source paths, and contract module selection.

The wrong contract is selected
Signal

Multiple packages or modules expose the same short contract name.

Response

Require the package and full module path, then resolve it through the Starknet artifact index.

A retry publishes a different request
Signal

The service recollects mutable files or floats toolchain versions after a transport failure.

Response

Retry from the immutable request bundle; create a new request when any build input changes.

Repositories and primary references

Read the implementation, specifications, and tool documentation behind the article.

Inspect the systems that ground this guide in implementation work.

Last updated: