Technical Overview

Understanding how Mirage works under the hood

Mirage is a decentralized, censorship-resistant discussion platform (Reddit-like UX) backed by an application-specific blockchain and a full web stack. It is designed so anyone can run a node that serves the site, participates in consensus, and mirrors global state. Users can participate without tokens using a lightweight, browser-executed Proof-of-Work (PoW), while token holders gain additional capabilities and guarantees.

This document explains how Mirage works at a high level for technical readers. It focuses on architecture, core flows, security model, and operational conventions, without going into wire formats or endpoint payloads.

Important: anyone can use Mirage without a wallet or tokens. The browser does a small PoW and your post/comment/vote is accepted. No "crypto bro" setup required. The token path adds priority and features, but is optional by design.

High-level goals

  • Censorship resistance through many independent nodes sharing a global state.
  • Low-friction onboarding via Free Tier (no wallet required) powered by client-side PoW.
  • Priority and advanced features through Pro Tier (token-paid) operations.
  • Clear architecture and operational simplicity while following proven blockchain conventions.

System Architecture

Mirage consists of four major parts that work together:

Application-specific blockchain

Using a Tendermint/CometBFT Byzantine Fault Tolerant (BFT) consensus engine that has been battle-tested for years; compiled as the miraged binary.

Core module x/core

Defines Mirage-specific logic (posts, votes, usernames, PoW accounting, minting parameters, moderation actions).

Web backend (Flask)

Relays user messages to the chain and exposes a simple HTTP API for the frontend and tools.

React frontend (SPA)

Provides the UI, performs local cryptography, and solves PoW in a Web Worker.

Optional components:

Indexer (/indexer) for read-optimized queries and analytics.

Chain layer

  • Mirage's own blockchain runs a CometBFT (Tendermint-family) BFT consensus.
  • Base denom: umirage (micro-denom). Bech32 address prefix: mirage.
  • Chain ID: mirage-1 (fixed).
  • Binary name: miraged.
  • Includes built-in modules for accounts, balances, staking, slashing, distribution, minting, governance, parameter management, upgrades, and interchain support (IBC wiring), plus the Mirage-specific x/core module.

Web backend

  • Python/Flask app that provides a stable HTTP surface for the frontend and scripts.
  • Constructs and relays transactions to the node's RPC/gRPC/ABCI interfaces.
  • Attaches transaction fees and handles networking, retries, and result propagation.
  • Runs under Gunicorn in production; simple app.run() in development.

Frontend

  • React SPA with a clean, responsive UI for browsing, posting, voting, profiles, and network status.
  • Generates/holds user keys client-side. The mnemonic/seed never leaves the browser.
  • Solves browser-based PoW using Argon2id inside a dedicated Web Worker to keep the UI responsive.

Indexer (optional)

Consumes chain state, events, and ABCI queries to build read-optimized views for the UI (feeds, profiles, summaries) and external analytics.

Data and Message Model

The x/core module defines the primary message families that represent user activity:

  • Posts and comments
  • Votes (upvote/downvote)
  • Username claims/changes
  • Moderation primitives (e.g., block post, block user, set moderators)
  • Utility messages (e.g., module-scoped send tokens, if enabled)

Mirage follows standard blockchain application patterns with a pre-execution check pipeline specific to Mirage's PoW and relay model.

Identity, Authorization, and Relay

