¿Por qué es necesario BIP-147 (Tratar con la maleabilidad del elemento de pila ficticia, parte de segwit)?

Dado BIP-11 (Transacciones estándar M-de-N), no está claro por qué es necesario BIP-147 (Tratar con maleabilidad de elementos de pila ficticia).

BIP-11 establece:

Las transacciones OP_CHECKMULTISIG se canjean mediante un scriptSig estándar:

OP_0 ...signatures...

(Se requiere OP_0 debido a un error en OP_CHECKMULTISIG; saca demasiados elementos de la pila de ejecución, por lo que se debe colocar un valor ficticio en la pila).

Sin embargo, BIP-147 afirma:

Una falla de diseño en OP_CHECKMULTISIG y OP_CHECKMULTISIGVERIFY hace que consuman un elemento de pila adicional ("elemento ficticio") después de la validación de la firma. El elemento ficticio no se inspecciona de ninguna manera y podría reemplazarse por cualquier valor sin invalidar el script. ... [énfasis mío]

Esta declaración parece contradecir BIP-11, que claramente requiere OP_0 como el primer elemento del script de validación.

Puedo pensar en dos razones para BIP-147:

  1. BIP-11 no requiere explícitamente que se verifique la pila, sino que un script de validación de múltiples firmas comienza con OP_0;
  2. BIP-11 no se aplica en absoluto a OP_CHECKMULTISIGVERIFY.

¿Son estas motivaciones para BIP-147 y hay otras?

Respuestas (1)

BIP 11 no es una regla de consenso, sino una recomendación sobre cómo usar multisig en la red.

BIP 147 es correcto al describir las reglas de consenso de red existentes: OP_CHECKMULTISIG y OP_CHECKMULTISIGVERIFY extraen un elemento más de la pila de lo necesario e ignoran ese elemento. BIP 147 cambia la regla para hacer que estos códigos de operación no ignoren el elemento, sino que requieran que sea un 0. Para cumplir con BIP 11, las transacciones ya tenían que poner un 0 cero allí, y en la práctica todos siempre lo han hecho. Pero no había ningún requisito de que las transacciones siguieran BIP11; solo era una recomendación para una mejor interoperabilidad. Con BIP147 se requiere tener un 0 allí para que cada transacción sea válida.

La razón para cambiar esto es la maleabilidad: actualmente, cualquiera puede tomar una transacción válida que use cualquiera de estos códigos de operación y tomar el 0 y reemplazarlo con cualquier otra cosa, sin invalidar la transacción.

Idealmente, nos gustaría corregir el error por completo y hacer que OP_CHECKMULTISIG y OP_CHECKMULTISIGVERIFY no aparezcan como un elemento de pila innecesario. Sin embargo, eso sería incompatible con versiones anteriores y, por lo tanto, solo se aplicaría a nuevas transacciones si no queremos romper el software existente. El enfoque en BIP147 se aplica a todas las transacciones multisig.

¿El error de elementos adicionales se aborda de manera diferente en las transacciones de SegWit? Estoy mirando una entrada de redención multisig de SegWit y creo que veo un elemento de pila "vacío" seguido de 2 firmas, luego seguido del script de canje de P2SH. ¿Ese primer elemento de la pila vacía ""es el elemento ficticio para CHECKMULTISIG?
@pinhead Sí y no. 0 está codificado como "" en la pila de ejecución del script, por lo que OP_0 realmente solo empuja un elemento de pila vacío, y BIP147 en realidad no requiere OP_0, solo requiere un elemento de pila vacío. En SegWit, la pila de entrada se codifica directamente en lugar de como una secuencia de códigos de operación (como es el caso de scriptSig). Como resultado, el argumento CMS ficticio en la pila de testigos es simplemente "".