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。

猜你喜欢

转载自blog.csdn.net/YSS_33521/article/details/111474199