<p>Changing the behavior of an op-code could mean that old (unupgraded) nodes interpret a transaction with that op-code differently than new (upgraded) nodes. If nodes interpret transactions in two different ways, this may cause the network to split as some nodes accept a block as valid while others reject it as invalid. We call such a breaking change in the protocol rules a “hard fork”.</p>
<p>Since we cannot go back and change how old software behaves and cannot force users to upgrade their software, we are careful to introduce changes in a forward-compatible manner. If we introduce new behavior, then in a way that makes the old nodes accept it, even when old nodes cannot fully validate the underlying script. We call this style of protocol rule upgrade a “soft fork”.</p>
<p>Changing <code>OP_CHECKMULTISIG</code> to pop one fewer element off the stack would be a hard fork. Even if a majority of the nodes was upgraded when such a rule took effect, the first transaction that makes use of the new rule would cause all old nodes to stop processing the most-work chain, forking the old nodes off the network.</p>

CC BY-SA 4.0
2023-01-31T13:24:28.243Z
Sure, there are ways to make it smoother, e.g. putting in the fix now to activate for outputs starting five years from now. It’s still a hard fork because anyone that will still fork off anyone that hasn’t upgraded at that time. And it would still break chains of presigned unbroadcast transactions.
Murch
CC BY-SA 4.0
2023-01-30T18:04:55.920Z
2023-01-30T18:04:55.920Z
Murch
<p>There are currently Bitcoin on the blockchain at various (non Taproot) addresses locked behind a script that includes the <code>CHECKMULTISIG</code> opcode with the bug in it. So you wouldn't want to change the scripts locking those funds because it might prevent the owner spending them. It would be changing the consensus rules for those funds without the owner's permission.</p>
<p>You could introduce a <code>CHECKMULTISIG2</code> opcode (as a soft fork) without the bug so that could be used instead of <code>CHECKMULTISIG</code> for future usage. However, the Taproot soft fork introduced a more efficient replacement for <code>CHECKMULTISIG</code> called <a href="https://bitcoin.stackexchange.com/questions/114465/how-does-the-checksigadd-opcode-work-how-does-it-compare-to-its-predecessor-che">CHECKSIGADD</a> that doesn't include the <code>CHECKMULTISIG</code> bug. If you use a SegWit v1 address (Taproot) you wouldn't use this <code>CHECKMULTISIG</code> opcode regardless (it was disabled for Taproot spends in <a href="https://github.com/bitcoin/bips/blob/master/bip-0342.mediawiki" rel="noreferrer">BIP342</a>) so there isn't much point introducing a <code>CHECKMULTISIG2</code> opcode.</p>

CC BY-SA 4.0
2023-01-31T03:00:06.700Z
You could also fix it by if (script_blockheight < CONSTANT) do_bugged_CHECKMULTISIG(); else do_fixed_CHECKMULTISIG(); that way the old ones work.
Joshua
CC BY-SA 4.0
2023-01-30T14:33:47.967Z
2023-01-30T14:39:02.703Z
2023-01-30T14:39:02.703Z
Michael Folkson
<p>I was reading Mastering Bitcoin and I read about a <strong>bug in CHECKMULTISIG</strong>. If the starting ideas of this command should work like this</p>
<pre><code>&lt;Signature B&gt;&lt;Signature C&gt; M &lt;Public key A&gt;&lt;Public key B&gt;&lt;Public key C&gt; N CHECKMULTISIG
</code></pre>
<p>But CHECKMULTISIG works like it needs an extra parameter, so M+1 parameters in total.
There's a workaround where you put a 0 at the beginning of the line, for instance, assume that M is equal to 2 and N to 3 (), like this</p>
<pre><code>0 &lt;Signature B&gt;&lt;Signature C&gt; 2 &lt;Public key A&gt;&lt;Public key B&gt;&lt;Public key C&gt; 3 CHECKMULTISIG
</code></pre>
<p>Why can't we fix this? If the consensus is reached, can we fix this? Why should someone not want to fix this?</p>

