Instantly share code, notes, and snippets.

What would you like to do?
Version bits BIP

  BIP: ??
  Title: Version bits
  Author: Pieter Wuille <>, Peter Todd <>, Greg Maxwell <>
  Status: Draft
  Type: Informational Track
  Created: 2015-01-16

Table of Contents


This document specifies a proposed change to the semantics of the 'version' field in Bitcoin blocks, allowing multiple backward-compatible changes (further called called "soft forks") being deployed in parallel. It relies on interpreting the version field as a bit vector, where each bit can be used to track an independent change. Once the consensus change takes place, the bit is no longer necessary, and can be reused for later changes. In case a change is not adopted by majority vote before a pre-set timestamp, it is reverted and the used bit becomes available again as well.


BIP 34 introduced a mechanism for doing soft-forking changes without predefined flag timestamp (or flag block height), instead relying on measuring miner support indicated by a higher version number in block headers. As it relies on comparing version numbers as integers however, it only supports one single change being rolled out at once, requiring coordination between proposals, and does not allow for permanent rejection: as long as one soft fork is not fully rolled out, no future one can be scheduled.

In addition, BIP 34 made the integer comparison (nVersion >= 2) a consensus rule after its 95% threshold was reached, removing 231+2 values from the set of valid version numbers (all negative numbers, as nVersion is interpreted as a signed integer, as well as 0 and 1). This indicates another downside this approach: every upgrade permanently restricts the set of allowed nVersion field values. This approach was later reused in BIP 66, which further removed nVersion = 2 as valid option. As will be shown further, this is unnecessary.



Bit flags We are permitting several independent soft forks to be deployed in parallel. For each, a bit B is chosen from the set {0,1,2,...,28}, which is not currently in use for any other ongoing soft fork that hasn't progressed into the implied or rejected state (see further). A deadline timestamp D is also chosen. Miners signal intent to enforce the new rules associated with the proposed soft fork by setting bit 1B in nVersion to 1 in their blocks, before the deadline D is reached.

High bits The highest 3 bits are set to 001, so the range of actually possible nVersion values is [0x20000000...0x3FFFFFFF], inclusive. This leaves two future upgrades for different mechanisms (top bits 010 and 011), while complying to the constraints set by BIP34 and BIP66. Having more than 29 available bits for parallel soft forks does not add anything anyway, as the (nVersion >= 3) requirement already makes that impossible.

Thresholds For each soft fork, two threshold conditions are tracked. Whenever A out of the W predecessors of a block, plus the block itself have bit B set, and all of those (W + 1) blocks have a GetMedianTimePast() below D, consensus rules related to the soft fork apply to that block (called activation). Whenever I out of any W subsequent blocks (regardless of the block itself) have bit B set, and all of those W blocks have a GetMedianTimePast() below D, the consensus rules related to that soft fork also apply (called implication) to any successor of those W blocks (called implication). Whenever a soft fork is implied for a block, its bit B should not be set anymore, allowing the bit to become available immediately again. The values A, I and W are chosen to be identical to BIP34 (750, 950, and 1000 for Bitcoin mainnet). Comparisons happen against the GetMedianTimePast(), because it is by consensus rules guaranteed to be monotonic.

Warning system To support upgrade warnings, an extra "unknown upgrade" is tracked, using the "implicit bit" mask = (block.nVersion & ~expectedVersion) != 0. Mask will be non-zero whenever an unexpected bit is set in nVersion. Whenever activation for the unknown upgrade is detected, the software should warn about the presence of an unknown network rule. When implications triggers, the software should warn even louder, and probably keep warning even if the threshold is not reached anymore for later blocks (assuming an unknown soft fork reached implied state, and is thus no longer detectable).

Support for future changes

The mechanism described above is very generic, and variations are possible for future soft forks. Here are some ideas that can be taken into account.

Modified thresholds The thresholds chosen in BIP 34 (750, 950, 1001) do not have to be maintained for eternity, but changes should take the effect on the warning system into account. In particular, having an implication threshold that is incompatible with the one used for the warning system may have long-term effects, as the warning system cannot rely on a permanently detectable condition anymore (as opposed to the BIP 34 based mechanism).

Conflicting soft forks At some point, two mutually exclusive soft forks may be proposed. The naive way to deal with this is to never create software that implements both, but that is a making a bet that at least one side is guaranteed to lose. Better would be to encode "soft fork X cannot be activated or implicated" as consensus rule for the conflicting soft fork - allowing software that supports both, but can never trigger conflicting changes.