Mirage separates "who executes the outer transaction" from "who authored the content."

  • The outer transaction signer (the "authority") is the relayer (typically the node's relay/faucet account or the governance module for parameter updates). The end-user is not the outer signer in the Free/relayed path.
  • The end-user's identity and authorization are embedded inside each Mirage message via a meta-signature (public key + signature over canonical bytes). This meta-signature is validated by a custom ante decorator before any state change.
  • The node attaches fees and broadcasts the transaction on behalf of the user. This enables Free Tier usage without requiring the user to fund an on-chain account.

This design keeps keys client-side while aligning with industry norms for fees, routing, and pre-execution verification.

Access Tiers and Anti‑Spam

Mirage supports two complementary paths for user actions:

Free Tier (default)

Actions are admitted through client-side PoW. No wallet or tokens are required. The browser computes a proof that meets the current chain difficulty, and the node relays the message to the chain.

Pro Tier

Actions pay fees in tokens and can bypass PoW. This provides priority and unlocks advanced functionality (custom usernames, guaranteed relaying, extended limits, optional moderation roles, and other perks).

This two-tier model keeps entry friction low while maintaining strong spam resistance and predictable throughput.

Note: this is deliberate: normal users can participate immediately without "doing crypto." Tokens are optional for priority and extra features.

Proof‑of‑Work (PoW)

  • Algorithm: Argon2id tuned for mobile devices (e.g., time=1, memory ~4–8 MiB, parallelism=1, 32-byte digest).
  • Executed client-side in a Web Worker for responsive UX.
  • Salt: recent block hash, with a bounded acceptance window to prevent stale or precomputed proofs.
  • Validity: digest must have a number of leading zero bits ≥ the active difficulty threshold.

Why Argon2id:

  • Memory-hard and bandwidth-bound which reduces specialized hardware advantage compared to hash-only schemes like SHA-256.
  • Tunable so puzzles complete in seconds on commodity laptops and mobile devices without excessive heat or battery drain.
  • Mature and audited with high quality WebAssembly implementations, suitable for secure execution inside the browser.
  • The Argon2id variant blends Argon2i and Argon2d to mitigate side-channel issues and GPU precomputation advantages.
  • Improves fairness and UX by emphasizing short, bounded CPU and memory bursts rather than continuous high-power mining.

Difficulty control:

Sliding-window scheme over recent blocks counts accepted PoW messages and adjusts difficulty up/down using parameters:

  • MinDifficulty
  • PowMessageWindow
  • BusyPeriodDefinition, DifficultyUpThreshold
  • CalmPeriodDefinition, DifficultyDownThreshold
  • BlockHashWindow
  • MintInterval, MintQuantity

All of these are on-chain module params and can be updated via governance.

Fees, Gas, and Economics

  • A minimum gas price is configured by validators. Mempool admission enforces this.
  • In the relayed path, the node pays chain gas/fees (sets a payer on the outer transaction), so Free Tier users do not need tokens.
  • Messages may include optional in-message "application fees" (distinct from gas). If set, these are deducted from the author's balance during delivery by the module.
  • Minting: at fixed intervals (MintInterval), the chain mints MintQuantity umirage into the module account and auto-distributes to the bonded pool/validators according to stake, keeping balances clean by burning residuals as needed.

Transaction Lifecycle

  1. User action (post, comment, vote) in the frontend.
  2. Frontend builds canonical bytes for the Mirage message and signs locally with the user's key.
  3. Frontend computes PoW (Free Tier) against the most recent block hash window.
  4. Frontend submits the meta-signed message and proof to the backend.
  5. Backend wraps the message in an outer transaction, attaches fees (payer is the node), and broadcasts to the chain.
  6. Node pre-execution handling:
    • Logging and basic checks (timeout/Tx size gas).
    • Ensure accounts exist for derived addresses when needed.
    • Pay fees from the designated payer.
    • Verify PoW against the active difficulty and block-hash window; record PoW counters.
    • Enforce chain-specific staking/usage rules.
    • Verify the meta-signature (author identity).
  7. DeliverTx executes the module message handler, emits events, and persists state.
  8. Indexer/UI observe state/events and update feeds and views.

Governance and Parameters

  • The x/core module exposes a parameter set that controls PoW difficulty behavior, minting schedule, and safety windows (as described above).
  • Governance proposals update params and can also enact administrative actions consistent with chain norms.

Validators and Staking

  • Follows standard staking and slashing conventions.
  • Enforces a minimum self-delegation of 1 MIRAGE (1,000,000 umirage) for MsgCreateValidator to ensure skin-in-the-game at the chain level.
  • Operational conventions (suggested):
    • Moniker format: mirage-node-X (e.g., mirage-node-1).
    • Minimum gas price set in app.toml and startup scripts to keep mempools healthy.

Security Model and Invariants

  • Private keys remain in the browser; the backend never receives the mnemonic/seed or private key.
  • The outer transaction signer is the relayer ("authority"), not the end-user; user identity is enforced by the validated meta-signature embedded in each Mirage message.
  • PoW gating throttles spam independently of account sequence economics.
  • Strict pre-execution ordering ensures: accounts exist, fees are covered, PoW passes, then the meta-signature is verified before any state change.
  • Only recent block hashes are accepted as PoW salts to prevent replay or precomputation.

Storage, Retention, and Content

The chain tracks consensus state and events. It is not a general-purpose permanent storage layer.

Persistent on-chain state includes:

  • Username registry and ownership mapping
  • Account addresses, balances, and transfers
  • Staking and validator metadata, slashing records, and related consensus data
  • Governance parameters, PoW difficulty state, and minting counters
  • Module configuration and moderation registries where applicable

Ephemeral and off-chain indexed content includes:

  • Post and comment bodies, attachments, and full discussion threads
  • Vote details and ranking views built for feeds
  • Reports, analytics, and other read models produced by indexers

Posts and comments are validated and finalized for inclusion, but their full content is not durably stored on-chain. Indexers persist and serve this content according to their own retention policies. If an indexer loses the history and no other node retains it, that content is gone. This is intentional and is the origin of the name Mirage.

In other words, user content such as posts and comments is ephemeral and exists only as long as nodes choose to keep it. Hence the name Mirage.

Because many nodes can mirror content, local hiding or removal by one node does not erase global availability. Users can switch nodes.

Deployment and Environments

  • The chain binary is miraged.
  • Chain ID is fixed to mirage-1.
  • Docker artifacts and helper scripts are provided under /deploy and /scripts (including Caddy integration and remote/local deployment helpers).
  • For local scripting and automation, a consistent Python environment is recommended; project scripts assume a stable environment for reproducibility.

Conventions and Where to Look in the Code

Chain application wiring and pre-execution (ante):

  • node/app/app.go (app wiring, pre-execution chains, proposal handlers)
  • node/app/ante_pow.go, node/app/ante_metasig.go, node/app/ante_relay_acc.go, node/app/ante_disable_staking.go, node/app/ante_log.go

Custom fee logic:

  • node/app/powfee.go

Core module:

  • node/x/core/types/* (params, message types, codec)
  • node/x/core/keeper/* (keepers, difficulty accounting, minting)
  • node/x/core/module/* (module interface and wiring)

Backend:

  • web/backend/app.py, web/backend/factory.py
  • web/backend/routes/* (public/core routes)
  • web/backend/pow.py, web/backend/tx.py, web/backend/params.py

Frontend:

  • web/frontend/src/App.js (routing, theme, data wiring)
  • web/frontend/src/utils/TransactionHandler.js (message build/submit, local caching)
  • web/frontend/public/pow/worker.js (Argon2id PoW worker)