-
Notifications
You must be signed in to change notification settings - Fork 0
/
chain.go
90 lines (83 loc) · 1.84 KB
/
chain.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 blockchain
import (
"database/sql"
_ "github.com/mattn/go-sqlite3"
"os"
"time"
)
func NewChain(filename, receiver string) error {
file, err := os.Create(filename)
if err != nil {
return err
}
file.Close()
db, err := sql.Open("sqlite3", filename)
if err != nil {
return err
}
defer db.Close()
_, err = db.Exec(CREATE_TABLE)
chain := &BlockChain{
DB: db,
}
genesis := &Block{
PrevHash: []byte(GENESIS_BLOCK),
Mapping: make(map[string]uint64),
Miner: receiver,
TimeStamp: time.Now().Format(time.RFC3339),
}
genesis.Mapping[STORAGE_CHAIN] = STORAGE_VALUE
genesis.Mapping[receiver] = GENESIS_REWARD
genesis.CurrHash = genesis.hash()
chain.AddBlock(genesis)
return nil
}
func LoadChain(filename string) *BlockChain {
db, err := sql.Open("sqlite3", filename)
if err != nil {
return nil
}
chain := &BlockChain{
DB: db,
}
return chain
}
func (chain *BlockChain) Size() uint64 {
var size uint64
row := chain.DB.QueryRow("SELECT Id FROM BlockChain ORDER BY Id DESC")
row.Scan(&size)
return size
}
func (chain *BlockChain) Balance(address string, size uint64) uint64 {
var (
sblock string
block *Block
balance uint64
)
rows, err := chain.DB.Query("SELECT Block FROM BlockChain WHERE Id <= $1 ORDER BY Id DESC", size)
if err != nil {
return balance
}
defer rows.Close()
for rows.Next() {
rows.Scan(&sblock)
block = DeserializeBlock(sblock)
if value, ok := block.Mapping[address]; ok {
balance = value
break
}
}
return balance
}
func (chain *BlockChain) LastHash() []byte {
var hash string
row := chain.DB.QueryRow("SELECT Hash FROM BlockChain ORDER BY Id DESC")
row.Scan(&hash)
return Base64Decode(hash)
}
func (chain *BlockChain) AddBlock(block *Block) {
chain.DB.Exec("INSERT INTO BlockChain (Hash, Block) VALUES ($1, $2)",
Base64Encode(block.CurrHash),
SerializeBlock(block),
)
}