Multi-stage soft forks Soft forks right now are typically treated as booleans: they go from an inactive to an active state in blocks. Perhaps at some point there is demand for a change that has a larger number of stages, with additional validation rules that get enabled one by by. The above mechanism can be adapted to support this, by interpreting a combination of bits as an integer, rather than as isolated bits. The warning system is compatible with this, as (nVersion & ~nExpectedVersion) will always be non-zero for increasing integers.


This comment has been minimized.

davecgh commented May 27, 2015

The word "called" is repeated in the first paragraph further called called "soft forks"

Under the Motivation section, "This indicates another downside of this approach"

The parenthesized statement (called implication) is repeated in the Mechanism -> Thresholds section.


This comment has been minimized.

domob1812 commented May 27, 2015

Note that this breaks the current mechanism employed for merge-mined chains (e. g., Namecoin). Merge-mining in the current specification relies on bit 8 to signal merge-mined blocks and bits 16+ to indicate the chain ID.

I realise this is not an important consideration for Bitcoin proper, but I wanted to mention it nevertheless. Particularly when merge-mining of sidechains may be important in the future (although a new protocol could be employed for them).


This comment has been minimized.

jtimon commented May 27, 2015

Why this new condition "all of those (W + 1) blocks have a GetMedianTimePast() below D"?
It would probably be useful to elaborate on this?

@domob1812 I didn't know this, but other merged mined chains can MM without using the version of the bitcoin block for signaling anything. The coinbase transaction should be enough.


This comment has been minimized.

jtimon commented Jun 26, 2015

One thing to note in the bip is that parallel softfork deployments multiply the test cases. For example, if feature 1 and 2 are being voted and you want to introduce feature 3, you have to test feture 3 without 1 or 2, feature 3 with only 1 activated and feature 3 with only 2 activated. All of them must work since you don't know when miners will adapt their software to support each of them.
In the same way, when feature 2 was introduced, it had to be tested with and without feature 1.


This comment has been minimized.

petertodd commented Jun 29, 2015

@jtimon Agreed. With some pretty significant (and risky!) code changes to the script verification mechanism, that might not matter as much, but right now the most likely class of soft-forks we'll see - new opcodes and opcode behavior - is all pretty hard to reason about.

I do wonder if the mining community is going to take a look at this and think "Nope!" Even simple soft-fork's like BIP66/65/34 have caused them issues re: upgrading.


This comment has been minimized.

jl2012 commented Jul 17, 2015

@domob1812 Is that true? I can't see any block version > 3 in the bitcoin blockchain


This comment has been minimized.

mruddy commented Aug 2, 2015

This part is worded confusingly to me: "Having more than 29 available bits for parallel soft forks does not add anything anyway, as the (nVersion >= 3) requirement already makes that impossible."

My initial reaction was:
No, it doesn't. 0x40000000-0x7fffffff allows 30 (= 32 - sign bit - proposal bit) concurrent soft forks yet doesn't violate the nVersion >=3 requirement. Also, only ever allowing 2^29 future soft forks with current design is not the same thing as only allowing 29 concurrent soft fork deployments (which unbound the total number of future soft forks due to bit re-use allowed by this proposal [although at the cost of having to consider the block's time and the median time of 11 preceding blocks]).

It took me a few reads before I got that what I think you meant was that the current way of handling nVersion means that only one soft fork can be rolled out at a time (so by implication, allowing 29 concurrent should be a plentiful enabler).

If that's what you meant, then maybe you could word that like, "Since the current version number comparison scheme allows only a single soft fork to be deployed at a time, the increase to allow up to 29 concurrent deployments should provide plentiful and sufficient flexibility.".


This comment has been minimized.

mruddy commented Aug 2, 2015

Also, is this proposal too greedy in how many bits it claims? It leaves only two other possible bip34/66 compatible mechanism changes with the top bits. How many concurrent soft forks are realistic? Likely a few at most due to the previously noted testing concerns. So, why not use like 10 bits for this proposal? They are recyclable bits. So, you'd choose maybe 0x400 as your proposal's bit. Thus versions in the range 0x400-0x7ff would be related to this mechanism. If this is not a concern, or you don't agree, then maybe a quick note of why in the proposal would be good.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment