Golang --Merkle tree

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。






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章