Skip to content

Local Deploy Guide

This guide explains how to build and deploy OHSHII Launcher canisters to a local dfx replica for testing and hash verification without deploying to mainnet.

Local deployment allows you to:

  • ✅ Verify that Docker-built WASM files install correctly
  • ✅ Confirm that WASM hashes are deterministic and reproducible
  • ✅ Test canister functionality locally before mainnet deployment
  • ✅ Validate upgrade hooks and initialization logic
  • NOT for production use - mainnet deployment requires ./docker-deploy.sh
  1. Docker Desktop - Must be running

    Terminal window
    docker --version # Should show Docker version
    docker info # Should not error
  2. dfx (Internet Computer SDK)

    Terminal window
    dfx --version # Should show dfx 0.15.0 or later
  3. Bash shell - macOS/Linux terminal or WSL on Windows

  • docker-build.sh - Builds reproducible WASM files
  • local-deploy.sh - Deploys to local replica (this guide)
  • Dockerfile - Docker build configuration
Terminal window
# 1. Build WASM files with Docker
./docker-build.sh
# 2. Deploy to local replica
./local-deploy.sh
# 3. Test (optional)
dfx canister call ohshii_launcher_backend get_version
# 4. Stop local replica when done
dfx stop
Terminal window
./docker-build.sh

What this does:

  1. Builds all canisters in Docker container (reproducible environment)
  2. Optimizes WASM files with ic-wasm
  3. Generates TypeScript declarations for sons_governance
  4. Outputs *_docker.wasm files in project root
  5. Saves SHA-256 hashes to WASM_HASHES.txt

Expected output:

ohshii_launcher_backend_docker.wasm
dao_storage_docker.wasm
pool_manager_docker.wasm
ohshii_governance_docker.wasm
sons_governance_docker.wasm

Time: ~5-10 minutes (first build), ~2-3 minutes (subsequent builds with Docker cache)

Terminal window
./local-deploy.sh

What this does:

  1. Checks if local dfx replica is running (starts it if not)
  2. Creates canisters on local network (if they don’t exist)
  3. Installs Docker-built WASM files with dfx canister install --mode reinstall
  4. Queries each canister’s module hash with dfx canister info
  5. Compares local WASM hash vs deployed module hash
  6. Reports verification results

Expected output:

========================================
OHSHII-LAUNCHER - Local Deploy
========================================
Step 1/5: Checking dfx local replica...
✓ Local replica is already running
Step 2/5: Creating canisters (if needed)...
✓ Canisters created/verified
Step 3/5: Installing Docker WASM files...
1/4 ohshii_launcher_backend
Deploying ohshii_launcher_backend...
✓ Installed
Verifying ohshii_launcher_backend hash...
[OK] Hash verified: abc123...
2/4 dao_storage
...
========================================
✓ All canisters deployed successfully!
✓ All hashes verified!
========================================

Time: ~2-3 minutes

Terminal window
# Get canister IDs
dfx canister id ohshii_launcher_backend
# Call a query method
dfx canister call ohshii_launcher_backend get_version
# Call an update method (example)
dfx canister call dao_storage get_campaign '("campaign-id-here")'
Terminal window
# Stop local replica
dfx stop
# Optional: Remove local state (fresh start next time)
rm -rf .dfx

Hash verification ensures:

  1. Reproducibility - Same source code → same WASM hash
  2. Transparency - Community can verify deployed code matches source
  3. Security - Prevents unauthorized code modifications
  4. DAO Compliance - Required for governance proposals
┌─────────────────────────────────────────────────────────────┐
│ 1. Docker Build │
│ Source Code → Docker Container → WASM File │
│ SHA-256(WASM) = abc123... │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 2. Local Deploy │
│ WASM File → dfx canister install → Canister │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 3. Hash Query │
│ dfx canister info → Module Hash = abc123... │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 4. Verification │
│ SHA-256(WASM) == Module Hash ? ✓ : ✗ │
└─────────────────────────────────────────────────────────────┘
[OK] Hash verified: 3a5f8c2e9b1d4a7c6e8f0b2d5a9c1e4f7b0d3a6c9e2f5b8d1a4c7e0f3b6d9a2c

This means:

  • ✅ Local WASM file matches deployed canister
  • ✅ Build is reproducible
  • ✅ No tampering or corruption
