parent
443ed41fcd
commit
10624beaf2
@ -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