Skip to main content
Prometheus Protocol uses a deterministic Docker-based build system to ensure that any developer or verifier can rebuild a WASM file from source and get byte-for-byte identical output. This technical reference explains how the system works.

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:
Key Features:
  • 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:
Build Process:
  1. Start from versioned base image
  2. Install locked dependencies from mops.toml
  3. Copy source files
  4. Execute build script

Build Script (build.sh)

The build script is a standardized bash script that compiles Motoko to optimized WASM:
Optimization Steps:
  • moc: Compile Motoko to unoptimized WASM
  • ic-wasm shrink: Remove debug symbols and optimize for size
  • sha256sum: Compute hash for verification

Docker Compose Configuration

The docker-compose.yml orchestrates the build:
Key Features:
  • 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 with app-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 in docker-compose.yml:

Locked Dependencies

Dependencies are locked in mops.toml:
The 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-cache flag)
  • 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)
All platforms produce byte-for-byte identical WASM when using the same tool versions.

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:
Layer caching speeds up dependency installation.

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:
  1. Different tool versions: Check MOC_VERSION in both environments
  2. Modified source code: Ensure exact commit hash is used
  3. Unlocked dependencies: Use mops-cli install --locked
  4. Platform differences: Ensure both use Linux x86_64 or macOS M1+
Debugging:

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:
  1. Network issues: Check internet connectivity
  2. Rate limiting: Use GITHUB_TOKEN for private package access
  3. Invalid mops.toml: Validate syntax
Fix:

Reference

Official Build Template

The canonical reproducible build template is maintained at:

Tool Documentation

ICRC Standards


For questions or issues with reproducible builds, join our Discord community or open an issue on GitHub.