-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathdestroy.go
141 lines (119 loc) · 3.69 KB
/
destroy.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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
package qlcchain
import (
"errors"
"fmt"
"math/big"
rpc "github.com/qlcchain/jsonrpc2"
"github.com/qlcchain/qlc-go-sdk/pkg/ed25519"
"github.com/qlcchain/qlc-go-sdk/pkg/types"
)
type DestroyApi struct {
client *QLCClient
}
// NewDestroyAPI creates destroy module for client
func NewDestroyAPI(c *QLCClient) *DestroyApi {
return &DestroyApi{client: c}
}
type APIDestroyParam struct {
Owner types.Address `json:"owner"`
Previous types.Hash `json:"previous"`
Token types.Hash `json:"token"`
Amount *big.Int `json:"amount"`
Sign types.Signature `json:"signature"`
}
type APIDestroyInfo struct {
Owner types.Address `json:"owner"`
Previous types.Hash `json:"previous"`
Token types.Hash `json:"token"`
Amount *big.Int `json:"amount"`
TimeStamp int64 `json:"timestamp"`
}
func (param *APIDestroyParam) Signature(acc *types.Account) (types.Signature, error) {
if acc.Address() == param.Owner {
var data []byte
data = append(data, param.Owner[:]...)
data = append(data, param.Previous[:]...)
data = append(data, param.Token[:]...)
data = append(data, param.Amount.Bytes()...)
var sig types.Signature
copy(sig[:], ed25519.Sign(acc.PrivateKey(), data))
return sig, nil
} else {
return types.ZeroSignature, fmt.Errorf("invalid address, exp: %s, act: %s",
param.Owner.String(), acc.Address().String())
}
}
// Verify destroy params
func (param *APIDestroyParam) Verify(c *rpc.Client) (bool, error) {
if param.Owner.IsZero() {
return false, errors.New("invalid account")
}
if param.Previous.IsZero() {
return false, errors.New("invalid previous")
}
var gasToken types.Hash
err := c.Call(&gasToken, "ledger_gasToken")
if err != nil {
return false, err
}
if param.Token != gasToken {
return false, errors.New("invalid token to be destroyed")
}
if param.Amount == nil || param.Amount.Sign() <= 0 {
return false, errors.New("invalid amount")
}
var data []byte
data = append(data, param.Owner[:]...)
data = append(data, param.Previous[:]...)
data = append(data, param.Token[:]...)
data = append(data, param.Amount.Bytes()...)
return param.Owner.Verify(data, param.Sign[:]), nil
}
type SignatureParam func() (types.Signature, error)
// GetSendBlock returns destory contract send block by destory parameters
func (b *DestroyApi) GetSendBlock(param *APIDestroyParam, sign SignatureParam) (*types.StateBlock, error) {
signature, err := sign()
if err != nil {
return nil, err
}
param.Sign = signature
if b, err := param.Verify(b.client.getClient()); err != nil {
return nil, err
} else if !b {
return nil, errors.New("invalid sign")
}
param.Sign = signature
var r types.StateBlock
err = b.client.getClient().Call(&r, "destroy_getSendBlock", param)
if err != nil {
return nil, err
}
return &r, nil
}
// GetRewardBlock returns contract reward block by destory contract send
func (b *DestroyApi) GetRewardsBlock(send *types.Hash) (*types.StateBlock, error) {
var r types.StateBlock
err := b.client.getClient().Call(&r, "destroy_getRewardsBlock", send)
if err != nil {
return nil, err
}
return &r, nil
}
// GetTotalDestroyInfo returns total amount of qgas destroyed
func (b *DestroyApi) GetTotalDestroyInfo(addr *types.Address) (types.Balance, error) {
var r types.Balance
err := b.client.getClient().Call(&r, "destroy_getTotalDestroyInfo", addr)
if err != nil {
return types.ZeroBalance, err
}
return r, nil
}
// GetDestroyInfoDetail returns detail info of qgas destroyed
func (b *DestroyApi) GetDestroyInfoDetail(addr *types.Address) ([]*APIDestroyInfo, error) {
var r []*APIDestroyInfo
err := b.client.getClient().Call(&r, "destroy_getDestroyInfoDetail", addr)
if err != nil {
return nil, err
}
return r, nil
}