BIP-110 Explained for Developers: How Bitcoin Soft Forks Actually Work
Published to Dev.to — Bitcoin Development Series, Part 1 of 4_ Bitcoin is heading toward an August 2026 deadline for BIP-110, a proposed temporary softfork that would restrict Ordinals-style arbitrary data from being embedded in transactions for one year. As of today, miner signaling sits at effectively zero. The proposal is almost certainly going to fail but the mechanics of why and how are worth understanding if you work anywhere near the Bitcoin protocol. This post walks through how soft fork activation works, what BIP-110 specifically proposes, and how to inspect miner signaling yourself with code. What Is a Soft Fork? A soft fork is a backward-compatible change to Bitcoin's consensus rules. Nodes running old software still accept blocks from nodes running the new rules — but not vice versa. This is what makes soft forks safer than hard forks in a permissionless network: you do not force everyone to upgrade on day one. Hard forks, by contrast, change rules in a way that causes old nodes to reject new blocks entirely. They require near-universal coordination, which is why Bitcoin has avoided them. How Soft Fork Activation Works: BIP 9 The dominant activation mechanism used since 2016 is defined in BIP 9 . The process works like this: A proposal is assigned a version bit (bit 0–28) in the block header's nVersion field. Miners signal readiness by setting that bit in blocks they produce. Activation requires 95% of blocks in a 2,016-block retarget window to signal support. There is a starttime and a timeout . If the threshold is not met before timeout , the proposal fails and is discarded. # Simplified BIP 9 state machine logic THRESHOLD = 0.95 # 95% of blocks in a retarget window WINDOW = 2016 # one retarget period def check_activation ( signaling_blocks : int , total_blocks : int ) -> str : ratio = signaling_blocks / total_blocks if ratio >= THRESHOLD : return " LOCKED_IN " # activates after one more window return " STARTED " # still counting print ( check_activati