區(qū)塊鏈java代碼實(shí)現(xiàn)
概述
MerkleTree被廣泛的應(yīng)用在比特幣技術(shù)中,本文旨在通過代碼實(shí)現(xiàn)一個簡單的MerkleTree,并計算出Merkle tree的 TreeRoot。
Merkle Tree 是一種數(shù)據(jù)結(jié)構(gòu),用于驗(yàn)證在計算機(jī)之間和之間存儲,處理和傳輸?shù)娜魏晤愋偷臄?shù)據(jù)。
目前,Merkle樹的主要用途是確保從對等網(wǎng)絡(luò)中接收的數(shù)據(jù)塊未受損和未改變,和檢查其他對等網(wǎng)絡(luò)沒有撒謊發(fā)送假數(shù)據(jù)塊。

Merkle Tree應(yīng)用舉例
比特幣
GitA
mazon's Dynamo
Gassandra
比特幣中的應(yīng)用
比特幣中每個塊中都包含了所有交易的集合簽名,這個簽名就是用Merkle tree實(shí)現(xiàn)的,Merkle樹用于比特幣以匯總塊中的所有事務(wù),產(chǎn)生整個事務(wù)集合的整體數(shù)字指紋,提供非常有效的過程來驗(yàn)證事務(wù)是否包括在塊中。
Merkle樹一個很重要的用處是檢查塊中是否包含指定的交易,Merkle樹是通過遞歸哈希節(jié)點(diǎn)對來構(gòu)造的,直到只有一個哈希。

Merkle tree 代碼實(shí)現(xiàn)
哈希樹的跟節(jié)點(diǎn)稱為Merkle根,Merkle樹可以僅用log2(N)的時間復(fù)雜度檢查任何一個數(shù)據(jù)元素是否包含在樹中:
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;
}
}
數(shù)據(jù)準(zhǔn)備
我們將交易的數(shù)據(jù),放入到List中:
List<String> tempTxList = new ArrayList<String>();
tempTxList.add("a");
tempTxList.add("b");
tempTxList.add("c");
tempTxList.add("d");
tempTxList.add("e");
實(shí)現(xiàn)過程
準(zhǔn)備交易數(shù)據(jù)
計算出每個數(shù)據(jù)的hash值,從左到右逐步組成樹的左右節(jié)點(diǎn)
執(zhí)行循環(huán)知道最后只剩下一個數(shù)據(jù)

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());
}
}
執(zhí)行結(jié)果

本文從簡單二叉樹的形式實(shí)現(xiàn)了簡單的MerkleTree,計算出TreeRoot,但是實(shí)際上的的MerkleTree不拘謹(jǐn)與二叉樹還可能是多叉樹。
本文90%來著于翻譯,原文地址
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Maven打包SpringBoot工程的實(shí)現(xiàn)示例
在使用Spring Boot和Maven的項目中,你可以使用Maven來打包你的項目,本文主要介紹了Maven打包SpringBoot工程的實(shí)現(xiàn)示例,具有一定的參考價值,感興趣的可以了解一下2024-05-05
Java使用easyExcel實(shí)現(xiàn)Excel文件解析
這篇文章主要為大家詳細(xì)介紹了Java如何使用easyExcel實(shí)現(xiàn)Excel文件解析,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2025-02-02
Java的靜態(tài)方法Arrays.asList()使用指南
Arrays.asList() 是一個 Java 的靜態(tài)方法,它可以把一個數(shù)組或者多個參數(shù)轉(zhuǎn)換成一個 List 集合,這個方法可以作為數(shù)組和集合之間的橋梁,方便我們使用集合的一些方法和特性,本文將介紹 Arrays.asList() 的語法、應(yīng)用場景、坑點(diǎn)和總結(jié)2023-09-09
springboot+idea熱部署的實(shí)現(xiàn)方法(自動刷新)
這篇文章主要介紹了springboot+idea熱部署的實(shí)現(xiàn)方法(自動刷新),本文分步驟通過實(shí)例代碼截圖相結(jié)合給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-05-05
SpringBoot統(tǒng)一響應(yīng)和統(tǒng)一異常處理詳解
在開發(fā)Spring Boot應(yīng)用時,處理響應(yīng)結(jié)果和異常的方式對項目的可維護(hù)性、可擴(kuò)展性和團(tuán)隊協(xié)作有著至關(guān)重要的影響,統(tǒng)一結(jié)果返回和統(tǒng)一異常處理是提升項目質(zhì)量的關(guān)鍵策略之一,所以本文給大家詳細(xì)介紹了SpringBoot統(tǒng)一響應(yīng)和統(tǒng)一異常處理,需要的朋友可以參考下2024-08-08

