默克尔树代码

1.示例代码Merkle树的结构图:

传入四个节点,两两节点进行合并,再次哈希计算,得到一个新的哈希值,完成第一层哈希,最终得到两个哈希值;

第二轮得到的两个哈希值继续合并,得到最终哈希值。

在这里插入图片描述

2.默克尔树的代码解析

1.数据结构定义
//节点结构体定义
type MerkleNode struct {
   Left  *MerkleNode
   Right *MerkleNode
   Data  []byte
}

//树的结构体定义
type MerkleTree struct {
   RootNode *MerkleNode
}
2.创建节点和树
//创建节点
func NewMerkleNode(left, right *MerkleNode, data []byte) *MerkleNode {
   mNode := MerkleNode{}
   //如果左右子树为空,那么data就是原始数据节点
   if left == nil && right == nil {
      //计算哈希
      hash := sha256.Sum256(data)
      mNode.Data = hash[:]
   } else {
      //将左右子树的数据集合在一起
      preHashes := append(left.Data, right.Data...)
      //计算哈希
      hash := sha256.Sum256(preHashes)
      mNode.Data = hash[:]
   }
   //左右子树赋值
   mNode.Left = left
   mNode.Right = right

   return &mNode
}

func NewMerkleTree(data [][]byte) *MerkleTree {
   var nodes []MerkleNode
   //如果是单数个节点,复制最后一个节点
   if len(data)%2 != 0 {
      data = append(data, data[len(data)-1])
   }
   //构造节点
   for _, datum := range data {
      node := NewMerkleNode(nil, nil, datum)
      nodes = append(nodes, *node)
   }
   //层层计算
   for i := 0; i < len(data)/2; i++ {
      var newLevel []MerkleNode
      //相邻两个节点合并
      for j := 0; j < len(nodes); j += 2 {
         node := NewMerkleNode(&nodes[j], &nodes[j+1], nil)
         newLevel = append(newLevel, *node)
      }
      nodes = newLevel
   }
   mTree := MerkleTree{&nodes[0]}
   return &mTree
}
3.以先序遍历的顺序打印结果
//节点信息打印函数
func PrintNode(node *MerkleNode) {
   fmt.Printf("%p\n", node)
   if node != nil {
      fmt.Printf("left[%p], right[%p], data(%x)\n", node.Left, node.Right, node.Data)
      fmt.Printf("check:%t\n", check(node))
   }
}

//先序遍历
func showMerkleTree(root *MerkleNode) {
   if root == nil {
      return
   } else {
      //打印节点信息
      PrintNode(root)
   }
   showMerkleTree(root.Left)
   showMerkleTree(root.Right)
}
4.结果检验
//检查结果是否正确
func check(node *MerkleNode) bool {
   if node.Left == nil {
      return true
   }
   //左右两个子树的data数值联合起来计算hash值并与父节点的data进行比较
   prevHashes := append(node.Left.Data, node.Right.Data...)
   hash32 := sha256.Sum256(prevHashes)
   hash := hash32[:]
   return bytes.Compare(hash, node.Data) == 0
}
5.测试
func main() {
   data := [][]byte{
      []byte("node1"),
      []byte("node2"),
      []byte("node3"),
      []byte("node4"),
   }

   tree := NewMerkleTree(data)
   showMerkleTree(tree.RootNode)
}

结果呈现:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9ZCKs74x-1651131579268)(C:\Users\李婕\AppData\Roaming\Typora\typora-user-images\image-20220428153327371.png)]

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yitahutu79

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值