Why is 20 the maximum public keys in a multisig transaction? In script.h the following limit is set:

MAX_PUBKEYS_PER_MULTISIG = 20

I'm wondering:


Why is the limit set to 20?
How would one would construct a script that allows n more than the current OP_16?


E.g. would this work?

OP_m &lt;pubKey1&gt; ... 1 20 OP_CHECKMULTISIG
The number 20 seems to originate from this commit : 8c9479c6bbbc38b897dc97de9d04e4d5a5a36730, also tagged as v0.3.12, which introduced the term 'SigOps".  Sadly, I don't see any mention of this change in the commit message itself, or in this version's release note, and there isn't any documentation.

We see that both a limit for a maximum number of sigops in a block was set :



static const int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50;


and a way of counting them :



int GetSigOpCount() const
{
    int n = 0;
    const_iterator pc = begin();
    while (pc &lt; end())
    {
        opcodetype opcode;
        if (!GetOp(pc, opcode))
            break;
        if (opcode == OP_CHECKSIG || opcode == OP_CHECKSIGVERIFY)
            n++;
        else if (opcode == OP_CHECKMULTISIG || opcode == OP_CHECKMULTISIGVERIFY)
            n += 20;
    }
    return n;
}


And the rules are still the same, specifically for bare multisig scripts (those not nested in p2sh or p2wsh).  A bare CHECKMULTISIG operation is always counted as 20 sigops (today 80, with witness scale factor), so allowing anything more than 20 checksigs in CHECKMULTISIG will invalidate this assumption and will make it so creating blocks with more then maximum allowed sigops possible.

The rules are less strict for p2sh\p2wsh scripts.  If the opcode just before CHECKMULTISIG is in the range [OP_1, OP_16], then that number is counted as the sigops for the multisig verification, with anything else counted as 20.  In practice, 15 is the maximum of pubkeys you can push as a p2sh script because of the 520 bytes push limit, but for p2wsh, an example of 17-of-20 would look like :

0x01 0x11 &lt;pubkey1&gt; &lt;pubkey2&gt; ... &lt;pubkey 20&gt; 0x01 0x14 CHECKMULTISIG