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. . .

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 ofwhyandhoware 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 9The dominant activation mechanism used since 2016 is defined inBIP 9. The process works like this:A proposal is assigned a version bit (bit 0–28) in the block header'snVersionfield. Miners signal readiness by setting that bit in blocks they produce. Activation requires95% of blocks in a 2,016-block retarget windowto signal support. There is astarttimeand atimeout. If the threshold is not met beforetimeout, the proposal fails and is discarded. # Simplified BIP 9 state machine logicTHRESHOLD=0. 95# 95% of blocks in a retarget windowWINDOW=2016# one retarget perioddefcheck_activation(signaling_blocks:int,total_blocks:int)->str:ratio=signaling_blocks/total_blocksifratio>=THRESHOLD:return"LOCKED_IN"# activates after one more windowreturn"STARTED"# still countingprint(check_activation(1914,2016))# => LOCKED_IN (95%)print(check_activation(1800,2016))# => STARTED (89. 3%)print(check_activation(5,2016))# => STARTED (0. 25%) — current BIP-110 situationEnter fullscreen modeExit fullscreen modeBIP-110 uses a variant of this with a hard deadline instead of an ongoing timeout. If signaling does not lock in before the August activation window closes, the proposal is considered rejected. What BIP-110 Actually ProposesBIP-110 is titled "Reduced Data Temporary Softfork. " It proposes to cap the amount of arbitrary data that can be pushed via witness scripts to42 bytes per input— effectively making Ordinals-style inscriptions impossible for a period of one year. The mechanism targets theOP_FALSE OP_IF . . . OP_ENDIFenvelope that Ordinals uses to embed data in the tapscript witness. Under BIP-110, a transaction would be invalid during the restriction window if any witness stack item exceeds the cap. # Standard Ordinals inscription envelope (what BIP-110 targets) OP_FALSE OP_IF OP_PUSH "ord" # protocol tag OP_PUSH 1 OP_PUSH "text/plain" # content type OP_PUSH 0 OP_PUSH OP_ENDIF Enter fullscreen modeExit fullscreen modeUnder BIP-110, thepush beyond 42 bytes would cause the transaction to be rejected by upgraded nodes. Non-upgraded nodes would still accept it which is what makes this a soft fork rather than a hard fork. Checking Miner Signaling On-ChainYou can inspect signaling using Bitcoin Core's RPC interface or a block explorer API. Here is how to do it with Python and thebitcoin-rpclibrary:pipinstallpython-bitcoinrpcEnter fullscreen modeExit fullscreen modefrombitcoinrpc. authproxyimportAuthServiceProxyimportstructRPC_URL="http://rpcuser:rpcpassword@127. 0. 0. 1:8332"BIP110_BIT=4# assigned version bit for BIP-110defget_rpc():returnAuthServiceProxy(RPC_URL)defcheck_version_bit(nversion:int,bit:int)->bool:"""BIP 9 signals when nVersion has bit N set and the high bits match 0x20000000. """BIP9_TOP_MASK=0xE0000000BIP9_TOP_BITS=0x20000000if(nversion&BIP9_TOP_MASK)!=BIP9_TOP_BITS:returnFalsereturnbool(nversion&(1dict:rpc=get_rpc()tip_hash=rpc. getbestblockhash()tip=rpc. getblock(tip_hash)tip_height=tip["height"]signaling=0total=0block_hash=tip_hashfor_inrange(num_blocks):block=rpc. getblock(block_hash)nversion=block["version"]ifcheck_version_bit(nversion,BIP110_BIT):signaling+=1total+=1block_hash=block. get("previousblockhash")ifnotblock_hash:breakreturn{"blocks_scanned":total,"signaling":signaling,"not_signaling":total-signaling,"signal_percentage":round((signaling/total)*100,2),"threshold_needed":95. 0,"locked_in":(signaling/total)>=0. 95,}result=scan_signaling(2016)print(result)# Current output (approximately): # {'blocks_scanned': 2016, 'signaling': 5, 'not_signaling': 2011, # 'signal_percentage': 0. 25, 'threshold_needed': 95. 0, 'locked_in': False}Enter fullscreen modeExit fullscreen modeIf you do not run a full node, you can query a public API instead:importhttpxdefcheck_signaling_via_api(num_blocks:int=100)->dict:"""Uses mempool. space API — no node required. """signaling=0# Get recent block heightsresp=httpx. get("https://mempool. space/api/blocks")blocks=resp. json()forblockinblocks[:num_blocks]:nversion=block["version"]ifcheck_version_bit(nversion,BIP110_BIT):signaling+=1return{"sample_size":len(blocks[:num_blocks]),"signaling":signaling,"signal_percentage":round((signaling/len(blocks[:num_blocks]))*100,2),}print(check_signaling_via_api())Enter fullscreen modeExit fullscreen modeWhy Saylor and Adam Back Oppose ItThe opposition from Michael Saylor and Adam Back is not purely technical it is about governance precedent. Their argument: Bitcoin's consensus layer should not be used to resolve application-level disputes. Ordinals are a use of witness space that Taproot technically permits. If the community dislikes it, the correct response is social (pools refusing transactions) or economic (higher fee competition), not a consensus rule change. The concern is that BIP-110 passing would establish a precedent where any sufficiently disliked use of block space can be banned by a temporary softfork which is a much larger surface area than the original dispute. What Happens If BIP-110 FailsIf the August window closes without 95% signaling, BIP-110 is discarded with no effect on the chain. The Consensus Cleanup effort (being split into independent BIPs per the latest Bitcoin Optech discussion) continues as a separate track, focused on fixing genuine protocol vulnerabilities rather than restricting applications. The Ordinals debate will continue but through fee pressure and mining pool policy, not consensus rules. Further ReadingBIP-110 full text — bitcoin/bips #2017Bitcoin Optech Newsletter #412— Consensus Cleanup BIP splitting discussionBIP 9 specificationmempool. space API docsNext in this series: How Ordinals Actually Work Under the Hood — the commit-reveal pattern, witness encoding, and a full inscription walkthrough with code.