Overview
Reproducible builds are the foundation of the verification network. They enable:- Build integrity verification: Proof that deployed code matches source code
- Independent verification: Multiple verifiers can confirm the same result
- Byzantine fault tolerance: Majority consensus prevents malicious approvals
- Cryptographic auditability: Permanent on-chain record of verification attestations
Architecture
Build Environment Components
The reproducible build system consists of several layers:Base Docker Image
Pre-built image with pinned versions of the Motoko compiler (
moc), WASM
optimizer (ic-wasm), and package manager (mops-cli).Build Script
A standardized
build.sh script that compiles Motoko source code to
optimized WASM using locked dependency versions.Docker Compose
Orchestrates the build process with proper dependency ordering and isolated
environments for each verification.
Verifier Bot
Automated service that clones repositories, triggers Docker builds, computes
hashes, and files on-chain attestations.
Dockerfile Structure
Base Image (Dockerfile.base)
The base image is built using Alpine Linux for minimal, reproducible builds:- Pinned versions: Every tool version is explicitly specified via
ARG - Deterministic downloads: Uses official releases with version tags
- Multi-stage build: Separates build-time dependencies from runtime
- Minimal runtime: Only essential tools in the final image
Project Image (Dockerfile)
Each project builds on the base image:- Start from versioned base image
- Install locked dependencies from
mops.toml - Copy source files
- Execute build script
Build Script (build.sh)
The build script is a standardized bash script that compiles Motoko to optimized WASM:moc: Compile Motoko to unoptimized WASMic-wasm shrink: Remove debug symbols and optimize for sizesha256sum: Compute hash for verification
Docker Compose Configuration
Thedocker-compose.yml orchestrates the build:
- depends_on: Ensures base image builds before project image
- volumes: Mounts output directory for extracting built WASM
- environment variables: Tool versions configured via
.env
Verification Workflow
1. Developer Builds Locally
Developer publishes withapp-store-cli release:
2. Verifier Bot Detects Pending Verification
Verifier bot polls the registry:3. Bot Performs Reproducible Build
The verifier bot automates the entire build process:4. Bot Files Attestation
If hashes match, the bot files an on-chain attestation:Ensuring Determinism
Pinned Tool Versions
All toolchain versions are pinned indocker-compose.yml:
Locked Dependencies
Dependencies are locked inmops.toml:
mops-cli install --locked command ensures exact versions are used.
Isolated Environment
Each build runs in a fresh Docker container with:- No network access during compilation
- No host system dependencies
- Clean filesystem (
--no-cacheflag) - Consistent timezone and locale
Cross-Platform Consistency
Since Motoko compiler version 0.13.4, builds are reproducible across:- Linux (x86_64)
- macOS (M1/M2 ARM and Intel)
- Windows (via WSL2)
Security Considerations
Supply Chain Security
Risk: What if a toolchain binary is compromised? Mitigation:- Tool binaries are fetched by version number AND hash verification
- Base images use SHA-256 pinning:
alpine:latest@sha256:... - Build template repo uses GitHub Dependabot and security scanning
- Multiple independent verifiers pulling from different CDN endpoints
- Community monitoring of unexpected hash changes
Build Environment Tampering
Risk: What if a verifier modifies the Docker build process? Mitigation:- Majority consensus (5 of 9) prevents single verifier attacks
- Each verifier operates independently (no coordination)
- Divergent results trigger manual security audit
- Economic staking disincentivizes dishonest behavior
Time-of-Check to Time-of-Use (TOCTOU)
Risk: What if code changes after verification? Mitigation:- Verifications are tied to specific Git commit hashes
- WASM hash is cryptographically bound to attestation
- Deployments only accept verified WASM hashes
- On-chain audit trail prevents tampering
Performance Optimization
Build Caching
For repeated builds of the same project:Parallel Verification
Verifier bots can process multiple verifications simultaneously:Resource Management
Recommended verifier server specs:- CPU: 2+ cores (for parallel builds)
- RAM: 4GB minimum, 8GB recommended
- Disk: 20GB+ SSD (for Docker images and build artifacts)
- Network: 100+ Mbps (for fast git clones)
Troubleshooting
Hash Mismatch
Symptoms: Verifier’s hash doesn’t match developer’s hash Common Causes:- Different tool versions: Check
MOC_VERSIONin both environments - Modified source code: Ensure exact commit hash is used
- Unlocked dependencies: Use
mops-cli install --locked - Platform differences: Ensure both use Linux x86_64 or macOS M1+
Build Timeout
Symptoms: Docker build exceeds 1-hour stake lock period Solutions:- Increase server resources (CPU/RAM)
- Use SSD storage for faster I/O
- Pre-pull base images:
docker pull motoko-build-base:moc-0.16.0
Dependency Installation Fails
Symptoms:mops-cli install --locked fails
Common Causes:
- Network issues: Check internet connectivity
- Rate limiting: Use GITHUB_TOKEN for private package access
- Invalid mops.toml: Validate syntax
Reference
Official Build Template
The canonical reproducible build template is maintained at:- GitHub: research-ag/motoko-build-template
- Container Registry:
ghcr.io/prometheus-protocol/motoko-build-template
Tool Documentation
- Motoko: internetcomputer.org/docs/motoko
- ic-wasm: github.com/research-ag/ic-wasm
- mops-cli: github.com/prometheus-protocol/mops-cli
- Docker: docs.docker.com
ICRC Standards
- ICRC-118: WASM Registry
- ICRC-120: Canister Orchestration
- ICRC-126: Verification & Auditing
- ICRC-127: Bounty System
For questions or issues with reproducible builds, join our Discord community or open an issue on GitHub.

