OSDN Git Service

update
[bytom/vapor.git] / asset / builder.go
1 package asset
2
3 import (
4         "context"
5         stdjson "encoding/json"
6
7         log "github.com/sirupsen/logrus"
8
9         "github.com/vapor/blockchain/txbuilder"
10         "github.com/vapor/consensus/federation"
11         "github.com/vapor/protocol/bc"
12         "github.com/vapor/protocol/bc/types"
13 )
14
15 // DecodeCrossInAction convert input data to action struct
16 func (r *Registry) DecodeCrossInAction(data []byte) (txbuilder.Action, error) {
17         a := &crossInAction{reg: r}
18         err := stdjson.Unmarshal(data, a)
19         return a, err
20 }
21
22 type crossInAction struct {
23         reg *Registry
24         bc.AssetAmount
25         SourceID        bc.Hash                      `json:"source_id"`
26         SourcePos       uint64                       `json:"source_pos"`
27         AssetDefinition map[string]interface{}       `json:"asset_definition"`
28         Arguments       []txbuilder.ContractArgument `json:"arguments"`
29 }
30
31 // TODO: filter double spent utxo in txpool?
32 // TODO: roll back unconfirmed or orphan?
33 func (a *crossInAction) Build(ctx context.Context, builder *txbuilder.TemplateBuilder) error {
34         var missing []string
35         if a.SourceID.IsZero() {
36                 missing = append(missing, "source_id")
37         }
38         if a.AssetId.IsZero() {
39                 missing = append(missing, "asset_id")
40         }
41         if a.Amount == 0 {
42                 missing = append(missing, "amount")
43         }
44         if len(missing) > 0 {
45                 return txbuilder.MissingFieldsError(missing...)
46         }
47
48         rawDefinitionByte, err := serializeAssetDef(a.AssetDefinition)
49         if err != nil {
50                 return ErrSerializing
51         }
52
53         // 1. arguments will be set when materializeWitnesses
54         // 2. need to fill in issuance program & here, and will need to deal with
55         // customized arguments
56         txin := types.NewCrossChainInput(nil, a.SourceID, *a.AssetId, a.Amount, a.SourcePos, nil, rawDefinitionByte)
57         log.Info("cross-chain input action built")
58         tplIn := &txbuilder.SigningInstruction{}
59         fed := federation.GetFederation()
60         tplIn.AddRawWitnessKeys(fed.XPubs, fed.Path(), fed.Quorum)
61
62         // TODO: if signer == nil ?
63         if a.Arguments != nil {
64                 if err := txbuilder.AddContractArgs(tplIn, a.Arguments); err != nil {
65                         return err
66                 }
67         }
68
69         return builder.AddInput(txin, tplIn)
70 }
71
72 func (a *crossInAction) ActionType() string {
73         return "cross_chain_in"
74 }