5 stdjson "encoding/json"
12 "github.com/vapor/config"
14 ipfs "github.com/ipfs/go-ipfs-api"
15 "github.com/vapor/common"
16 "github.com/vapor/consensus"
17 "github.com/vapor/encoding/json"
18 "github.com/vapor/protocol/bc"
19 "github.com/vapor/protocol/bc/types"
20 "github.com/vapor/protocol/vm/vmutil"
23 // DecodeControlAddressAction convert input data to action struct
24 func DecodeControlAddressAction(data []byte) (Action, error) {
25 a := new(controlAddressAction)
26 err := stdjson.Unmarshal(data, a)
30 type controlAddressAction struct {
32 Address string `json:"address"`
35 func (a *controlAddressAction) Build(ctx context.Context, b *TemplateBuilder) error {
38 missing = append(missing, "address")
40 if a.AssetId.IsZero() {
41 missing = append(missing, "asset_id")
44 missing = append(missing, "amount")
47 return MissingFieldsError(missing...)
50 address, err := common.DecodeAddress(a.Address, &consensus.ActiveNetParams)
54 redeemContract := address.ScriptAddress()
57 switch address.(type) {
58 case *common.AddressWitnessPubKeyHash:
59 program, err = vmutil.P2WPKHProgram(redeemContract)
60 case *common.AddressWitnessScriptHash:
61 program, err = vmutil.P2WSHProgram(redeemContract)
63 return errors.New("unsupport address type")
69 out := types.NewTxOutput(*a.AssetId, a.Amount, program)
70 return b.AddOutput(out)
73 func (a *controlAddressAction) ActionType() string {
74 return "control_address"
77 // DecodeControlProgramAction convert input data to action struct
78 func DecodeControlProgramAction(data []byte) (Action, error) {
79 a := new(controlProgramAction)
80 err := stdjson.Unmarshal(data, a)
84 type controlProgramAction struct {
86 Program json.HexBytes `json:"control_program"`
89 func (a *controlProgramAction) Build(ctx context.Context, b *TemplateBuilder) error {
91 if len(a.Program) == 0 {
92 missing = append(missing, "control_program")
94 if a.AssetId.IsZero() {
95 missing = append(missing, "asset_id")
98 missing = append(missing, "amount")
100 if len(missing) > 0 {
101 return MissingFieldsError(missing...)
104 out := types.NewTxOutput(*a.AssetId, a.Amount, a.Program)
105 return b.AddOutput(out)
108 func (a *controlProgramAction) ActionType() string {
109 return "control_program"
112 // DecodeRetireAction convert input data to action struct
113 func DecodeRetireAction(data []byte) (Action, error) {
114 a := new(retireAction)
115 err := stdjson.Unmarshal(data, a)
119 type retireAction struct {
121 Arbitrary json.HexBytes `json:"arbitrary"`
124 func (a *retireAction) Build(ctx context.Context, b *TemplateBuilder) error {
126 if a.AssetId.IsZero() {
127 missing = append(missing, "asset_id")
130 missing = append(missing, "amount")
132 if len(missing) > 0 {
133 return MissingFieldsError(missing...)
136 program, err := vmutil.RetireProgram(a.Arbitrary)
140 out := types.NewTxOutput(*a.AssetId, a.Amount, program)
141 return b.AddOutput(out)
144 func (a *retireAction) ActionType() string {
153 // DecodeIpfsDataAction convert input data to action struct
154 func DecodeIpfsDataAction(data []byte) (Action, error) {
156 err := stdjson.Unmarshal(data, a)
160 type dataAction struct {
162 Type uint32 `json:"data_type"`
163 Data string `json:"data"`
166 func (a *dataAction) Build(ctx context.Context, b *TemplateBuilder) error {
171 fi, err := os.Stat(a.Data)
172 if os.IsNotExist(err) {
176 return fmt.Errorf("data [%s] is directory", a.Data)
178 r, err = os.Open(a.Data)
184 return errors.New("data is empty")
186 r = strings.NewReader(a.Data)
190 sh := ipfs.NewShell(config.CommonConfig.IpfsAddress)
191 cid, err := sh.Add(r)
196 program, err := vmutil.RetireProgram([]byte(cid))
200 out := types.NewTxOutput(*a.AssetId, 0, program)
201 return b.AddOutput(out)
204 func (a *dataAction) ActionType() string {