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.
The service reconstructs a build and compares class identities before an explorer publishes the submitted source.
Source: Voyager Verifier repository- 01ResolveAddress → class hash on one network
- 02CollectWorkspace + manifest + lockfile
- 03CompilePinned Scarb/Cairo profile
- 04CompareSierra and compiled class hashes
- 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.
- 01Resolve
- Input
- workspace root + contract name
- Assertion
- one package and one contract target
- Output
- resolved package manifest
- Failure
- ambiguous or missing target
- 02Compile
- Input
- Scarb profile + source tree
- Assertion
- Sierra and CASM artifacts exist
- Output
- compiler artifacts + metadata
- Failure
- profile or compiler mismatch
- 03Normalize
- Input
- local artifacts
- Assertion
- comparison ignores no semantic field
- Output
- normalized Sierra/CASM pair
- Failure
- unsupported artifact schema
- 04Compare
- Input
- normalized local + on-chain class
- Assertion
- program and entry points match
- Output
- class-hash comparison report
- Failure
- compiled class hash differs
- 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.
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[[target.starknet-contract]]
sierra = true
casm = trueDecision log
The choices that shape the design—and what each choice costs.
- 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. - 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. - 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.
- Voyager Verifier repositoryRust CLI and reusable library for Voyager Starknet class verification.
- Voyager Verifier documentationCurrent configuration, batch, status, history, and troubleshooting guides.
- Starknet Foundry verify commandOfficial sncast reference for submitting verification to Voyager or Walnut.
- Scarb Starknet contract artifactsOfficial description of Sierra, CASM, and the generated artifact index.
Related projects
Inspect the systems that ground this guide in implementation work.
- Rust · Starknet · CairoVoyager VerifierStarknet contract verification tooling with compiler integration and status tracking.
- TypeScript · CLI · AI ToolingSkills DoctorTypeScript CLI for auditing Claude/Codex Agent Skills for quality, structure, scoring, and repair readiness.
- Rust · Docker · SolidityAggSandboxCross-chain infrastructure experiments using LayerZero, AggLayer concepts, and executable contract scripts.
Last updated: