概述
MerkleTree被广泛的应用在比特币技术中,本文旨在通过代码实现一个简单的MerkleTree,并计算出Merkle tree的 TreeRoot。
Merkle Tree 是一种数据结构,用于验证在计算机之间和之间存储,处理和传输的任何类型的数据。
目前,Merkle树的主要用途是确保从对等网络中接收的数据块未受损和未改变,和检查其他对等网络没有撒谎发送假数据块。
比特币
Git
Amazon’s Dynamo
Gassandra

比特币中每个块中都包含了所有交易的集合签名,这个签名就是用Merkle tree实现的,Merkle树用于比特币以汇总块中的所有事务,产生整个事务集合的整体数字指纹,提供非常有效的过程来验证事务是否包括在块中。
Merkle树一个很重要的用处是检查块中是否包含指定的交易,Merkle树是通过递归哈希节点对来构造的,直到只有一个哈希。
哈希树的跟节点称为Merkle根,Merkle树可以仅用log2(N)的时间复杂度检查任何一个数据元素是否包含在树中:
packagetest;importjava.security.MessageDigest;importjava.util.ArrayList;importjava.util.List;publicclassMerkleTrees{// transaction ListList txList;// Merkle RootString root;/** * constructor * @paramtxList transaction List 交易List */publicMerkleTrees(List txList) {this.txList = txList; root =""; }/**
* execute merkle_tree and set root.
*/publicvoidmerkle_tree() { List tempTxList =newArrayList();for(inti =0; i newTxList = getNewTxList(tempTxList);while(newTxList.size() !=1) { newTxList = getNewTxList(newTxList); }this.root = newTxList.get(0); }/** * return Node Hash List. * @paramtempTxList * @return*/privateListgetNewTxList(List tempTxList) { List newTxList =newArrayList();intindex =0;while(index < tempTxList.size()) {// leftString left = tempTxList.get(index); index++;// rightString right ="";if(index != tempTxList.size()) { right = tempTxList.get(index); }// sha2 hex valueString sha2HexValue = getSHA2HexValue(left + right); newTxList.add(sha2HexValue); index++; }returnnewTxList; }/** * Return hex string * @paramstr * @return*/publicStringgetSHA2HexValue(String str) {byte[] cipher_byte;try{ MessageDigest md = MessageDigest.getInstance("SHA-256"); md.update(str.getBytes()); cipher_byte = md.digest(); StringBuilder sb =newStringBuilder(2* cipher_byte.length);for(byteb: cipher_byte) { sb.append(String.format("%02x", b&0xff) ); }returnsb.toString(); }catch(Exception e) { e.printStackTrace(); }return""; }/** * Get Root * @return*/publicStringgetRoot() {returnthis.root; } }
我们将交易的数据,放入到List中:
List tempTxList = new ArrayList();tempTxList.add("a");tempTxList.add("b");tempTxList.add("c");tempTxList.add("d");tempTxList.add("e");
准备交易数据
计算出每个数据的hash值,从左到右逐步组成树的左右节点
执行循环知道最后只剩下一个数据
privateListgetNewTxList(ListtempTxList) {ListnewTxList=newArrayList(); int index=0;while(index
packagetest;importjava.util.ArrayList;importjava.util.List;publicclassApp{publicstaticvoidmain(String [] args) { List tempTxList =newArrayList(); tempTxList.add("a"); tempTxList.add("b"); tempTxList.add("c"); tempTxList.add("d"); tempTxList.add("e"); MerkleTrees merkleTrees =newMerkleTrees(tempTxList); merkleTrees.merkle_tree(); System.out.println("root : "+ merkleTrees.getRoot()); } }
执行结果
本文从简单二叉树的形式实现了简单的MerkleTree,计算出TreeRoot,但是实际上的的MerkleTree不拘谨与二叉树还可能是多叉树。
网友评论