前言
学习区块链技术,那么Merkle树不得不去深入了解。本文将用java手写Merkle树
一、Merkle树简介
Merkle树是1979 年Ralph Merkle提出并用自己名字命名的一种数据结构。什么是 Merkle 树呢?维基百科中对 Merkle 树的定义如下:
收集一个或多个新记录块,对这些记录进行散列,再将散列配对,散列,再次配对并再次散列,直到单个散列保留这个单独的哈希被称为merkle树的Merkle根。在比特币浏览器中如下图所示:
图中的1 2 3 4二二合一,最终得到了Merkle Root:f3e94742aca4b5ef85488dc37c06c3282295ffec960994b2c0d5ac2a25a95766
有兴趣的可以看看bitcoin代码之MerkleTree这篇文章。
二、java实现
1.代码如下:
package org.xiangbiao;
import cn.hutool.crypto.SecureUtil;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* @author larry.xiang
*/
public class MerkleTrees { // 默克根 String merkleRoot; // 交易集合 List txLst; /** * 初始化 * * @param txList 交易集合 */ public MerkleTrees(List txList) { this.txLst = txList; merkleRoot = ""; } /** * 获取Node Hash List * @return */ private List getNodeHashList(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); } // 两两加密 String sha2HexValue = SecureUtil.sha256(left + right); // 双重hash sha2HexValue = SecureUtil.sha256(sha2HexValue); newTxList.add(sha2HexValue); index++; } return newTxList; } /** * 构造默克树,设置默克根 */ public void merkle_tree() { List tempTxList = new ArrayList(); for (int i = 0; i < this.txLst.size(); i++) { tempTxList.add(this.txLst.get(i)); } List newTxList = getNodeHashList(tempTxList); //一直循环直到只剩下一个hash值 while (newTxList.size() != 1) { newTxList = getNodeHashList(newTxList); } this.merkleRoot = newTxList.get(0); } /** * 获取默克根 * * @return */ public String getMerkleRoot() { return this.merkleRoot; }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
2.测试
代码如下(示例):
public static void main(String[] args) { List tempTxList = new ArrayList(); tempTxList.add("80c6f121c3e9fe0a59177e49874d8c703cbadee0700a782e4002e87d862373c6"); tempTxList.add("b86f5ef1da8ddbdb29ec269b535810ee61289eeac7bf2b2523b494551f03897c"); //Collections.reverse(tempTxList); MerkleTrees merkleTrees = new MerkleTrees(tempTxList); merkleTrees.merkle_tree(); System.out.println("root : " + merkleTrees.getMerkleRoot()); }
}1
2
3
4
5
6
7
8
9
10
11
12
13
总结
由于哈希算法结果较长,我们用简化版的结果来举例,假设目前某区块包含两笔交易,双重哈希之后:
在执行【两两一组拼接】时,简单将111和222拼一起:111222,就完成拼接了。(实际的拼接,是需要将哈希结果解码为计算机语言、位移、拼接、编码、位移,最终才能得到结果。)
拼接前,所有交易假设有n个,拼接后,剩下的个数就为n/2个了。
多次【双重哈希算法+两两一组拼接】,就是多次执行上述操作,最开始总交易个数有n个,执行一次,还有n/2个,再执行一次,还有n/4个,最终执行到结果只有1个的时候停止,再对结果做两次哈希运算,得到的结果就是merkle根值了。
文章来源: blog.csdn.net,作者:向彪-fisco bcos,版权归原作者所有,如需转载,请联系作者。
原文链接:blog.csdn.net/ws327443752/article/details/109208567