MIDSTATE

System Overview

Midstate is a peer-to-peer electronic cash system engineered from the ground up for constrained edge environments (specifically Cortex-A53/A72/A76 architectures). It entirely abandons elliptic curve mathematics in favor of post-quantum hash functions.

By enforcing sequential CPU mining, forcing all UTXOs into uniform power-of-2 denominations, it creates a robust, relatively private financial network that cannot be dominated by parallel ASICs or dismantled by blockchain surveillance firms.

Why the name "Midstate"?

In traditional blockchains, blocks are distinct data structures linked by their header hashes. Midstate abandons this design. Instead, the entire blockchain is mathematically modeled as a single, continuous BLAKE3 hash function.

graph LR M0([Midstate N-1]) --> Combine1{+ State Root
+ Nonce} Combine1 --> HashLoop1[BLAKE3
x 1,000,000] HashLoop1 --> M1([Midstate N]) M1 --> Combine2{+ State Root
+ Nonce} Combine2 --> HashLoop2[BLAKE3
x 1,000,000] HashLoop2 --> M2([Midstate N+1]) M2 -.-> Combine3{...} style M0 fill:#431407,stroke:#ea580c,stroke-width:2px style M1 fill:#431407,stroke:#ea580c,stroke-width:2px style M2 fill:#431407,stroke:#ea580c,stroke-width:2px style HashLoop1 fill:#064e3b,stroke:#10b981,stroke-width:2px style HashLoop2 fill:#064e3b,stroke:#10b981,stroke-width:2px

The midstate is the 32-byte internal state of this global hash function. When a miner processes a block, they aren't hashing a static header—they are taking the current network midstate, injecting the new transactions, and advancing it by exactly 1,000,000 sequential BLAKE3 compression cycles. Every transaction permanently mutates this singular, ongoing mathematical state.

How is Midstate Different?

Unlike first-generation blockchains (like Bitcoin or Ethereum), Midstate was engineered specifically to solve hardware centralization and on-chain surveillance:

  • No Elliptic Curves (Post-Quantum): It uses zero ECC math (no secp256k1). Every signature, commitment, and script relies solely on the BLAKE3 hash function, immunizing the network against Shor's algorithm.
  • Sequential vs. Parallel Mining: Typical PoW allows ASICs to run trillions of hashes in parallel. Midstate forces miners to compute hashes in a strict, unrollable sequence, shifting the bottleneck from parallel throughput to single-thread latency.
  • Power-of-2 UTXOs: Standard UTXOs use exact amounts (e.g., 1.452 coins), creating unique cryptographic fingerprints. Midstate forces all coins into identical power-of-2 denominations, fracturing surveillance graphs.
  • Commit-Reveal Mempool: Standard mempools broadcast cleartext trades, enabling MEV (Miner Extractable Value) front-running. Midstate blinds transactions in the mempool until a miner cryptographically commits to processing them.
  • Bounded State (Sparse Merkle Trees): Instead of an infinitely growing LevelDB database, Midstate accumulates UTXOs into a rolling Sparse Merkle Tree, heavily capping the RAM required to run a full node.
Core Hash Primitive
BLAKE3
Block Time & Diff
60s / ASERT
UTXO Model
Powers of 2 Only
22:49:44.101 INFO Loaded state: height=29000 depth=14859300 coins=4582 commitments=12
22:49:44.150 INFO Node started (mining: true, threads: 4, rpc: 8545)
22:49:44.152 INFO Mining SIMD: NEON 4-way (4 nonces/batch)
22:50:11.883 INFO Mined batch! height=29001 outputs=2 target=000ffff...

A full Midstate node can sync, validate transaction proofs, and mine blocks concurrently on a $15 Raspberry Pi Zero 2 W with 512MB of RAM.

Post-Quantum Cryptography

Elliptic Curve Cryptography (secp256k1) is vulnerable to Shor's algorithm via quantum computers. Midstate uses exactly zero elliptic curve mathematics, relying strictly on the BLAKE3 hash function for all cryptographic signatures, commitments, and proofs.

Winternitz One-Time Signatures (WOTS+)

Standard receiving keys and change outputs use WOTS+. Because hash-based signatures reveal parts of the private key during use, WOTS keys must never sign more than once.

To prevent accidental key reuse across sibling UTXOs (coins sent to the same address), Midstate enforces a strict "co-spend grouping" rule in the wallet. If a user attempts to spend one coin, the wallet will autonomously pull in all sibling coins at that address. Spending them in the exact same transaction produces an identical commitment hash, meaning the WOTS signature is identical, resulting in zero additional key leakage.

The Mathematics of w=16

Most WOTS implementations use w=8 (8 bits per digit), which creates 32 message chains of max depth 255. Midstate uses an extreme parameter of w=16.

Message Chains: 256 bits / 16 = 16 chains
Checksum Chains: Σ(65535 - d_i) fits in 20 bits → 2 chains
Total Chains: 18
Max Chain Depth: 65,535 hashes

The Tradeoff: By using w=16, the signature size shrinks from ~1,088 bytes down to exactly 576 bytes (18 chains × 32 bytes). The cost is CPU computation: signing or verifying requires up to 65,535 hashes per chain. This is solved via SIMD acceleration.

Merkle Signature Scheme (MSS)

If a user requires a static, reusable address (e.g., for a donation page or a mining pool payout), Midstate wraps thousands of WOTS keys into an MSS binary tree. The Master Public Key is the root of the Merkle tree.

Generating a default height-10 tree (1,024 signatures) locally takes ~1-2 seconds on modern CPUs. The signature size increases logarithmically: a 576-byte WOTS payload + (Height × 33 bytes for the authentication path).

The Replay Defense (Spent Oracle)

To prevent replay attacks during chain reorgs, the consensus engine maintains a spent_addresses database table.

For standard WOTS, the address hash is burned. For MSS, burning the address would destroy the entire tree. Instead, the protocol dynamically extracts the specific leaf's WOTS public key from the MSS signature and burns that specific nullifier. If the exact same transaction is replayed during a reorg, the commitment hashes match and it is accepted. If a different transaction attempts to reuse that leaf, it is rejected by consensus.

The SIMD Masking Trick

With w=16, WOTS chain iterations vary wildly. Chain 0 might need 5 hashes, while Chain 1 needs 60,000 hashes. Standard scalar execution handles these one by one.

Midstate accelerates this using hardware SIMD registers (AVX2 256-bit on x86, NEON 128-bit on ARM). But because SIMD lanes execute in strict lockstep, how do you handle varying lengths?

Ghost Hashing

Midstate feeds 8 chains (AVX2) into a single register. It loops up to the maximum iterations required by the longest chain in the batch. As the loop progresses, it checks if the current step matches a lane's target depth. If it does, it extracts and saves that lane's 32-byte state. The lane then continues to compute garbage hashes ("ghost hashing") alongside its neighbors until the longest chain finishes.

Even with millions of wasted "ghost" cycles, keeping the CPU pipeline saturated via SIMD results in a 10x faster signature generation on edge devices.

Mining & Consensus

Neutralizing Parallel ASICs

Traditional Proof-of-Work (like SHA-256) operates in O(1) time and O(N) space. Finding a nonce is like buying lottery tickets: if you buy 100,000 tickets at once, you find the winner 100,000 times faster. ASICs achieve massive hashrates by stamping millions of parallel hash cores onto a single silicon die.

Midstate inverts this model using Sequential Hashing. Finding a nonce is no longer a lottery; it is a marathon.

graph TD subgraph Parallel [Bitcoin: Parallel PoW - ASIC Friendly] direction LR N1([Nonce 1]) -.-> H1[SHA256] --> C1{Check} N2([Nonce 2]) -.-> H2[SHA256] --> C2{Check} N3([Nonce 3]) -.-> H3[SHA256] --> C3{Check} end subgraph Sequential [Midstate: Sequential PoW - CPU Friendly] direction LR S1([State + Nonce]) --> S2[BLAKE3] --> S3[BLAKE3] --> S4[... x 1,000,000] --> S5[Final Hash] --> C4{Check} end style Parallel fill:#1f2937,stroke:#4b5563,stroke-width:2px,color:#d1d5db style Sequential fill:#431407,stroke:#ea580c,stroke-width:2px,color:#fed7aa style S2 fill:#064e3b,stroke:#10b981,stroke-width:2px style S3 fill:#064e3b,stroke:#10b981,stroke-width:2px style S4 fill:#064e3b,stroke:#10b981,stroke-width:2px style S5 fill:#064e3b,stroke:#10b981,stroke-width:2px

To mine a block, a node must calculate 1,000,000 BLAKE3 hashes in a strict sequence: H_n = BLAKE3(H_{n-1}). Because the input of the next hash relies entirely on the output of the previous, the computation cannot be unrolled or divided across multiple cores.

Proof 1: The Poisson Process (Memorylessness)

Does sequential hashing make block times predictable (like a VDF)? No. The algorithm does not guarantee a block after 1,000,000 hashes. It guarantees that a single attempt (one nonce) takes exactly 1,000,000 hashes. The miner must still check if the final_hash meets the difficulty target.

