OSDN Git Service

Hulk did something
[bytom/vapor.git] / blockchain / txbuilder / actions.go
1 package txbuilder
2
3 import (
4         "context"
5         stdjson "encoding/json"
6         "errors"
7
8         "github.com/vapor/common"
9         "github.com/vapor/consensus"
10         "github.com/vapor/encoding/json"
11         "github.com/vapor/protocol/bc"
12         "github.com/vapor/protocol/bc/types"
13         "github.com/vapor/protocol/vm/vmutil"
14 )
15
16 // DecodeControlAddressAction convert input data to action struct
17 func DecodeControlAddressAction(data []byte) (Action, error) {
18         a := new(controlAddressAction)
19         err := stdjson.Unmarshal(data, a)
20         return a, err
21 }
22
23 type controlAddressAction struct {
24         bc.AssetAmount
25         Address string `json:"address"`
26 }
27
28 func (a *controlAddressAction) Build(ctx context.Context, b *TemplateBuilder) error {
29         var missing []string
30         if a.Address == "" {
31                 missing = append(missing, "address")
32         }
33         if a.AssetId.IsZero() {
34                 missing = append(missing, "asset_id")
35         }
36         if a.Amount == 0 {
37                 missing = append(missing, "amount")
38         }
39         if len(missing) > 0 {
40                 return MissingFieldsError(missing...)
41         }
42
43         address, err := common.DecodeAddress(a.Address, &consensus.ActiveNetParams)
44         if err != nil {
45                 return err
46         }
47         redeemContract := address.ScriptAddress()
48         program := []byte{}
49
50         switch address.(type) {
51         case *common.AddressWitnessPubKeyHash:
52                 program, err = vmutil.P2WPKHProgram(redeemContract)
53         case *common.AddressWitnessScriptHash:
54                 program, err = vmutil.P2WSHProgram(redeemContract)
55         default:
56                 return errors.New("unsupport address type")
57         }
58         if err != nil {
59                 return err
60         }
61
62         out := types.NewTxOutput(*a.AssetId, a.Amount, program)
63         return b.AddOutput(out)
64 }
65
66 func (a *controlAddressAction) ActionType() string {
67         return "control_address"
68 }
69
70 // DecodeControlProgramAction convert input data to action struct
71 func DecodeControlProgramAction(data []byte) (Action, error) {
72         a := new(controlProgramAction)
73         err := stdjson.Unmarshal(data, a)
74         return a, err
75 }
76
77 type controlProgramAction struct {
78         bc.AssetAmount
79         Program json.HexBytes `json:"control_program"`
80 }
81
82 func (a *controlProgramAction) Build(ctx context.Context, b *TemplateBuilder) error {
83         var missing []string
84         if len(a.Program) == 0 {
85                 missing = append(missing, "control_program")
86         }
87         if a.AssetId.IsZero() {
88                 missing = append(missing, "asset_id")
89         }
90         if a.Amount == 0 {
91                 missing = append(missing, "amount")
92         }
93         if len(missing) > 0 {
94                 return MissingFieldsError(missing...)
95         }
96
97         out := types.NewTxOutput(*a.AssetId, a.Amount, a.Program)
98         return b.AddOutput(out)
99 }
100
101 func (a *controlProgramAction) ActionType() string {
102         return "control_program"
103 }
104
105 // DecodeRetireAction convert input data to action struct
106 func DecodeRetireAction(data []byte) (Action, error) {
107         a := new(retireAction)
108         err := stdjson.Unmarshal(data, a)
109         return a, err
110 }
111
112 type retireAction struct {
113         bc.AssetAmount
114         Arbitrary json.HexBytes `json:"arbitrary"`
115 }
116
117 func (a *retireAction) Build(ctx context.Context, b *TemplateBuilder) error {
118         var missing []string
119         if a.AssetId.IsZero() {
120                 missing = append(missing, "asset_id")
121         }
122         if a.Amount == 0 {
123                 missing = append(missing, "amount")
124         }
125         if len(missing) > 0 {
126                 return MissingFieldsError(missing...)
127         }
128
129         program, err := vmutil.RetireProgram(a.Arbitrary)
130         if err != nil {
131                 return err
132         }
133         out := types.NewTxOutput(*a.AssetId, a.Amount, program)
134         return b.AddOutput(out)
135 }
136
137 func (a *retireAction) ActionType() string {
138         return "retire"
139 }