Skip to main content
Verifiable builds ensure that the binary deployed on-chain can be independently reproduced from source code. This is critical for security audits and establishing trust in deployed programs.

Why Verifiable Builds?

Building Solana programs with the standard toolchain can embed machine-specific information into the resulting binary. This means:
  • Building the same source code on different machines produces different binaries
  • It’s impossible to verify that deployed code matches the published source
  • Auditors cannot confirm the on-chain program matches reviewed code
Verifiable builds solve this by building inside a Docker container with pinned dependencies, ensuring identical outputs regardless of the build environment.

Prerequisites

Before creating verifiable builds, install Docker: Verify Docker is running:
docker --version

Building with —verifiable

Anchor handles all Docker operations automatically. To create a verifiable build:
anchor build --verifiable
This command:
  1. Pulls the official Anchor Docker image for your version
  2. Mounts your project directory into the container
  3. Builds your program(s) in the isolated environment
  4. Outputs the compiled .so files to target/verifiable/
The first verifiable build downloads the Docker image (~1-2 GB) which may take several minutes. Subsequent builds are much faster.

Build Output

Verifiable builds create additional output:
project/
├── target/
│   ├── deploy/              # Standard builds
│   │   └── program.so
│   └── verifiable/          # Verifiable builds
│       └── program.so
│   └── idl/
│       └── program.json

Verifying Deployed Programs

To verify that a deployed program matches your local build:
anchor verify -p <lib-name> <program-id>
Where:
  • <lib-name>: The library name from your program’s Cargo.toml
  • <program-id>: The on-chain program address

Example

# Verify a program on mainnet
anchor verify -p my_program Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS
The verification process:
  1. Builds your program verifiably
  2. Fetches the deployed program binary from the blockchain
  3. Compares the two binaries byte-by-byte
  4. If an IDL exists, verifies the on-chain IDL matches your local version

Verification Output

Success:
 Successfully verified program my_program
  On-chain program hash: abc123...
  Built program hash:    abc123...
  IDL hash:             def456...
Failure:
 Verification failed for program my_program
  On-chain hash: abc123...
  Built hash:    xyz789...
  
  The deployed program does not match your local build.

Docker Images

Anchor publishes official Docker images on Docker Hub for each release.

Image Tags

Images follow the format: solanafoundation/anchor:v<version>
# Pull a specific version
docker pull solanafoundation/anchor:v0.32.1

# List locally available images
docker images | grep anchor

Image Contents

Each image includes:
  • Anchor CLI (matching version)
  • Solana CLI tools
  • Rust toolchain (specific version)
  • Build dependencies

Specifying Versions

Control which versions are used for verifiable builds through Anchor.toml:
Anchor.toml
[toolchain]
anchor_version = "0.32.1"    # Anchor CLI version
solana_version = "2.3.0"     # Solana tools version
When you run anchor build --verifiable, Anchor uses the Docker image matching your specified anchor_version.
If anchor_version is not specified in Anchor.toml, Anchor uses the version of your currently installed CLI, which may not match the deployed program.

Advanced Usage

Build Specific Programs

Build only certain programs from a multi-program workspace:
anchor build --verifiable -p program_name

Custom Docker Image

Use a custom Docker image for builds:
anchor build --verifiable --docker-image custom/anchor:latest

Source Code Verification

For building from a specific commit:
# Checkout specific commit
git checkout <commit-hash>

# Build verifiably
anchor build --verifiable

# Verify against deployed program
anchor verify -p program_name <program-id>

Troubleshooting

Docker Container Issues

If a verifiable build is interrupted, the container may still be running:
# List running containers
docker ps

# Remove the Anchor build container
docker rm -f anchor-program

Disk Space

Docker images consume significant disk space. Clean up old images:
# Remove unused images
docker image prune

# Remove specific Anchor image
docker rmi solanafoundation/anchor:v0.32.1

Build Failures

Dependency Resolution Issues: If builds fail due to dependency resolution, ensure your Cargo.lock is committed:
git add Cargo.lock
git commit -m "Lock dependencies for verifiable builds"
Version Mismatches: Verify your local Anchor version matches Anchor.toml:
anchor --version
Use AVM to switch versions:
avm use 0.32.1

Permission Errors

On Linux, Docker may create files owned by root. Fix ownership:
sudo chown -R $USER:$USER target/verifiable/

CI/CD Integration

Integrate verifiable builds into your deployment pipeline:

GitHub Actions Example

.github/workflows/verifiable-build.yml
name: Verifiable Build

on:
  push:
    branches: [main]
  pull_request:

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Install Anchor
        run: |
          cargo install --git https://github.com/coral-xyz/anchor anchor-cli --locked --force
      
      - name: Run verifiable build
        run: anchor build --verifiable
      
      - name: Upload artifacts
        uses: actions/upload-artifact@v3
        with:
          name: verifiable-builds
          path: target/verifiable/

Best Practices

Never deploy programs built without the --verifiable flag to mainnet:
# Production deployment
anchor build --verifiable
anchor deploy --provider.cluster mainnet
Specify exact versions in Anchor.toml to ensure reproducibility:
[toolchain]
anchor_version = "0.32.1"  # Not "0.32" or "latest"
solana_version = "2.3.0"   # Not "2.3" or "latest"
Always commit your Cargo.lock file:
# .gitignore
# Cargo.lock  # <- DO NOT IGNORE for programs
This ensures dependency versions are locked across all builds.
Include verification steps in your README:
## Verification

To verify the deployed program matches this repository:

1. Checkout the deployment commit: `git checkout abc123`
2. Build: `anchor build --verifiable`
3. Verify: `anchor verify -p program_name PROGRAM_ID`
Verify the build process works before deploying:
# Build verifiably
anchor build --verifiable

# Deploy to devnet first
anchor deploy --provider.cluster devnet

# Verify the devnet deployment
anchor verify -p program_name <devnet-program-id>

Security Considerations

  • Source Code Availability: Publish your source code in a public repository
  • Commit Hash: Document which commit corresponds to deployed versions
  • Build Reproducibility: Test that multiple people can reproduce your build
  • Upgrade Authority: Consider program upgradeability when planning verifiable deployments

Resources

Build docs developers (and LLMs) love