-
Notifications
You must be signed in to change notification settings - Fork 7
/
blockchain.go
90 lines (76 loc) · 1.91 KB
/
blockchain.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
package main
import (
"fmt"
"strconv"
"sync"
"time"
)
//Blockchain s
type Blockchain struct {
Mutex sync.RWMutex
Node *Node
Pbft *Pbft
Blocks []*Block
BlockMap map[string]struct{}
}
//NewBlockchain create a new blockchain
func NewBlockchain(node *Node) *Blockchain {
genesisBlock := NewGenesisBlock()
bc := &Blockchain{
Node: node,
Pbft: node.Pbft,
Blocks: make([]*Block, 0),
BlockMap: make(map[string]struct{}, 0),
}
bc.Blocks = append(bc.Blocks, genesisBlock)
bc.Mutex.Lock()
bc.BlockMap[genesisBlock.GetHash()] = struct{}{}
bc.Mutex.Unlock()
return bc
}
//CreateBlock create a block
func (bc *Blockchain) CreateBlock() *Block {
lastBlock := bc.GetLastBlock()
b := &Block{
Version: 1,
Height: lastBlock.GetHeight() + 1,
Timestamp: time.Now().Unix(),
PrevBlockHash: lastBlock.GetHash(),
Forger: strconv.FormatInt(bc.Node.ID, 10),
Transactions: make([]Transaction, 0),
}
b.CalculateHash()
return b
}
func (bc *Blockchain) printBlockchain() {
fmt.Printf("NodeId %d ", bc.Node.ID)
for i := 0; i < len(bc.Blocks); i++ {
fmt.Printf("%s -> ", bc.Blocks[i].GetForger())
}
fmt.Println()
}
//CommitBlock add block into chain
func (bc *Blockchain) CommitBlock(block *Block) {
bc.Blocks = append(bc.Blocks, block)
bc.Mutex.Lock()
bc.BlockMap[block.GetHash()] = struct{}{}
bc.Mutex.Unlock()
bc.printBlockchain()
}
//GetLastBlock get last block of the chain
func (bc *Blockchain) GetLastBlock() *Block {
return bc.Blocks[len(bc.Blocks)-1]
}
//HasBlock check the block whether in the chain or not
func (bc *Blockchain) HasBlock(hash string) bool {
bc.Mutex.RLock()
_, ok := bc.BlockMap[hash]
bc.Mutex.RUnlock()
return ok
}
//ValidateBlock valiate block
func (bc *Blockchain) ValidateBlock(block *Block) bool {
lastBlock := bc.GetLastBlock()
return block.GetHeight() == lastBlock.GetHeight()+1 &&
block.GetPrevBlockHash() == lastBlock.GetHash()
}