Bitcoin-Core

在 Java 中為 sha256 轉換字元串/十六進制/字節 - 格式錯誤?

  • December 30, 2017

我正在嘗試轉換比特幣地址並從此處獲取以下程式碼(從公共地址計算隔離見證地址,第二個答案):

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

現在我想在 Java 中做到這一點。我目前有以下程式碼。無論我嘗試什麼,我都沒有得到正確的結果。:(

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

輸出:

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

有人能幫我嗎?我認為問題出在某處進行轉換 String/hex/byte …?我真的很努力,但找不到正確的方法。

我還嘗試將地址轉換為十六進制,然後再轉換為字節,但都不起作用。:/

// 更新後的文章…仍然沒有顯示正確的結果:/

//更新2:

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));

輸出

address byte array: [B@108c4c35
address hex: 314c383853323643356f796a4c31676b58734265597748486a764776436369647239
result: 62ab42cba5d2632d1350fafb2587f5d2ece445d3

好的,下面是從 legacy 轉換為 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);

正如我之前提到的,函式(如 org.bitcoinj.core.Utils.parseAsHexOrBase58)取自bitcoinJ庫。

結果地址為3G7YPGDLLeaf1R36wrVxnSAhWMaA81oNhJ。可以在這裡查看:Bip39附助記詞:“罩致命捲心菜驕傲舉起驚人今天媽媽混亂裝飾永恆動作沖頭完成掉落物雞主人侵蝕豆救援義務芒果雙”。為此,您應該選擇“BIP49”並查看生成的隔離見證地址。對應的遺留地址可以在 BIP32 選項卡中找到,但您應該手動插入派生路徑 m/49’/0’/0’/0。請注意,它們的私鑰是相等的: L38zkVFvLmVmHTpFdqfSP2WrQ1qcZnB829rthRS1rRexcc7RKuHr

您的地址1L88S26C5oyjL1gkXsBeYwHHjvGvCcidr9轉換為39gGJc9HiemSJwpa2smXgCXMW8y9FNzFDe

引用自:https://bitcoin.stackexchange.com/questions/66957