Warum ist BIP-147 (Dealing with Dummy Stack Element Temperierbarkeit, Teil von Segwit) notwendig?

Angesichts von BIP-11 (M-of-N-Standardtransaktionen) ist nicht klar, warum BIP-147 (Dealing with Dummy Stack Element Temperierbarkeit) notwendig ist.

BIP-11 gibt an:

OP_CHECKMULTISIG-Transaktionen werden mit einem Standard-ScriptSig eingelöst:

OP_0 ...signatures...

(OP_0 ist aufgrund eines Fehlers in OP_CHECKMULTISIG erforderlich; es entfernt ein Element zu viel vom Ausführungsstapel, sodass ein Dummy-Wert auf dem Stapel abgelegt werden muss).

Doch BIP-147 behauptet:

Ein Designfehler in OP_CHECKMULTISIG und OP_CHECKMULTISIGVERIFY führt dazu, dass sie nach der Signaturvalidierung ein zusätzliches Stapelelement ("Dummy-Element") verbrauchen. Das Dummy-Element wird in keiner Weise überprüft und kann durch einen beliebigen Wert ersetzt werden, ohne das Skript ungültig zu machen. ... [meine Betonung]

Diese Aussage scheint BIP-11 zu widersprechen, das eindeutig OP_0 als erstes Validierungsskriptelement erfordert.

Ich kann mir zwei Gründe für BIP-147 vorstellen:

  1. BIP-11 verlangt nicht explizit, dass der Stack überprüft wird, sondern nur, dass ein Multisignatur-Validierungsskript mit OP_0 beginnt;
  2. BIP-11 gilt überhaupt nicht für OP_CHECKMULTISIGVERIFY.

Sind das tatsächlich Beweggründe für BIP-147 und gibt es noch andere?

Antworten (1)

BIP 11 ist keine Konsensregel, sondern eine Empfehlung zur Verwendung von Multisig im Netzwerk.

BIP 147 beschreibt korrekt die bestehenden Netzwerkkonsensregeln: OP_CHECKMULTISIG und OP_CHECKMULTISIGVERIFY entfernen ein Element mehr vom Stapel als benötigt und ignorieren dieses Element. BIP 147 ändert die Regel so, dass diese Opcodes das Element nicht ignorieren, sondern eine 0 erfordern. Um mit BIP 11 konform zu sein, mussten Transaktionen dort bereits eine 0 Null setzen, und in der Praxis hat es jeder immer getan. Aber es gab keine Anforderung, dass Transaktionen BIP11 folgen mussten – es war nur eine Empfehlung für eine bessere Interoperabilität. Mit BIP147 wird es erforderlich, dort eine 0 zu haben, damit jede Transaktion gültig ist.

Der Grund für die Änderung ist die Formbarkeit: Derzeit kann jeder eine gültige Transaktion nehmen, die einen dieser Opcodes verwendet, und die 0 nehmen und durch etwas anderes ersetzen, ohne die Transaktion ungültig zu machen.

Idealerweise möchten wir den Fehler vollständig beheben und dafür sorgen, dass OP_CHECKMULTISIG und OP_CHECKMULTISIGVERIFY nicht von einem unnötigen Stapelelement abspringen. Das wäre jedoch abwärtskompatibel und würde daher nur für neue Transaktionen gelten, wenn wir bestehende Software nicht kaputt machen wollen. Der Ansatz in BIP147 gilt für alle Multisig-Transaktionen.

Wird der Extra-Element-Fehler in SegWit-Transaktionen anders behandelt? Ich schaue mir eine SegWit-Multisig-Einlösungseingabe an und sehe ein "leeres" Stapelelement, gefolgt von 2 Signaturen, dann gefolgt vom P2SH-Einlösungsskript. Ist das erste leere Stapelelement ""das Dummy-Element für CHECKMULTISIG?
@pinhead ja und nein. 0 wird als "" auf dem Skriptausführungsstapel codiert, also schiebt OP_0 wirklich nur ein leeres Stapelelement, und BIP147 erfordert nicht wirklich OP_0 - es erfordert nur ein leeres Stapelelement. In SegWit wird der Eingabestapel direkt codiert und nicht als Folge von Opcodes (wie es in scriptSig der Fall ist). Infolgedessen ist das Dummy-CMS-Argument im Zeugenstapel tatsächlich nur "".