Schritt-für-Schritt-Beispiel zum Einlösen eines P2SH-Ausgangs erforderlich

Ich bin BIP16 bei der Erstellung einer P2SH-Transaktion gefolgt. Ich möchte ein einfaches (eine Signatur) P2SH erstellen. Ich erhalte eine Fehlermeldung, wenn ich versuche, den Tx zu übertragen. Fehler ist16: mandatory-script-verify-flag-failed (Signature must be zero for failed CHECK(MULTI)SIG operation)

Um es klar zu sagen, ich versuche es nicht mit Multisig. Was ich tue, lässt sich am besten beschreiben als P2SH-P2PK, obwohl ich diesen Begriff noch nicht gesehen habe. Dies ist das einzige Beispiel in BIP16, also sollte es funktionieren.

Folgendes habe ich versucht (Testnet):

private key: BB2AC60BC518C0E239D5AF9D8D051A6BDFD0D931268DCA70C59E5992 
public key: 039f53e45f8f18b8ed294378bda342eff69b2053debf27fbede7d2d6bd84be6235 
(compressed)

redeemScript: [{pubKeySize,pubKey}] [OP_CHECKSIG]
21039F53E45F8F18B8ED294378BDA342EFF69B2053DEBF27FBEDE7D2D6BD84BE6235AC 

redeemScriptHash: RIPEMD160(SHA256(redeemScript))  
323D0E8A083E98010299109337850D05DD6157F7

p2shAddress: Base58Check(0xC4 + redeemScriptHash) (C4 for testnet)
2MwprvB9tUMtX4vK8zJK8K329fNu79CJgR7

Die obige Adresse hat zwei UTOXs im Testnet:

UTXO1: e434a13cac79dc3d26e7279bff05c0f071a2df03e2ba6ca13c88f0e82dca9998:0
UTXO2: 9b4943e7ab5f4512e42c94254eb6aab4c6823ce06d4ff816b7ce4fda155a2571:0

Ich möchte nun beide UTXOs ausgeben und folgende Ausgaben behalten:

Out1: 2MwprvB9tUMtX4vK8zJK8K329fNu79CJgR7 34000000 Satoshis
Out2: 2N8hwP1WmJrFF5QWABn38y63uYLhnJYJYTF 100000000 Satoshis   

Ich habe den TX wie folgt erstellt:

  1. Erstellen Sie unsignierte Transaktionen, bei denen alle scriptSigs leer sind

  2. Setzen Sie für jede zu signierende Eingabe ihre scriptSig auf resolveScript: 21039F53E45F8F18B8ED294378BDA342EFF69B2053DEBF27FBEDE7D2D6BD84BE6235AC, und lassen Sie andere scriptSigs leer.

  3. Serialisieren Sie den neuen tx und hängen Sie SIGHASHALL-Bytes (0x01) in Little Endian 4 Bytes an

  4. Verdoppeln Sie Sha256 oben und signieren Sie den resultierenden Wert. Fügen Sie der Signatur ein Byte 0x01 hinzu, um SIGHASH_ALL anzuzeigen. Sei sigder resultierende Wert.

  5. Legen Sie die scriptSig fest als:

    [0x00] [{sigSize, sig}] [{pubKeySize, pubKey}] [OP_CHECKSIG]

Ich gehe davon aus, dass folgender scriptPubKey verwendet wird:

[OP_HASH160] [{scriptHashSize, scriptHash}] [OP_EQUAL]

Im Folgenden sind die k, rund s-Werte für die Signatur jeder Eingabe aufgeführt:

Eingang 1:

k = 98790447509501799195296257240616657470656053786701275200434341714298778299820  
r = 96398386359095408146340664941016369169423137684113382189227162443480418477689
s = 62903510511574365450545635776206168644738316078298063260649088246548574249129

Eingang 2:

k = 109372172176680138721552873719725202562296645126925021083510279924852033069204  
r = 105162394984132461723584277789901247831150698039237112243693144757926439529504
s = 62903510511574365450545635776206168644738316078298063260649088246548574249129

Danach erhalte ich den folgenden Fehler in Bitcoin für das Senden des TX:

error code: -26
error message:
16: mandatory-script-verify-flag-failed 
(Signature must be zero for failed CHECK(MULTI)SIG operation)

Was mache ich falsch?

BEARBEITEN: Dank der Antwort von Arubi stellte ich fest, dass es bei den obigen Schritten zwei Probleme gab. Das erste, was ich falsch gemacht habe, war, die redeemScriptDaten nicht als Stack zu codieren. Das Zweite, was ich falsch gemacht habe, war das Einsetzen [0x00]von scriptSig. Nachdem Sie das behoben haben, sollte Schritt 5 sein:

  1. Setzen Sie das redeemScriptals[{pubKeySize, pubKey}] [OP_CHECKSIG]

  2. Setzen Sie das scriptSigals[{sigSize, sig}] [{redeemScriptSize, redeemScript}]

Antworten (1)

Das Problem ist, dass scriptsig das eigentliche RedeemScript anstelle des serialisierten Skripts als Push enthält. Der zweite Fehler, das Redeemscript, enthält einen irrelevanten 0x00Wert, der nicht vorhanden sein sollte, da es sich um eine einfache CHECKSIG.

Es ist erwähnenswert, dass der 0x00auf dem Stack verbleibende Wert die Transaktion nicht ungültig macht, sondern nicht vor der Weiterleitung durch die lokale Richtlinie abgefangen wird, da er sich nicht an die cleanstackRegel hält.
Wenn ein Knoten den tx mit dem führenden abbaut 0x00, wird er als gültig betrachtet?
Ja, ich denke, es wird gültig sein, da das OP_CHECKSIG, das zuletzt ausgeführt wird, einen Wert, der zu True ( 0x01in diesem Fall) ausgewertet wird, an die Spitze des Stapels schiebt. Der Stack wird sein: 0x01 0x00 Das gesamte Skript zu True auswerten lassen.