Javaの実際の手書きブロックチェーンのマークルツリー

翔彪


序文

ブロックチェーン技術を学ぶには、マークルツリーを深く理解する必要があります。この記事では、java手書きのMerkleツリーを使用します


1.マークルツリーの紹介

Merkleツリーは、1979年にRalph Merkleによって提案され、彼自身にちなんで名付けられたデータ構造です。マークルツリーとは何ですか?ウィキペディアでのマークルツリーの定義は次のとおりです。


暗号化およびコンピュータサイエンスでは、ハッシュツリーまたはマークルツリーは、各リーフノードがデータブロックのハッシュでマークされ、各非リーフノードがそのサブセクションまたはラベルでマークされているツリーです。暗号化されたハッシュMerkleツリーにより、大規模なデータ構造のコンテンツを効果的かつ安全に検証できます。これは、ハッシュリストとハッシュチェーンの一般化です。
Merkleツリーの構造を次の図に示します。

ここに写真の説明を挿入
1つ以上の新しいレコードブロックを収集し、これらのレコードをハッシュし、ハッシュをペアリングし、ハッシュし、再度ペアリングし、再度ハッシュします。単一のハッシュがこの単一のハッシュを保持するまで、マークルツリーのマークルルートと呼ばれます。 。次の図に示すようにビットコインブラウザで:図
ここに写真の説明を挿入
の1 2 3 4ツーインワンは、最終的にMerkleルートを取得しました:f3e94742aca4b5ef85488dc37c06c3282295ffec960994b2c0d5ac2a25a95766
興味がある場合は、ビットコインコードのMerkleTreeの記事を読むことができます

2、javaの実装

1.コードは次のとおりです。

package org.xiangbiao;

import cn.hutool.crypto.SecureUtil;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @author larry.xiang
 */
public class MerkleTrees {
    
    

    // 默克根
    String merkleRoot;

    // 交易集合
    List<String> txLst;

    /**
     * 初始化
     *
     * @param txList 交易集合
     */
    public MerkleTrees(List<String> txList) {
    
    
        this.txLst = txList;
        merkleRoot = "";
    }


    /**
     * 获取Node Hash List
     * @return
     */
    private List<String> getNodeHashList(List<String> tempTxList) {
    
    

        List<String> newTxList = new ArrayList<String>();
        int index = 0;
        while (index < tempTxList.size()) {
    
    
            // left
            String left = tempTxList.get(index);
            index++;
            // right
            String right = "";
            if (index != tempTxList.size()) {
    
    
                right = tempTxList.get(index);
            }
            // 两两加密
            String sha2HexValue = SecureUtil.sha256(left + right);
            // 双重hash
            sha2HexValue = SecureUtil.sha256(sha2HexValue);
            newTxList.add(sha2HexValue);
            index++;
        }
        return newTxList;
    }


    /**
     * 构造默克树,设置默克根
     */
    public void merkle_tree() {
    
    
        List<String> tempTxList = new ArrayList<String>();
        for (int i = 0; i < this.txLst.size(); i++) {
    
    
            tempTxList.add(this.txLst.get(i));
        }
        List<String> newTxList = getNodeHashList(tempTxList);
        //一直循环直到只剩下一个hash值
        while (newTxList.size() != 1) {
    
    
            newTxList = getNodeHashList(newTxList);
        }

        this.merkleRoot = newTxList.get(0);
    }
    

    /**
     * 获取默克根
     *
     * @return
     */
    public String getMerkleRoot() {
    
    
        return this.merkleRoot;
    }

2.テスト

コードは次のとおりです(例)。

public static void main(String[] args) {
    
    

        List<String> tempTxList = new ArrayList<String>();
        tempTxList.add("80c6f121c3e9fe0a59177e49874d8c703cbadee0700a782e4002e87d862373c6");
        tempTxList.add("b86f5ef1da8ddbdb29ec269b535810ee61289eeac7bf2b2523b494551f03897c");

        //Collections.reverse(tempTxList);
        MerkleTrees merkleTrees = new MerkleTrees(tempTxList);
        merkleTrees.merkle_tree();
        System.out.println("root : " + merkleTrees.getMerkleRoot());

    }
}

ここに写真の説明を挿入


総括する

ハッシュアルゴリズムの結果が長いため、例として簡略化されたバージョンを使用します。ダブルハッシュの後、ブロックに現在2つのトランザクションが含まれていると仮定します。

[ツーツーグループスプライシング]を実行する場合は、111と222を111222で結合するだけで、スプライシングが完了します。(実際のスプライシングでは、ハッシュ結果をコンピューター言語、置換、スプライシング、エンコード、および置換にデコードして、最終結果を取得する必要があります。)

スプライシング前は、すべてのトランザクションがnであると想定されます。スプライシング後、残りの数はn / 2です。

複数回[ダブルハッシュアルゴリズム+2 x 2セットのスプライシング]は、上記の操作を複数回実行することです。最初は、トランザクションの総数はnで、1回実行され、n / 2があり、次に再度実行され、n /図4に示すように、結果が1つしかない場合、最終的な実行は停止し、その後、結果は2回ハッシュされ、その結果は、メルクルルート値である。

おすすめ

転載: blog.csdn.net/ws327443752/article/details/109208567