5 stdjson "encoding/json"
8 "github.com/vapor/config"
10 "github.com/vapor/common"
11 "github.com/vapor/consensus"
12 "github.com/vapor/encoding/json"
13 "github.com/vapor/protocol/bc"
14 "github.com/vapor/protocol/bc/types"
15 "github.com/vapor/protocol/vm/vmutil"
18 // DecodeControlAddressAction convert input data to action struct
19 func DecodeControlAddressAction(data []byte) (Action, error) {
20 a := new(controlAddressAction)
21 err := stdjson.Unmarshal(data, a)
25 type controlAddressAction struct {
27 Address string `json:"address"`
30 func (a *controlAddressAction) Build(ctx context.Context, b *TemplateBuilder) error {
33 missing = append(missing, "address")
35 if a.AssetId.IsZero() {
36 missing = append(missing, "asset_id")
39 missing = append(missing, "amount")
42 return MissingFieldsError(missing...)
45 address, err := common.DecodeAddress(a.Address, &consensus.ActiveNetParams)
50 redeemContract := address.ScriptAddress()
52 switch address.(type) {
53 case *common.AddressWitnessPubKeyHash:
54 program, err = vmutil.P2WPKHProgram(redeemContract)
55 case *common.AddressWitnessScriptHash:
56 program, err = vmutil.P2WSHProgram(redeemContract)
58 return errors.New("unsupport address type")
64 out := types.NewIntraChainOutput(*a.AssetId, a.Amount, program)
65 return b.AddOutput(out)
68 func (a *controlAddressAction) ActionType() string {
69 return "control_address"
72 // DecodeControlProgramAction convert input data to action struct
73 func DecodeControlProgramAction(data []byte) (Action, error) {
74 a := new(controlProgramAction)
75 err := stdjson.Unmarshal(data, a)
79 type controlProgramAction struct {
81 Program json.HexBytes `json:"control_program"`
84 func (a *controlProgramAction) Build(ctx context.Context, b *TemplateBuilder) error {
86 if len(a.Program) == 0 {
87 missing = append(missing, "control_program")
89 if a.AssetId.IsZero() {
90 missing = append(missing, "asset_id")
93 missing = append(missing, "amount")
96 return MissingFieldsError(missing...)
99 out := types.NewIntraChainOutput(*a.AssetId, a.Amount, a.Program)
100 return b.AddOutput(out)
103 func (a *controlProgramAction) ActionType() string {
104 return "control_program"
107 // DecodeRetireAction convert input data to action struct
108 func DecodeRetireAction(data []byte) (Action, error) {
109 a := new(retireAction)
110 err := stdjson.Unmarshal(data, a)
114 type retireAction struct {
116 Arbitrary json.HexBytes `json:"arbitrary"`
119 func (a *retireAction) Build(ctx context.Context, b *TemplateBuilder) error {
121 if a.AssetId.IsZero() {
122 missing = append(missing, "asset_id")
125 missing = append(missing, "amount")
127 if len(missing) > 0 {
128 return MissingFieldsError(missing...)
131 program, err := vmutil.RetireProgram(a.Arbitrary)
135 out := types.NewIntraChainOutput(*a.AssetId, a.Amount, program)
136 return b.AddOutput(out)
139 func (a *retireAction) ActionType() string {
143 // DecodeCrossOutAction convert input data to action struct
144 func DecodeCrossOutAction(data []byte) (Action, error) {
145 a := new(crossOutAction)
146 err := stdjson.Unmarshal(data, a)
150 type crossOutAction struct {
152 Address string `json:"address"`
155 func (a *crossOutAction) Build(ctx context.Context, b *TemplateBuilder) error {
158 missing = append(missing, "address")
160 if a.AssetId.IsZero() {
161 missing = append(missing, "asset_id")
164 missing = append(missing, "amount")
166 if len(missing) > 0 {
167 return MissingFieldsError(missing...)
170 address, err := common.DecodeAddress(a.Address, &consensus.MainNetParams)
175 redeemContract := address.ScriptAddress()
177 switch address.(type) {
178 case *common.AddressWitnessPubKeyHash:
179 program, err = vmutil.P2WPKHProgram(redeemContract)
180 case *common.AddressWitnessScriptHash:
181 program, err = vmutil.P2WSHProgram(redeemContract)
183 return errors.New("unsupport address type")
189 out := types.NewCrossChainOutput(*a.AssetId, a.Amount, program)
190 return b.AddOutput(out)
193 func (a *crossOutAction) ActionType() string {
194 return "cross_chain_out"
197 // DecodeVoteOutputAction convert input data to action struct
198 func DecodeVoteOutputAction(data []byte) (Action, error) {
199 a := new(voteOutputAction)
200 err := stdjson.Unmarshal(data, a)
204 type voteOutputAction struct {
206 Address string `json:"address"`
207 Vote json.HexBytes `json:"vote"`
210 func (a *voteOutputAction) Build(ctx context.Context, b *TemplateBuilder) error {
213 missing = append(missing, "address")
215 if a.AssetId.IsZero() {
216 missing = append(missing, "asset_id")
219 missing = append(missing, "amount")
221 if len(a.Vote) == 0 {
222 missing = append(missing, "vote")
224 if len(missing) > 0 {
225 return MissingFieldsError(missing...)
228 address, err := common.DecodeAddress(a.Address, &consensus.ActiveNetParams)
233 redeemContract := address.ScriptAddress()
235 switch address.(type) {
236 case *common.AddressWitnessPubKeyHash:
237 program, err = vmutil.P2WPKHProgram(redeemContract)
238 case *common.AddressWitnessScriptHash:
239 program, err = vmutil.P2WSHProgram(redeemContract)
241 return errors.New("unsupport address type")
247 out := types.NewVoteOutput(*a.AssetId, a.Amount, program, a.Vote)
248 return b.AddOutput(out)
251 func (a *voteOutputAction) ActionType() string {
255 // DecodeCrossInAction convert input data to action struct
256 func DecodeCrossInAction(data []byte) (Action, error) {
257 a := new(crossInAction)
258 err := stdjson.Unmarshal(data, a)
262 type crossInAction struct {
264 SourceID bc.Hash `json:"source_id"`
265 SourcePos uint64 `json:"source_pos"`
266 bc.CrossChainAssetDefinition
269 func (a *crossInAction) Build(ctx context.Context, builder *TemplateBuilder) error {
271 if a.SourceID.IsZero() {
272 missing = append(missing, "source_id")
274 if a.AssetId.IsZero() {
275 missing = append(missing, "asset_id")
278 missing = append(missing, "amount")
280 if len(missing) > 0 {
281 return MissingFieldsError(missing...)
284 if err := a.checkAssetID(); err != nil {
288 // arguments will be set when materializeWitnesses
289 fedProg := config.FederationProgrom(config.CommonConfig)
290 txin := types.NewCrossChainInput(nil, a.SourceID, *a.AssetId, a.Amount, a.SourcePos, fedProg, a.CrossChainAssetDefinition)
291 tplIn := &SigningInstruction{}
292 fed := config.CommonConfig.Federation
293 tplIn.AddRawWitnessKeys(fed.Xpubs, nil, fed.Quorum)
294 return builder.AddInput(txin, tplIn)
297 func (a *crossInAction) ActionType() string {
298 return "cross_chain_in"
301 func (c *crossInAction) checkAssetID() error {
302 if *c.AssetId == *consensus.BTMAssetID {
306 assetID := c.CrossChainAssetDefinition.ComputeAssetID()
308 if assetID != *c.AssetAmount.AssetId {
309 return errors.New("incorrect asset_idincorrect asset_id")