完整的比特幣數據庫(也就是區塊鏈)須要超過 140 Gb 的磁盤空間。由於比特幣的去中心化特性,網絡中的每一個節點必須是獨立,自給自足的,也就是每一個節點必須存儲一個區塊鏈的完整副本。隨着愈來愈多的人使用比特幣,這條規則變得愈來愈難以遵照:由於不太可能每一個人都去運行一個全節點。而且,因爲節點是網絡中的徹底參與者,它們負有相關責任:節點必須驗證交易和區塊。另外,要想與其餘節點交互和下載新塊,也有必定的網絡流量需求。html
在中本聰的 比特幣原始論文 中,對這個問題也有一個解決方案:簡易支付驗證(Simplified Payment Verification, SPV)。SPV 是一個比特幣輕節點,它不須要下載整個區塊鏈,也不須要驗證區塊和交易。相反,它會在區塊鏈查找交易(爲了驗證支付),而且須要鏈接到一個全節點來檢索必要的數據。這個機制容許在僅運行一個全節點的狀況下有多個輕錢包。node
爲了實現 SPV,須要有一個方式來檢查是否一個區塊包含了某筆交易,而無須下載整個區塊。這就是 Merkle 樹所要完成的事情。ios
比特幣用 Merkle 樹來獲取交易哈希,哈希被保存在區塊頭中,並會用於工做量證實系統。到目前爲止,咱們只是將一個塊裏面的每筆交易哈希鏈接了起來,將在上面應用了 SHA-256 算法。雖然這是一個用於獲取區塊交易惟一表示的一個不錯的途徑,可是它沒有利用到 Merkle 樹。c++
來看一下 Merkle 樹:算法
每一個塊都會有一個 Merkle 樹,它從葉子節點(樹的底部)開始,一個葉子節點就是一個交易哈希(比特幣使用雙 SHA256 哈希)。葉子節點的數量必須是雙數,可是並不是每一個塊都包含了雙數的交易。由於,若是一個塊裏面的交易數爲單數,那麼就將最後一個葉子節點(也就是 Merkle 樹的最後一個交易,不是區塊的最後一筆交易)複製一份湊成雙數。數據庫
從下往上,兩兩成對,鏈接兩個節點哈希,將組合哈希做爲新的哈希。新的哈希就成爲新的樹節點。重複該過程,直到僅有一個節點,也就是樹根。根哈希而後就會當作是整個塊交易的惟一標示,將它保存到區塊頭,而後用於工做量證實。網絡
Merkle 樹的好處就是一個節點能夠在不下載整個塊的狀況下,驗證是否包含某筆交易。而且這些只須要一個交易哈希,一個 Merkle 樹根哈希和一個 Merkle 路徑。app
最後,來寫代碼:ide
1 package main 2 3 import ( 4 "crypto/sha256" 5 "fmt" 6 "encoding/hex" 7 ) 8 9 type MerkleTree struct{ 10 RootNode * MerkleNode 11 } 12 13 type MerkleNode struct{ 14 Left *MerkleNode 15 Right *MerkleNode 16 Data []byte 17 } 18 19 func NewMerkleTree(data [][]byte) * MerkleTree{ 20 var nodes []MerkleNode 21 if len(data)%2 != 0{ 22 data = append(data,data[len(data)-1]) 23 } 24 25 for _,datum := range data{ 26 node := NewMerkleNode(nil,nil,datum) 27 nodes = append(nodes,*node) 28 } 29 30 for i := 0;i < len(data)/2;i++{ 31 var newLevel []MerkleNode 32 33 for j := 0;j < len(nodes);j += 2{ 34 node := NewMerkleNode(&nodes[j],&nodes[j+1],nil) 35 newLevel = append(newLevel,*node) 36 } 37 nodes = newLevel 38 } 39 40 mTree := MerkleTree{&nodes[0]} 41 return &mTree 42 } 43 44 func NewMerkleNode(left,right *MerkleNode,data []byte)*MerkleNode{ 45 mNode := MerkleNode{} 46 47 if left == nil && right == nil{ 48 hash := sha256.Sum256(data) 49 mNode.Data = hash[:] 50 }else{ 51 prevHashes := append(left.Data,right.Data...) 52 hash := sha256.Sum256(prevHashes) 53 mNode.Data = hash[:] 54 } 55 56 mNode.Left = left 57 mNode.Right = right 58 59 return &mNode 60 } 61 //============================================================== 62 63 func testNewMerkleNode1(){ 64 data := [][]byte{ 65 []byte("node1"), 66 []byte("node2"), 67 []byte("node3"), 68 } 69 70 n1 := NewMerkleNode(nil,nil,data[0]) 71 n2 := NewMerkleNode(nil,nil,data[1]) 72 n3 := NewMerkleNode(nil,nil,data[2]) 73 n4 := NewMerkleNode(nil,nil,data[2]) 74 75 76 n5 := NewMerkleNode(n1,n2,nil) 77 n6 := NewMerkleNode(n3,n4,nil) 78 79 n7 := NewMerkleNode(n5,n6,nil) 80 81 fmt.Println("n5 = ",hex.EncodeToString(n5.Data)) 82 fmt.Println("n6 = ",hex.EncodeToString(n6.Data)) 83 fmt.Println("n7 = ",hex.EncodeToString(n7.Data)) 84 } 85 86 func testNewMerkleNode2(){ 87 data := [][]byte{ 88 []byte("node1"), 89 []byte("node2"), 90 []byte("node3"), 91 } 92 // Level 1 93 n1 := NewMerkleNode(nil, nil, data[0]) 94 n2 := NewMerkleNode(nil, nil, data[1]) 95 n3 := NewMerkleNode(nil, nil, data[2]) 96 n4 := NewMerkleNode(nil, nil, data[2]) 97 98 // Level 2 99 n5 := NewMerkleNode(n1, n2, nil) 100 n6 := NewMerkleNode(n3, n4, nil) 101 102 // Level 3 103 n7 := NewMerkleNode(n5, n6, nil) 104 105 rootHash := fmt.Sprintf("%x", n7.Data) 106 mTree := NewMerkleTree(data) 107 108 fmt.Println("roothash =\t",(rootHash)) 109 fmt.Println("mTree =\t\t",hex.EncodeToString(mTree.RootNode.Data)) 110 } 111 112 113 114 func main() { 115 testNewMerkleNode1() 116 testNewMerkleNode2() 117 }
c++須要導入以前的sha256 https://www.cnblogs.com/itdef/p/9435218.html區塊鏈
sha256.cpp sha256.h
1 // 1111.cpp: 定義控制檯應用程序的入口點。 2 // 3 4 #include "sha256.h" 5 #include <string> 6 #include <vector> 7 #include <iostream> 8 9 10 using namespace std; 11 12 13 typedef struct merklenode { 14 struct merklenode* left; 15 struct merklenode* right; 16 string data; 17 }MerkleNode; 18 19 20 typedef struct merkletree { 21 MerkleNode* merkleNode; 22 }MerkleTree; 23 24 MerkleNode* NewMerkleNode(MerkleNode* left, MerkleNode* right, string data) { 25 MerkleNode* mNode = new MerkleNode{}; 26 27 if (left == nullptr && right == nullptr) { 28 string hash = sha256(data); 29 mNode->data = hash; 30 } 31 else { 32 string prevHashes = left->data + right->data; 33 string hash = sha256(prevHashes); 34 mNode->data = hash; 35 } 36 37 mNode->left = left; 38 mNode->right = right; 39 40 return mNode; 41 } 42 43 MerkleTree* NewMerkleTree(vector<string> data) { 44 vector<MerkleNode*> nodes; 45 46 if ((data.size() % 2) != 0) { 47 data.push_back(data[data.size() - 1]); 48 } 49 50 for (const auto& datum : data) { 51 MerkleNode* node = NewMerkleNode(nullptr, nullptr, datum); 52 nodes.push_back(node); 53 } 54 55 for (int i = 0; i < (data.size() / 2); i++) { 56 vector<MerkleNode*> newLevel; 57 58 for (int j = 0; j < nodes.size(); j += 2) { 59 MerkleNode* node = NewMerkleNode(nodes[j], nodes[j + 1], ""); 60 newLevel.push_back(node); 61 } 62 nodes = newLevel; 63 } 64 65 MerkleTree* mTree = new MerkleTree{ nodes[0] }; 66 return mTree; 67 } 68 69 void testNewMerkleNode1() { 70 vector<string> data{ "node1","node2","node3" }; 71 72 MerkleNode* n1 = NewMerkleNode(nullptr, nullptr, data[0]); 73 MerkleNode* n2 = NewMerkleNode(nullptr, nullptr, data[1]); 74 MerkleNode* n3 = NewMerkleNode(nullptr, nullptr, data[2]); 75 MerkleNode* n4 = NewMerkleNode(nullptr, nullptr, data[2]); 76 77 MerkleNode* n5 = NewMerkleNode(n1, n2, ""); 78 MerkleNode* n6 = NewMerkleNode(n3, n4, ""); 79 80 MerkleNode* n7 = NewMerkleNode(n5, n6, ""); 81 82 std::cout << "n5 = " << n5->data << std::endl; 83 std::cout << "n6 = " << n6->data << std::endl; 84 std::cout << "n7 = " << n7->data << std::endl; 85 } 86 87 void testNewMerkleNode2() { 88 vector<string> data{ "node1","node2","node3" }; 89 90 MerkleNode* n1 = NewMerkleNode(nullptr, nullptr, data[0]); 91 MerkleNode* n2 = NewMerkleNode(nullptr, nullptr, data[1]); 92 MerkleNode* n3 = NewMerkleNode(nullptr, nullptr, data[2]); 93 MerkleNode* n4 = NewMerkleNode(nullptr, nullptr, data[2]); 94 95 MerkleNode* n5 = NewMerkleNode(n1, n2, ""); 96 MerkleNode* n6 = NewMerkleNode(n3, n4, ""); 97 98 MerkleNode* n7 = NewMerkleNode(n5, n6, ""); 99 100 MerkleTree* mTree = NewMerkleTree(data); 101 102 std::cout << "roothash = "<< n7->data << std::endl; 103 std::cout << "mTree = " << mTree->merkleNode->data << std::endl; 104 105 106 } 107 108 109 110 int main() 111 { 112 testNewMerkleNode1(); 113 testNewMerkleNode2(); 114 return 0; 115 }
參考
https://blog.csdn.net/simple_the_best/article/details/78462129