OSDN Git Service

Modify the dependency on path
[bytom/vapor.git] / blockchain / txbuilder / mainchain / signing_instruction.go
1 package mainchain
2
3 import (
4         "encoding/json"
5
6         "github.com/vapor/blockchain/txbuilder"
7         "github.com/vapor/crypto/ed25519/chainkd"
8         chainjson "github.com/vapor/encoding/json"
9         "github.com/vapor/errors"
10 )
11
12 // AddWitnessKeys adds a SignatureWitness with the given quorum and
13 // list of keys derived by applying the derivation path to each of the
14 // xpubs.
15 func (si *SigningInstruction) AddWitnessKeys(xpubs []chainkd.XPub, quorum int) {
16
17         keyIDs := make([]keyID, 0, len(xpubs))
18         for _, xpub := range xpubs {
19                 keyIDs = append(keyIDs, keyID{XPub: xpub})
20         }
21
22         sw := &SignatureWitness{
23                 Quorum: quorum,
24                 Keys:   keyIDs,
25         }
26         si.WitnessComponents = append(si.WitnessComponents, sw)
27 }
28
29 // AddRawWitnessKeys adds a SignatureWitness with the given quorum and
30 // list of keys derived by applying the derivation path to each of the
31 // xpubs.
32 func (si *SigningInstruction) AddRawWitnessKeys(xpubs []chainkd.XPub, path [][]byte, quorum int) {
33         hexPath := make([]chainjson.HexBytes, 0, len(path))
34         for _, p := range path {
35                 hexPath = append(hexPath, p)
36         }
37
38         keyIDs := make([]keyID, 0, len(xpubs))
39         for _, xpub := range xpubs {
40                 keyIDs = append(keyIDs, keyID{xpub, hexPath})
41         }
42
43         sw := &RawTxSigWitness{
44                 Quorum: quorum,
45                 Keys:   keyIDs,
46         }
47         si.WitnessComponents = append(si.WitnessComponents, sw)
48 }
49
50 func (si *SigningInstruction) AddRawWitnessKeysWithoutPath(xpubs []chainkd.XPub, quorum int) {
51
52         keyIDs := make([]keyID, 0, len(xpubs))
53         for _, xpub := range xpubs {
54                 keyIDs = append(keyIDs, keyID{XPub: xpub})
55         }
56
57         sw := &RawTxSigWitness{
58                 Quorum: quorum,
59                 Keys:   keyIDs,
60         }
61         si.WitnessComponents = append(si.WitnessComponents, sw)
62 }
63
64 // SigningInstruction gives directions for signing inputs in a TxTemplate.
65 type SigningInstruction struct {
66         Position          uint32             `json:"position"`
67         WitnessComponents []witnessComponent `json:"witness_components,omitempty"`
68 }
69
70 // witnessComponent is the abstract type for the parts of a
71 // SigningInstruction.  Each witnessComponent produces one or more
72 // arguments for a VM program via its materialize method. Concrete
73 // witnessComponent types include SignatureWitness and dataWitness.
74 type witnessComponent interface {
75         Materialize(*[][]byte) error
76 }
77
78 // UnmarshalJSON unmarshal SigningInstruction
79 func (si *SigningInstruction) UnmarshalJSON(b []byte) error {
80         var pre struct {
81                 Position          uint32            `json:"position"`
82                 WitnessComponents []json.RawMessage `json:"witness_components"`
83         }
84         err := json.Unmarshal(b, &pre)
85         if err != nil {
86                 return err
87         }
88
89         si.Position = pre.Position
90         for i, wc := range pre.WitnessComponents {
91                 var t struct {
92                         Type string
93                 }
94                 err = json.Unmarshal(wc, &t)
95                 if err != nil {
96                         return errors.Wrapf(err, "unmarshaling error on witness component %d, input %s", i, wc)
97                 }
98                 switch t.Type {
99                 case "data":
100                         var d struct {
101                                 Value chainjson.HexBytes
102                         }
103                         err = json.Unmarshal(wc, &d)
104                         if err != nil {
105                                 return errors.Wrapf(err, "unmarshaling error on witness component %d, type data, input %s", i, wc)
106                         }
107                         si.WitnessComponents = append(si.WitnessComponents, DataWitness(d.Value))
108
109                 case "signature":
110                         var s SignatureWitness
111                         err = json.Unmarshal(wc, &s)
112                         if err != nil {
113                                 return errors.Wrapf(err, "unmarshaling error on witness component %d, type signature, input %s", i, wc)
114                         }
115                         si.WitnessComponents = append(si.WitnessComponents, &s)
116
117                 case "raw_tx_signature":
118                         var s RawTxSigWitness
119                         err = json.Unmarshal(wc, &s)
120                         if err != nil {
121                                 return errors.Wrapf(err, "unmarshaling error on witness component %d, type raw_signature, input %s", i, wc)
122                         }
123                         si.WitnessComponents = append(si.WitnessComponents, &s)
124
125                 default:
126                         return errors.WithDetailf(txbuilder.ErrBadWitnessComponent, "witness component %d has unknown type '%s'", i, t.Type)
127                 }
128         }
129         return nil
130 }