CC BY-SA 4.0
2023-01-30T13:50:46.200Z
I think it remains for backward compatibility. If it changed, then older transactions would no longer work. So it would probably require a new opcode.
Zephyrus
<script><multi-signature><consensus><taproot>
Why can the CHECKMULTISIG bug not be solved?
Paro
# Why can the CHECKMULTISIG bug not be solved?

(Asked by: username_0 on 2023-01-30)

I was reading Mastering Bitcoin and I read about a **bug in CHECKMULTISIG**. If the starting ideas of this command should work like this

```
<Signature B><Signature C> M <Public key A><Public key B><Public key C> N CHECKMULTISIG

```

But CHECKMULTISIG works like it needs an extra parameter, so M+1 parameters in total.
There's a workaround where you put a 0 at the beginning of the line, for instance, assume that M is equal to 2 and N to 3 (), like this

```
0 <Signature B><Signature C> 2 <Public key A><Public key B><Public key C> 3 CHECKMULTISIG

```

Why can't we fix this? If the consensus is reached, can we fix this? Why should someone not want to fix this?

**Tags:** script, multi-signature, consensus, taproot

> **Comments:**
> **username_1**: I think it remains for backward compatibility. If it changed, then older transactions would no longer work. So it would probably require a new opcode.  

---

## 2 answers

### Answer by username_3 on 2023-01-30. Score: 7 | Accepted answer

There are currently Bitcoin on the blockchain at various (non Taproot) addresses locked behind a script that includes the `CHECKMULTISIG` opcode with the bug in it. So you wouldn't want to change the scripts locking those funds because it might prevent the owner spending them. It would be changing the consensus rules for those funds without the owner's permission.

You could introduce a `CHECKMULTISIG2` opcode (as a soft fork) without the bug so that could be used instead of `CHECKMULTISIG` for future usage. However, the Taproot soft fork introduced a more efficient replacement for `CHECKMULTISIG` called [CHECKSIGADD](https://bitcoin.stackexchange.com/questions/114465/how-does-the-checksigadd-opcode-work-how-does-it-compare-to-its-predecessor-che) that doesn't include the `CHECKMULTISIG` bug. If you use a SegWit v1 address (Taproot) you wouldn't use this `CHECKMULTISIG` opcode regardless (it was disabled for Taproot spends in [BIP342](https://github.com/bitcoin/bips/blob/master/bip-0342.mediawiki)) so there isn't much point introducing a `CHECKMULTISIG2` opcode.

> **Comments:**
> **username_4**: You could also fix it by if (script_blockheight < CONSTANT) do_bugged_CHECKMULTISIG(); else do_fixed_CHECKMULTISIG(); that way the old ones work.  

---

### Answer by username_2 on 2023-01-30. Score: 4

Changing the behavior of an op-code could mean that old (unupgraded) nodes interpret a transaction with that op-code differently than new (upgraded) nodes. If nodes interpret transactions in two different ways, this may cause the network to split as some nodes accept a block as valid while others reject it as invalid. We call such a breaking change in the protocol rules a “hard fork”.

Since we cannot go back and change how old software behaves and cannot force users to upgrade their software, we are careful to introduce changes in a forward-compatible manner. If we introduce new behavior, then in a way that makes the old nodes accept it, even when old nodes cannot fully validate the underlying script. We call this style of protocol rule upgrade a “soft fork”.

Changing `OP_CHECKMULTISIG` to pop one fewer element off the stack would be a hard fork. Even if a majority of the nodes was upgraded when such a rule took effect, the first transaction that makes use of the new rule would cause all old nodes to stop processing the most-work chain, forking the old nodes off the network.

> **Comments:**
> **username_2**: Sure, there are ways to make it smoother, e.g. putting in the fix now to activate for outputs starting five years from now. It’s still a hard fork because anyone that will still fork off anyone that hasn’t upgraded at that time. And it would still break chains of presigned unbroadcast transactions.  

---

