亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

一個簡單的 merkle-tree 在 java 中的實現

一個簡單的 merkle-tree 在 java 中的實現

牛魔王的故事 2022-12-28 10:02:45
我正在嘗試用 Java 編寫一個非常簡單的 merkle-tree 實現。我使用比特幣區塊鏈上第170 個區塊中的 txid 值作為參考,所以我可以看到正確的結果應該是什么。該區塊對應的txid如下:b1fea52486ce0c62bb442b530a3f0132b826c74e473d1f2c220bfa78111c5082f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16據我了解,比特幣的 merkle-tree 實現方式如下:將區塊中的交易拆分成對字節交換 txid連接 txid對連接的對進行雙重哈希需要注意的是:If there's no additional pairs of txids, concatenate the result of the first pair after double hashing with itself and repeat我寫的 swapEndianness 方法不是真正的“字節級”交換,而只是改變了字符串的順序,它看起來像這樣:public static String swapEndianness(String hash) {        char[] hashAsCharArray = hash.toCharArray();        StringBuilder sb = new StringBuilder();        for (int i = hash.length() - 1; i > 0; i-=2) {            sb.append(hashAsCharArray[i - 1]);            sb.append(hashAsCharArray[i]);        }        return sb.toString();    }這兩個 txid 的默克爾根的預期結果是:7dac2c5666815c17a3b36427de37bb9d2e2c5ccec3f8633eb91a4205cb4c10ff然而,我最終得到的結果是:3b40cab1157838cc41b08e27641f65d245957ab07b3504d94bc2d355abaed06c我沒有得到我期望的結果是因為我在進行字節交換時作弊,因為我錯過了一個步驟,還是因為我的代碼有錯誤(或這些錯誤的某種組合)?任何幫助,將不勝感激!
查看完整描述

1 回答

?
慕容3067478

TA貢獻1773條經驗 獲得超3個贊

您不了解 Java 中的 byte[] 是什么。您示例中的字符串是 byte[] 的“十六進制”表示形式。請參閱如何在 Java 中初始化字節數組?


public class MerkleTree {

    static MessageDigest digest;

    public static void main(String[] args) throws NoSuchAlgorithmException {

        digest = MessageDigest.getInstance("SHA-256");

        new MerkleTree().run();

    }

    private void run() {

        // txid A

        byte[] A = hexStringToByteArray("b1fea52486ce0c62bb442b530a3f0132b826c74e473d1f2c220bfa78111c5082");

        System.out.println(Arrays.toString(A));

        // txid A byte-swapped

        byte[] A_little = swapEndianness(A);

        System.out.println(Arrays.toString(A_little));


        // txid B

        byte[] B = hexStringToByteArray("f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16");

        System.out.println(Arrays.toString(B));


        // txid B byte-swapped

        byte[] B_little = swapEndianness(B);

        System.out.println(Arrays.toString(B_little));


        // txid A + B concatenated

        byte[] AB_little = Arrays.copyOf(A_little, A_little.length + B_little.length);

        System.arraycopy(B_little, 0, AB_little, A_little.length, B_little.length);

        System.out.println(Arrays.toString(AB_little));


        // double hash of byte-swapped concatenated A+B

        byte[] ABdoubleHash = SHA256(SHA256(AB_little));

        System.out.println(Arrays.toString(ABdoubleHash));


        // print result byte-swapped back to big-endian

        byte[] result = swapEndianness(ABdoubleHash);

        System.out.println(Arrays.toString(result));

        System.out.println(getHex(result));         

    }

    byte[] swapEndianness(byte[] hash) {

        byte[] result = new byte[hash.length];

        for (int i = 0; i < hash.length; i++) {

            result[i] = hash[hash.length-i-1];

        }

        return result;

    }

    byte[] SHA256(byte[] obytes) {

        return digest.digest(obytes);

    }

    byte[] hexStringToByteArray(String s) {

        int len = s.length();

        byte[] data = new byte[len / 2];

        for (int i = 0; i < len; i += 2) {

            data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)

                                 + Character.digit(s.charAt(i+1), 16));

        }

        return data;

    }

    private static final String    HEXES    = "0123456789abcdef";

    String getHex(byte[] raw) {

        final StringBuilder hex = new StringBuilder(2 * raw.length);

        for (final byte b : raw) {

            hex.append(HEXES.charAt((b & 0xF0) >> 4)).append(HEXES.charAt((b & 0x0F)));

        }

        return hex.toString();

    }

最后參考Java代碼將byte轉Hexadecimal


編輯:這在資源上會好一些,因為您經常想做很多這類事情。


    // txid A byte-swapped

    byte[] A = swapEndianness(

            hexStringToByteArray("b1fea52486ce0c62bb442b530a3f0132b826c74e473d1f2c220bfa78111c5082")

        );

    // txid B byte-swapped

    byte[] B = swapEndianness(

            hexStringToByteArray("f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16")

        );

    // txid A + B concatenated

    byte[] AB = Arrays.copyOf(A, A.length + B.length);

    System.arraycopy(B, 0, AB, A.length, B.length);


    // print result byte-swapped back to big-endian

    String result = getHex(swapEndianness(SHA256(SHA256(AB))));

    System.out.println(result);         

    }

    byte[] swapEndianness(byte[] hash) {

        for (int i = 0; i < hash.length/2; i++) {

            byte t = hash[hash.length-i-1];

            hash[hash.length-i-1] = hash[i]; 

            hash[i] = t; 

        }

        return hash;

    }


查看完整回答
反對 回復 2022-12-28
  • 1 回答
  • 0 關注
  • 209 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號