5 stdjson "encoding/json"
8 log "github.com/sirupsen/logrus"
10 "github.com/vapor/blockchain/txbuilder"
11 chainjson "github.com/vapor/encoding/json"
12 "github.com/vapor/errors"
13 "github.com/vapor/protocol/bc"
14 "github.com/vapor/protocol/bc/types"
17 // DecodeCrossInAction convert input data to action struct
18 func (r *Registry) DecodeCrossInAction(data []byte) (txbuilder.Action, error) {
19 a := &crossInAction{reg: r}
20 err := stdjson.Unmarshal(data, a)
24 type crossInAction struct {
27 SourceID string `json:"source_id"` // AnnotatedUTXO
28 SourcePos uint64 `json:"source_pos"`
29 Program chainjson.HexBytes `json:"control_program"`
30 AssetDefinition map[string]interface{} `json:"asset_definition"`
31 Arguments []chainjson.HexBytes `json:"arguments"`
34 // TODO: also need to hard-code mapTx
35 // TODO: iter cross-in and save asset, saveExternalAssetDefinition
36 // TODO: federation can sign? check arguments length?
37 func (a *crossInAction) Build(ctx context.Context, builder *txbuilder.TemplateBuilder) error {
39 if len(a.Program) == 0 {
40 missing = append(missing, "control_program")
43 missing = append(missing, "source_id")
45 if a.AssetId.IsZero() {
46 missing = append(missing, "asset_id")
49 missing = append(missing, "amount")
52 return txbuilder.MissingFieldsError(missing...)
57 if preAsset, _ := a.reg.GetAsset(a.AssetId.String()); preAsset != nil {
60 asset.RawDefinitionByte, err = serializeAssetDef(a.AssetDefinition)
65 if !chainjson.IsValidJSON(asset.RawDefinitionByte) {
66 return errors.New("asset definition is not in valid json format")
69 asset.DefinitionMap = a.AssetDefinition
71 // TODO: asset.IssuanceProgram
72 asset.AssetID = *a.AssetId
73 extAlias := a.AssetId.String()
74 asset.Alias = &(extAlias)
75 a.reg.SaveAsset(asset, extAlias)
78 arguments := [][]byte{}
79 for _, argument := range a.Arguments {
80 arguments = append(arguments, argument)
84 if err := sourceID.UnmarshalText([]byte(a.SourceID)); err != nil {
85 return errors.New("invalid sourceID format")
88 txin := types.NewCrossChainInput(arguments, sourceID, *a.AssetId, a.Amount, a.SourcePos, a.Program, asset.RawDefinitionByte)
89 log.Info("cross-chain input action built")
90 builder.RestrictMinTime(time.Now())
91 return builder.AddInput(txin, &txbuilder.SigningInstruction{})
94 func (a *crossInAction) ActionType() string {
95 return "cross_chain_in"