-
Notifications
You must be signed in to change notification settings - Fork 77
/
policy.go
247 lines (210 loc) · 11.1 KB
/
policy.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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
/*
Package policy allows to work with the native PolicyContract contract via RPC.
Safe methods are encapsulated into ContractReader structure while Contract provides
various methods to perform PolicyContract state-changing calls.
*/
package policy
import (
"github.com/nspcc-dev/neo-go/pkg/core/native/nativehashes"
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
"github.com/nspcc-dev/neo-go/pkg/neorpc/result"
"github.com/nspcc-dev/neo-go/pkg/rpcclient/unwrap"
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
"github.com/nspcc-dev/neo-go/pkg/util"
)
// Invoker is used by ContractReader to call various methods.
type Invoker interface {
Call(contract util.Uint160, operation string, params ...any) (*result.Invoke, error)
}
// Actor is used by Contract to create and send transactions.
type Actor interface {
Invoker
MakeCall(contract util.Uint160, method string, params ...any) (*transaction.Transaction, error)
MakeRun(script []byte) (*transaction.Transaction, error)
MakeUnsignedCall(contract util.Uint160, method string, attrs []transaction.Attribute, params ...any) (*transaction.Transaction, error)
MakeUnsignedRun(script []byte, attrs []transaction.Attribute) (*transaction.Transaction, error)
SendCall(contract util.Uint160, method string, params ...any) (util.Uint256, uint32, error)
SendRun(script []byte) (util.Uint256, uint32, error)
}
// Hash stores the hash of the native PolicyContract contract.
var Hash = nativehashes.PolicyContract
const (
execFeeSetter = "setExecFeeFactor"
feePerByteSetter = "setFeePerByte"
storagePriceSetter = "setStoragePrice"
attributeFeeSetter = "setAttributeFee"
)
// ContractReader provides an interface to call read-only PolicyContract
// contract's methods.
type ContractReader struct {
invoker Invoker
}
// Contract represents a PolicyContract contract client that can be used to
// invoke all of its methods.
type Contract struct {
ContractReader
actor Actor
}
// NewReader creates an instance of ContractReader that can be used to read
// data from the contract.
func NewReader(invoker Invoker) *ContractReader {
return &ContractReader{invoker}
}
// New creates an instance of Contract to perform actions using
// the given Actor. Notice that PolicyContract's state can be changed
// only by the network's committee, so the Actor provided must be a committee
// actor for all methods to work properly.
func New(actor Actor) *Contract {
return &Contract{*NewReader(actor), actor}
}
// GetExecFeeFactor returns current execution fee factor used by the network.
// This setting affects all executions of all transactions.
func (c *ContractReader) GetExecFeeFactor() (int64, error) {
return unwrap.Int64(c.invoker.Call(Hash, "getExecFeeFactor"))
}
// GetFeePerByte returns current minimal per-byte network fee value which
// affects all transactions on the network.
func (c *ContractReader) GetFeePerByte() (int64, error) {
return unwrap.Int64(c.invoker.Call(Hash, "getFeePerByte"))
}
// GetStoragePrice returns current per-byte storage price. Any contract saving
// data to the storage pays for it according to this value.
func (c *ContractReader) GetStoragePrice() (int64, error) {
return unwrap.Int64(c.invoker.Call(Hash, "getStoragePrice"))
}
// GetAttributeFee returns current fee for the specified attribute usage. Any
// contract saving data to the storage pays for it according to this value.
func (c *ContractReader) GetAttributeFee(t transaction.AttrType) (int64, error) {
return unwrap.Int64(c.invoker.Call(Hash, "getAttributeFee", byte(t)))
}
// IsBlocked checks if the given account is blocked in the PolicyContract.
func (c *ContractReader) IsBlocked(account util.Uint160) (bool, error) {
return unwrap.Bool(c.invoker.Call(Hash, "isBlocked", account))
}
// SetExecFeeFactor creates and sends a transaction that sets the new
// execution fee factor for the network to use. The action is successful when
// transaction ends in HALT state. The returned values are transaction hash, its
// ValidUntilBlock value and an error if any.
func (c *Contract) SetExecFeeFactor(value int64) (util.Uint256, uint32, error) {
return c.actor.SendCall(Hash, execFeeSetter, value)
}
// SetExecFeeFactorTransaction creates a transaction that sets the new execution
// fee factor. This transaction is signed, but not sent to the network,
// instead it's returned to the caller.
func (c *Contract) SetExecFeeFactorTransaction(value int64) (*transaction.Transaction, error) {
return c.actor.MakeCall(Hash, execFeeSetter, value)
}
// SetExecFeeFactorUnsigned creates a transaction that sets the new execution
// fee factor. This transaction is not signed and just returned to the caller.
func (c *Contract) SetExecFeeFactorUnsigned(value int64) (*transaction.Transaction, error) {
return c.actor.MakeUnsignedCall(Hash, execFeeSetter, nil, value)
}
// SetFeePerByte creates and sends a transaction that sets the new minimal
// per-byte network fee value. The action is successful when transaction ends in
// HALT state. The returned values are transaction hash, its ValidUntilBlock
// value and an error if any.
func (c *Contract) SetFeePerByte(value int64) (util.Uint256, uint32, error) {
return c.actor.SendCall(Hash, feePerByteSetter, value)
}
// SetFeePerByteTransaction creates a transaction that sets the new minimal
// per-byte network fee value. This transaction is signed, but not sent to the
// network, instead it's returned to the caller.
func (c *Contract) SetFeePerByteTransaction(value int64) (*transaction.Transaction, error) {
return c.actor.MakeCall(Hash, feePerByteSetter, value)
}
// SetFeePerByteUnsigned creates a transaction that sets the new minimal per-byte
// network fee value. This transaction is not signed and just returned to the
// caller.
func (c *Contract) SetFeePerByteUnsigned(value int64) (*transaction.Transaction, error) {
return c.actor.MakeUnsignedCall(Hash, feePerByteSetter, nil, value)
}
// SetStoragePrice creates and sends a transaction that sets the storage price
// for contracts. The action is successful when transaction ends in HALT
// state. The returned values are transaction hash, its ValidUntilBlock value
// and an error if any.
func (c *Contract) SetStoragePrice(value int64) (util.Uint256, uint32, error) {
return c.actor.SendCall(Hash, storagePriceSetter, value)
}
// SetStoragePriceTransaction creates a transaction that sets the storage price
// for contracts. This transaction is signed, but not sent to the network,
// instead it's returned to the caller.
func (c *Contract) SetStoragePriceTransaction(value int64) (*transaction.Transaction, error) {
return c.actor.MakeCall(Hash, storagePriceSetter, value)
}
// SetStoragePriceUnsigned creates a transaction that sets the storage price
// for contracts. This transaction is not signed and just returned to the
// caller.
func (c *Contract) SetStoragePriceUnsigned(value int64) (*transaction.Transaction, error) {
return c.actor.MakeUnsignedCall(Hash, storagePriceSetter, nil, value)
}
// SetAttributeFee creates and sends a transaction that sets the new attribute
// fee value for the specified attribute. The action is successful when
// transaction ends in HALT state. The returned values are transaction hash, its
// ValidUntilBlock value and an error if any.
func (c *Contract) SetAttributeFee(t transaction.AttrType, value int64) (util.Uint256, uint32, error) {
return c.actor.SendCall(Hash, attributeFeeSetter, byte(t), value)
}
// SetAttributeFeeTransaction creates a transaction that sets the new attribute
// fee value for the specified attribute. This transaction is signed, but not
// sent to the network, instead it's returned to the caller.
func (c *Contract) SetAttributeFeeTransaction(t transaction.AttrType, value int64) (*transaction.Transaction, error) {
return c.actor.MakeCall(Hash, attributeFeeSetter, byte(t), value)
}
// SetAttributeFeeUnsigned creates a transaction that sets the new attribute fee
// value for the specified attribute. This transaction is not signed and just
// returned to the caller.
func (c *Contract) SetAttributeFeeUnsigned(t transaction.AttrType, value int64) (*transaction.Transaction, error) {
return c.actor.MakeUnsignedCall(Hash, attributeFeeSetter, nil, byte(t), value)
}
// BlockAccount creates and sends a transaction that blocks an account on the
// network (via `blockAccount` method), it fails (with FAULT state) if it's not
// successful. The returned values are transaction hash, its
// ValidUntilBlock value and an error if any.
func (c *Contract) BlockAccount(account util.Uint160) (util.Uint256, uint32, error) {
return c.actor.SendRun(blockScript(account))
}
// BlockAccountTransaction creates a transaction that blocks an account on the
// network and checks for the result of the appropriate call, failing the
// transaction if it's not true. This transaction is signed, but not sent to the
// network, instead it's returned to the caller.
func (c *Contract) BlockAccountTransaction(account util.Uint160) (*transaction.Transaction, error) {
return c.actor.MakeRun(blockScript(account))
}
// BlockAccountUnsigned creates a transaction that blocks an account on the
// network and checks for the result of the appropriate call, failing the
// transaction if it's not true. This transaction is not signed and just returned
// to the caller.
func (c *Contract) BlockAccountUnsigned(account util.Uint160) (*transaction.Transaction, error) {
return c.actor.MakeUnsignedRun(blockScript(account), nil)
}
func blockScript(account util.Uint160) []byte {
// We know parameters exactly (unlike with nep17.Transfer), so this can't fail.
script, _ := smartcontract.CreateCallWithAssertScript(Hash, "blockAccount", account)
return script
}
// UnblockAccount creates and sends a transaction that removes previously blocked
// account from the stop list. It uses `unblockAccount` method and checks for the
// result returned, failing the transaction if it's not true. The returned values
// are transaction hash, its ValidUntilBlock value and an error if any.
func (c *Contract) UnblockAccount(account util.Uint160) (util.Uint256, uint32, error) {
return c.actor.SendRun(unblockScript(account))
}
// UnblockAccountTransaction creates a transaction that unblocks previously
// blocked account via `unblockAccount` method and checks for the result returned,
// failing the transaction if it's not true. This transaction is signed, but not
// sent to the network, instead it's returned to the caller.
func (c *Contract) UnblockAccountTransaction(account util.Uint160) (*transaction.Transaction, error) {
return c.actor.MakeRun(unblockScript(account))
}
// UnblockAccountUnsigned creates a transaction that unblocks the given account
// if it was blocked previously. It uses `unblockAccount` method and checks for
// its return value, failing the transaction if it's not true. This transaction
// is not signed and just returned to the caller.
func (c *Contract) UnblockAccountUnsigned(account util.Uint160) (*transaction.Transaction, error) {
return c.actor.MakeUnsignedRun(unblockScript(account), nil)
}
func unblockScript(account util.Uint160) []byte {
// We know parameters exactly (unlike with nep17.Transfer), so this can't fail.
script, _ := smartcontract.CreateCallWithAssertScript(Hash, "unblockAccount", account)
return script
}