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:
Erstellen Sie unsignierte Transaktionen, bei denen alle scriptSigs leer sind
Setzen Sie für jede zu signierende Eingabe ihre scriptSig auf resolveScript: 21039F53E45F8F18B8ED294378BDA342EFF69B2053DEBF27FBEDE7D2D6BD84BE6235AC
, und lassen Sie andere scriptSigs leer.
Serialisieren Sie den neuen tx und hängen Sie SIGHASHALL-Bytes (0x01) in Little Endian 4 Bytes an
Verdoppeln Sie Sha256 oben und signieren Sie den resultierenden Wert. Fügen Sie der Signatur ein Byte 0x01 hinzu, um SIGHASH_ALL anzuzeigen. Sei sig
der resultierende Wert.
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
, r
und 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 redeemScript
Daten 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:
Setzen Sie das redeemScript
als[{pubKeySize, pubKey}] [OP_CHECKSIG]
Setzen Sie das scriptSig
als[{sigSize, sig}] [{redeemScriptSize, redeemScript}]
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 0x00
Wert, der nicht vorhanden sein sollte, da es sich um eine einfache CHECKSIG
.
Arubi
0x00
auf 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 diecleanstack
Regel hält.Jus12
0x00
, wird er als gültig betrachtet?Arubi
OP_CHECKSIG
, das zuletzt ausgeführt wird, einen Wert, der zu True (0x01
in diesem Fall) ausgewertet wird, an die Spitze des Stapels schiebt. Der Stack wird sein: 0x01 0x00 Das gesamte Skript zu True auswerten lassen.