Überprüfung der Bitcoin-Signatur

Ich versuche, den OP_CHECKSIG-Opcode von Bitcoin zu implementieren und zu überprüfen, ob eine Signatur gültig ist oder nicht. Ich habe die Signatur, die ich aus den Transaktionsdaten und dem öffentlichen Schlüssel erhalte (das Hex-Feld einer P2PKH-Transaktion sollte beides enthalten). Ich versuche herauszufinden, was der Message Digest selbst ist, der signiert ist. Soweit ich weiß, sind dies die erforderlichen Elemente -

1. Die Versionsnummer (4 Bytes)
2. Die Anzahl der Eingaben (1 Byte)
3. Transaktions-Hash der einzulösenden Eingabe
4. Index der einzulösenden Ausgabe (4 Bytes)
5. ScriptPubKey der einzulösenden Ausgabe vorangestellt die Länge des Skripts
6.Sequenznummer (4 Byte)
7.Anzahl der Ausgaben, die wir signieren (1 Byte)
8.Gesamtwert der Ausgabe (8 Byte)
9.SkriptSig für die Ausgabe mit vorangestellter Länge
10.Sperrzeit Feld (4 Bytes)
11.Hashcode-Typ (4 Bytes)

Wenn ich also diese Daten im Byte-Format zweimal mit dem SHA256-Algorithmus hash, würde meine Signaturprüfung bestehen? Ich versuche dies mit Java zu implementieren und das ist mein Code -

public static boolean verifyUsingSecp256k1(byte[] pub, byte[] dataForSigning,
    BigInteger[] rs) throws Exception {
ECDSASigner signer = new ECDSASigner();
X9ECParameters params = SECNamedCurves.getByName("secp256k1");
ECDomainParameters ecParams = new ECDomainParameters(params.getCurve(),
        params.getG(), params.getN(), params.getH());
ECPublicKeyParameters pubKeyParams = new ECPublicKeyParameters(ecParams
        .getCurve().decodePoint(pub), ecParams);
signer.init(false, pubKeyParams);

return signer.verifySignature(dataForSigning, rs[0].abs(), rs[1].abs());}

Wenn ich jedoch versuche, meine Signatur zu überprüfen, wird sie als falsch zurückgegeben. Übersehe ich hier etwas?

Lesen Sie zuerst diese Antwort . Zur Verifizierung müssen Sie dieselben ersten 14 Schritte ausführen.
@CodingEnthusiast Ich möchte die Antwort eher zum Überprüfen einer Transaktion als zum Signieren einer Transaktion. Mit den ersten 14 Schritten habe ich alles versucht, scheint aber nicht zu funktionieren.
CompactIntKönnten Sie das Byte-Array (Schritt 13) posten, bevor Sie in Schritt 14 hashen. Normalerweise ist es leicht, Endianness, Größe von zu übersehen, SignatureScriptnachdem Sie es durch ersetzt haben PubkeyScript, ... Zur Überprüfung müssen Sie den verwendeten Code überprüfen. nicht sicher, welche Bibliothek das ist.
@CodingEnthusiast Here is my byte array - 0200000001ce8310077e52959fc1046478629a1d7e522ba8445ff780d0229367ee48ac8146000000001976a9141c156160c943f58b30c1ff2be1cc225485f903bd88acffffffff01808900610d0000001976a914505ec67e233a71908713c500487307c59a6c5c1f88ac0000000081000000 I am using the Sighash type as - ALLL|ANYONE_CAN_PAY hence 81 at the end. Ich hoffe, das ist kein Problem bei der Erfassung der Nachrichtendaten.
Ich sehe kein Problem mit diesen Bytes, und Ihr Hash (dataForSigning) sollte das Doppelte von SHA256 sein, was bedeutetc3b0386c0d990ab628ac505e8fb612f67d052c5f3cd0ac517854c2efc24ab3e7
@CodingEnthusiast Ich verwende die Bouncy Castle-Bibliothek für das Überprüfungsverfahren! Also muss ich die doppelt SHA-256-gehashten Nachrichtendaten an die obige Funktion übergeben!

Antworten (1)

Alle oben genannten Schritte sind jedoch korrekt. Der einzige Haken hier ist, dass außer den Skripten alles andere im Little-Endian-Format erfasst wird (aus welchen Gründen auch immer). Bis auf Step 5 und Step 9 werden also alle anderen Daten im Little-Endian-Format gespeichert. Ich habe eine Weile gebraucht, um zu dieser Antwort zu kommen! Nur ein kleiner Tipp, den Sie bei der Umsetzung beachten sollten!