Konvertierung zwischen String/Hex/Byte in Java für sha256 - falsches Format?

Ich versuche, eine Bitcoin-Adresse zu konvertieren und habe den folgenden Code von hier ( Segwit-Adresse aus öffentlicher Adresse berechnen , 2. Antwort):

Step1: $ printf 1L88S26C5oyjL1gkXsBeYwHHjvGvCcidr9 > adr.txt
Step2: $ printf $( cat adr.txt | sed 's/[[:xdigit:]]\{2\}/\\x&/g' ) >adr.hex
Step3: $ openssl dgst -sha256 -binary <adr.hex >tmp_sha256.hex
Step4: $ openssl dgst -ripemd160  <tmp_sha256.hex
## result should be: 56379c7bcd6b41188854e74169f844e8676cf8b8

Jetzt möchte ich dies in Java tun. Aktuell habe ich folgenden Code. Egal was ich versuche, ich bekomme nicht das richtige Ergebnis. :(

String address = "1L88S26C5oyjL1gkXsBeYwHHjvGvCcidr9"; // step 1
System.out.println("address: " + address);
String addressHex = toHex(address);
System.out.println("address hex: " + addressHex);
byte[] addressBytes = addressHex.getBytes(StandardCharsets.UTF_8); // step 2
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hash = digest.digest(addressBytes); // step 3
RIPEMD160Digest digest2 = new RIPEMD160Digest(); // steps 4
digest2.update(hash, 0, hash.length);
byte[] out = new byte[20];
digest2.doFinal(out, 0);
System.out.println("result: " + bytesToHex(out)); // = 62ab42cba5d2632d1350fafb2587f5d2ece445d3
                                                  // should be 56379c7bcd6b41188854e74169f844e8676cf8b8

Ausgabe:

address: 1L88S26C5oyjL1gkXsBeYwHHjvGvCcidr9
address hex: 314c383853323643356f796a4c31676b58734265597748486a764776436369647239
result: 62ab42cba5d2632d1350fafb2587f5d2ece445d3

Kann mir jemand helfen? Ich denke, das Problem liegt irgendwo bei der Konvertierung String/Hex/Byte ...? Ich habe mich wirklich bemüht, aber ich kann den richtigen Weg nicht finden, es zu tun.

Ich habe auch versucht, die Adresse in Hex und danach in Bytes umzuwandeln, aber beides funktioniert nicht. :/

// aktualisierter Beitrag ... zeigt immer noch nicht das richtige Ergebnis :/

// update2:

byte[] address = ("1L88S26C5oyjL1gkXsBeYwHHjvGvCcidr9").getBytes();
System.out.println("address byte array: " + address);
String addressHex = bytesToHex(address);
System.out.println("address hex: " + addressHex);
byte[] addressBytes = addressHex.getBytes();
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hash = digest.digest(addressBytes);
RIPEMD160Digest digest2 = new RIPEMD160Digest();
digest2.update(hash, 0, hash.length);
byte[] out = new byte[20];
digest2.doFinal(out, 0);
System.out.println("result: " + bytesToHex(out));

Ausgabe

address byte array: [B@108c4c35
address hex: 314c383853323643356f796a4c31676b58734265597748486a764776436369647239
result: 62ab42cba5d2632d1350fafb2587f5d2ece445d3
Bitte lesen Sie meine Antwort in der von Ihnen verlinkten ursprünglichen Frage. Der Code, den Sie konvertieren möchten, ist überhaupt falsch

Antworten (3)

Ok, hier ist der einfache Code für die Konvertierung von Legacy zu Segwit:

    String addressToConvert = "1BGJEft81aaudqaCCcNnhsRQBA3Y96KYtx";
    byte[] decoded = org.bitcoinj.core.Utils.parseAsHexOrBase58(addressToConvert);
    // We should throw off header byte that is 0 for Bitcoin (Main)
    byte[] pureBytes = new byte[20];
    System.arraycopy(decoded, 1, pureBytes, 0, 20);
    // Than we should prepend the following bytes:
    byte[] scriptSig = new byte[pureBytes.length + 2];
    scriptSig[0] = 0x00;
    scriptSig[1] = 0x14;
    System.arraycopy(pureBytes, 0, scriptSig, 2, pureBytes.length);
    byte[] addressBytes = org.bitcoinj.core.Utils.sha256hash160(scriptSig);
    // Here are the address bytes
    byte[] readyForAddress = new byte[addressBytes.length + 1 + 4];
    // prepending p2sh header:
    readyForAddress[0] = (byte) 5;
    System.arraycopy(addressBytes, 0, readyForAddress, 1, addressBytes.length);
    // But we should also append check sum:
    byte[] checkSum = Sha256Hash.hashTwice(readyForAddress, 0, addressBytes.length + 1);
    System.arraycopy(checkSum, 0, readyForAddress, addressBytes.length + 1, 4);
    // To get the final address:
    String segwitAddress = Base58.encode(readyForAddress);

Funktionen (wie org.bitcoinj.core.Utils.parseAsHexOrBase58) stammen aus der bitcoinJ- Bibliothek, wie ich bereits erwähnt habe.

Die resultierende Adresse ist 3G7YPGDLLeaf1R36wrVxnSAhWMaA81oNhJ . Es kann hier überprüft werden: Bip39 mit Merksatz: "Haube fatal Kohl stolz Heben erstaunlich heute Mutter Unordnung schmücken ewig Aktion Schlagen beenden Fallenlassen Ding Huhn Wirt erodieren Bohne Rettung verpflichten Mango doppelt". Dazu sollten Sie "BIP49" auswählen und die erzeugte Segwit-Adresse sehen. Die entsprechende Legacy-Adresse finden Sie auf der Registerkarte BIP32, aber Sie sollten den Ableitungspfad m/49'/0'/0'/0 manuell einfügen. Beachten Sie, dass die privaten Schlüssel für sie gleich sind: L38zkVFvLmVmHTpFdqfSP2WrQ1qcZnB829rthRS1rRexcc7RKuHr

Ihre Adresse 1L88S26C5oyjL1gkXsBeYwHHjvGvCcidr9 wird in 39gGJc9HiemSJwpa2smXgCXMW8y9FNzFDe umgewandelt .

Wie kann ich Ihnen 10 Millionen Upvotes geben? Vielen Dank! Funktioniert perfekt! TY TY TY!

Die Adresse ist im Base58-Format. Wenn Sie also eine Hex-Darstellung erhalten möchten, sollten Sie zuerst den base58-Adress-String in ein Byte-Array konvertieren und ihn dann in einen Hex-String konvertieren. Die bitcoinJ- Bibliothek hat Dienstprogramme dafür, Sie können dort alle Konvertierungen finden.

Vielen Dank! Ich habe versucht, Ihren Vorschlag umzusetzen, aber ich bin immer noch nicht in der Lage, das richtige Ergebnis zu erhalten. Ich habe meinen Beitrag aktualisiert ("update2"). ty!

Ich habe die Java-Lösung nicht, aber ich kann den Fehler anzeigen. Die Konvertierung in Hex fehlt anscheinend. Wenn ich den Hash auf die Textdatei selbst mache, bekomme ich auch das falsche Ergebnis:

$ printf 1L88S26C5oyjL1gkXsBeYwHHjvGvCcidr9 > adr.txt
$ openssl dgst -sha256 -binary <adr.txt >tmp_sha256.hex
$ openssl dgst -ripemd160  <tmp_sha256.hex
(stdin)= db151e871af66b1323893e3f527e22f7684718af

Die Umwandlung in ein Hex-Byte-Array "addressHex" fehlt also mit Sicherheit etwas.

Aktualisieren:

Ich kann die Funktion "bytesToHex()" sehen, war das der Code aus dem Link, den ich in dem anderen Thread bereitgestellt habe? Wenn dies der Fall ist, versuchen Sie, die Ausgabe Ihres Java in eine Datei zu kopieren, und verwenden Sie zur Überprüfung hexdump. Sie können sich also auf diese beiden Zeilen konzentrieren (ich habe den sed-Befehl kürzer gemacht, ohne "cat"):

$ printf 1L88S26C5oyjL1gkXsBeYwHHjvGvCcidr9 > adr.txt
$ printf $( sed 's/[[:xdigit:]]\{2\}/\\x&/g' adr.txt ) >adr.hex
$ hexdump -C adr.hex 
00000000  31 4c 88 53 26 c5 6f 79  6a 4c 31 67 6b 58 73 be  |1L.S&.oyjL1gkXs.|
00000010  59 77 48 48 6a 76 47 76  cc 69 64 72 39           |YwHHjvGv.idr9|
0000001d

Hier sollten Sie das gleiche Ergebnis von Ihrem Java-Code erhalten, dann können Sie loslegen :-)

Danke, ich habe meinen Code bearbeitet, aber es funktioniert immer noch nicht. Ich habe auch meinen Beitrag bearbeitet, um jetzt den neuen Code anzuzeigen.
Siehe mein Update, das ist bisher alles, was ich tun kann ...
Bitte hör dir meine Antwort im anderen Thread an, der Ansatz ist von Anfang an völlig falsch und du kannst am Ende Geld verlieren, wenn du ihn verwendest. Sie sollten die Adresse überhaupt nicht hashen