/
issue.go
104 lines (94 loc) · 2.44 KB
/
issue.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
package tx
import (
"bytes"
"encoding/json"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/crypto"
"github.com/amolabs/amoabci/amo/code"
"github.com/amolabs/amoabci/amo/store"
"github.com/amolabs/amoabci/amo/types"
)
type IssueParam struct {
UDC uint32 `json:"udc"` // required
Desc string `json:"desc"` // optional
Operators []crypto.Address `json:"operators"` // optional
Amount types.Currency `json:"amount"` // required
}
func parseIssueParam(raw []byte) (IssueParam, error) {
var param IssueParam
err := json.Unmarshal(raw, ¶m)
if err != nil {
return param, err
}
return param, nil
}
type TxIssue struct {
TxBase
Param IssueParam `json:"-"`
}
func (t *TxIssue) Check() (uint32, string) {
param := t.Param
for _, op := range param.Operators {
if len(op) != crypto.AddressSize {
return code.TxCodeBadParam, "wrong size of operator address"
}
if bytes.Equal(t.GetSender(), op) {
return code.TxCodeSelfTransaction,
"operator is same as the issuer"
}
}
return code.TxCodeOK, "ok"
}
func (t *TxIssue) Execute(s *store.Store) (uint32, string, []abci.Event) {
param := t.Param
sender := t.GetSender()
if param.Amount.LessThan(zero) {
return code.TxCodeInvalidAmount, "invalid amount", nil
}
udc := s.GetUDC(param.UDC, false)
if udc == nil {
stakes := s.GetTopStakes(ConfigAMOApp.MaxValidators, sender, false)
if len(stakes) == 0 {
return code.TxCodePermissionDenied, "permission denied", nil
}
udc = &types.UDC{
Owner: sender,
Operators: param.Operators,
Desc: param.Desc,
Total: param.Amount,
}
} else {
if bytes.Equal(sender, udc.Owner) == false {
match := false
for _, op := range udc.Operators {
if bytes.Equal(sender, op) {
match = true
break
}
}
if match == false {
return code.TxCodePermissionDenied, "permission denied", nil
}
}
// update fields
udc.Operators = param.Operators
udc.Desc = param.Desc
udc.Total.Add(¶m.Amount)
}
// update UDC balance
bal := s.GetUDCBalance(param.UDC, sender, false)
if bal == nil {
bal = new(types.Currency)
}
after := bal.Add(¶m.Amount)
err := s.SetUDCBalance(param.UDC, sender, after)
if err != nil {
return code.TxCodeUnknown, err.Error(), nil
}
// store UDC registry
err = s.SetUDC(param.UDC, udc)
if err != nil {
return code.TxCodeUnknown, err.Error(), nil
}
return code.TxCodeOK, "ok", nil
}