cranberry
1package merkle
2
3import (
4"crypto/sha256"
5"encoding/hex"
6
7pbapi "gitverse.ru/IvanTimofeev/cranberry/pkg/grpc"
8utility "gitverse.ru/IvanTimofeev/cranberry/pkg/utility"
9)
10
11type node struct {
12Left *node
13Right *node
14Hash []byte
15}
16
17func MerkleRoot(txcs []*pbapi.TxContainer) string {
18if txcs == nil || len(txcs) == 0 {
19return ""
20}
21return hex.EncodeToString(buildMerkleTree(txcs).Hash)
22}
23
24func buildMerkleTree(txcs []*pbapi.TxContainer) *node {
25var nodes []*node
26for _, txc := range txcs {
27hash := sha256.Sum256(utility.TxToBytes(txc.Tx))
28nodes = append(nodes, &node{Hash: hash[:]})
29}
30
31for len(nodes) > 1 {
32var newLevel []*node
33for i := 0; i < len(nodes); i += 2 {
34if len(nodes) > i+1 {
35combined := make([]byte, len(nodes[i].Hash)+len(nodes[i+1].Hash))
36copy(combined, nodes[i].Hash)
37copy(combined[len(nodes[i].Hash):], nodes[i+1].Hash)
38newHash := sha256.Sum256(combined)
39newnode := &node{Left: nodes[i], Right: nodes[i+1], Hash: newHash[:]}
40newLevel = append(newLevel, newnode)
41} else {
42newLevel = append(newLevel, nodes[i])
43}
44}
45nodes = newLevel
46}
47return nodes[0]
48}
49