[ERROR] Hash mismatch!
Expected (local): 3a5f8c2e...
Actual (deployed): 9f2b4d7a...

This indicates:

  • ❌ WASM file doesn’t match deployed code
  • ❌ Possible causes:
    • Wrong WASM file deployed
    • Incomplete Docker build
    • Corrupted WASM file
    • Different source code version

Solution: Re-run ./docker-build.sh and ./local-deploy.sh

CanisterPurposeWASM File
ohshii_launcher_backendCore business logicohshii_launcher_backend_docker.wasm
dao_storageData persistencedao_storage_docker.wasm
pool_managerLiquidity pool managementpool_manager_docker.wasm
ohshii_governanceGovernance proposalsohshii_governance_docker.wasm
  • ohshii_launcher_frontend - Not needed for hash verification
  • External canisters (ICP ledger, cycles_ledger, etc.) - Not available locally
AspectLocal DeploymentMainnet Deployment
Script./local-deploy.sh./docker-deploy.sh
NetworkLocal dfx replicaInternet Computer mainnet
Canister IDsAuto-generated (temporary)Fixed production IDs
PasswordNot requiredRequired (from .env.deploy)
External canistersNot availableFully functional
FrontendNot deployedDeployed to asset canister
CostFree (local cycles)Real cycles consumed
PurposeTesting & verificationProduction deployment

Cause: Docker Desktop is not started

Solution:

Terminal window
# macOS: Open Docker Desktop app
open -a Docker
# Wait for Docker to start, then retry
./docker-build.sh

Cause: docker-build.sh was not run or failed

Solution:

Terminal window
# Run Docker build first
./docker-build.sh
# Then deploy
./local-deploy.sh

Cause: dfx replica crashed or hung

Solution:

Terminal window
# Stop and clean
dfx stop
rm -rf .dfx
# Restart
dfx start --background --clean
# Retry deployment
./local-deploy.sh

Cause: WASM file doesn’t match deployed canister

Solution:

Terminal window
# Rebuild from scratch
./docker-build.sh
# Redeploy with fresh WASMs
./local-deploy.sh

Warning: “Could not retrieve module hash”

Section titled “Warning: “Could not retrieve module hash””

Cause: Canister info query failed or output format changed

Solution:

Terminal window
# Manually check hash
dfx canister info ohshii_launcher_backend
# Compare with local WASM
shasum -a 256 ohshii_launcher_backend_docker.wasm
Terminal window
# Create canister
dfx canister create ohshii_launcher_backend
# Install WASM
dfx canister install ohshii_launcher_backend \
--wasm ./ohshii_launcher_backend_docker.wasm \
--mode reinstall \
--yes
# Verify hash
dfx canister info ohshii_launcher_backend
shasum -a 256 ohshii_launcher_backend_docker.wasm
Terminal window
# Stop replica
dfx stop
# Remove all local state
rm -rf .dfx
# Start fresh
dfx start --background --clean
# Redeploy
./local-deploy.sh
Terminal window
# First deployment
./local-deploy.sh
# Make code changes, rebuild
./docker-build.sh
# Redeploy (replica stays running)
./local-deploy.sh
  1. Test locally - Verify canister methods work as expected
  2. Review logs - Check for any warnings or errors
  3. Stop replica - dfx stop when done testing
  1. Verify all hashes - Ensure local deployment succeeded
  2. Review changes - Confirm code changes are correct
  3. Backup data - Export important state if needed
  4. Create .env.deploy - Add password for mainnet deployment
  5. Run mainnet deploy - ./docker-deploy.sh
  1. Always build with Docker - Ensures reproducibility
  2. Verify hashes locally first - Catch issues before mainnet
  3. Test upgrade hooks - Ensure post_upgrade works correctly
  4. Stop replica when done - Frees system resources
  5. Never use local for production - Always use mainnet for real users
Terminal window
# Complete workflow
./docker-build.sh # Build reproducible WASMs
./local-deploy.sh # Deploy & verify locally
dfx stop # Clean up when done
# For mainnet deployment
./docker-deploy.sh # Deploy to production (requires password)

Remember: Local deployment is for testing and verification only. Always use ./docker-deploy.sh for mainnet deployments.