Each full sequence remains an independent Bernoulli trial. If the probability of meeting the target is p, and the network computes λ sequences per second, the probability of finding a block in time t follows the standard exponential distribution:

P(T ≤ t) = 1 - e-λpt

Midstate simply scales the duration of the trial. Block arrivals remain a memoryless Poisson process, preserving the exact game theory and security guarantees of Nakamoto Consensus.

Proof 2: The Ratio of Power (ASIC Resistance Bound)

In Bitcoin, parallel hashrate is H = C / L (where C is cores, L is latency). ASICs win by scaling C to millions.

In Midstate, a trial requires S sequential hashes. The time for one trial is S × L_core. An ASIC designer must optimize L_core (clock speed) because increasing parallel cores requires duplicating the entire 1,000,000-step state machine per core, demanding massive silicon area.

The Maximum Attacker Advantage (A_max) is the ratio of an ASIC's latency to a consumer CPU's latency:

A_max = L_cpu / L_asic

Because silicon physics caps clock speeds around 4–5 GHz, L_asic cannot physically be millions of times faster than L_cpu. While a datacenter will mine more blocks, their advantage is strictly bounded by single-thread execution limits, creating a provable ~1000:1 hardware ceiling between a supercomputer and a Raspberry Pi.

ASERT Difficulty Adjustment

Sliding-window difficulty algorithms (like LWMA or Bitcoin's 2016-block window) are highly vulnerable to time-warp attacks, hash-and-flee exploits, and echo effects. Midstate adjusts difficulty continuously on every block based on the absolute time elapsed since genesis.

  • Target Block Time: 60 Seconds
  • Adaptation Half-Life: 4 Hours (240 Blocks)

If the network hashrate spikes and blocks are mined in 30 seconds, the ASERT algorithm guarantees the difficulty will exactly double every 4 hours until the 60-second equilibrium is restored.

// ASERT Algorithm
drift = actual_elapsed_time - (height * 60_seconds)
target = genesis_target * 2(drift / 4_hours)

The Determinism Problem

Calculating 2^x requires floating-point math (IEEE 754). Different CPU architectures (x86 vs ARM) or even different compiler optimization flags can yield slightly different results at the far decimal places. In a consensus system, a 1-bit discrepancy results in a permanent chain fork.

Midstate solves this natively using deterministic integer math via a 16.16 fixed-point Taylor polynomial approximation. It calculates the fractional exponent strictly using bitwise shifts, guaranteeing cross-architecture determinism.

let shifts = exponent >> 16; // whole powers of 2
let frac = exponent & 0xFFFF; // fractional part

let mut factor = 65536i64;
factor += (frac * 45426) >> 16;
factor += (frac * frac * 15746) >> 32;
factor += (frac * frac * frac * 3643) >> 48;

Bayesian Finality: Autonomous Risk Management

Most blockchains rely on arbitrary "magic numbers" for finality (e.g., Bitcoin's 6-block rule). This assumes the network's hashpower distribution is static and universally honest. In reality, networks experience partitions, hashpower drops, and active 51% attacks. A static rule is dangerously fragile during a consensus crisis.

Midstate solves this by treating finality as a dynamic probability problem. Every node runs a Bayesian Finality Estimator that continuously models network health to calculate the exact depth z required to keep the risk of a chain reorganization below a strict 10-6 threshold.

1. The Base Model: Gambler's Ruin

Assume honest miners control proportion p of the total hashpower, and an attacker controls q = 1 - p. The probability of an attacker successfully rewriting z blocks of history is a classic Gambler's Ruin problem:

If p > 0.5: P(catchup | p, z) = (q / p)z = ((1 - p) / p)z
If p ≤ 0.5: P(catchup | p, z) = 1.0 (Catchup is mathematically guaranteed)

2. Modeling Uncertainty (The Beta Distribution)

In a decentralized network, a node never truly knows the exact value of p. It must infer it from local observations. Midstate models this uncertainty using a Beta distribution parameterized by α and β.

The Game-Theoretic Prior: Nodes initialize with a hostile prior (e.g., α=2, β=8), assuming 80% of the network is malicious until proven otherwise. As blocks arrive, the node updates its parameters:

// Update Rules (Capped at 10,000 to maintain agility)
On valid block extension: α = min(α + 1, 10000)
On orphan or reorg: β = min(β + 1, 10000)

If we didn't cap these values, a node running for 5 years would have such a high α that it would become completely blind to a sudden 51% attack. The 10,000 cap ensures the node's memory is bounded, allowing the probability density function (PDF) to shift rapidly if hostility spikes.

3. The Expected Risk Integral

Rather than blindly trusting the average estimate of p, the node calculates the Expected Risk by integrating the Gambler's Ruin probability across the entire Beta PDF. It searches for the lowest depth z where this risk drops below 1-in-a-million:

Expected Risk = ∫01 P(catchup | p, z) * fBeta(p; α, β) dp  ≤  10-6

Engineering detail: To prevent IEEE-754 floating-point underflow in Rust, this integral is approximated using Log-Sum-Exp over 1,000 discrete slices.

Game Theory: Bankrupting the Attacker

In Bitcoin, an attacker renting hashpower for a 51% attack simply waits 6 blocks to execute an exchange double-spend. The cost of the attack is fixed and predictable.

In Midstate, an attacker trying to secretly mine a shadow chain will inevitably cause orphan races as their blocks occasionally leak or compete with honest blocks. Every orphan increments β on honest nodes. As β rises, the variance of the Beta distribution widens, increasing the "tail risk" that p ≤ 0.5. The integral forces the safe depth z to skyrocket.

Instead of waiting 6 blocks, merchants and exchanges are mathematically instructed by their nodes to wait 100+ blocks. The attacker is forced to burn millions of dollars sustaining their 51% hashpower monopoly for hours or days, completely bankrupting them before the victim ever considers the transaction "final."

Pool Mining Protocol

Because Midstate uses Sequential Hashing, traditional Bitcoin stratum protocols (where the pool builds the block and sends just the header to the miner) do not work. Miners must construct the block template locally to run the 1,000,000-hash state progression.

To enable pooled mining without allowing miners to steal blocks, Midstate employs a Cryptographic Watermark system.

The Watermark Defense

When a miner configures their node for a pool, they assign the block's reward address to the Pool's MSS Public Key. To prove they actually did the work, the miner embeds their own payout address deep within the Coinbase transaction's salt parameter.

salt = BLAKE3("pool_share" || miner_address || height || output_idx)

When the miner submits a share, the pool server independently recalculates this hash. If it matches, the pool knows the miner expended the PoW for the pool's benefit. The miner cannot redirect the funds to themselves without changing the address, which would change the state root, invalidating the entire 1,000,000-hash PoW sequence.

Share Aggregation & Payouts

The pool server accepts shares at a lower difficulty target (e.g., 20 leading zeros instead of 30) and tallies them in an ACID database (redb). If a submitted share happens to meet the actual network difficulty, the pool server immediately broadcasts it to the network as a full block win.

Periodically, an automated Payout Engine scans the chain for the pool's UTXOs. It calculates proportional payouts based on the tallied shares, constructs a massive 1-to-N transaction, and executes the 2-phase Commit-Reveal spend using the pool's reusable MSS keys.

Economics & Supply

Sound money requires an unforgeable costliness to produce and a strictly bounded, mathematically predictable supply schedule. Midstate enforces a disinflationary emission curve that asymptotically approaches a hard cap, but includes a vital tail emission to ensure perpetual security.

Maximum Supply
1.12 Quadrillion
Halving Interval
525,600 blocks (1 Year)
Initial Reward
230 (1.07 Billion)

The 64-bit Engineering Advantage

A maximum supply of 1.12 quadrillion sounds massive, but a standard unsigned 64-bit integer (u64) can hold up to 18.4 quintillion. Midstate's entire lifetime supply uses only 0.006% of a u64's capacity.

This is a critical architectural decision: the node never has to perform expensive BigInt or 256-bit math to calculate balances, entirely preventing integer overflow vulnerabilities.

The Disinflationary Curve

The block reward begins at 1,073,741,824 units per 60-second block. Every 525,600 blocks (exactly one year), the reward is bit-shifted to the right (halved).

Unlike Bitcoin, which will eventually hit a block reward of exactly 0, Midstate enforces a Tail Emission. After 30 years, the block reward reaches a permanent floor of 1 unit per block. This guarantees miners are always mathematically incentivized to process blocks and secure the chain, even if transaction volume temporarily drops to zero.

The Two-Dimensional Fee Market

Most blockchains operate a single-dimensional fee market: you pay capital to buy block space. Midstate decouples transaction inclusion into two distinct markets, protecting edge nodes from spam while keeping fees predictable.

Phase 1: Commits
Paid via Energy (PoW)
Phase 2: Reveals
Paid via Capital (Value)

1. The Energy Market (Commits)

Because Commit transactions do not transfer value, they cannot pay a standard fee. Instead, users pay for mempool inclusion using CPU cycles. The required Proof-of-Work scales dynamically based on mempool congestion. If the network is quiet, a commit takes ~15 milliseconds to generate. If the network is under a DoS attack, the PoW requirement skyrockets, bankrupting the attacker's CPU resources before they can exhaust node RAM.

2. The Capital Market & RBF (Reveals)

Reveal transactions execute the actual state change and consume block space. Therefore, they must pay a capital fee. The node enforces a minimum relay fee of 10 units per Kilobyte.

Mempool Bounding & Replace-By-Fee (RBF)

To guarantee that Midstate can run on a 512MB Raspberry Pi indefinitely, the Mempool is mathematically capped at 100 Megabytes or 9,000 transactions, whichever is reached first.

When the mempool fills up, the node initiates deterministic Replace-By-Fee (RBF) eviction. The node calculates the fee rate (Fee / Byte Size) of all pending transactions and permanently drops the lowest-paying transactions to make room for higher-paying ones. Because block space is scarce, users must bid against each other to have their Reveals mined during high congestion.

Genesis Construction & Provable Fair Launch

Midstate was engineered with absolute mathematical certainty that no pre-mining, no developer allocation, and no hidden coins ever existed. The entire genesis block is deterministically derived from a real, verifiable Bitcoin block mined in 2026 — making it impossible to have started the chain one second earlier.

Bitcoin Block Anchor (Height 938708)

The genesis midstate is not arbitrary. It is constructed by hashing a specific Bitcoin block that everyone could independently verify existed on the Bitcoin network:

// Bitcoin block used as cryptographic anchor BITCOIN_BLOCK_HASH = "000000000000000000018f5ad5625d43356136c2e50c6dc18967a90a18f0af2e"
BITCOIN_BLOCK_HEIGHT = 938708
BITCOIN_BLOCK_TIME = 1772274770 (Feb 24 2026 UTC)

initial_midstate = BLAKE3( BitcoinHash || Height.to_le_bytes() )

Anyone can open any Bitcoin explorer (e.g. mempool.space, blockchain.com) and confirm this exact block existed. Because the Midstate genesis depends on its hash, the Midstate chain could not have been started before that Bitcoin block was mined.

The Permanent Inscription (Burned Genesis Coins)

The genesis coinbase creates exactly the initial reward of 2³⁰ = 1,073,741,824 units — split into two power-of-2 outputs of 2²⁹ = 536,870,912 each (perfectly compliant with the power-of-2 UTXO rule).

Instead of real public keys, the address and salt fields contain the following plaintext inscription, permanently embedded into the blockchain on disk:

Harvest Now, Decrypt Later: The Quantum Era's Encryption Challenge
(Published Feb 24, 2026, by RBC Disruptors)

This is the exact Rust code that generates the genesis block (from the canonical implementation):

impl State {
    pub fn genesis() -> (Self, Vec<CoinbaseOutput>) {
        // Bitcoin block anchor
        const BITCOIN_BLOCK_HASH: &str = "000000000000000000018f5ad5625d43356136c2e50c6dc18967a90a18f0af2e";
        const BITCOIN_BLOCK_HEIGHT: u64 = 938708;
        const BITCOIN_BLOCK_TIME: u64 = 1772274770;

        let anchor = hash(BITCOIN_BLOCK_HASH.as_bytes());

        // --- The Genesis Inscription (split across address + salt) ---
        let mut chunk0 = [0u8; 32]; chunk0.copy_from_slice(b"Harvest Now, Decrypt Later: The ");
        let mut chunk1 = [0u8; 32]; chunk1.copy_from_slice(b"Quantum Era's Encryption Challen");
        let mut chunk2 = [0u8; 32]; chunk2.copy_from_slice(b"ge (Published Feb 24, 2026, by R");
        let mut chunk3 = [0u8; 32]; chunk3[..13].copy_from_slice(b"BC Disruptors)");

        let genesis_coinbase = vec![
            CoinbaseOutput { address: chunk0, value: 536_870_912, salt: chunk1 },
            CoinbaseOutput { address: chunk2, value: 536_870_912, salt: chunk3 }
        ];

        let initial_midstate = hash_concat(&anchor, &BITCOIN_BLOCK_HEIGHT.to_le_bytes());
        // ... (difficulty target, MMR, etc.)
        (state, genesis_coinbase)
    }
}

Why These Coins Are Mathematically Burned

The address fields contain human-readable text instead of valid WOTS+ or MSS public keys. There is no corresponding private key anywhere in the universe that can spend them. The outputs are therefore provably unspendable — they are permanently removed from the circulating supply the instant the genesis block is created. This is the cryptographic equivalent of burning the initial coins in public.

Mathematical Proof of No Pre-Mining

  • Time-lock via Bitcoin anchor: The chain cannot exist before Bitcoin block 938708 was mined (verifiable by every node).
  • Inscription date lock: The embedded message explicitly references February 24, 2026. Any earlier genesis would have a different anchor hash.
  • Exact initial supply: 1.073 billion units created in the coinbase, immediately burned → zero developer allocation, zero hidden pre-mine.
  • Deterministic & auditable: Every node recomputes the exact same genesis state from the same Bitcoin block. There is no “trusted setup” or hidden parameters.
graph LR BTC[Bitcoin Block 938708
Feb 2026] --> Hash[BLAKE3 Anchor Hash
+ Inscription Chunks] Hash --> Midstate[Genesis Midstate
+ Burned Coinbase] Midstate --> Block0([Block 0
Fair Launch Proven]) style BTC fill:#1f2937,stroke:#4b5563,stroke-width:2px,color:#d1d5db style Hash fill:#064e3b,stroke:#10b981,stroke-width:2px style Midstate fill:#064e3b,stroke:#10b981,stroke-width:2px style Block0 fill:#431407,stroke:#ea580c,stroke-width:2px,color:#fed7aa

Verify It Yourself on Your Own Node

Because Midstate's storage engine saves blocks as raw bincode serialized files, any node operator can inspect the genesis block directly on disk. The ASCII text of the burned coinbase outputs is clearly visible within the binary data.

Use hexdump to view the exact hexadecimal memory layout of the burned genesis UTXOs, showing exactly how the message spans across the 32-byte address and salt arrays:

$ hexdump -C data/db/batches/000000/batch_0.bin | grep -A 8 "Harvest"
00000050  02 00 00 00 00 00 00 00  48 61 72 76 65 73 74 20  |........Harvest |
00000060  4e 6f 77 2c 20 44 65 63  72 79 70 74 20 4c 61 74  |Now, Decrypt Lat|
00000070  65 72 3a 20 54 68 65 20  00 00 00 20 00 00 00 00  |er: The ... ....|
00000080  51 75 61 6e 74 75 6d 20  45 72 61 27 73 20 45 6e  |Quantum Era's En|
00000090  63 72 79 70 74 69 6f 6e  20 43 68 61 6c 6c 65 6e  |cryption Challen|
000000a0  67 65 20 28 50 75 62 6c  69 73 68 65 64 20 46 65  |ge (Published Fe|
000000b0  62 20 32 34 2c 20 32 30  32 36 2c 20 62 79 20 52  |b 24, 2026, by R|
000000c0  00 00 00 20 00 00 00 00  42 43 20 44 69 73 72 75  |... ....BC Disru|
000000d0  70 74 6f 72 73 29 00 00  00 00 00 00 00 00 00 00  |ptors)..........|

Every single Midstate node in the world independently verifies this construction. There is no trust required — only math.

Privacy & MEV Resistance

Midstate achieves profound transaction privacy without compromising the auditability of the global state.

The Fingerprint Problem & Power-of-2 UTXOs

In standard blockchains, UTXOs have unique, highly specific amounts (e.g., 1.45239 coins). These exact amounts act as cryptographic fingerprints. When a user sends 1.0 coins and receives 0.45239 back as change, blockchain surveillance firms can easily deduce which output was the payment and which was the change, tracing value graphs across dozens of hops even through naive mixers.

Midstate radically solves this by forcing all UTXOs to be strict powers of 2 (1, 2, 4, 8, 16, 32...).

Because there are no arbitrary denominations, every 16-value coin looks identical to every other 16-value coin on the network. A user cannot send 10 coins; their wallet automatically breaks the transaction down into independent 8 and 2 coin sends. This naturally fractures tracking graphs.

MEV Resistance: Two-Phase Mempool

Standard mempools broadcast transaction details in cleartext, allowing miners to reorder or front-run trades (Miner Extractable Value). Midstate enforces a two-phase Commit-Reveal protocol:

1. Commit
Blinded hash + Anti-Spam PoW
2. Mine
Miner commits to processing tx
3. Reveal
Reveal details and pay fee

The Commit phase binds the transaction inputs and outputs via a BLAKE3 hash. The network sees a commit, but has no idea who is sending money to whom, or how much. Only after the commit is permanently mined into a block does the user broadcast the Reveal, providing the signatures to execute the spend.

This mechanism blinds transaction topology prior to block inclusion and enforces perfect subset sum ambiguity upon execution.

Two-Phase Dark Pool Execution

Transactions are split into Commit and Reveal phases to decouple mempool admission from the cleartext execution of the state transition.

  • Commit Phase: A 32-byte hash binds the inputs, outputs, and a 32-byte cryptographic salt: BLAKE3(NETWORK_MAGIC || input_coin_ids || output_commit_hashes || salt). The client must compute a Proof-of-Work nonce yielding 16 to 30 leading zero bits (dynamically scaled based on current mempool congestion) to admit the Commit into the mempool.
  • Reveal Phase: After the Commit is included in a block, the user broadcasts the Reveal transaction containing the cleartext preimages, executing the state transition. Commitments expire and are garbage-collected from the state after COMMITMENT_TTL (1,000 blocks).
Dynamic Anti-Spam PoW

To prevent attackers from filling the mempool with free commitments (which cost zero fees), the node dynamically enforces an anti-spam PoW requirement (spam_nonce) that scales automatically under network congestion.

If the mempool has <500 pending commits, the requirement is 24 leading zero bits (~16M hashes, ~15ms). If the pool fills to 900+, the requirement jumps to 30 bits (~1B hashes, ~1s), throttling spam while remaining virtually instant for legitimate users submitting a single transaction.

Native CoinJoin

Midstate ships a denomination-uniform CoinJoin mixer built directly into the wallet and P2P layer. The final on-chain transaction is an ordinary Reveal that passes every validation rule. The privacy guarantee is mathematical: because every input and every output (except the mandatory fee coin) has identical power-of-2 value, subset-sum analysis yields zero information about the input→output mapping.

Core Invariants (from wallet/coinjoin.rs)

  • MIN_MIX_PARTICIPANTS = 2, MAX_MIX_PARTICIPANTS = 16
  • All mix inputs and outputs must share the exact same power-of-2 denomination (1, 2, 4, …, 2⁶³)
  • Exactly one additional input of value 1 covers the mandatory network fee
  • Coordinator is ephemeral — any node can start a session; no trusted third party

Ephemeral CoinJoin Coordination (libp2p)

Any node can initialise a session by broadcasting a MixAnnounce message containing a unique MixID and the target denomination.

graph TD C(("Coordinator
PeerID: QmYw...")) -->|"Broadcast MixAnnounce
MixID: 0xabc123...
Denom: 8"| N["P2P Network"] subgraph PeerA ["Peer A (PeerID: QmXa...)"] direction TB P1["Receive Announce"] --> P2["Compute PoW Nonce"] P2 -->|"BLAKE3(mix_id || coin_id || peer_id || nonce) ≥ 24 leading zeros"| P3{"Sufficient?"} P3 --Yes--> P4["Send MixJoin"] P3 --No--> P2 end N --> P1 P4 -->|"Route to QmYw..."| C style C fill:#2e1065,stroke:#8b5cf6,stroke-width:2px,color:#fff style P2 fill:#1f2937,stroke:#8b5cf6,color:#fff,stroke-dasharray: 5 5 style P3 fill:#064e3b,stroke:#10b981,color:#fff

The coordinator broadcasts the session. Peers prove they control a real coin (and are not Sybils) by solving a BLAKE3 PoW challenge bound to their PeerId and coin_id. This anti-Sybil mechanism is exactly the same 24-bit target used for commit spam protection.

graph LR subgraph libp2p Network A[Peer A: Input + PoW] -->|MixJoin| M B[Peer B: Input + PoW] -->|MixJoin| M C[Peer C: Fee Input] -->|MixFee| M end M((Ephemeral
Coordinator)) subgraph Canonical Proposal M -->|Lexicographical Sort by coin_id
Fee input appended last| P[MixProposal] P -.->|Verify MY outputs present?| A P -.->|Verify MY outputs present?| B P -.->|Verify MY outputs present?| C end style M fill:#2e1065,stroke:#8b5cf6,stroke-width:2px style A fill:#1f2937,stroke:#4b5563,color:#fff style B fill:#1f2937,stroke:#4b5563,color:#fff style C fill:#1f2937,stroke:#4b5563,color:#fff

Participants register their InputReveal and desired OutputData. When the session reaches the minimum participant count and the fee input is supplied, the coordinator produces a deterministic MixProposal (see MixSession::proposal()). Inputs are sorted by coin_id (mix coins first, fee last); outputs are sorted by coin_id. This ordering guarantees every honest participant computes the exact same commitment hash.

sequenceDiagram participant C as Coordinator participant P as Peer A participant L as Peer A Local State Note over C: All registrations received.
Inputs/Outputs deterministically sorted. C->>P: Broadcast MixProposal (Registered Inputs + Desired Outputs) Note over P: Begin Verification Procedure P->>L: Retrieve locally registered outputs rect rgb(30, 41, 59) Note over P, L: CRITICAL CHECK: Are MY outputs in the coordinator's proposal? alt Outputs Missing or Altered P--x C: DROP PROPOSAL (Refuse to Sign) Note right of P: Coordinator attempt failed. Funds safe. else Outputs Matched Exactly P->>P: Sign Proposal Commitment Hash P->>C: Send Signature end end

This is the trustless verification step. Each peer independently checks that the coordinator has not altered, omitted, or stolen their outputs before signing the single 32-byte commitment hash. If the check fails, the peer aborts — the coordinator gains nothing. The collected signatures are later assembled into the final Reveal transaction.

  • Uniformity Constraints: Enforced in MixSession::register and set_fee_input. DataBurn outputs are explicitly forbidden.
  • Anti-Sybil Proof-of-Work: BLAKE3(mix_id || coin_id || peer_id || nonce) ≥ 24 leading zeros — exactly the same constant used for mempool spam protection (MIX_JOIN_POW_BITS).
  • Trustless Proposal Assembly: Lexicographical sort by coin_id (see proposal()). Participants sign only the final commitment hash after local verification.
  • On-Chain Detection: Any observer can call is_uniform_mix(tx) — it simply counts inputs/outputs of identical power-of-2 value plus at most one fee coin. The transaction remains fully valid even if the heuristic is unknown.

Dandelion++ Stem Routing (Post-Mix Privacy)

After the reveal is constructed, the wallet routes the final Reveal transaction through Dandelion++ to decouple the broadcasting node’s IP from the transaction payload.

graph LR A([Origin Node]) -.->|Stem phase| B([Node 2]) B -.->|10% Probability| C([Node 3]) C -.->|10% Probability| D([Node 4]) D ==>|Broadcast Trigger| E([Peer A]) D ==>|Broadcast| F([Peer B]) D ==>|Broadcast| G([Peer C]) style A fill:#2e1065,stroke:#8b5cf6,stroke-width:2px,color:#fff style D fill:#064e3b,stroke:#10b981,stroke-width:2px,color:#fff

Diagram explanation: Transactions stay in the “stem” (single-peer forwarding) until a random 10% probability (STEM_FLUFF_PERCENT) flips them into the public “fluff” phase. Stem pool is capped at 1,000 entries to prevent memory exhaustion.

// Commitment Hash (identical on every honest node) commitment = BLAKE3( input_coin_ids_sorted || output_commit_hashes_sorted || session_salt )

The entire mixing protocol lives in wallet/coinjoin.rs (≈180 LOC). It is used automatically by the wallet’s --private send flag and can be invoked manually via the CLI or libp2p RPC for advanced users.

State Management & Syncing

Midstate discards the traditional unbounded UTXO database model (like Bitcoin's LevelDB). Instead, unspent outputs, pending commitments, and chain history are mathematically accumulated into cryptographically verifiable data structures, strictly bounding the RAM requirements for edge devices.

The SMT & MMR State Root

The global state_root of the Midstate network is a combination of two distinct data structures:

1. The UTXO Sparse Merkle Tree (SMT)

Active UTXOs and mempool commitments are stored in a 256-level Sparse Merkle Tree. To achieve O(log N) insertion and verification without overflowing the RAM of edge devices, the tree is split into two access tiers:

  • Top Cache: The top 16 levels are cached persistently in memory, strictly bounded to a maximum of 65,536 nodes.
  • Dynamic Folding: The bottom 240 levels are computed on the fly when proofs are required. Because coins are sorted lexicographically by their 32-byte hashes, this is computed near-instantly via binary searching over buckets.

2. The Merkle Mountain Range (MMR)

While the SMT tracks active state, the MMR tracks historical state. Every time a block is mined, its final_hash is appended to the MMR. This provides an append-only log of the entire chain history, allowing light clients to request O(log N) inclusion proofs to verify that a specific block existed at a specific height in the past.

graph TD Root([Global State Root]) --> SMT([Combined SMT Root]) Root --> MMR([Chain History MMR Root]) SMT --> Mempool([Pending Commits SMT]) SMT --> UTXO([Active UTXO SMT]) UTXO --> TopCache[Top 16 Levels
RAM Cache
Max 65,536 Nodes] TopCache -.-> BottomTree[Bottom 240 Levels
Disk-backed
Dynamic Bucket Folding] MMR --> B1[Block 1] MMR --> B2[Block 2] MMR --> B3[Block N...] style Root fill:#431407,stroke:#ea580c,stroke-width:2px style TopCache stroke:#3b82f6,stroke-dasharray: 5 5 style BottomTree stroke:#64748b
// The Final State Root Equation
smt_root = BLAKE3( utxo_smt_root || pending_commitments_smt_root )
state_root = BLAKE3( smt_root || historical_chain_mmr_root )

Fast-Forward Syncing

A major issue with sequential hashing is the sync time. If a node goes offline for a month, replaying 1,000,000 hashes per block to catch up would take days on a Raspberry Pi. Midstate solves this via cryptographic Fast-Forwarding.

Nodes save full state snapshots to disk every 100 blocks. When a node is syncing, it can download a recent snapshot from a peer instead of starting from genesis.

Snapshot Cryptographic Validation

How does a node trust a peer's snapshot without replaying the history? It uses the headers. The node downloads the lightweight headers and verifies the Proof-of-Work. If the very first header mathematically builds exactly on top of the downloaded snapshot's midstate, the snapshot is authentic.

The Security Gate: To prevent an attacker from forging a fake snapshot and mining just 1 or 2 blocks on top of it, Midstate enforces a PRUNE_DEPTH rule. A node will only trust a snapshot if the peer can provide 1,000 valid blocks of Proof-of-Work natively built on top of it (1 billion sequential hashes). This makes state injection economically impossible.

Reorg Defense & Frankenstein Chains

When a node detects a longer chain, it must perform a reorg. A catastrophic failure mode during sync is the "Frankenstein chain"—where a node writes the peer's alternative blocks to disk, but crashes before updating the STATE_TABLE pointer. Upon reboot, the database has half the old chain and half the new chain, destroying consensus.

Midstate prevents this via strict ACID transactions. Incoming alternative batches are written to .tmp files. Only after the STATE_TABLE pointer is atomically updated in the redb database does the node promote the files to .bin. If a crash occurs, the node's WAL recovery checks the committed height and either deletes orphaned .tmp files or finishes the promotion, ensuring the disk is always perfectly coherent.

Compact Block Filters (Neutrino Privacy)

Light wallets need to know when they receive funds, but asking a public RPC node "Do you have any transactions for Address X?" completely destroys user privacy, linking their IP address to their wallet balance.

Midstate implements client-side block filtering using Golomb-Rice Coding (P=20). Instead of asking for specific addresses, the wallet downloads a tiny, highly compressed filter (a few kilobytes) for each block.

  • Local Matching: The wallet checks its own addresses against the filter locally. If there is a match (which includes a 1-in-1,000,000 false positive rate), the wallet downloads the entire raw block and scans it locally.
  • Zero Knowledge Leakage: The RPC node never learns which addresses the wallet actually owns; it only sees the wallet requesting sequential filter data and occasional full blocks.
  • Precomputation Defense: To prevent malicious miners from artificially bloating filters or crafting false positives, all elements inserted into the filter are cryptographically keyed using the block's final_hash.

Virtual Machine

Every UTXO in Midstate is locked by a compiled bytecode script. The VM executes witness inputs pushed onto the SmallVec stack, then evaluates the locking script. Execution succeeds if and only if the final top-of-stack item is exactly [1].

The stack machine in Midstate is Turing-incomplete by design — no loops, no unbounded recursion, no on-chain state mutation. What it does have is output introspection via OP_SUM_TO_ADDR, a capability Bitcoin still lacks natively. This single opcode unlocks covenants, streaming payments, DAOs, and inheritance contracts without any smart contract risk surface.

Max Script Size
1,024 bytes
Max Stack Depth
64 items
Clean Stack Rule
Exactly [1]

Midscript: Language Reference

Writing raw stack manipulation assembly is hostile to developers and difficult to audit. Midscript is a high-level, expression-oriented language built directly into the Web IDE. It compiles down to zero-overhead Midstate stack machine bytecode, allowing you to write readable contracts without sacrificing VM performance or hitting the 1,024-byte limit.

Compile-Time Types
Hex, Int, Bool
Memory Allocation
Zero
Paradigm
Stack-Oriented

The Zero-Cost Abstraction Guarantee

Midscript has no concept of on-chain memory, heap allocation, or local variables. Constructs like let, macro, and repeat are evaluated entirely at compile time. They act as pre-processor directives that unroll and inline your logic directly into raw PUSH and stack opcodes.

1. Syntax & Data Types

Midscript supports three literal types, which are all ultimately pushed to the stack as byte arrays.

  • Hex Strings: "a1b2c3d4" compiles to PUSH_HEX a1b2c3d4.
  • Integers: 10000 compiles to PUSH_INT 10000 (little-endian byte array).
  • Booleans: true and false compile to PUSH_INT 1 and PUSH_INT 0.

2. Compile-Time Metaprogramming

Because there are no local variables on the blockchain, Midscript provides powerful compile-time aliases and inlining.

// 1. Constants (Aliases)
// Aliases inject their value wherever referenced. They do not consume stack space.
let TIMEOUT = 500000;
let ALICE_PK = "02aaaa1234567890abcdef...";

// 2. Macros (Inline functions)
// Macros unroll into the bytecode exactly where they are called.
macro check_both_sigs() {
    swap();
    check_sig(ALICE_PK);
    swap();
    check_sig("03bbbb...");
    add();
}

// 3. Compile-Time Loops
// Unrolls the block N times in the final bytecode.
// Useful for batch processing without adding looping opcodes to the VM.
repeat(3) {
    drop();
}

3. Built-In Standard Library

Midscript provides syntactic sugar for standard stack manipulations and cryptographic checks. These map directly to underlying opcodes.

FunctionCompiled OpcodesDescription
peek()DUPDuplicates the top stack item.
drop()DROPDiscards the top stack item.
swap()SWAPSwaps the top two stack items.
over()OVERCopies the second-to-top item to the top.
rot()ROTRotates the top three items (3rd to top).
fail()PUSH_INT 0Pushes 0 (forces a failure if left at end of execution).
check_sig(pk)pk CHECKSIGVerifies signature against pubkey. Pushes 1 (valid) or 0 (invalid).
require_sig(pk)pk CHECKSIGVERIFYVerifies signature and aborts script immediately if invalid.
require_time(h)h CHECKTIMEVERIFYAborts if block height is less than h.
require_preimage(h)HASH h EQUALVERIFYHashes top item and aborts if it doesn't equal h.
require_transfer(a, v)a SUM_TO_ADDR v EQUALVERIFYCovenant: Aborts if transaction doesn't send exactly v units to address a.
verify_gte(v)v GREATER_OR_EQUAL VERIFYAborts if the top item is less than v.

4. Math & Logic Operators

You can use standard infix operators. The compiler automatically translates these into postfix stack operations.

  • + compiles to ADD
  • - compiles to SUB
  • == compiles to EQUAL
  • >= compiles to GREATER_OR_EQUAL
  • && compiles to ADD PUSH_INT 2 EQUAL
  • || compiles to ADD PUSH_INT 0 GREATER_OR_EQUAL

5. Raw Assembly Interop

If you need to drop down to bare metal, you can write raw opcodes directly in Midscript by typing them in all-caps.

let ADMIN = "a1b2...";
PUSH_HEX(ADMIN);
CHECKSIGVERIFY;
PUSH_INT(1);

Contract Examples

Example 1: Atomic Swap (HTLC)

A cross-chain atomic swap. Alice can claim the funds if she reveals the preimage to a hash. If she doesn't, Bob can take the funds back after a timeout.

let SECRET_HASH = "5fbf08af2b116ab8f7f3c14b8ec01a46ce23d290e2ebc7a752d0982d54c054f2";
let ALICE_PK = "02aaaa...";
let BOB_PK = "03bbbb...";
let TIMEOUT = 600000;

// Witness expected:
// Alice claim: [Alice_Sig, Secret_Preimage, 1]
// Bob refund:  [Bob_Sig, 0, 0]

if (peek() == 1) {
    drop(); // Drop the routing boolean
    require_preimage(SECRET_HASH);
    require_sig(ALICE_PK);
} else {
    drop(); // Drop routing boolean
    drop(); // Drop empty preimage
    require_time(TIMEOUT);
    require_sig(BOB_PK);
}
true; // Clean stack rule

Example 2: Decentralized Limit Order (AMM)

Using covenants to enforce a trade. Anyone can spend this UTXO, provided the transaction routes exactly 500 units to the Maker's address.

let MAKER_ADDR = "9f8e1234567890abcdef1234567890abcdef1234567890abcdef1234567890";
let PRICE = 500;
let FEE = 10;

// Covenant: Enforce that the transaction pays MAKER_ADDR (PRICE - FEE)
require_transfer(MAKER_ADDR, PRICE - FEE);

// Taker must authorize the spend
require_sig("TAKER_PK");
true;

Example 3: 2-of-3 Multisig using Arithmetic

Requires signatures from any two of the three defined public keys.

let PK_A = "02aaaa...";
let PK_B = "03bbbb...";
let PK_C = "04cccc...";

// Witness expected: [Sig_C, Sig_B, Sig_A] (use "00" for missing sigs)

check_sig(PK_A);

swap();
check_sig(PK_B);
add(); // Sum the successful signatures

swap();
check_sig(PK_C);
add(); // Sum again

// Check if total valid signatures >= 2
verify_gte(2);
true;

Pay-to-Public-Key (P2PK)

The default script type. The owner's public key is embedded in the locking script. To spend, the owner provides a WOTS+ or MSS signature in the witness.

Script:  PUSH_DATA(<owner_pk>) CHECKSIGVERIFY PUSH_INT(1)
Witness: [ <signature> ]

Execution Trace:
1. Stack: [ <signature> ]
2. PUSH_DATA(<owner_pk>)
   Stack: [ <signature>, <owner_pk> ]
3. CHECKSIGVERIFY
   (Pops pk and sig. Verifies WOTS+/MSS signature against the commitment hash.)
   Stack: []
4. PUSH_INT(1)
   Stack: [ 1 ]

Result: VALID ✓

P2SH Addresses

In practice, wallets hash the entire locking script with BLAKE3 and present only the 32-byte hash as the "address." The sender locks funds to HASH PUSH_DATA(<script_hash>) EQUALVERIFY <script>. This hides the script until spend time, improving privacy and keeping addresses a uniform 32 bytes regardless of script complexity.

M-of-N Multi-Signature

Funds that require multiple independent parties to sign before they can be spent. Useful for joint accounts, exchange cold storage, and escrow. Because the Midstate stack machine executes CHECKSIGVERIFY sequentially, M-of-N is constructed by chaining signature checks — no special opcode needed.

2-of-3 Example

Alice, Bob, and Carol hold keys. Any two of the three must sign to release funds.

// Locking Script (2-of-3: Alice, Bob, Carol)
Script:
  IF
    PUSH_DATA(<alice_pk>) CHECKSIGVERIFY
    PUSH_DATA(<bob_pk>)   CHECKSIGVERIFY
  ELSE
    PUSH_DATA(<alice_pk>) CHECKSIGVERIFY
    PUSH_DATA(<carol_pk>) CHECKSIGVERIFY
  ENDIF
  PUSH_INT(1)

// Witness for Alice + Bob path:
Witness: [ <alice_sig>, <bob_sig>, <1> ]   // 1 = take IF branch

// Witness for Alice + Carol path:
Witness: [ <alice_sig>, <carol_sig>, <0> ]  // 0 = take ELSE branch

Execution Trace (Alice + Bob):
1. Stack: [ <alice_sig>, <bob_sig>, 1 ]
2. IF → condition is 1 (true), take IF branch
   Stack: [ <alice_sig>, <bob_sig> ]
3. PUSH_DATA(<alice_pk>) CHECKSIGVERIFY
   (Verifies alice_sig. Pops both.)
   Stack: [ <bob_sig> ]
4. PUSH_DATA(<bob_pk>) CHECKSIGVERIFY
   (Verifies bob_sig. Pops both.)
   Stack: []
5. PUSH_INT(1)
   Stack: [ 1 ]

Result: VALID ✓

Key Type Flexibility

Each signer can independently use WOTS+ one-time keys or MSS reusable keys. A company cold wallet might use MSS (so the address never changes) while individual signers rotate fresh WOTS+ keys for each co-signature. The VM doesn't care — CHECKSIGVERIFY handles both signature types transparently.

Atomic Swaps via Hash Time-Locked Contracts (HTLCs)

HTLCs enable trustless cross-chain swaps and payment channels. Alice locks funds that can be claimed by Bob only if he reveals a secret preimage within a time window. If Bob doesn't claim in time, Alice gets her funds back.

Alice locks funds
Commits to BLAKE3(secret)
Bob reveals secret
Claims within timeout
OR: Timeout expires
Alice reclaims funds
// Locking Script
Script:
  IF
    HASH
    PUSH_HEX <secret_hash>    // BLAKE3(secret)
    EQUALVERIFY
    PUSH_DATA(<bob_pk>)
    CHECKSIGVERIFY
  ELSE
    DROP
    PUSH_INT <timeout_height>
    CHECKTIMEVERIFY
    PUSH_DATA(<alice_pk>)
    CHECKSIGVERIFY
  ENDIF
  PUSH_INT 1

// Bob claims (knows the secret):
Witness: [ <bob_sig>, <secret_preimage>, <1> ]

// Alice reclaims after timeout:
Witness: [ <alice_sig>, <0> ]

Execution Trace (Bob claims):
1. Stack: [ <bob_sig>, <secret>, 1 ]
2. IF → take IF branch
   Stack: [ <bob_sig>, <secret> ]
3. HASH
   Stack: [ <bob_sig>, BLAKE3(<secret>) ]
4. PUSH_HEX <secret_hash>
   Stack: [ <bob_sig>, BLAKE3(<secret>), <secret_hash> ]
5. EQUALVERIFY
   (Checks BLAKE3(secret) == secret_hash. Fails if secret is wrong.)
   Stack: [ <bob_sig> ]
6. PUSH_DATA(<bob_pk>) CHECKSIGVERIFY
   Stack: []
7. PUSH_INT(1)
   Stack: [ 1 ]

Result: VALID ✓  Bob receives funds and reveals the secret.
Cross-Chain Atomic Swaps

Alice wants to swap Midstate coins for coins on another chain. She generates a random secret S and computes H = BLAKE3(S). She locks her Midstate coins in an HTLC using H as the hash lock, with a 48-hour timeout. Bob simultaneously locks the agreed amount on the other chain using the same H (adapted for that chain's hash function), with a 24-hour timeout.

Bob claims Alice's Midstate coins by revealing S. Alice now sees S on-chain and uses it to claim Bob's coins before his 24-hour timeout expires. If either party abandons the swap, both get their funds back after their respective timeouts. No trusted third party required.

Timelocks & Dead Man's Switch

CHECKTIMEVERIFY (CTV) compares a height encoded in the script against the current block height. The script hard-fails if the chain hasn't reached that height yet. This enables inheritance contracts, vesting schedules, and dead man's switches.

Inheritance Contract

Alice can spend at any time. If she doesn't spend within ~1 year (52,560 blocks), Bob can claim the funds as an heir.

// Locking Script
Script:
  IF
    PUSH_DATA(<alice_pk>)
    CHECKSIGVERIFY
  ELSE
    DROP
    PUSH_INT <current_height + 52560>
    CHECKTIMEVERIFY
    PUSH_DATA(<bob_pk>)
    CHECKSIGVERIFY
  ENDIF
  PUSH_INT 1

// Alice spends normally (any time):
Witness: [ <alice_sig>, <1> ]

// Bob inherits (after 52,560 blocks):
Witness: [ <bob_sig>, <0> ]

Vesting Schedule

A team member's allocation unlocks in tranches. Each UTXO is created with a different CHECKTIMEVERIFY height, so 25% unlocks per year over four years automatically — no central custodian needed.

// Year 1 tranche (locked until height 525,600)
Script: DROP PUSH_INT 525600 CHECKTIMEVERIFY PUSH_DATA(<team_pk>) CHECKSIGVERIFY PUSH_INT 1

// Year 2 tranche (locked until height 1,051,200)
Script: DROP PUSH_INT 1051200 CHECKTIMEVERIFY PUSH_DATA(<team_pk>) CHECKSIGVERIFY PUSH_INT 1

Dead Man's Switch

Funds auto-release to a backup address if the primary key holder goes dark for 6 months (~26,280 blocks). The primary holder simply needs to "refresh" the timelock by spending and re-locking to a new output before the deadline.

Script:
  IF
    PUSH_DATA(<primary_pk>)
    CHECKSIGVERIFY
  ELSE
    DROP
    PUSH_INT <last_seen_height + 26280>
    CHECKTIMEVERIFY
    PUSH_DATA(<backup_pk>)
    CHECKSIGVERIFY
  ENDIF
  PUSH_INT 1

Height vs. Time

Midstate's CHECKTIMEVERIFY operates on block height, not Unix timestamps. At a 60-second target block time, 1 year ≈ 525,600 blocks, 6 months ≈ 262,800 blocks, 1 week ≈ 10,080 blocks. Height-based locks are more predictable than timestamp-based ones since miners cannot trivially manipulate the block height.

Covenants via OP_SUM_TO_ADDR

The Capability Bitcoin Still Lacks

OP_SUM_TO_ADDR introspects the current transaction's outputs at script execution time. It pops an address from the stack, sums the total value of all outputs in the transaction sent to that address, and pushes the result. This is output-set awareness — the ability for a locking script to constrain how the coin can be spent, not just who can spend it. Bitcoin has been debating adding this capability (OP_CTV, OP_CAT) for years. Midstate ships it natively.

Enforced Donation (Simple Covenant)

"You can spend this coin, but only if you send at least 100 units to Alice in the same transaction."

Script:
  PUSH_HEX <alice_addr>
  SUM_TO_ADDR             // Sums all outputs going to alice_addr in this tx
  PUSH_INT 100
  GREATER_OR_EQUAL        // Is the total to Alice >= 100?
  VERIFY
  PUSH_DATA <owner_pk>
  CHECKSIGVERIFY
  PUSH_INT 1

Execution Trace (owner spends, sending 150 to Alice):
1. Stack: []
2. PUSH_HEX <alice_addr>
   Stack: [ <alice_addr> ]
3. SUM_TO_ADDR
   (Introspects tx outputs. Finds 150 units going to alice_addr.)
   Stack: [ 150 ]
4. PUSH_INT 100
   Stack: [ 150, 100 ]
5. GREATER_OR_EQUAL
   Stack: [ 1 ]  // 150 >= 100 → true
6. VERIFY
   Stack: []
7. PUSH_DATA <owner_pk> CHECKSIGVERIFY
   Stack: []
8. PUSH_INT 1
   Stack: [ 1 ]

Result: VALID ✓

// If owner tries to spend without sending to Alice:
// Step 3 returns 0. GREATER_OR_EQUAL → 0. VERIFY → FAIL ✗

Percentage-Based Covenant

Enforce that at least 10% of any spend goes to a community fund — useful for protocol treasuries, royalties, or charitable commitments baked into a UTXO at creation time.

// Suppose the coin has value V. Owner must route at least V/10 to the fund.
// Since we can't divide on-stack, the wallet constructs outputs such that
// fund_output >= total_input / 10. The script verifies the absolute amount:

Script:
  PUSH_HEX <fund_addr>
  SUM_TO_ADDR
  PUSH_INT <minimum_fund_amount>   // computed off-chain by wallet: input_value / 10
  GREATER_OR_EQUAL
  VERIFY
  PUSH_DATA <owner_pk>
  CHECKSIGVERIFY
  PUSH_INT 1

DAO Treasury

A decentralized treasury where funds can only be disbursed if multiple keyholders agree AND the transaction routes a minimum amount to the treasury's own address (enforcing that the DAO can't be fully drained in a single transaction).

// DAO Treasury Script
// Rules:
//   1. Requires 2-of-3 signatures from council members
//   2. At least 50% of the treasury UTXO value must remain in the treasury
//      (i.e., the treasury address must receive >= half the input value)
//   3. The disbursement address receives the rest

Script:
  // Rule 2: Covenant — treasury must retain at least half
  PUSH_HEX <treasury_addr>
  SUM_TO_ADDR
  PUSH_INT <half_of_input_value>    // wallet computes this off-chain
  GREATER_OR_EQUAL
  VERIFY

  // Rule 1: 2-of-3 multisig (Alice OR Bob, plus Carol always required)
  IF
    PUSH_DATA <alice_pk>  CHECKSIGVERIFY
  ELSE
    PUSH_DATA <bob_pk>    CHECKSIGVERIFY
  ENDIF
  PUSH_DATA <carol_pk>    CHECKSIGVERIFY   // Carol always required

  PUSH_INT 1

// Witness (Alice + Carol disbursement):
Witness: [ <alice_sig>, <carol_sig>, <1> ]

// The wallet MUST construct the tx so that treasury_addr receives
// >= half the input. If it doesn't, SUM_TO_ADDR will return a lower
// value and VERIFY will fail — regardless of whether the sigs are valid.

No Smart Contract Runtime Required

This DAO has zero on-chain state. There's no contract account, no storage slots, no gas, no upgrade proxy. The rules are entirely encoded in the UTXO's locking script. An auditor can read 12 lines of Midstate stack machine assembly and fully understand every constraint. Contrast this with a Solidity DAO where you need to audit thousands of lines of EVM bytecode and re-entrancy guards.

Bootstrapping a DAO Treasury

To bootstrap a DAO, a founder creates a UTXO locked with the treasury script above and sends it to the DAO's treasury address. Any subsequent spend of that UTXO must satisfy both the multisig AND the covenant — meaning the treasury can never be fully drained by a single colluding quorum. The only way to wind down the DAO is to progressively drain it across many transactions, each time leaving at least half behind, which requires sustained consensus across many blocks.

New contributions to the treasury simply send coins to the treasury address. Those coins become locked under the same script when the next disbursement transaction consumes them as inputs.

Streaming / Rate-Limited Payments

A covenant that enforces a maximum withdrawal rate per transaction. Useful for salary streams, subscription services, and protocol treasury drawdowns. The key insight: SUM_TO_ADDR can verify that the "change" output sent back to the sender is large enough, which is mathematically equivalent to verifying the withdrawal is small enough.

Salary Stream

An employer locks 1,000,000 units for an employee. The employee can withdraw at most 10,000 units per spend. The remaining balance must be routed back to the stream address, re-locking it under the same script.

// Stream Script (max 10,000 units per withdrawal)
// The stream_addr is this script's own P2SH address.
// After each withdrawal, the change goes back to stream_addr,
// re-locking it under the same rules.

Script:
  // Enforce that stream_addr receives back (input_value - max_withdrawal)
  // i.e., at least (input_value - 10000) must be returned to the stream.
  PUSH_HEX <stream_addr>
  SUM_TO_ADDR
  PUSH_INT <input_value_minus_10000>   // computed off-chain: input - 10000
  GREATER_OR_EQUAL
  VERIFY

  // Employee must sign to authorize the withdrawal
  PUSH_DATA <employee_pk>
  CHECKSIGVERIFY
  PUSH_INT 1

// tx structure for a valid withdrawal:
//   Input:  stream UTXO (value: 1,000,000)
//   Output 1: employee_addr (value: 10,000)     ← the withdrawal
//   Output 2: stream_addr   (value: 990,000)    ← change, re-locked

// SUM_TO_ADDR(stream_addr) returns 990,000.
// 990,000 >= (1,000,000 - 10,000) = 990,000 → VALID ✓

// If employee tries to withdraw 50,000:
//   Output 2: stream_addr (value: 950,000)
//   SUM_TO_ADDR returns 950,000.
//   950,000 >= 990,000 → FALSE → VERIFY FAILS ✗

The Change Re-Lock Pattern

For streaming payments to work correctly, the wallet must send the change output to the exact same stream address (which hashes to the same script). If the change goes to any other address, SUM_TO_ADDR returns 0 for the stream address and the transaction fails. This self-enforcing property means the employee cannot accidentally (or intentionally) break the stream by sending change elsewhere.

Subscription Service

A user locks funds for a service provider. The provider can pull exactly the subscription fee per billing period, enforced by combining SUM_TO_ADDR with CHECKTIMEVERIFY.

// Subscription: provider pulls 500/month, user can cancel anytime

Script:
  IF
    // Provider pull: max 500, must be after next billing height
    PUSH_INT <next_billing_height>
    CHECKTIMEVERIFY
    PUSH_HEX <subscription_addr>
    SUM_TO_ADDR
    PUSH_INT <balance_minus_500>
    GREATER_OR_EQUAL
    VERIFY
    PUSH_DATA <provider_pk>
    CHECKSIGVERIFY
  ELSE
    // User cancels: full balance, any time
    PUSH_DATA <user_pk>
    CHECKSIGVERIFY
  ENDIF
  PUSH_INT 1

Writing & Compiling Midstate Stack Machine Bytecode

Midstate Stack Machine Code assembly files use the .msc extension. Compile them with the CLI:

$ midstate wallet compile --file my_script.msc
SUCCESS Compiled to 48 bytes. P2SH address: 9f3a...c12b

Stack Opcodes

MnemonicStack EffectDescription
PUSH_INT <n>→ nPush integer literal
PUSH_HEX <hex>→ bytesPush raw bytes from hex string
PUSH_DATA <data>→ dataPush data blob (pk, address, etc.)
DROPx →Discard top item
DUPx → x xDuplicate top item
SWAPa b → b aSwap top two items
OVERa b → a b aCopy second-to-top item to top
ROTa b c → b c aRotate top three items

Arithmetic & Logic

MnemonicStack EffectDescription
ADDa b → a+bInteger addition
SUBa b → a-bInteger subtraction (fails on underflow)
EQUALa b → boolPush 1 if equal, 0 otherwise
EQUALVERIFYa b →Fail if not equal, else pop both
GREATER_OR_EQUALa b → boolPush 1 if a >= b
VERIFYx →Fail if top is not 1

Control Flow

MnemonicDescription
IFPops top item. Executes IF block if 1, ELSE block if 0.
ELSEAlternate branch of IF.
ENDIFCloses IF/ELSE block.

Cryptographic Opcodes

MnemonicStack EffectDescription
HASHdata → BLAKE3(data)BLAKE3 hash of top item
CHECKSIGsig pk → boolVerify WOTS+/MSS signature. Push result.
CHECKSIGVERIFYsig pk →Verify signature. Fail if invalid.

Introspection & Covenants

MnemonicStack EffectDescription
CHECKTIMEVERIFYheight →Fail if chain height < height. Pop height.
SUM_TO_ADDRaddr → amountSum all output values in this tx sent to addr. Push total.

The Clean Stack Rule

Every valid script execution must leave exactly one item on the stack at termination, and it must be [1]. A script that leaves [1, 1] or terminates with an empty stack both fail. This prevents scripts from accidentally succeeding due to leftover garbage values and makes script behavior unambiguous.

The MidstateAxe Ecosystem

The Midstate node is highly optimized for the MidstateAxe—a custom OS image built via Buildroot for Raspberry Pi hardware (Zero 2 W, Pi 3, Pi 4). The node exposes exclusive hardware APIs when it detects the physical device.

Memory Footprint
< 150 MB
Jemalloc
Anti-Fragmentation
OS Environment
Embedded Linux

Hardware APIs

When the node detects it is running on Axe hardware (via device tree inspection), it unlocks a suite of captive-portal and management endpoints over the Axum RPC server:

  • /axe/stats: Reads the CPU's thermal zone (in milli-Celsius), system uptime, and fetches the real-time atomic hardware hashrate counter.
  • /axe/wifi: Acts as a captive portal, allowing users to configure wpa_supplicant.conf and reload the wlan0 interface live via wpa_cli.
  • /axe/overclock: Safely modifies /boot/config.txt to adjust arm_freq and over_voltage, then orchestrates a system reboot.
  • /axe/rewards: Serves the coinbase_seeds.jsonl file directly to the user so they can import their offline mined rewards into a standard Desktop wallet.

DataBurn UTXOs (OP_RETURN)

The MidstateAxe nodes are protected from state bloat. Users can embed arbitrary data in the blockchain using OutputData::DataBurn (capped at 80 bytes). However, these outputs yield no coin_id and are completely ignored by the UTXO Sparse Merkle Tree. Miners process the data, but the RAM of edge devices is never burdened by tracking unspendable data.

CLI Quickstart Guide

Midstate is controlled entirely via a unified command-line interface. This guide covers the essential commands for interacting with the network, managing keys, and sending private transactions.

Creating a Wallet

Midstate uses HD (Hierarchical Deterministic) wallets by default. To create a new wallet, run:

$ midstate wallet create
INFO Enter a strong password to encrypt your wallet.dat file.
SUCCESS Wallet created. Write down your 24-word seed phrase.

Checking Your Balance

To view your total balance, live on-chain coins, and pending commits:

$ midstate wallet balance
Coins in wallet: 45
Live on-chain: 42 (value: 10500)
Unused keys: 5
Pending commits: 1

Always Scan Before Spending!

Because Midstate uses client-side compact block filters for privacy, your wallet does not automatically know when it receives funds. You must scan the chain to update your local state:

$ midstate wallet scan

Receiving Funds (One-Time Addresses)

By default, Midstate uses WOTS+ signatures. These are strictly one-time-use to preserve post-quantum security. To generate a fresh receiving address:

$ midstate wallet receive --label "Payment from Alice"
Your receiving address:
7a9b...c3d4
Share this with the sender.

Reusable Addresses (MSS)

If you need a static address (e.g., for a mining pool payout or a donation link), you must generate a Merkle Signature Scheme (MSS) tree. A height-10 tree allows exactly 1,024 signatures.

$ midstate wallet generate-mss --height 10 --label "Donations"
INFO Generating MSS tree (Height 10 = 1024 signatures)...
SUCCESS Address: 9f8e...1a2b

Sending Funds

To send funds, specify the destination address and the exact amount. The wallet will automatically select the necessary UTXOs, group WOTS siblings to prevent key reuse, and generate exact change.

$ midstate wallet send --to 7a9b...c3d4:500
INFO Submitting Phase 1 Commit...
SUCCESS Commit mined!
INFO Submitting Phase 2 Reveal...
SUCCESS Transfer complete!

Private Sending (Dandelion++)

To maximize privacy, use the --private flag. This instructs the wallet to split your payment into independent power-of-2 denominations, route them through the Dandelion++ stem network, and add random execution delays to thwart timing analysis.

$ midstate wallet send --to 7a9b...c3d4:500 --private
Private send: 3 independent transaction(s)

Running a Full Node & Mining

To start a full node, sync the chain, and begin CPU mining on all available cores, simply run:

$ midstate node --mine
14:02:11 INFO Node started (mining: true, threads: 8, rpc: 8545)
14:02:11 INFO Mining SIMD: AVX2 8-way (8 nonces/batch)

Fast-Forward Syncing

If you are spinning up a new node, you can sync from a specific trusted peer. The node will download the latest state snapshot and cryptographically verify it against the headers.

$ midstate sync --peer /ip4/198.51.100.5/tcp/9333/p2p/12D3K...

Architecture Comparison

Subsystem Legacy Chains Midstate
Cryptography Elliptic Curve (Shor vulnerable) BLAKE3, WOTS+, MSS
Mining Hardware Parallel ASICs / GPUs Sequential Hashing (CPUs)
Transaction Ordering Cleartext Bidding (MEV) 2-Phase Commit-Reveal
Value Privacy Public cleartext ledgers Power-of-2 UTXOs & Coinjoin
State Storage Unbounded UTXO LevelDB Pruned Sparse Merkle Tree
Difficulty Target Sliding-window average ASERT (16.16 Fixed Point)

Adversarial Analysis & Edge Cases

A protocol is only as robust as its worst-case scenario. Midstate was designed with strict mathematical bounds to survive hostility, spam, and hardware constraints without relying on benevolent actor assumptions.

Mempool DoS & Dynamic PoW

The Threat: In Midstate's 2-phase mempool, the Commit phase does not require a fee (fees are paid during the Reveal). An attacker could attempt to exhaust node RAM by flooding the network with millions of fake commitments.

The Mathematical Defense: Midstate enforces a dynamic Proof-of-Work spam nonce that scales exponentially based on mempool congestion. The target is defined by the number of leading zero bits required in the hash: BLAKE3(commitment || nonce).

  • < 500 pending commits: 24 bits (~16.7 million hashes)
  • 500 - 749 pending commits: 26 bits (~67.1 million hashes)
  • 750 - 899 pending commits: 28 bits (~268.4 million hashes)
  • > 900 pending commits: 30 bits (~1.07 billion hashes)

Attacker Bankruptcy

If an attacker wants to hold 1,000 garbage commits in the mempool to degrade network performance, the cost per transaction becomes ~1.07 billion hashes. To sustain a flood of 100 tx/sec at this congestion level, the attacker must sustain 107 Billion hashes per second—all while legitimate users easily bypass the spam by submitting a single transaction taking ~1 second on a standard laptop. The attacker burns immense CPU power, while the node uses just kilobytes of RAM.

UTXO Fragmentation Bound (The Greedy Snowball)

The Threat: By forcing all UTXOs to be strict powers of 2 (for privacy), a transaction of value 1,023 requires 10 distinct UTXOs (512+256+128+64+32+16+8+4+2+1). Critics argue this will cause the global UTXO set to fracture infinitely into "dust," bloating the state.

The Mathematical Defense: The Midstate wallet implements a Greedy Snowball Defragmentation algorithm. It mathematically guarantees that a user's wallet fragmentation is strictly bounded to O(log₂ V), where V is their total balance.

// The Greedy Snowball Algorithm
1. Select minimum coins needed to satisfy payment.
2. Calculate resulting change denominations.
3. IF wallet contains a live coin matching a change denomination:
    Pull that coin into the transaction inputs.
    GOTO 2 (Merge up to the next power of 2).

Proof by Example: You need to pay 6. Your wallet contains [8, 2, 2].
- Normal selection picks 8. Change is 2. Wallet becomes [2, 2, 2] (Fragmentation worsened).
- Greedy selection picks 8. Sees change is 2. Pulls in an existing 2. Total input 10. Change is 4. Wallet becomes [4, 2] (Defragmented!). Every transaction actively cleans the global UTXO set.

OOM Defense: SMT Memory Bounding

The Threat: Bitcoin relies on an unbounded LevelDB database for its chainstate. As the network grows to billions of UTXOs, edge devices (like Raspberry Pis) will inevitably suffer Out-Of-Memory (OOM) panics or fatal disk I/O bottlenecks.

The Mathematical Defense: Midstate replaces the unbounded database with a 256-level Sparse Merkle Tree (SMT). We mathematically guarantee that the node's RAM requirements will never exceed a fixed threshold, regardless of how many UTXOs exist.

The Cache Boundary Theorem

A full 256-level binary tree contains ~1077 nodes, which is impossible to store. Midstate truncates memory allocation exactly at CACHE_MIN_HEIGHT = 240.

The top 16 levels of the tree are cached in RAM. 2^16 = 65,536 maximum possible nodes. At 32 bytes per node hash, the absolute maximum memory footprint for the entire global state root index is exactly 2.09 MB. The bottom 240 levels are never stored; they are dynamically folded in O(log N) time using a binary search over bucketed UTXOs on disk. The node cannot be OOM-crashed by state bloat, period.