Also versuche ich, meine eigenen Zeugenunterschriften zu machen, wie in bip143 beschrieben. Ich habe Code, der die Beispielsignatur korrekt überprüft, also dachte ich, ich hätte die grundlegende Signierung und Überprüfung im Griff. Ich habe Code, der die Signaturen in bip143 korrekt überprüfen kann, und mit demselben Code verifiziere ich diese Ausgabe korrekt, daher bin ich mir nicht sicher, wie ich feststellen kann, was falsch läuft. Der Fehler, den ich bekomme, ist
error code: -26
error message:
non-mandatory-script-verify-flag (Non-canonical DER signature)
Ich vermute, dass ich die Byte-Reihenfolge in etwas nicht umkehre, aber ich bin mir wirklich nicht sicher, wie ich dies weiter diagnostizieren soll.
----unsignierte Transaktion------- 020000000102303e285bb228344346acb5292397a761103efcd0182c4cf95b4d01b2bdda400000000000ffffffff02400d03000000000016001453f0b90d7be69d4f5f1356908a9e12fef93561df74e0022a010000001600140f54e16bd59da94840741b69ab9b9db99467a85800000000 -------unsignierte Transaktion beenden------ dhash(prevouts)=02303e285bb228344346acb5292397a761103efcd0182c4cf95b4d01b2bdda4000000000 dhash(sequenzen)=ffffffff dhash (Ausgänge) = 400d030000000000001453f0b90d7be69d4f5f1356908a9e12fef93561df74e0022a0100000000140f54e16bd59da94840741b69ab9b9db99467a858 Version: 02000000 hashPrevouts: 9ebc8589966e2dd13cd64af1835262c2d8e931b4388a8ebe76620814b4f407bd Hash-Sequenz: 3bb13029ce7b1f559ef5e747fcac439f1455a2ec7c5f09b72290795e70665044 Endpunkt: 02303e285bb228344346acb5292397a761103efcd0182c4cf95b4d01b2bdda4000000000 scriptCode: 1976a914992fda25fdf8447092aa223a34bedd3572173d8688ac Betrag: 00f2052a01000000 nSequenz: ffffffff Hash gibt a54e6a8744fa773a5f1c64d7f60d53efd69f8d76e85e7817970a87990874e4c1 aus nSperrzeit 00000000 nHashType 01000000 pre hash image: 020000009ebc8589966e2dd13cd64af1835262c2d8e931b4388a8ebe76620814b4f407bd3bb13029ce7b1f559ef5e747fcac439f1455a2ec7c5f09b72290795e7066504402303e285bb228344346acb5292397a761103efcd0182c4cf95b4d01b2bdda40000000001976a914992fda25fdf8447092aa223a34bedd3572173d8688ac00f2052a01000000ffffffffa54e6a8744fa773a5f1c64d7f60d53efd69f8d76e85e7817970a87990874e4c10000000001000000 gestricheltes Bild: 4f8fce636bb4a44aa6a241e9597bbe54fce3bfe3426a49a94c5b006d42eac007 Rawsig: 2cbb748d06a1b87c933a3118d8c2a5a0ab02111bae777a9e52ba8571eee2d549e80a6e4cef24a172e64d11aa7b83c8005fe6fc078307b9e663ef9eb14fce05a3 der sig: 304402202cbb748d06a1b87c933a3118d8c2a5a0ab02111bae777a9e52ba8571eee2d5490220e80a6e4cef24a172e64d11aa7b83c8005fe6fc078307b9ebe663fce05a307b9ebe663fce Pub-Schlüssel des Skripts: 992fda25fdf8447092aa223a34bedd3572173d86 Pub-Schlüssel: 0392ff36d0ae9f3a74c0483fd309ff9144972b1dce6d6dfe4d9de474c721b36521 ----unterzeichnete Transaktion------- 0200000000010102303e285bb228344346acb5292397a761103efcd0182c4cf95b4d01b2bdda400000000000ffffffff02400d03000000000016001453f0b90d7be69d4f5f1356908a9e12fef93561df74e0022a010000001600140f54e16bd59da94840741b69ab9b9db99467a8580247304402202cbb748d06a1b87c933a3118d8c2a5a0ab02111bae777a9e52ba8571eee2d5490220e80a6e4cef24a172e64d11aa7b83c8005fe6fc078307b9e663ef9eb14fce05a301210392ff36d0ae9f3a74c0483fd309ff9144972b1dce6d6dfe4d9de474c721b3652100000000 -------signierte Transaktion beenden------
Dies läuft auf meinem Regtest. Ich kann alle zusätzlichen Informationen bereitstellen, die die Leute für hilfreich halten könnten. Ich habe viele Stunden damit verbracht, alles Mögliche mit allen Beispielen zu vergleichen, bevor ich hier gepostet habe. Ich weiß, es heißt non connical der sig, aber bei meiner Recherche sagen andere Leute, dass Fehler passieren, wenn viele verschiedene Dinge schief gehen. Auch wenn ich die Signatur mit den signierten Cores vergleiche, stimmen sie im Format genau mit "30440220" überein, dann 32 Bytes, dann 0220, dann die anderen 32 Bytes. Das einzige, was anders ist, sind die tatsächlichen Signaturdaten. Außerdem erhalte ich den gleichen Fehler, wenn ich eine native konische DER-Ausgabe verwende. Jede Hilfe wird wie immer sehr geschätzt
-----UPDATE-----
Das Problem mit dem obigen Skript besteht also hauptsächlich darin, dass es nicht korrekt DER-codiert ist, was bedeutet, dass wenn s oder r das meiste MSB > 0x80 ist, es als negativ behandelt wird, da es sich um eine vorzeichenbehaftete Ganzzahl handelt. In diesem Beispiel ist das MSB von S 0xE8, was größer als 0x80 ist. bitcoin hat eine richtlinie, dass es tatsächlich kleiner als der ecdsa-kurvenwert "n" sein muss. Zuerst unten ist der Code, der das Problem behebt, und ich kann die Signatur überprüfen (aber der Fehler existiert immer noch im Bitcoin-Kern). Code zum Invertieren von S in Python:
n=115792089237316195423570985008687907852837564279074904382605163141518161494337
s = bytearray(s_bytes)
sint = 0
cnt = 31
for bb in s:
sint += bb << cnt*8
cnt -= 1
if sint >= n/2:
print("Negated")
sint = n-sint
s = bytearray(sint.to_bytes(32, byteorder='big'))
Nicht schlecht. Und was r betrifft, signiert der Bitcoin-Kern einfach neu, bis er niedriger als 0x80 ist. es ist zulässig, dass es höher ist, wenn der Encoder das MSB korrekt auffüllt). Habe es genauso gemacht. Unten ist eine neue Transaktion, bei der das Problem behoben wurde, obwohl ich immer noch den gleichen Fehler bekomme :-/.
----unsignierte Transaktion------- 020000000102303e285bb228344346acb5292397a761103efcd0182c4cf95b4d01b2bdda400000000000ffffffff02400d03000000000016001453f0b90d7be69d4f5f1356908a9e12fef93561df74e0022a010000001600140f54e16bd59da94840741b69ab9b9db99467a85800000000 -------unsignierte Transaktion beenden------ dhash(prevouts)=02303e285bb228344346acb5292397a761103efcd0182c4cf95b4d01b2bdda4000000000 dhash(sequenzen)=ffffffff dhash (Ausgänge) = 400d030000000000001453f0b90d7be69d4f5f1356908a9e12fef93561df74e0022a0100000000140f54e16bd59da94840741b69ab9b9db99467a858 Version: 02000000 hashPrevouts: 9ebc8589966e2dd13cd64af1835262c2d8e931b4388a8ebe76620814b4f407bd Hash-Sequenz: 3bb13029ce7b1f559ef5e747fcac439f1455a2ec7c5f09b72290795e70665044 Endpunkt: 02303e285bb228344346acb5292397a761103efcd0182c4cf95b4d01b2bdda4000000000 scriptCode: 1976a914992fda25fdf8447092aa223a34bedd3572173d8688ac Betrag: 00f2052a01000000 nSequenz: ffffffff Hash gibt a54e6a8744fa773a5f1c64d7f60d53efd69f8d76e85e7817970a87990874e4c1 aus nSperrzeit 00000000 nHashType 01000000 pre hash image: 020000009ebc8589966e2dd13cd64af1835262c2d8e931b4388a8ebe76620814b4f407bd3bb13029ce7b1f559ef5e747fcac439f1455a2ec7c5f09b72290795e7066504402303e285bb228344346acb5292397a761103efcd0182c4cf95b4d01b2bdda40000000001976a914992fda25fdf8447092aa223a34bedd3572173d8688ac00f2052a01000000ffffffffa54e6a8744fa773a5f1c64d7f60d53efd69f8d76e85e7817970a87990874e4c10000000001000000 gehashtes Bild: 4f8fce636bb4a44aa6a241e9597bbe54fce3bfe3426a49a94c5b006d42eac007 Rawsig: 38d610fa975440d09b501864185e656546015ee98dd8b5b58eb41be547b6a686be784798307a123bdfefce7463b6e7203b69d18950ea95ae684dddb5a9bcaeaf s vorher: be784798307a123bdfefce7463b6e7203b69d18950ea95ae684dddb5a9bcaeaf Negiert s nach: 4187b867cf85edc42010318b9c4918de7f450b5d5e5e0a8d578480d726799292 der sig: 3044022038d610fa975440d09b501864185e656546015ee98dd8b5b58eb41be547b6a68602204187b867cf85edc42010318b9c4918de7f450b5d5e5e0a8d5784.90d7267 Pub-Schlüssel des Skripts: 992fda25fdf8447092aa223a34bedd3572173d86 Pub-Schlüssel: 0392ff36d0ae9f3a74c0483fd309ff9144972b1dce6d6dfe4d9de474c721b36521 ----unterzeichnete Transaktion------- 0200000000010102303e285bb228344346acb5292397a761103efcd0182c4cf95b4d01b2bdda400000000000ffffffff02400d03000000000016001453f0b90d7be69d4f5f1356908a9e12fef93561df74e0022a010000001600140f54e16bd59da94840741b69ab9b9db99467a85802473044022038d610fa975440d09b501864185e656546015ee98dd8b5b58eb41be547b6a68602204187b867cf85edc42010318b9c4918de7f450b5d5e5e0a8d578480d72679929201210392ff36d0ae9f3a74c0483fd309ff9144972b1dce6d6dfe4d9de474c721b3652100000000 -------signierte Transaktion beenden------
Auch hier ist Hilfe willkommen
ok habs kapiert! nach etwa einer Woche :-D. Ich möchte dies posten, weil ich die letzte Woche damit verbracht habe, den Bitcoin-Kern zu lernen, die intermittierenden Werte während des Seufzers zum Vergleich auszugeben. Jeder andere, der wirklich verstehen muss, wie der Kern funktioniert, wird hoffentlich wirklich hilfreich sein. Also zuerst mein spezifisches Problem: Mein Ausgabeskript war einfach völlig falsch, ich glaube, ich habe das Sperr- und das Entsperrskript verwechselt, was die Signatur immer noch nicht ungültig machen sollte, aber dann bemerken Sie auch, dass die Ausgabe im Beispiel so ist:
202cb20600000000 1976a9148280b37df378db99f66f85c95a783a76ac7a6d5988ac
Nun, das erste 0x19 ist nicht Teil des öffentlichen Schlüssels des Skripts (die Art und Weise, wie die Rohtransaktion angezeigt wird). Also in der Beschreibung wo es steht
Wenn der Sighash-Typ weder SINGLE noch NONE ist, ist hashOutputs das doppelte SHA256 der Serialisierung aller Ausgabemengen (8-Byte Little Endian) mit scriptPubKey (serialisiert als Skripte in CTxOuts);
Sie hashen mit dem Längenpräfix 0x19. Ich habe die Länge in die Gesamttransaktion aufgenommen, sodass sie immer noch gut dekodiert wurde, aber nicht so, wie ich sie gehasht habe. Einfaches Missverständnis.
Unten ist, wie ich den Kern (0.21.1) gebaut und modifiziert habe, um die Werte auszugeben, um dies herauszufinden
std::string hexhalftostr(unsigned char val) { wenn (wert <= 9) Rückgabe std::to_string(val); sonst if(val ==10) gib "A" zurück; sonst if(val ==11) gib "B" zurück; sonst if(val ==12) gib "C" zurück; sonst if(val ==13) gib "D" zurück; sonst if(val ==14) gib "E" zurück; sonst if(val ==15) gib "F" zurück; Sonst "" zurückgeben; } void logbytes(unsigned char *data, int len) { std::ofstream meinedatei; myfile.open ("/home/ubuntu/btc/bitcoinsource/bitcoin-0.21.1/special.log", std::ios_base::app); std::string ss = ""; für (int i = 0;i < len;i++) { Zeichen lsb, msb; lsb = 0x0f & Daten[i]; msb = 0x0f & (Daten [i] << 4); ss += hexhalftostr(msb) + hexhalftostr(lsb); } meinedatei << ss; meinedatei.close(); } void logbigint (uint256-Daten) { Logbytes (data.data(), 32); } void logint (unsigned int data) { unsigned char arrayOfByte[4]; für (int i = 0; i < 4; i++) arrayOfByte[i] = (Daten << (i * 8)); Logbytes (ArrayOfByte, 4); } void loglong (unsignierte lange Daten) { unsigned char arrayOfByte[8]; für (int i = 0; i < 8; i++) arrayOfByte[i] = (Daten << (i * 8)); Logbytes (arrayOfByte, 8); } void logtext(std::string ss) { std::ofstream meinedatei; myfile.open ("/home/ubuntu/btc/bitcoinsource/bitcoin-0.21.1/special.log", std::ios_base::app); meinedatei << ss; meinedatei.close(); }
logtext("\nnVersion: "); logint(txTo.nVersion); logtext("\nhashPrevouts: "); logbigint(hashPrevouts); logtext("\nhashSquence: "); logbigint(hashFolge); logtext("\noutpoint: "); logbigint(txTo.vin[nIn].prevout.hash); logint(txTo.vin[nIn].prevout.n); // Ich kann nicht herausfinden, wie ich die Bytes abrufen soll ////logtext("\nscriptCode: "); ////logbigint(scriptCode); logtext("\namount: "); loglong(Menge); logtext("\nnSequenz: "); logint(txTo.vin[nIn].nSequence); logtext("\nhashAusgaben: "); Logbigint (Hash-Ausgaben); logtext("\nnSperrzeit: "); logint(txTo.nLockTime); logtext("\nhashType: "); logint(nHashType);
Und die Rückgabe der Funktion musste ersetzt werden, weil der sha256-Hash die Daten so verbraucht
return ss.GetHash();
Wird
uint256 sighash = ss.GetHash();
logtext("\nhashed image: ");
logbigint(sighash);
logtext("\n");
//return ss.GetHash();
return sighash;
Pieter Wuille
niemand392
niemand392
Pieter Wuille
Pieter Wuille
niemand392
Pieter Wuille
niemand392
Pieter Wuille
niemand392
Pieter Wuille
niemand392