BUIP039: Upgrade via extension point


Active Member
Sep 18, 2016
Proposer: Amaury SECHET
Submitted on: 12/04/2016


To this date, there are only 2 ways to upgrade the Bitcoin network, commonly know as hard fork and soft fork. Both mechanisms have their own shortcomings. Soft forks are activated by miners and there is no way for node operators to voice their opinion on the fork nor is there a mechanism for them to oppose it. On the other hand, hard forks require everybody to upgrade in lockstep and create risk at activation time.

This BUIP proposes to upgrade using known extension points to introduce new feature into bitcoin. Because nodes known about these extension points, they can notice feature activation, even of features they don't know about, and act accordingly.

This BUIP defines OP_NOP1, OP_NOP4, OP_NOP5, OP_NOP6, OP_NOP7, OP_NOP8, OP_NOP0 and OP_NOP10 as extension points. Future BUIP should specify the extension points they add if appropriate.

After this BUIP activates, soft forks must be considered as 51% attack and dealt with accordingly. Adding new extension points should either be done using an existing extension points, or via a hard forks.

Extension activation, signaling and acceptance:

To start using an extension point, miner can signal their intention to do so using BIP9 signaling. When the extension point activates, node can either accept blocks using the extension point, or use their AD parameter to wait and see if the block is accepted by the network at large before accepting it itself, if they don't know about this new feature, or do not wish to activate it. Effectively, if too many nodes reject the block using the new extension point, the block will be orphaned.

The process repeats for each extension point.

Nodes can signal the extension they are willing to activate in their user agent string in a / separated string as they do for MG/EB/AD . For OP_NOP, They can signal using the OP_NOP prefix followed by a coma separated list of number indicating which OP_NOP the node is willing to activate. For instance, OP_NOP1,5,8 indicate that the node is willing to activate use of OP_NOP1, OP_NOP5 and OP_NOP8. other OP_NOP uses will be rejected until AD blocks are constructed on top of the first block that uses it.


This BUIP introduces an upgrade mechanism that has guarantee close the ones of a hard fork, while greatly diminishing the risks involved. Most upgrade to the consensus code which have been done over the years do fit what this BUIP describes, except P2SH and SegWit. This process has been relatively successful and should serve as a model for future upgrades. Adding the capability for nodes to voice their intention add insurance that the interests of various actors are aligned.
Last edited:


Active Member
Sep 18, 2016
So I got some feedback on this and the #1 feed back is that they were confused. I tried to put the post above is abstract terms as I don't wanted to tie the idea to a specific implementation of the idea (as I wanted to ruse it for BUIP037).

In order to makes things clearer, I'll explain how the mechanism would work specifically for OP_NOPs.

Bitcoin uses a script mechanism to check the validity of transaction. This script allows for non Turing complete smart contracts. The script are made of opcodes and each opcodes does something, such as checking if a signature is valid.

The scripting language have several operation knows as OP_NOPX where X is a number that do nothing. These opcodes can be repurposed to add new feature to bitcoin. This is how
OP_CHECKLOCKTIMEVERIFY was a repruposing of OP_NOP2 . Old nodes do nothing when encountering this opcode, while newer nodes will check that the lock time is what's expected.

The way opcodes are repuposed as soft fork today imposes some limitations on what these new opcodes can do. They cannot modify the stack, cannot produce result, and can only conditionally fail to validate a transaction.

Upgrading via soft fork has the problem that old nodes are fooled into thinking they do validate the blockchain when they actually can't. In addition, soft forks imposes design constraint on how things can be done, and lead to accumulating technical debt. On the other hand, hard fork imposes everybody to upgrade at once, and older nodes cannot validate either as they can't make sense of the blockchain and/or transactions they receive. Both situation aren't ideal.

I propose to define all the remaining OP_NOPs as "extension point". An extension point is something that is agreed upon up front that it will be used to add new feature to the protocol. Once OP_NOPs are defined to be extension point, the protocol can be extended by assigning a specific feature to this extension point.

New node, which supports the feature can accept and validate transactions using it. On the other hand, old nodes who see the usage of an extension point they do not know about will know that a feature they do not understand triggered on the network. At this point, they have various options:
- They can chose to treat these extension point as a soft fork and skip the script signature if the script uses the extension point.
- They can chose to wait for AD blocks and see if the use of the extension point is accepted by the network at large. If so, they proceed by skipping signature checks for these specific transactions.
- They can chose to not follow the chain and wait for an operator to upgrade, which is threating the extension point as a hard fork.

If extension points are tied to the AD parameter, then all 3 behaviors can be achieved by choosing an appropriate value for AD.

In short, current nodes have 2 state for the validity of the chain: valid or invalid. Using extension point, you get 3: valid, invalid, and "something I do not understand happened". As for soft forks, old nodes can still operate on the network with reduced security, however, contrary to soft forks, these nodes KNOW they are operating under reduced security condition and aren't fooled into think they still validate. In addition, nodes can refuse to accept the new feature if they so wish.

I hope that makes things clearer.


Well-Known Member
Mar 13, 2016
is there an unlimited number of these "OP_NOPX"

IDK but i get the feeling this proposal isn't using OP_NOPX as intended.

can't you pull off the same thing (valid, invalid, and "something I do not understand happened") by looking at the version number of a TX?
Wow, I like this, but am still confused ...

Do we need at first a hardfork to make all the nodes ready for dealing with extension-block-updates?

What kind of updates are possible with this? Every kind, or just modification of the scripting system?

Do I get this right that upgrades with extension points is something like a fork in a bag; it depends on the reaction of the nodes if nothing happens, it becomes a softfork (who doesn't upgrade accepts, but don't verifies) or a hardfork (nodes which don't upgrade are kicked out)?

If this provides a method to integrate the updating of scripts and more with the "unlimited philosophy" I'm conceptionally in, but like to see a description of the idea with more details (links to the feedbacks / discussion?) and a proposal for a interface of it.


Active Member
Sep 18, 2016
Implementing this wouldn't be a hard fork.
Implementing some new feature using this will be a hard fork as far as non BUIP039 node are concerned.

This can only be used to extend the script format using the current transaction format. This can be used to add pretty much whatever we want (as long as node operator decide to accept it) using BUIP037's transaction format.

And yes, your "fork in a bag" description is accurate. However, I'd like to not name this a fork, as naming something by its worse possible outcome is a very good way to taint the discussion from the get go. This is a way to upgrade the protocol, and it uses previously agreed upon extension points to do so. Let's name it in a way that reflect this mechanism.


Active Member
Sep 18, 2016
I don't think there is more formal discussion on this, just informal chat comments.

There is no way to implement a quadratic hashing or malleability fix with this. In fact you can only fix these as a hard fork. (No SegWit as a soft fork doesn't do this, it only creates new UTXO, which aren't affected).