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.
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.
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.
Unlike first-generation blockchains (like Bitcoin or Ethereum), Midstate was engineered specifically to solve hardware centralization and on-chain surveillance:
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.
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.
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.
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.
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.
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).
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.
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?
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.
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.
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.
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:
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.
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:
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.
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.
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.
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.
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.
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:
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:
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.
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:
Engineering detail: To prevent IEEE-754 floating-point underflow in Rust, this integral is approximated using Log-Sum-Exp over 1,000 discrete slices.
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."
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.
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.
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.
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.
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 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.
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.
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.
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.
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.
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.
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:
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 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:
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)
}
}
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.
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:
Every single Midstate node in the world independently verifies this construction. There is no trust required — only math.
Midstate achieves profound transaction privacy without compromising the auditability of the global state.
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.
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:
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.
Transactions are split into Commit and Reveal phases to decouple mempool admission from the cleartext execution of the state transition.
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.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).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.
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.
wallet/coinjoin.rs)MIN_MIX_PARTICIPANTS = 2, MAX_MIX_PARTICIPANTS = 161 covers the mandatory network feeAny node can initialise a session by broadcasting a MixAnnounce message containing a unique MixID and the target denomination.
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.
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.
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.
MixSession::register and set_fee_input. DataBurn outputs are explicitly forbidden.BLAKE3(mix_id || coin_id || peer_id || nonce) ≥ 24 leading zeros — exactly the same constant used for mempool spam protection (MIX_JOIN_POW_BITS).coin_id (see proposal()). Participants sign only the final commitment hash after local verification.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.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.
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.
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.
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 global state_root of the Midstate network is a combination of two distinct data structures:
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:
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.
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.
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.
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.
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.
final_hash.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.
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.
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.
Midscript supports three literal types, which are all ultimately pushed to the stack as byte arrays.
"a1b2c3d4" compiles to PUSH_HEX a1b2c3d4.10000 compiles to PUSH_INT 10000 (little-endian byte array).true and false compile to PUSH_INT 1 and PUSH_INT 0.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();
}
Midscript provides syntactic sugar for standard stack manipulations and cryptographic checks. These map directly to underlying opcodes.
| Function | Compiled Opcodes | Description |
|---|---|---|
peek() | DUP | Duplicates the top stack item. |
drop() | DROP | Discards the top stack item. |
swap() | SWAP | Swaps the top two stack items. |
over() | OVER | Copies the second-to-top item to the top. |
rot() | ROT | Rotates the top three items (3rd to top). |
fail() | PUSH_INT 0 | Pushes 0 (forces a failure if left at end of execution). |
check_sig(pk) | pk CHECKSIG | Verifies signature against pubkey. Pushes 1 (valid) or 0 (invalid). |
require_sig(pk) | pk CHECKSIGVERIFY | Verifies signature and aborts script immediately if invalid. |
require_time(h) | h CHECKTIMEVERIFY | Aborts if block height is less than h. |
require_preimage(h) | HASH h EQUALVERIFY | Hashes top item and aborts if it doesn't equal h. |
require_transfer(a, v) | a SUM_TO_ADDR v EQUALVERIFY | Covenant: Aborts if transaction doesn't send exactly v units to address a. |
verify_gte(v) | v GREATER_OR_EQUAL VERIFY | Aborts if the top item is less than v. |
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_EQUALIf 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);
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
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;
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;
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 ✓
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.
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.
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 ✓
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.
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.
// 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.
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.
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.
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> ]
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
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
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.
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.
"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 ✗
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
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.
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.
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.
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.
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 ✗
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.
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
Midstate Stack Machine Code assembly files use the .msc extension. Compile them with the CLI:
| Mnemonic | Stack Effect | Description |
|---|---|---|
PUSH_INT <n> | → n | Push integer literal |
PUSH_HEX <hex> | → bytes | Push raw bytes from hex string |
PUSH_DATA <data> | → data | Push data blob (pk, address, etc.) |
DROP | x → | Discard top item |
DUP | x → x x | Duplicate top item |
SWAP | a b → b a | Swap top two items |
OVER | a b → a b a | Copy second-to-top item to top |
ROT | a b c → b c a | Rotate top three items |
| Mnemonic | Stack Effect | Description |
|---|---|---|
ADD | a b → a+b | Integer addition |
SUB | a b → a-b | Integer subtraction (fails on underflow) |
EQUAL | a b → bool | Push 1 if equal, 0 otherwise |
EQUALVERIFY | a b → | Fail if not equal, else pop both |
GREATER_OR_EQUAL | a b → bool | Push 1 if a >= b |
VERIFY | x → | Fail if top is not 1 |
| Mnemonic | Description |
|---|---|
IF | Pops top item. Executes IF block if 1, ELSE block if 0. |
ELSE | Alternate branch of IF. |
ENDIF | Closes IF/ELSE block. |
| Mnemonic | Stack Effect | Description |
|---|---|---|
HASH | data → BLAKE3(data) | BLAKE3 hash of top item |
CHECKSIG | sig pk → bool | Verify WOTS+/MSS signature. Push result. |
CHECKSIGVERIFY | sig pk → | Verify signature. Fail if invalid. |
| Mnemonic | Stack Effect | Description |
|---|---|---|
CHECKTIMEVERIFY | height → | Fail if chain height < height. Pop height. |
SUM_TO_ADDR | addr → amount | Sum all output values in this tx sent to addr. Push total. |
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 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.
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.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.
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.
Midstate uses HD (Hierarchical Deterministic) wallets by default. To create a new wallet, run:
To view your total balance, live on-chain coins, and pending commits:
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
By default, Midstate uses WOTS+ signatures. These are strictly one-time-use to preserve post-quantum security. To generate a fresh receiving address:
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.
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.
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.
To start a full node, sync the chain, and begin CPU mining on all available cores, simply run:
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.
| 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) |
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.
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).
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.
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.
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.
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.
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.