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"
15 "github.com/vapor/testutil"
18 // DecodeCrossInAction convert input data to action struct
19 func (r *Registry) DecodeCrossInAction(data []byte) (txbuilder.Action, error) {
20 a := &crossInAction{assets: r}
21 err := stdjson.Unmarshal(data, a)
25 type crossInAction struct {
28 SourceID string `json:"source_id"` // AnnotatedUTXO
29 SourcePos uint64 `json:"source_pos"`
30 Program json.HexBytes `json:"control_program"`
31 AssetDefinition map[string]interface{} `json:"asset_definition"`
32 UpdateAssetDef bool `json:"update_asset_definition"`
33 Arguments []txbuilder.ContractArgument `json:"arguments"`
36 // type AnnotatedInput struct {
37 // Type string `json:"type"`
38 // AssetID bc.AssetID `json:"asset_id"`
39 // AssetAlias string `json:"asset_alias,omitempty"`
40 // AssetDefinition *json.RawMessage `json:"asset_definition,omitempty"`
41 // Amount uint64 `json:"amount"`
42 // ControlProgram chainjson.HexBytes `json:"control_program,omitempty"`
43 // Address string `json:"address,omitempty"`
44 // SpentOutputID *bc.Hash `json:"spent_output_id,omitempty"`
45 // AccountID string `json:"account_id,omitempty"`
46 // AccountAlias string `json:"account_alias,omitempty"`
47 // Arbitrary chainjson.HexBytes `json:"arbitrary,omitempty"`
48 // InputID bc.Hash `json:"input_id"`
49 // WitnessArguments []chainjson.HexBytes `json:"witness_arguments"`
52 func (a *crossInAction) Build(ctx context.Context, builder *txbuilder.TemplateBuilder) error {
54 if len(a.Program) == 0 {
55 missing = append(missing, "control_program")
57 if a.AssetId.IsZero() {
58 missing = append(missing, "asset_id")
61 missing = append(missing, "amount")
64 return txbuilder.MissingFieldsError(missing...)
67 // Handle asset definition.
68 // Asset issuance's legality is guaranteed by the federation.
69 rawDefinition, err := SerializeAssetDef(a.AssetDefinition)
73 // TODO: may need to skip here
74 if !chainjson.IsValidJSON(rawDefinition) {
75 return errors.New("asset definition is not in valid json format")
77 if preAsset, _ := a.assets.GetAsset(a.AssetId.String()); preAsset != nil {
78 // GetAsset() doesn't unmashall for RawDefinitionBytes
79 preRawDefinition, err := SerializeAssetDef(preAsset.DefinitionMap)
84 if !testutil.DeepEqual(preRawDefinition, rawDefinition) && !a.UpdateAssetDef {
85 return errors.New("asset definition mismatch with previous definition")
87 // TODO: update asset def here?
90 // TODO: also need to hard-code mapTx
91 // TODO: save AssetDefinition
93 sourceID := testutil.MustDecodeHash(a.SourceID)
94 // input's arguments will be set when signing
96 // in := types.NewCrossChainInput(arguments [][]byte, sourceID bc.Hash, assetID bc.AssetID, amount, sourcePos uint64, controlProgram, assetDefinition []byte)
97 txin := types.NewCrossChainInput(nil, sourceID, *a.AssetId, a.Amount, a.SourcePos, a.Program, rawDefinition)
98 log.Info("cross-chain input action build")
99 builder.RestrictMinTime(time.Now())
100 return builder.AddInput(txin, &txbuilder.SigningInstruction{})
103 func (a *crossInAction) ActionType() string {
104 return "cross_chain_in"