OSDN Git Service

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