¿Por qué 20 son las claves públicas máximas en una transacción multisig?

En script.hel siguiente límite se establece:

MAX_PUBKEYS_PER_MULTISIG = 20

Me pregunto:

  • ¿Por qué se establece el límite en 20?
  • ¿Cómo se construiría un script que permita nmás que el actual OP_16?

Por ejemplo, ¿funcionaría esto?

OP_m <pubKey1> ... 1 20 OP_CHECKMULTISIG

Respuestas (1)

El número 20 parece originarse en este compromiso: 8c9479c6bbbc38b897dc97de9d04e4d5a5a36730, también etiquetado como v0.3.12, que introdujo el término 'SigOps'. Lamentablemente, no veo ninguna mención de este cambio en el mensaje de compromiso en sí, o en la nota de lanzamiento de esta versión, y hay no es ninguna documentación.

Vemos que se estableció un límite para un número máximo de sigops en un bloque:

static const int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50;

y una forma de contarlos:

int GetSigOpCount() const
{
    int n = 0;
    const_iterator pc = begin();
    while (pc < 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;
}

Y las reglas siguen siendo las mismas, específicamente para los scripts multisig simples (aquellos que no están anidados en p2sho p2wsh). Una CHECKMULTISIGoperación simple siempre se cuenta como 20 sigops (hoy 80, con factor de escala testigo), por lo que permitir más de 20 checksigs CHECKMULTISIGinvalidará esta suposición y hará que se creen bloques con más sigops permitidos que el máximo posible.

Las reglas son menos estrictas para los scripts p2sh\p2wsh. Si el código de operación justo antes CHECKMULTISIGestá en el rango [OP_1, OP_16], entonces ese número se cuenta como los sigops para la verificación multisig, y cualquier otra cosa se cuenta como 20. En la práctica, 15 es el máximo de claves públicas que puede enviar como un script p2sh debido al 520 límite de inserción de bytes, pero para p2wsh, un ejemplo de 17 de 20 se vería así:

0x01 0x11 <pubkey1> <pubkey2> ... <pubkey 20> 0x01 0x14 CHECKMULTISIG