-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
94 lines (71 loc) · 1.47 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
package main
import (
"crypto/sha256"
"fmt"
"math"
"math/rand"
"time"
)
type Chain struct {
Blocks []Block
}
type Block struct {
Data string
Hash string
PrevHash string
}
func CreateChain() *Chain {
return &Chain{
Blocks: []Block{CreateGenesisBlock()},
}
}
func RandInt() int {
seed := rand.NewSource(time.Now().UnixNano())
r := rand.New(seed)
return r.Intn(math.MaxInt64)
}
func (block *Block) GenerateHash() {
block.Hash = CalculateHash(block)
}
func CalculateHash(block *Block) string {
hasher := sha256.New()
hasher.Write([]byte(block.Data + block.PrevHash))
return fmt.Sprintf("%x", hasher.Sum(nil))
}
func CreateGenesisBlock() Block {
block := Block{
Data: fmt.Sprintf("GENESIS_BLOCK_%d", RandInt()),
PrevHash: "0",
}
block.GenerateHash()
return block
}
func (chain *Chain) AddBlock(data string) {
prevBlock := chain.Blocks[len(chain.Blocks)-1]
newBlock := Block{
Data: data,
PrevHash: prevBlock.Hash,
}
newBlock.GenerateHash()
chain.Blocks = append(chain.Blocks, newBlock)
}
func (chain *Chain) IsValid() bool {
for i := 0; i < len(chain.Blocks); i++ {
// Genesis block
if i == 0 {
if chain.Blocks[i].Hash != CalculateHash(&chain.Blocks[i]) {
return false
}
continue
}
prevBlock := chain.Blocks[i-1]
currentBlock := chain.Blocks[i]
if currentBlock.PrevHash != prevBlock.Hash {
return false
}
if currentBlock.Hash != CalculateHash(¤tBlock) {
return false
}
}
return true
}