-
Notifications
You must be signed in to change notification settings - Fork 16
/
transactionPayload.go
202 lines (163 loc) · 5.09 KB
/
transactionPayload.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
package aptos
import (
"errors"
"fmt"
"github.com/aptos-labs/aptos-go-sdk/bcs"
)
//region TransactionPayload
type TransactionPayloadVariant uint32
const (
TransactionPayloadVariantScript TransactionPayloadVariant = 0
TransactionPayloadVariantModuleBundle TransactionPayloadVariant = 1 // Deprecated
TransactionPayloadVariantEntryFunction TransactionPayloadVariant = 2
TransactionPayloadVariantMultisig TransactionPayloadVariant = 3
)
type TransactionPayloadImpl interface {
bcs.Struct
PayloadType() TransactionPayloadVariant // This is specifically to ensure that wrong types don't end up here
}
// TransactionPayload the actual instructions of which functions to call on chain
type TransactionPayload struct {
Payload TransactionPayloadImpl
}
//region TransactionPayload bcs.Struct
func (txn *TransactionPayload) MarshalBCS(ser *bcs.Serializer) {
if txn == nil || txn.Payload == nil {
ser.SetError(fmt.Errorf("nil transaction payload"))
return
}
ser.Uleb128(uint32(txn.Payload.PayloadType()))
txn.Payload.MarshalBCS(ser)
}
func (txn *TransactionPayload) UnmarshalBCS(des *bcs.Deserializer) {
payloadType := TransactionPayloadVariant(des.Uleb128())
switch payloadType {
case TransactionPayloadVariantScript:
txn.Payload = &Script{}
case TransactionPayloadVariantModuleBundle:
// Deprecated, should never be in production
des.SetError(fmt.Errorf("module bundle is not supported as a transaction payload"))
return
case TransactionPayloadVariantEntryFunction:
txn.Payload = &EntryFunction{}
case TransactionPayloadVariantMultisig:
txn.Payload = &Multisig{}
default:
des.SetError(fmt.Errorf("bad txn payload kind, %d", payloadType))
return
}
txn.Payload.UnmarshalBCS(des)
}
//endregion
//endregion
//region ModuleBundle
// ModuleBundle is long deprecated and no longer used, but exist as an enum position in TransactionPayload
type ModuleBundle struct{}
func (txn *ModuleBundle) PayloadType() TransactionPayloadVariant {
return TransactionPayloadVariantModuleBundle
}
func (txn *ModuleBundle) MarshalBCS(ser *bcs.Serializer) {
ser.SetError(errors.New("ModuleBundle unimplemented"))
}
func (txn *ModuleBundle) UnmarshalBCS(des *bcs.Deserializer) {
des.SetError(errors.New("ModuleBundle unimplemented"))
}
//endregion ModuleBundle
//region EntryFunction
// EntryFunction call a single published entry function arguments are ordered BCS encoded bytes
type EntryFunction struct {
Module ModuleId
Function string
ArgTypes []TypeTag
Args [][]byte
}
//region EntryFunction TransactionPayloadImpl
func (sf *EntryFunction) PayloadType() TransactionPayloadVariant {
return TransactionPayloadVariantEntryFunction
}
//endregion
//region EntryFunction bcs.Struct
func (sf *EntryFunction) MarshalBCS(ser *bcs.Serializer) {
sf.Module.MarshalBCS(ser)
ser.WriteString(sf.Function)
bcs.SerializeSequence(sf.ArgTypes, ser)
ser.Uleb128(uint32(len(sf.Args)))
for _, a := range sf.Args {
ser.WriteBytes(a)
}
}
func (sf *EntryFunction) UnmarshalBCS(des *bcs.Deserializer) {
sf.Module.UnmarshalBCS(des)
sf.Function = des.ReadString()
sf.ArgTypes = bcs.DeserializeSequence[TypeTag](des)
alen := des.Uleb128()
sf.Args = make([][]byte, alen)
for i := range alen {
sf.Args[i] = des.ReadBytes()
}
}
//endregion
//endregion
//region Multisig
// Multisig is an on-chain multisig transaction, that calls an entry function associated
type Multisig struct {
MultisigAddress AccountAddress
Payload *MultisigTransactionPayload // Optional
}
//region Multisig TransactionPayloadImpl
func (sf *Multisig) PayloadType() TransactionPayloadVariant {
return TransactionPayloadVariantMultisig
}
//endregion
//region Multisig bcs.Struct
func (sf *Multisig) MarshalBCS(ser *bcs.Serializer) {
ser.Struct(&sf.MultisigAddress)
if sf.Payload == nil {
ser.Bool(false)
} else {
ser.Bool(true)
ser.Struct(sf.Payload)
}
}
func (sf *Multisig) UnmarshalBCS(des *bcs.Deserializer) {
des.Struct(&sf.MultisigAddress)
if des.Bool() {
sf.Payload = &MultisigTransactionPayload{}
des.Struct(sf.Payload)
}
}
//endregion
//endregion
//region MultisigTransactionPayload
type MultisigTransactionPayloadVariant uint32
const (
MultisigTransactionPayloadVariantEntryFunction MultisigTransactionPayloadVariant = 0
)
type MultisigTransactionImpl interface {
bcs.Struct
}
// MultisigTransactionPayload is an enum allowing for multiple types of transactions to be called via multisig
//
// Note this does not implement TransactionPayloadImpl
type MultisigTransactionPayload struct {
Variant MultisigTransactionPayloadVariant
Payload MultisigTransactionImpl
}
//region MultisigTransactionPayload bcs.Struct
func (sf *MultisigTransactionPayload) MarshalBCS(ser *bcs.Serializer) {
ser.Uleb128(uint32(sf.Variant))
ser.Struct(sf.Payload)
}
func (sf *MultisigTransactionPayload) UnmarshalBCS(des *bcs.Deserializer) {
variant := MultisigTransactionPayloadVariant(des.Uleb128())
switch variant {
case MultisigTransactionPayloadVariantEntryFunction:
sf.Payload = &EntryFunction{}
default:
des.SetError(fmt.Errorf("bad variant %d for MultisigTransactionPayload", variant))
return
}
des.Struct(sf.Payload)
}
//endregion
//endregion