概述
MerkleTree被廣泛的應用在比特幣技術中,本文旨在通過代碼實現一個簡單的MerkleTree,併計算出Merkle tree的TreeRoot。
Merkle Tree 是一種數據結構,用於驗證在計算機之間和之間存儲,處理和傳輸的任何類型的數據。
目前,Merkle樹的主要用途是確保從對等網絡中接收的數據塊未受損和未改變,和檢查其他對等網絡沒有撒謊發送假數據塊。
Merkle Tree應用舉例
比特幣
GitA
mazon's Dynamo
Gassandra
比特幣中的應用
比特幣中每個塊中都包含了所有交易的集合簽名,這個簽名就是用Merkle tree實現的,Merkle樹用於比特幣以匯總塊中的所有事務,產生整個事務集合的整體數字指紋,提供非常有效的過程來驗證事務是否包括在塊中。
Merkle樹一個很重要的用處是檢查塊中是否包含指定的交易,Merkle樹是通過遞歸哈希節點對來構造的,直到只有一個哈希。
Merkle tree 代碼實現
哈希樹的跟節點稱為Merkle根,Merkle樹可以僅用log2(N)的時間複雜度檢查任何一個數據元素是否包含在樹中:
package test;import java.security.MessageDigest;import java.util.ArrayList;import java.util.List;public class MerkleTrees { // transaction List List<String> txList; // Merkle Root String root; /** * constructor * @param txList transaction List 交易List */ public MerkleTrees(List<String> txList) { this.txList = txList; root = ""; } /** * execute merkle_tree and set root. */ public void merkle_tree() { List<String> tempTxList = new ArrayList<String>(); for (int i = 0; i < this.txList.size(); i++) { tempTxList.add(this.txList.get(i)); } List<String> newTxList = getNewTxList(tempTxList); while (newTxList.size() != 1) { newTxList = getNewTxList(newTxList); } this.root = newTxList.get(0); } /** * return Node Hash List. * @param tempTxList * @return */ private List<String> getNewTxList(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); } // 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; } }數據準備
我們將交易的數據,放入到List中:
List<String> tempTxList = new ArrayList<String>();tempTxList.add("a");tempTxList.add("b");tempTxList.add("c");tempTxList.add("d");tempTxList.add("e");實現過程
準備交易數據計算出每個數據的hash值,從左到右逐步組成樹的左右節點執行循環知道最後只剩下一個數據
private List<String> getNewTxList(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); } // sha2 hex value String sha2HexValue = getSHA2HexValue(left + right); newTxList.add(sha2HexValue); index++; }測試
package test;import java.util.ArrayList;import java.util.List;public class App { public static void main(String [] args) { List<String> tempTxList = new ArrayList<String>(); 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()); } }執行結果
本文從簡單二叉樹的形式實現了簡單的MerkleTree,計算出TreeRoot,但是實際上的的MerkleTree不拘謹與二叉樹還可能是多叉樹。
本文90%來著於翻譯,原文地址
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。