Wie stark unterscheidet sich die Gewichtung von 2-von-3-Multisignatur-Eingaben zwischen P2SH und P2SH-P2WSH?

Ich versuche, das Gewicht einer 2-von-3-Multisignatur-P2SH-P2WSH-Eingabe zu berechnen. Ich habe die verwandte Frage Predict Multi Signature Transaction Size gefunden , die ich hier berechnet habe m=2, n=3:

pubkeySize=33
sigSize=72

SizeOfRedeemScript = 1+n*(1+pubkeySize)+1+1
// 2-of-3: SizeOfRedeemScript = 1+3*(1+33)+1+1 = 105

SizeOfScriptSig = 1+m*(1+sigSize)+SizeOfPushDataFor(RedeemScript)+SizeOfRedeemScript
// 2-of-3: SizeOfScriptSig = 1+2*(1+72)+2+105 = 1 + 146 + 2 + 105 = 254

sizeOf(input) = 32+4+SizeOfCsuintFor(SizeOfScriptSig) + SizeOfScriptSig + 4
// 2-of-3: sizeOf(input) = 32+4+3+254+4 = 297

Die Größe der 2-von-3-Eingabe in P2SH beträgt 293 bis 297 Bytes 1 . Das entspräche also bis zu 297*4 bytes = 1188 wu.

Wie würde ich das entsprechende Gewicht für eine 2-von-3-Multisignatur-P2SH-P2WSH-Eingabe berechnen?


1 Beachten Sie, dass, wenn beide Signaturen 71 Bytes groß sind, die scriptSig 252 Bytes beträgt , was als Länge in 1 Byte codiert werden kann , aber im schlimmsten Fall sind beide Signaturen 72 Bytes groß und die Länge der scriptSig benötigt 3 Bytes.

Antworten (2)

Um die Blockgewichtung zu berechnen, müssen Sie die Größe der Nichtzeugendaten in Byte und die Größe der Zeugendaten in Byte kennen.

Bei einer P2SH-P2WSH-Eingabe ist Ihre scriptSig immer 36 Byte groß. Dadurch wird die Größe der Eingaben in Bytes zu 36 + 36 + 4 = 76. Die Zeugen enthalten Ihre Unterschriften und Skripte, daher ist der Zeuge für diese Eingabe 1+m*(1 + sigSize) + SizeOfVarIntFor(RedeemScript) + SizeOfRedeemScript. Für eine 2-von-3-Multsig-Eingabe haben Sie somit 1 + 2*(1 + 72) + 2 + 105 = 254die Größe Ihres Zeugen in Bytes.

Die Formel zur Berechnung des Blockgewichts lautet base size * 3 + total size. Die Basisgröße ist die Größe aller Nicht-Zeugendaten, also beträgt Ihre Basisgröße 76 Bytes. Die Gesamtgröße ist die Größe aller Daten, einschließlich Zeugen, also beträgt Ihre Gesamtgröße 76 + 254 = 330. Das Einsetzen in die Formel ergibt 76 * 3 + 330 = 558. Somit beträgt die Gewichtung des P2SH-P2WSH 2-of-3 Multisig 558.

*Beachten Sie, dass dies SizeOfVarIntFor(RedeemScript)tatsächlich zwei Bytes sind, da Sie OP_PUSHDATA1 verwenden müssen, da die Länge des Einlöseskripts länger als 75 Bytes ist.

Wenn SizeOfVarIntFor(RedeemScript)es zwei Bytes wären, weil das Einlösungsskript länger als 75 Bytes ist, würde das nicht auch für SizeOfVarIntFor(SizeOfScriptSig)251 gelten SizeOfScriptSig?
@Murch Nein. Es gibt zwei Möglichkeiten, die Größe von Dingen in Transaktionen darzustellen. Innerhalb eines Skripts selbst verwenden wir eigentlich Pushdata-Opcodes. Wir benötigen zwei Bytes für Skripte, die länger als 75 Bytes sind, da wir dann den OP_PUSHDATA1-Opcode vor dem Größenbyte verwenden müssen. Für Größen von Dingen außerhalb von Skripten wie SizeOfScriptSigverwenden wir jedoch Compact Size Unsigned Integers. Die csuint benötigt nur dann ein zusätzliches Byte über der Nummer selbst, wenn die Nummer selbst mehr als 1 Byte benötigt. Sie können hier sehen, wie csuint funktioniert: bitcoin.org/en/…

Die Unterschiede zwischen P2SH, P2SH-P2WSH und P2WSH sind die folgenden:

  • P2SH: Der scriptPubKey hat ein P2SH-Programm. Das scriptSig stellt die entsprechenden Skriptargumente und das Einlösungsskript bereit, um das P2SH-Programm zu erfüllen.
  • P2SH-P2WSH: Der scriptPubKey hat ein P2SH-Programm. Das scriptSig hat das Witness-Programm und leitet es zur Auswertung an den Witness-Stack weiter. Der Zeugenstapel stellt die Skriptargumente und das Zeugenskript bereit.
  • P2WSH: scriptPubKey hat ein Witness-Programm, scriptSig ist leer und der Witness-Stack stellt die Skriptargumente und das Witness-Skript bereit.
  • Der Zeugenstapel ist für äquivalente P2SH-P2WSH- und P2WSH-Eingaben identisch.

Um also die Größe einer P2SH-P2WSH-Multisig zu berechnen, werden die Skriptargumente und das Erlöseskript als Skriptargumente und Zeugenskript in den Zeugenstapel verschoben, und Sie müssen die Kosten des Weiterleitungsskripts hinzufügen.

