commit
1c95f52e81
@ -0,0 +1,65 @@ |
|||||||
|
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 { |
||||||
|
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 |
||||||
|
} |
||||||
|
|
||||||
|
// NewMerkleNode creates a new Merkle tree node
|
||||||
|
func NewMerkleNode(left, right *MerkleNode, data []byte) *MerkleNode { |
||||||
|
mNode := MerkleNode{} |
||||||
|
|
||||||
|
if left == nil && right == nil { |
||||||
|
hash := sha256.Sum256(data) |
||||||
|
mNode.Data = hash[:] |
||||||
|
} else { |
||||||
|
prevHashes := append(left.Data, right.Data...) |
||||||
|
hash := sha256.Sum256(prevHashes) |
||||||
|
mNode.Data = hash[:] |
||||||
|
} |
||||||
|
|
||||||
|
mNode.Left = left |
||||||
|
mNode.Right = right |
||||||
|
|
||||||
|
return &mNode |
||||||
|
} |
Loading…
Reference in new issue