github.com/Bytom/bytom@v1.1.2-0.20210127130405-ae40204c0b09/blockchain/txbuilder/actions.go (about) 1 package txbuilder 2 3 import ( 4 "context" 5 stdjson "encoding/json" 6 "errors" 7 8 "github.com/bytom/bytom/common" 9 "github.com/bytom/bytom/consensus" 10 "github.com/bytom/bytom/encoding/json" 11 "github.com/bytom/bytom/protocol/bc" 12 "github.com/bytom/bytom/protocol/bc/types" 13 "github.com/bytom/bytom/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 }