JAVA简单实现MerkleTree

八月中秋白露,路上行人凄凉。
小桥明月桂花香,日夜千思万想。
心中万般宁静,青春好读文章。
十年苦读在书房,方见才学益广。

最近要自己实现一个区块链,其中区块体用到MerkleTree,找了好久终于找到了一个可以看懂的实现—_—

简单来说就是每笔交易的hash都两两结合最后生成跟(root)hash,结构图如下:

image.png

话不多说懂的懂,不懂的看代码也会懂,如果跟作者一样没有天分,那就复制代码打断点运行一步一步看也会懂

package cn.cnic.chain.merkle;

import org.springframework.util.CollectionUtils;

import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.List;

/**
 * java实现默克尔树
 */
public class MerkleTrees {

    // MerkleRoot
    private String root;

    // 交易集合
    private List<String> txList;

    /**
     * 构造方法
     * 初始化所有txid , root设置成""
     */
    public MerkleTrees(List<String> txList) {
        this.txList = txList;
        root = "";
    }

    /**
     * 根据txid动态求出root
     */
    public void merkle_tree() {

        if (CollectionUtils.isEmpty(txList)){
            return;
        }

        List<String> tempTxList = new ArrayList<>();

//        for (int i = 0; i < this.txList.size(); i++) {
//            tempTxList.add(this.txList.get(i));
//        }
        tempTxList.addAll(txList);

        //不是是否可以直接把参数设置为 txList
        List<String> newTxList = getNewTxList(tempTxList);

        //执行循环,直到只剩下一个hash值
        while (newTxList.size() != 1) {
            newTxList = getNewTxList(newTxList);
        }

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

    /**
     * 求出上一层所有节点hash
     *
     * @param tempTxList
     * @return
     */
    private List<String> getNewTxList(List<String> tempTxList) {

        List<String> newTxList = new ArrayList<>();
        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);
            }
            // parent = left + right
            String sha2HexValue = getSHA2HexValue(left + right);
            newTxList.add(sha2HexValue);
            index++;

        }
        return newTxList;
    }

    /**
     * left 、right 求出具体的父类节点hash
     *
     * @param str
     * @return
     */
    public String getSHA2HexValue(String str) {
        byte[] cipher_byte;
        try{
            MessageDigest md = MessageDigest.getInstance("SHA-256");
            md.update(str.getBytes());
            cipher_byte = md.digest();
            StringBuilder sb = new StringBuilder(2 * cipher_byte.length);
            for(byte b: cipher_byte) {
                sb.append(String.format("%02x", b&0xff) );
            }
            return sb.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return "";
    }

    /**
     * 获取跟节点hash
     * @return
     */
    public String getRoot() {
        return this.root;
    }
}

测试方法如下:

package cn.cnic.chain.merkle;

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

/**
 * 构建MerkleTree测试类
 */
public class App {
    public static void main(String[] args) {
        List<String> tempTxList = new ArrayList<>();
        tempTxList.add("a");
        tempTxList.add("b");
        tempTxList.add("c");
        tempTxList.add("d");
        tempTxList.add("e");

        MerkleTrees merkleTrees = new MerkleTrees(tempTxList);
        merkleTrees.merkle_tree();

        System.out.println("root : " + merkleTrees.getRoot());

    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 前面两章说了许多关于区块链的理论知识,这一章我们将会将前面的所有的理论知识结合起来,用java简答实现一套区块链。...
    Vlice阅读 7,647评论 0 0
  • 1. 概念 侧链这一术语在Adam Back等人2014年左右的论文《用楔入式侧链实现区块链的创新》被首次讨论。论...
    文博园阅读 4,086评论 0 1
  • 概述 MerkleTree被广泛的应用在比特币技术中,本文旨在通过代码实现一个简单的MerkleTree,并计算出...
    新媒体观察员阅读 4,432评论 2 0
  • 夜莺2517阅读 127,782评论 1 9
  • 版本:ios 1.2.1 亮点: 1.app角标可以实时更新天气温度或选择空气质量,建议处女座就不要选了,不然老想...
    我就是沉沉阅读 11,828评论 1 6