-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathblockchain.go
More file actions
156 lines (134 loc) · 3.79 KB
/
blockchain.go
File metadata and controls
156 lines (134 loc) · 3.79 KB
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
package blockchain
import (
"crypto/sha256"
"fmt"
)
var (
GenesisAmount float32 = 100
BlockHeightCounter = 1
)
// Transactions : Represents a single transaction
type Transaction struct {
Sender string
Receiver string
Amount float32
Fee float32
}
func (tr Transaction) String() string {
if tr.Sender == "" {
tr.Sender = "none"
}
return " 【 Sender: " + tr.Sender +
"▕ Receiver: " + tr.Receiver +
"▕ Amount: " + fmt.Sprintf("%f", tr.Amount) +
"▕ Fee: " + fmt.Sprintf("%f", tr.Fee) +
" 】 "
}
// Block : Represents a Block on the Blockchain
type Block struct {
Transactions []Transaction
PrevBlockHash [32]byte
PrevBlock *Block
}
// GetBlockHash : Calculates the Sha256 hash of any given Block
func GetBlockHash(block* Block) [32]byte {
toByte := fmt.Sprintf("%v", block.Transactions) + fmt.Sprintf("%v", block.PrevBlockHash)
hashVal := sha256.Sum256([]byte(toByte))
return hashVal
}
// InsertBlock : Adds a new Block to the Blockchain
func InsertBlock(transaction []Transaction, chainHead *Block) *Block {
var hash [32]byte
if chainHead != nil {
hash = GetBlockHash(chainHead)
}
newBlock := Block{Transactions: transaction,
PrevBlockHash: hash,
PrevBlock: chainHead,
}
// fmt.Println("\nInserting Block ", blockHeightCounter)
// fmt.Printf(" Block Address: %p\n", &newBlock)
// fmt.Println(fmt.Sprintf(" Block Hash: %v", GetBlockHash(&newBlock)))
BlockHeightCounter++
return &newBlock
}
// ListBlocks : Prints all the Blocks in the Blockchain
func ListBlocks(chainHead *Block) {
temp := chainHead
fmt.Println("\n………………… 𝐁𝐥𝐎𝐂𝐊𝐂𝐇𝐀𝐈𝐍 …………………\n")
for (temp != nil) {
fmt.Println("Transactions: ")
for _,txn := range temp.Transactions{
fmt.Println(" ", txn)
}
fmt.Println("\nPrevious Block Hash: ", temp.PrevBlockHash)
fmt.Printf("Previous Block Address: %p\n", temp.PrevBlock)
fmt.Printf("Current Block Address: %p\n", temp)
fmt.Println()
temp = temp.PrevBlock
}
}
// GetBalance : Gets the current balance of a node
func GetBalance(chainHead* Block, node string) float32 {
var amount float32
temp := chainHead
for (temp != nil) {
for _, trans := range temp.Transactions {
if trans.Sender == node {
amount -= trans.Amount
} else if (trans.Receiver == node) {
amount += trans.Amount
}
}
temp = temp.PrevBlock
}
return amount
}
func VerifyTxHistory(TxHistory[] Transaction, chain* Block) bool {
if len(TxHistory) == 0 {
return true
}
temp := chain
iterator := 0
for temp != nil {
for _, trans := range temp.Transactions {
if trans.Sender == TxHistory[iterator].Sender && trans.Fee == TxHistory[iterator].Fee &&
trans.Amount == TxHistory[iterator].Amount && trans.Receiver == TxHistory[iterator].Receiver {
iterator += 1
}
if iterator == len(TxHistory) {
return true
}
}
temp = temp.PrevBlock
}
if iterator != len(TxHistory) { return false }
return false
}
// ValidateTransaction : Validates whether given transaction is valid
func ValidateTransaction(tr Transaction, chainHead *Block) bool {
senderBalance := GetBalance(chainHead, tr.Sender)
return (tr.Sender == "" || senderBalance >= tr.Amount)
}
// DoesStakeExist : Check if given staking txn is part of the Blockchain
func DoesStakeExist(stakeTxn Transaction, chainHead *Block) bool {
currBlock := chainHead
for currBlock != nil {
for _, trans := range currBlock.Transactions {
if trans == stakeTxn {
return true
}
}
currBlock = currBlock.PrevBlock
}
return false
}
// ValidateTransactions: Validates all the Transactions in the given array
func ValidateTransactions(trans []Transaction, chainHead *Block) bool {
for _, tr := range trans {
if ValidateTransaction(tr, chainHead) == false {
return false
}
}
return true
}