Golang Merkle tree
個人博客:https://www.huixinyixiao.xn–6qq986b3xl/
Golang 實作Merkle 樹
實作Merkle樹,需要使用:
"github.com/cbergoon/merkletree"
這個package中含有建構式,以及介面函式,所有,通過這個包實作Merkle樹的相關操作,是很好的,
官方實體代碼
// 在這里撰寫代碼
package main
import (
"crypto/sha256"
"github.com/cbergoon/merkletree"
"log"
)
//TestContent implements the Content interface provided by merkletree and represents the content stored in the tree.
type TestContent struct {
x string
}
//CalculateHash hashes the values of a TestContent
func (t TestContent) CalculateHash() ([]byte, error) {
h := sha256.New()
if _, err := h.Write([]byte(t.x)); err != nil {
return nil, err
}
return h.Sum(nil), nil
}
//Equals tests for equality of two Contents
func (t TestContent) Equals(other merkletree.Content) (bool, error) {
return t.x == other.(TestContent).x, nil
}
func main() {
//Build list of Content to build tree
var list []merkletree.Content
/*測驗檔案*/
var list02 []merkletree.Content
list02 = append(list02, TestContent{"shan"})
list = append(list, TestContent{x: "Hello"})
list = append(list, TestContent{x: "Hi"})
list = append(list, TestContent{x: "Hey"})
list = append(list, TestContent{x: "Hola"})
//Create a new Merkle Tree from the list of Content
t, err := merkletree.NewTree(list)
if err != nil {
log.Fatal(err)
}
//Get the Merkle Root of the tree
mr := t.MerkleRoot()
log.Println("Merkle Root:", mr)
//Verify the entire tree (hashes for each node) is valid
vt, err := t.VerifyTree()
if err != nil {
log.Fatal(err)
}
log.Println("Verify Tree: ", vt)
//Verify a specific content in in the tree
vc, err := t.VerifyContent(list02[0])
if err != nil {
log.Fatal(err)
}
log.Println("Verify Content: ", vc)
//String representation
log.Println(t)
}
Note:我改變了驗證的資訊內容(list02),為了驗證這個package 可用性,
1. 源package 解讀
在package 中的interface,需要實作兩個函式
//Content represents the data that is stored and verified by the tree. A type that
//implements this interface can be used as an item in the tree.
type Content interface {
CalculateHash() ([]byte, error)
Equals(other Content) (bool, error)
}

只是代碼實作中需要注意的,可以添加自己實作的演算法,比如更改sha256等,
其他函式的呼叫,不需要做任何改變,直接呼叫就好,
從上圖中可以看出對于所有的交易資料,都是葉子,并且,如果添加的交易數是奇數,也就是黃色區域表示的那樣,那么,就會復制最后一個交易,形成偶數個交易數,也就是最后的兩個交易其實是一樣的,
2. 查詢資料路徑,重新構造Merkle tree ,看看和我們想的是否一樣,
通過插入四個資料:
func appendListData(number int) {
// 隨機產生資料
for i := 0; i < number; i++ {
nodeId := "hello" + strconv.Itoa(i)
list = append(list, TestContent{nodeId})
}
}
上述代碼,實作插入資料的功能,
主函式里面直接呼叫,另外需要將list全域宣告,我們查詢兩個資料hello0和hello1的路徑,此時,設定number為4:

從紅色區域可以知道,兩個葉子節點的父節點是一樣的,也就是hello0和hello1葉子共同hash得到,
我們再次查詢兩個資料hello2和hello3的路徑,此時,同樣設定number為4:

看,結果如我們所說的那樣,
如果我們將上面的兩個圖中的紅色的資料進行hash,一定是root hash,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/238602.html
標籤:區塊鏈
