Merkle树的实现

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

简介

本篇文章是对Merkle tree的解释。Merkle tree是一种应用在比特币中的技术。本文的目标是通过代码来理解它的实现过程。

环境

Jdk 1.8.0_66

Idea

Merkle树

Merkle tree(哈希树)是一种数据结构,用于验证任何类型的数据存储、处理和传输。

目前,Merkle树的主要用途是确保在对等网络中从其他对等网络接收到的数据块未被损坏和修改,甚至检查其他对等网络是否存在并发送假块。

Merkle树应用范围:git, Amazon的Dynamo, Cassandra和 比特币

比特币区块链中的每一个区块都包含了区块中所有交易的摘要,使用的是Merkle树。

Merkle树的实现_第1张图片

Merkle树被用在比特币中,用来汇总一个区块的所有交易,生成整个交易集的整体数字指纹,提供一个非常有效的过程来验证一个交易是否被包含在一个块中。

重要的是检查是否包含块中的特定事务。为了这个,使用Merkle根。

Merkle树是通过递归的散列成对的节点来构建的,直到只有一个散列。这个创建的哈希被称为根,或merkle根。Merkle树可以通过log2(N)计算查看树中是否包含任何数据元素。

实现过程

准备交易数据

Merkle树的实现_第2张图片

创建合并左事务和右事务的散列数据

Merkle树的实现_第3张图片

执行循环直到只有一个散列

Merkle树的实现_第4张图片

算法和实现 

com.goroom.merkle.MerkleTrees.java

package com.goroom.merkle;

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

/**
 * Created by andyfeng on 2017/12/20.
 */
public class MerkleTrees {
    // transaction List
    List txList;
    // Merkle Root
    String root;

    /**
     * constructor
     * @param txList transaction List 交易List
     */
    public MerkleTrees(List txList) {
        this.txList = txList;
        root = "";
    }

    /**
     * execute merkle_tree and set root.
     */
    public void merkle_tree() {

        List tempTxList = new ArrayList();

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

        List newTxList = getNewTxList(tempTxList);

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

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

    /**
     * return Node Hash List.
     * @param tempTxList
     * @return
     */
    private List getNewTxList(List tempTxList) {

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

        }

        return newTxList;
    }

    /**
     * Return hex string
     * @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 "";
    }

    /**
     * Get Root
     * @return
     */
    public String getRoot() {
        return this.root;
    }
}

 

测试执行

com.goroom.merkle.App.java

package com.goroom.merkle;

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

/**
 * Created by andyfeng on 2017/12/20.
 */
public class App {
    public static void main(String [] args) {
        List 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());
    }
}

Merkle树的实现_第5张图片

 

英文原文:http://java-lang-programming.com/en/articles/29

 

代码地址:https://gitee.com/andyfeng/merkletrees

转载于:https://my.oschina.net/andyfeng/blog/1592589

你可能感兴趣的:(java,python,c/c++)