Merkle tree in Java actual handwriting blockchain

Xiang Biao


Preface

To learn blockchain technology, then the Merkle tree has to be deeply understood. This article will use java handwritten Merkle tree


1. Introduction to Merkle Tree

Merkle tree is a data structure proposed by Ralph Merkle in 1979 and named after himself. What is a Merkle tree? The definition of Merkle tree in Wikipedia is as follows:


In cryptography and computer science, a hash tree or Merkle tree is a tree in which each leaf node is marked with the hash of the data block, and each non-leaf node is marked with its subsection, or label The encrypted hash Merkle tree allows effective and safe verification of the contents of large data structures, which is a generalization of hash lists and hash chains!
The structure of the Merkle tree is shown in the figure below:

Insert picture description here
Collect one or more new record blocks, hash these records, pair the hashes, hash, pair again and hash again, until a single hash retains this single hash is called the Merkle root of the merkle tree . As shown in the figure below in the Bitcoin browser :
Insert picture description here
the 1 2 3 4 two-in-one in the figure, finally got the Merkle Root: f3e94742aca4b5ef85488dc37c06c3282295ffec960994b2c0d5ac2a25a95766 If you
are interested, you can read this article on the Bitcoin code MerkleTree .

Two, java implementation

1. The code is as follows:

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. Test

The code is as follows (example):

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

    }
}

Insert picture description here


to sum up

Since the hash algorithm results are longer, we use the simplified version as an example. Assuming that a block currently contains two transactions, after double hashing:

When executing [two-two-group splicing], simply join 111 and 222 together: 111222, and the splicing is completed. (The actual splicing requires decoding the hash result into computer language, displacement, splicing, encoding, displacement, and finally the result can be obtained.)

Before splicing, all transactions are assumed to have n. After splicing, the remaining number is n/2.

Many times [double hash algorithm + two-by-two sets of splicing] means to perform the above operations multiple times. At the beginning, the total number of transactions is n, executed once, and there are n/2, and then executed again, and n/ 4, the final execution stops when there is only one result, and then the result is hashed twice, and the result is the merkle root value.

Guess you like

Origin blog.csdn.net/ws327443752/article/details/109208567