-
Notifications
You must be signed in to change notification settings - Fork 16
/
currency.go
125 lines (97 loc) · 2.93 KB
/
currency.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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/*
____ _ _ _____ _ _
/ __ \ | | | | | __ \ | | | |
| | | |_ __ ___| | ___ __| | __ _ ___ _ __ | |__) | __ ___ | |_ ___ ___ ___ | |
| | | | '_ \ / _ \ | / _ \/ _` |/ _` |/ _ \ '__| | ___/ '__/ _ \| __/ _ \ / __/ _ \| |
| |__| | | | | __/ |___| __/ (_| | (_| | __/ | | | | | | (_) | || (_) | (_| (_) | |
\____/|_| |_|\___|______\___|\__,_|\__, |\___|_| |_| |_| \___/ \__\___/ \___\___/|_|
__/ |
|___/
Copyright 2017 - 2019 OneLedger
*/
package balance
import (
"encoding/hex"
"encoding/json"
"github.com/Oneledger/protocol/utils"
"math"
"math/big"
"github.com/Oneledger/protocol/data/chain"
)
/*
Currency starts here
*/
type Currency struct {
Name string `json:"name"`
Chain chain.Type `json:"chain"`
Decimal int64 `json:"decimal"`
}
func (c Currency) Base() *big.Int {
return big.NewInt(0).Exp(big.NewInt(10), big.NewInt(c.Decimal), nil)
}
// Create a coin from integer (not fractional)
func (c Currency) NewCoinFromInt(amount int64) Coin {
return Coin{
Currency: c,
Amount: big.NewInt(0).Mul(big.NewInt(amount), c.Base()),
}
}
func (c Currency) StringKey() string {
return hex.EncodeToString(c.Bytes())
}
func (c Currency) Bytes() []byte {
dat, _ := json.Marshal(c)
return utils.Hash(dat)
}
// TODO
// Create a coin from float
func (c Currency) NewCoinFromFloat64(amount float64) Coin {
base := math.Pow10(int(c.Decimal))
amountBigFloat := new(big.Float)
amountBigFloat.SetFloat64(amount)
// Set precision if required.
// amountBigFloat.SetPrec(64)
baseFloat := new(big.Float)
baseFloat.SetFloat64(base)
amountBigFloat.Mul(amountBigFloat, baseFloat)
result := new(big.Int)
amountBigFloat.Int(result) // store converted number in result
return Coin{
Currency: c,
Amount: result,
}
}
// Create a coin from bytes, the bytes must come from Big.Int.
func (c Currency) NewCoinFromBytes(amount []byte) Coin {
return Coin{
Currency: c,
Amount: big.NewInt(0).SetBytes(amount),
}
}
type CurrencyList struct {
nameMap map[string]Currency
keyMap map[string]Currency
}
func NewCurrencyList() *CurrencyList {
return &CurrencyList{nameMap: make(map[string]Currency), keyMap: make(map[string]Currency)}
}
func (cl *CurrencyList) Register(c Currency) error {
_, ok := cl.nameMap[c.Name]
if ok { // If the currency is already registered, return a duplicate error
return ErrDuplicateCurrency
}
cl.nameMap[c.Name] = c
cl.keyMap[c.StringKey()] = c
return nil
}
func (cl *CurrencyList) GetCurrencyByName(name string) (Currency, bool) {
c, ok := cl.nameMap[name]
return c, ok
}
func (cl *CurrencyList) GetCurrencyByStringKey(key string) (Currency, bool) {
c, ok := cl.keyMap[key]
return c, ok
}
func (cl CurrencyList) Len() int {
return len(cl.nameMap)
}