區(qū)塊鏈java代碼實(shí)現(xiàn)
概述
MerkleTree被廣泛的應(yīng)用在比特幣技術(shù)中,本文旨在通過(guò)代碼實(shí)現(xiàn)一個(gè)簡(jiǎn)單的MerkleTree,并計(jì)算出Merkle tree的 TreeRoot。
Merkle Tree 是一種數(shù)據(jù)結(jié)構(gòu),用于驗(yàn)證在計(jì)算機(jī)之間和之間存儲(chǔ),處理和傳輸?shù)娜魏晤?lèi)型的數(shù)據(jù)。
目前,Merkle樹(shù)的主要用途是確保從對(duì)等網(wǎng)絡(luò)中接收的數(shù)據(jù)塊未受損和未改變,和檢查其他對(duì)等網(wǎng)絡(luò)沒(méi)有撒謊發(fā)送假數(shù)據(jù)塊。
Merkle Tree應(yīng)用舉例
比特幣
GitA
mazon's Dynamo
Gassandra
比特幣中的應(yīng)用
比特幣中每個(gè)塊中都包含了所有交易的集合簽名,這個(gè)簽名就是用Merkle tree實(shí)現(xiàn)的,Merkle樹(shù)用于比特幣以匯總塊中的所有事務(wù),產(chǎn)生整個(gè)事務(wù)集合的整體數(shù)字指紋,提供非常有效的過(guò)程來(lái)驗(yàn)證事務(wù)是否包括在塊中。
Merkle樹(shù)一個(gè)很重要的用處是檢查塊中是否包含指定的交易,Merkle樹(shù)是通過(guò)遞歸哈希節(jié)點(diǎn)對(duì)來(lái)構(gòu)造的,直到只有一個(gè)哈希。
Merkle tree 代碼實(shí)現(xiàn)
哈希樹(shù)的跟節(jié)點(diǎn)稱為Merkle根,Merkle樹(shù)可以僅用log2(N)的時(shí)間復(fù)雜度檢查任何一個(gè)數(shù)據(jù)元素是否包含在樹(shù)中:
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)過(guò)程
準(zhǔn)備交易數(shù)據(jù)
計(jì)算出每個(gè)數(shù)據(jù)的hash值,從左到右逐步組成樹(shù)的左右節(jié)點(diǎn)
執(zhí)行循環(huán)知道最后只剩下一個(gè)數(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++; }
測(cè)試
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é)果
本文從簡(jiǎn)單二叉樹(shù)的形式實(shí)現(xiàn)了簡(jiǎn)單的MerkleTree,計(jì)算出TreeRoot,但是實(shí)際上的的MerkleTree不拘謹(jǐn)與二叉樹(shù)還可能是多叉樹(shù)。
本文90%來(lái)著于翻譯,原文地址
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Java中動(dòng)態(tài)規(guī)則的實(shí)現(xiàn)方式示例詳解
這篇文章主要介紹了Java中動(dòng)態(tài)規(guī)則的實(shí)現(xiàn)方式,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-08-08IDEA遇到Internal error. Please refer to http://jb. gg/ide/crit
這篇文章主要介紹了IDEA遇到Internal error. Please refer to http://jb. gg/ide/critical-startup-errors的問(wèn)題及解決辦法,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),需要的朋友可以參考下2020-08-08JDBC連接mysql亂碼異常問(wèn)題處理總結(jié)
這篇文章主要介紹了JDBC連接mysql亂碼異常問(wèn)題處理的辦法和思路,有需要的朋友參考學(xué)習(xí)下。2017-12-12Java代碼實(shí)現(xiàn)Map和Object互轉(zhuǎn)及Map和Json互轉(zhuǎn)
這篇文章主要介紹了Java代碼實(shí)現(xiàn)map和Object互轉(zhuǎn)及Map和json互轉(zhuǎn)的相關(guān)資料,需要的朋友可以參考下2016-05-05Intellij IDEA 2019 最新亂碼問(wèn)題及解決必殺技(必看篇)
大家在使用Intellij IDEA 的時(shí)候會(huì)經(jīng)常遇到各種亂碼問(wèn)題,今天小編給大家分享一些關(guān)于Intellij IDEA 2019 最新亂碼問(wèn)題及解決必殺技,感興趣的朋友跟隨小編一起看看吧2020-04-04java多線程實(shí)現(xiàn)交通燈管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了java多線程實(shí)現(xiàn)交通燈管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08Elasticsearch?Recovery索引分片分配詳解
這篇文章主要為大家介紹了關(guān)于Elasticsearch的Recovery索引分片分配詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪<BR>2022-04-04SpringBoot中定時(shí)任務(wù)的使用方法解析
這篇文章主要介紹了SpringBoot中定時(shí)任務(wù)的使用方法解析,@EnableScheduling?注解,它的作用是發(fā)現(xiàn)注解?@Scheduled的任務(wù)并由后臺(tái)執(zhí)行,沒(méi)有它的話將無(wú)法執(zhí)行定時(shí)任務(wù),需要的朋友可以參考下2024-01-01Java函數(shù)式編程(三):列表的轉(zhuǎn)化
這篇文章主要介紹了Java函數(shù)式編程(二):列表的轉(zhuǎn)化,lambda表達(dá)式不僅能幫助我們遍歷集合,并且可以進(jìn)行集合的轉(zhuǎn)化,需要的朋友可以參考下2014-09-09