1
1
package block
2
2
3
3
import (
4
+ "crypto/ecdsa"
4
5
"crypto/sha256"
5
6
"encoding/json"
6
7
"fmt"
8
+ "goBlockchain/utils"
7
9
"log"
8
10
"strings"
9
11
"time"
@@ -18,14 +20,23 @@ const (
18
20
type Block struct {
19
21
timestamp int64
20
22
nonce int
21
- prevHash [32 ]byte
23
+ previousHash [32 ]byte
22
24
transactions []* Transaction
23
25
}
24
26
27
+ func NewBlock (nonce int , previousHash [32 ]byte , transactions []* Transaction ) * Block {
28
+ b := new (Block )
29
+ b .timestamp = time .Now ().UnixNano ()
30
+ b .nonce = nonce
31
+ b .previousHash = previousHash
32
+ b .transactions = transactions
33
+ return b
34
+ }
35
+
25
36
func (b * Block ) Print () {
26
- fmt .Printf ("Timestamp %d\n " , b .timestamp )
27
- fmt .Printf ("Nonce %d\n " , b .nonce )
28
- fmt .Printf ("Previous_hash %x\n " , b .prevHash )
37
+ fmt .Printf ("timestamp %d\n " , b .timestamp )
38
+ fmt .Printf ("nonce %d\n " , b .nonce )
39
+ fmt .Printf ("previous_hash %x\n " , b .previousHash )
29
40
for _ , t := range b .transactions {
30
41
t .Print ()
31
42
}
@@ -38,69 +49,101 @@ func (b *Block) Hash() [32]byte {
38
49
39
50
func (b * Block ) MarshalJSON () ([]byte , error ) {
40
51
return json .Marshal (struct {
41
- Nonce int `json:"nonce"`
42
- PrevHash [32 ]byte `json:"prevHash"`
43
52
Timestamp int64 `json:"timestamp"`
53
+ Nonce int `json:"nonce"`
54
+ PreviousHash string `json:"previous_hash"`
44
55
Transactions []* Transaction `json:"transactions"`
45
56
}{
46
- Nonce : b .nonce ,
47
- PrevHash : b .prevHash ,
48
57
Timestamp : b .timestamp ,
58
+ Nonce : b .nonce ,
59
+ PreviousHash : fmt .Sprintf ("%x" , b .previousHash ),
49
60
Transactions : b .transactions ,
50
61
})
51
62
}
52
63
53
- func newBlock (nonce int , previousHash [32 ]byte , transactions []* Transaction ) * Block {
54
- b := new (Block )
55
- b .timestamp = time .Now ().UnixNano ()
56
- b .nonce = nonce
57
- b .prevHash = previousHash
58
- b .transactions = transactions
59
- return b
60
- }
61
-
62
64
type Blockchain struct {
63
65
transactionPool []* Transaction
64
66
chain []* Block
65
67
blockchainAddress string
68
+ port uint16
66
69
}
67
70
68
- func newBlockchain (blockchainAddress string ) * Blockchain {
71
+ func NewBlockchain (blockchainAddress string , port uint16 ) * Blockchain {
69
72
b := & Block {}
70
73
bc := new (Blockchain )
71
74
bc .blockchainAddress = blockchainAddress
72
- bc .createBlock (0 , b .Hash ())
75
+ bc .CreateBlock (0 , b .Hash ())
76
+ bc .port = port
73
77
return bc
74
78
}
75
79
76
- func (bc * Blockchain ) createBlock (nonce int , previousHash [32 ]byte ) * Block {
77
- b := newBlock (nonce , previousHash , bc .transactionPool )
80
+ func (bc * Blockchain ) MarshalJSON () ([]byte , error ) {
81
+ return json .Marshal (struct {
82
+ Blocks []* Block `json:"chains"`
83
+ }{
84
+ Blocks : bc .chain ,
85
+ })
86
+ }
87
+
88
+ func (bc * Blockchain ) CreateBlock (nonce int , previousHash [32 ]byte ) * Block {
89
+ b := NewBlock (nonce , previousHash , bc .transactionPool )
78
90
bc .chain = append (bc .chain , b )
79
91
bc .transactionPool = []* Transaction {}
80
92
return b
81
93
}
82
94
95
+ func (bc * Blockchain ) LastBlock () * Block {
96
+ return bc .chain [len (bc .chain )- 1 ]
97
+ }
98
+
83
99
func (bc * Blockchain ) Print () {
84
100
for i , block := range bc .chain {
85
- fmt .Printf ("%s Chain %d %s\n " , strings .Repeat ("=" , 25 ), i , strings .Repeat ("=" , 25 ))
101
+ fmt .Printf ("%s Chain %d %s\n " , strings .Repeat ("=" , 25 ), i ,
102
+ strings .Repeat ("=" , 25 ))
86
103
block .Print ()
87
104
}
88
105
fmt .Printf ("%s\n " , strings .Repeat ("*" , 25 ))
89
106
}
90
107
91
- func (bn * Blockchain ) LastBlock () * Block {
92
- return bn .chain [len (bn .chain )- 1 ]
108
+ func (bc * Blockchain ) AddTransaction (sender string , recipient string , value float32 ,
109
+ senderPublicKey * ecdsa.PublicKey , s * utils.Signature ) bool {
110
+ t := NewTransaction (sender , recipient , value )
111
+
112
+ if sender == MINING_SENDER {
113
+ bc .transactionPool = append (bc .transactionPool , t )
114
+ return true
115
+ }
116
+
117
+ if bc .VerifyTransactionSignature (senderPublicKey , s , t ) {
118
+ /*
119
+ if bc.CalculateTotalAmount(sender) < value {
120
+ log.Println("ERROR: Not enough balance in a wallet")
121
+ return false
122
+ }
123
+ */
124
+ bc .transactionPool = append (bc .transactionPool , t )
125
+ return true
126
+ } else {
127
+ log .Println ("ERROR: Verify Transaction" )
128
+ }
129
+ return false
130
+
93
131
}
94
132
95
- func (bc * Blockchain ) addTransaction (sender string , recipient string , value float32 ) {
96
- t := NewTransaction (sender , recipient , value )
97
- bc .transactionPool = append (bc .transactionPool , t )
133
+ func (bc * Blockchain ) VerifyTransactionSignature (
134
+ senderPublicKey * ecdsa.PublicKey , s * utils.Signature , t * Transaction ) bool {
135
+ m , _ := json .Marshal (t )
136
+ h := sha256 .Sum256 ([]byte (m ))
137
+ return ecdsa .Verify (senderPublicKey , h [:], s .R , s .S )
98
138
}
99
139
100
140
func (bc * Blockchain ) CopyTransactionPool () []* Transaction {
101
141
transactions := make ([]* Transaction , 0 )
102
142
for _ , t := range bc .transactionPool {
103
- transactions = append (transactions , NewTransaction (t .senderAddress , t .recipientAddress , t .value ))
143
+ transactions = append (transactions ,
144
+ NewTransaction (t .senderBlockchainAddress ,
145
+ t .recipientBlockchainAddress ,
146
+ t .value ))
104
147
}
105
148
return transactions
106
149
}
@@ -123,56 +166,71 @@ func (bc *Blockchain) ProofOfWork() int {
123
166
}
124
167
125
168
func (bc * Blockchain ) Mining () bool {
126
- bc .addTransaction (MINING_SENDER , bc .blockchainAddress , MINING_REWARD )
169
+ bc .AddTransaction (MINING_SENDER , bc .blockchainAddress , MINING_REWARD , nil , nil )
127
170
nonce := bc .ProofOfWork ()
128
171
previousHash := bc .LastBlock ().Hash ()
129
- bc .createBlock (nonce , previousHash )
172
+ bc .CreateBlock (nonce , previousHash )
130
173
log .Println ("action=mining, status=success" )
131
174
return true
132
175
}
133
176
134
- // User amount
135
177
func (bc * Blockchain ) CalculateTotalAmount (blockchainAddress string ) float32 {
136
- var totalValue float32 = 0.0
178
+ var totalAmount float32 = 0.0
137
179
for _ , b := range bc .chain {
138
180
for _ , t := range b .transactions {
139
181
value := t .value
140
- if blockchainAddress == t .recipientAddress {
141
- totalValue += value
182
+ if blockchainAddress == t .recipientBlockchainAddress {
183
+ totalAmount += value
142
184
}
143
- if blockchainAddress == t .senderAddress {
144
- totalValue -= value
185
+
186
+ if blockchainAddress == t .senderBlockchainAddress {
187
+ totalAmount -= value
145
188
}
146
189
}
147
190
}
148
- return totalValue
191
+ return totalAmount
149
192
}
150
193
151
194
type Transaction struct {
152
- senderAddress string
153
- recipientAddress string
154
- value float32
195
+ senderBlockchainAddress string
196
+ recipientBlockchainAddress string
197
+ value float32
155
198
}
156
199
157
200
func NewTransaction (sender string , recipient string , value float32 ) * Transaction {
158
- return & Transaction {senderAddress : sender , recipientAddress : recipient , value : value }
201
+ return & Transaction {sender , recipient , value }
159
202
}
160
203
161
204
func (t * Transaction ) Print () {
162
205
fmt .Printf ("%s\n " , strings .Repeat ("-" , 40 ))
163
- fmt .Printf (" sender_blockchain_address %s\n " , t .senderAddress )
164
- fmt .Printf (" recipient_blockchain_address %s\n " , t .recipientAddress )
165
- fmt .Printf (" transaction_value %.1f\n " , t .value )
206
+ fmt .Printf (" sender_blockchain_address %s\n " , t .senderBlockchainAddress )
207
+ fmt .Printf (" recipient_blockchain_address %s\n " , t .recipientBlockchainAddress )
208
+ fmt .Printf (" value %.1f\n " , t .value )
166
209
}
167
210
168
211
func (t * Transaction ) MarshalJSON () ([]byte , error ) {
169
212
return json .Marshal (struct {
170
- Sender string `json:"senderAddress "`
171
- Recipient string `json:"recipientAddress "`
213
+ Sender string `json:"sender_blockchain_address "`
214
+ Recipient string `json:"recipient_blockchain_address "`
172
215
Value float32 `json:"value"`
173
216
}{
174
- Sender : t .senderAddress ,
175
- Recipient : t .recipientAddress ,
217
+ Sender : t .senderBlockchainAddress ,
218
+ Recipient : t .recipientBlockchainAddress ,
176
219
Value : t .value ,
177
220
})
178
221
}
222
+
223
+ type TransactionRequest struct {
224
+ SenderBlockchainAddress * string `json:"sender_blockchain_address"`
225
+ RecipientBlockchainAddress * string `json:"recipient_blockchain_address"`
226
+ SenderPublicKey * string `json:"sender_public_key"`
227
+ Value * float32 `json:"value"`
228
+ Signature * string `json:"signature"`
229
+ }
230
+
231
+ func (tr * TransactionRequest ) Validate () bool {
232
+ if tr .SenderBlockchainAddress == nil || tr .RecipientBlockchainAddress == nil || tr .SenderPublicKey == nil || tr .Value == nil || tr .Signature == nil {
233
+ return false
234
+ }
235
+ return true
236
+ }
0 commit comments