package blockchain import ( "crypto/sha256" ) // MerkleTree represent a Merkle tree type MerkleTree struct { RootNode *MerkleNode } // MerkleNode represent a Merkle tree node type MerkleNode struct { Left *MerkleNode Right *MerkleNode Data []byte } // NewMerkleTree creates a new Merkle tree from a sequence of data func NewMerkleTree(data [][]byte) *MerkleTree { if len(data) == 0 { return nil } var nodes []*MerkleNode for _, datum := range data { node := NewMerkleNode(nil, nil, datum) nodes = append(nodes, node) } for len(nodes) > 1 { var newLevel []*MerkleNode if len(nodes)%2 != 0 { nodes = append(nodes, nodes[len(nodes)-1]) } 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 } // NewMerkleNode creates a new Merkle tree node func NewMerkleNode(left, right *MerkleNode, data []byte) *MerkleNode { mNode := MerkleNode{} prevHashes := []byte{} if left != nil { prevHashes = append(prevHashes, left.Data...) } if right != nil { prevHashes = append(prevHashes, right.Data...) } prevHashes = append(prevHashes, data...) hash := sha256.Sum256(prevHashes) mNode.Data = hash[:] mNode.Left = left mNode.Right = right return &mNode }