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

    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值