-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwallet.go
111 lines (86 loc) · 2.17 KB
/
wallet.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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
package capusta
import (
"sync"
)
type Wallet struct {
owner string
blockchain *blockchain
transactions map[[32]byte]float64
lock sync.Mutex
}
func (w *Wallet) UnlockInput(ti TInput) bool {
return ti.from == w.owner
}
func (w *Wallet) UnlockOutput(to TOutput) bool {
return to.to == w.owner
}
func (w *Wallet) GetBalance() float64 {
allMoney := 0.0
w.RefreshTransactions() // this need to refactor
w.lock.Lock()
defer w.lock.Unlock()
for _, money := range w.transactions {
allMoney += money
}
return allMoney
}
func (w *Wallet) TransferMoney(to *Wallet, amount float64) (string, error) {
w.RefreshTransactions() // this need to refactor
w.lock.Lock()
defer w.lock.Unlock()
transfered := 0.00
inputs := []TInput{}
outputs := []TOutput{}
for id, money := range w.transactions {
inputs = append(inputs, TInput{id, money, w.owner})
transfered += money
}
if transfered < amount {
return "", ErrorNotEnoghtMoney
}
outputs = append(outputs, TOutput{value: amount, to: to.owner})
change := transfered - amount
if change != 0.0 {
outputs = append(outputs, TOutput{value: change, to: w.owner})
}
transaction := NewTransaction(inputs, outputs)
w.blockchain.transactions = append(w.blockchain.transactions, transaction)
return transaction.getID(), nil
}
func (w *Wallet) CheckTransactionOwner(t Transaction) (bool, float64, bool) {
var owner bool = false
var money float64 = 0
var haveInput bool = false
for _, out := range t.outputs {
if w.UnlockOutput(out) {
owner = true
money += out.value
}
}
for _, in := range t.inputs {
if w.UnlockInput(in) {
owner = true
haveInput = true
}
}
return owner, money, haveInput
}
func (w *Wallet) RefreshTransactions() {
w.lock.Lock()
defer w.lock.Unlock()
w.transactions = map[[32]byte]float64{}
for curBlock := range w.blockchain.Iterator() {
for _, tr := range curBlock.GetTransactions() {
owner, money, used := w.CheckTransactionOwner(tr)
if owner == false {
continue
}
if money > 0 {
w.transactions[tr.hash] = w.transactions[tr.hash] + money
}
if _, ok := w.transactions[tr.hash]; ok && used {
delete(w.transactions, tr.hash)
}
}
}
}