Die scriptSig in P2SH-P2WSH besteht aus scriptLength witnessProgramLength witnessVersion hashLength hashoder varInt PUSHBYTES OP_0 PUSHBYTES <hash>. Die Länge der scriptSig kann in einem 1-Byte-VarInt ausgedrückt werden, sodass die scriptSig insgesamt 1 + 1 + 1 + 1 + 32 = 36 B benötigt. Dies bedeutet, dass die Nicht-Witness-Bytes der Eingabe der Endpunkt sind (32 +4 B), das scriptSig (36 B) und die nSequence (4 B), die insgesamt 76 B ergeben.

Der Zeugenstapel enthält die Anzahl der Zeugenelemente (1 WU), die drei Skriptargumente, ein leeres Dummy-Element, da OP_CHECKMULTISIG ein zusätzliches Element des Stapels ausgibt, und die beiden Signaturen (1+2×(1+72) = 147 WU ) und das Zeugenskript, witnessScriptLength OP_m n×(PUSHBYTES+pubkey) OP_n OP_CHECKMULTISIG(1+1+3×(1+33)+1+1 = 106 WU).

Insgesamt ist die vsize einer 2-aus-3-P2SH-P2WSH-Eingabe also:

txid:vout:scriptSig:nSeq::witLength:scriptArgs:witScript
 32 +  4 +    36   +  4  +    1    +    147   +    106  = 76 + 254/4 = 139.5 vB 

Ausführliche Informationen zu allen drei Typen folgen unten für Ihre Bequemlichkeit.

P2SH

Die Größe einer P2SH-basierten 2-von-3-Multisig-Eingabe beträgt 293, 296 oder 297 Bytes, wie in der Frage beschrieben.

PREVOUT:
  hash (32 bytes)
  index (4 bytes)
SCRIPTSIG:
  length (varInt 1 or 3 bytes)
  signatures¹ (1+2×(1+72²) bytes = 147 bytes)
    dummy-OP_0 
    m×(PUSHBYTES+sig)
  OP_PUSHDATA1 len(redeemscript) (2 bytes)
  redeemscript (1+3×(1+33)+1+1 = 105 bytes)
    OP_m n×(PUSHBYTES+pubkey) OP_n OP_CHECKMULTISIG
nSequence (4 bytes)

32 + 4 + 3 + 1 + 2×(1+72) + 2 + 1 + 3×(1+33) + 1 + 1 + 4 =
36 + 3 + 147 + 2 + 105 + 4 = 297 B

Da Signaturen 71 oder 72 Bytes groß sein können, ergibt sich, dass die Eingabe eine 1-Byte-VarInt benötigt, um die Länge des scriptSig für zwei Low-r-Signaturen auszudrücken. Wenn eine oder beide Signaturen hoch-r sind, wird ein 3-Byte-VarInt benötigt, um die Länge der scriptSig auszudrücken.

P2SH-P2WSH

Das Gewicht eines P2SH-P2WSH 2-of-3 beträgt 556–558 WU, was 139,0–139,5 vB entspricht.

PREVOUT:
  hash (32 bytes)
  index (4 bytes)
SCRIPTSIG:
  length (varInt 1 byte)
  witness program: (1 + 1 + 1 + 32 = 35 bytes)
    length
    version (OP_0) 
    PUSHBYTES <32-byte hash>
nSequence (4 bytes)
WITNESS STACK:
  item count (1 WU)
  script arguments (1 + 2×(1+72²) WU)
    dummy-empty-element¹
    m×(varInt+sig)
  witnessScript (1+1+3×(1+33)+1+1 = 106 WU)
    length (varInt 1 WU)
    OP_m n×(PUSHBYTES+pubkey) OP_n OP_CHECKMULTISIG
  
32 + 4 + 1 + 1 + 1 + 1 + 32 + 4
+ [1 + 1 + 2×(1+72) + 1+1+3×(1+33)+1+1]/4
= 36 + 1 + 35 + 4 + [1 + 147 + 106]/4
= 76 + [254]/4
= 76 + 63.5
= 139.5 vB

P2WSH

Der P2WSH hat den gleichen Witness-Stack wie der P2SH-P2WSH, spart also genau die 35 B von der Umgehung des Redescripts. Das Gewicht eines P2WSH 2-of-3 beträgt 416–418 WU, was 104,0–104,5 vB entspricht.

PREVOUT:
  hash (32 bytes)
  index (4 bytes)
SCRIPTSIG:
  length (varInt 1 byte)
nSequence (4 bytes)
WITNESS STACK:
  item count (1 WU)
  script arguments (1 + 2×(1+72²) WU)
    dummy-empty-element¹ 
    m×(varInt+sig)
  witnessScript (1+1+3×(1+33)+1+1 = 106 WU)
    length (varInt 1 WU)
    OP_m n×(PUSHBYTES+pubkey) OP_n OP_CHECKMULTISIG

32 + 4 + 1 + 4
+ [1 + 1 + 2×(1+72) + 1 + 1 + 3×(1+33) + 1 + 1]/4
= 36 + 1 + 4 + [1 + 147 + 106]/4
= 41 + [254]/4
= 41 + 63.5 
= 104.5 vB

¹ OP_CHECKMULTISIG entfernt ein zusätzliches Element vom Stack
² Signaturen können 71 oder 72 Byte groß sein (oder selten noch kleiner)