You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
69 lines
1.3 KiB
69 lines
1.3 KiB
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
|
|
}
|
|
|