Glosario / Protocolo y actualizaciones
OP_CHECKSIGADD
- ¿Qué es OP_CHECKSIGADD?
- OP_CHECKSIGADD cuenta firmas clave por clave dentro de tapscript y reemplaza el antiguo opcode (código de operación) de multisig por una comprobación compatible con la verificación por lotes y con futuros tipos de clave.
Se especifica en el BIP-342.
El opcode toma tres elementos de la pila, una firma, un recuento acumulado y una clave pública, y vuelve a apilar el recuento sin cambios o aumentado en uno. BIP-342 le asignó el opcode 186 y, al mismo tiempo, desactivó el opcode OP_CHECKMULTISIG, así que todo multisig en scripts Taproot se escribe de esta manera. La ventaja práctica es que una política de umbral ya no se detiene en 20 claves.
Cómo funciona
Un umbral en tapscript es una serie de verificaciones de firma con un recuento que pasa de una a la siguiente, y una comparación al final.
Escrito por extenso, un dos de tres queda así: apilar la primera clave pública, OP_CHECKSIG, apilar la segunda, OP_CHECKSIGADD, apilar la tercera, OP_CHECKSIGADD, apilar 2, OP_NUMEQUAL. La ejecución avanza de izquierda a derecha. OP_CHECKSIG deja 1 o 0 en la pila, y cada OP_CHECKSIGADD desapila una clave pública, desapila ese total acumulado, desapila la firma ofrecida para esa clave y vuelve a apilar el total sumándole 1 si la firma se verificó. La comparación final decide si se verificaron suficientes.
Un firmante que no participa aporta una cadena de bytes vacía en lugar de una firma. El opcode la ve, trata esa posición como sin firmar y devuelve el recuento intacto, lo que cuesta un solo byte en el testigo. Ese es todo el mecanismo, y elimina el elemento ficticio de la pila que OP_CHECKMULTISIG exigía por un error por uno (off-by-one) de la implementación original.
De verificar una clave frente a una firma se derivan dos consecuencias. La verificación pasa a poder hacerse por lotes: un nodo puede reunir todas las firmas Schnorr del bloque en una sola comprobación agregada en lugar de probar claves candidatas en orden, lo que constituye buena parte de la aceleración de la validación de Taproot. Y el número de claves lo limita el presupuesto de validación de tapscript, que gasta 50 unidades de peso por cada firma verificada, y no un tope fijo escrito en el opcode.
Dónde aparece
OP_CHECKSIGADD aparece en cualquier script Taproot que necesite más de un firmante, lo que en el software de billetera suele significar un descriptor y no un script en bruto.
Bitcoin Core lo expone como los fragmentos multi_a y sortedmulti_a dentro de un descriptor tr(), de modo que un quórum de tres claves se escribe como tr(internalkey,multi_a(2,KEY1,KEY2,KEY3)) y el software genera por usted la secuencia de opcodes. Miniscript lo trata de la misma manera, y los dispositivos de hardware que admiten políticas Taproot firman estos scripts sin necesidad de conocer la configuración de antemano.
El diseño también cambia la forma de construir un quórum. En lugar de una hoja que contenga las tres claves, un taptree (árbol de scripts de Taproot) puede contener tres hojas separadas de dos claves, una por cada pareja posible, y un gasto revela entonces solo la pareja que realmente firmó. Eso cuesta más en hojas de script y ahorra una clave pública en el testigo, y es una mejora real de privacidad frente a publicar el conjunto completo de claves en cada gasto.
OP_CHECKSIGADD frente a OP_CHECKMULTISIG
Tanto OP_CHECKSIGADD como OP_CHECKMULTISIG cuentan firmas frente a un conjunto de claves, y solo uno de los dos funciona en una hoja de Taproot. OP_CHECKMULTISIG sigue siendo perfectamente válido en los scripts heredados (legacy) y SegWit de versión 0, así que el multisig bc1q que la gente usa desde hace años no se ve afectado y no necesita ninguna migración.
Dentro de tapscript, los opcodes OP_CHECKMULTISIG y OP_CHECKMULTISIGVERIFY están desactivados por completo. Más allá de dónde funciona cada uno, importan tres diferencias: el opcode antiguo limita un script a 20 claves públicas y el nuevo no tiene ese número, el antiguo requiere un elemento ficticio adicional en la pila, que BIP-147 obligó más tarde a dejar vacío como regla de consenso, y el antiguo no puede verificarse por lotes porque un verificador no sabe de antemano a qué clave pertenece cada firma.