OSDN Git Service

update dashboard (#232)
[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 // AddRawWitnessKeys adds a SignatureWitness with the given quorum and
33 // list of keys derived by applying the derivation path to each of the
34 // xpubs.
35 func (si *SigningInstruction) AddRawWitnessKeys(xpubs []chainkd.XPub, path [][]byte, quorum int) {
36         hexPath := make([]chainjson.HexBytes, 0, len(path))
37         for _, p := range path {
38                 hexPath = append(hexPath, p)
39         }
40
41         keyIDs := make([]keyID, 0, len(xpubs))
42         for _, xpub := range xpubs {
43                 keyIDs = append(keyIDs, keyID{xpub, hexPath})
44         }
45
46         sw := &RawTxSigWitness{
47                 Quorum: quorum,
48                 Keys:   keyIDs,
49         }
50         si.WitnessComponents = append(si.WitnessComponents, sw)
51 }
52
53 // SigningInstruction gives directions for signing inputs in a TxTemplate.
54 type SigningInstruction struct {
55         Position          uint32             `json:"position"`
56         WitnessComponents []witnessComponent `json:"witness_components,omitempty"`
57 }
58
59 // witnessComponent is the abstract type for the parts of a
60 // SigningInstruction.  Each witnessComponent produces one or more
61 // arguments for a VM program via its materialize method. Concrete
62 // witnessComponent types include SignatureWitness and dataWitness.
63 type witnessComponent interface {
64         materialize(*[][]byte) error
65 }
66
67 // UnmarshalJSON unmarshal SigningInstruction
68 func (si *SigningInstruction) UnmarshalJSON(b []byte) error {
69         var pre struct {
70                 Position          uint32            `json:"position"`
71                 WitnessComponents []json.RawMessage `json:"witness_components"`
72         }
73         err := json.Unmarshal(b, &pre)
74         if err != nil {
75                 return err
76         }
77
78         si.Position = pre.Position
79         for i, wc := range pre.WitnessComponents {
80                 var t struct {
81                         Type string
82                 }
83                 err = json.Unmarshal(wc, &t)
84                 if err != nil {
85                         return errors.Wrapf(err, "unmarshaling error on witness component %d, input %s", i, wc)
86                 }
87                 switch t.Type {
88                 case "data":
89                         var d struct {
90                                 Value chainjson.HexBytes
91                         }
92                         err = json.Unmarshal(wc, &d)
93                         if err != nil {
94                                 return errors.Wrapf(err, "unmarshaling error on witness component %d, type data, input %s", i, wc)
95                         }
96                         si.WitnessComponents = append(si.WitnessComponents, DataWitness(d.Value))
97
98                 case "signature":
99                         var s SignatureWitness
100                         err = json.Unmarshal(wc, &s)
101                         if err != nil {
102                                 return errors.Wrapf(err, "unmarshaling error on witness component %d, type signature, input %s", i, wc)
103                         }
104                         si.WitnessComponents = append(si.WitnessComponents, &s)
105
106                 case "raw_tx_signature":
107                         var s RawTxSigWitness
108                         err = json.Unmarshal(wc, &s)
109                         if err != nil {
110                                 return errors.Wrapf(err, "unmarshaling error on witness component %d, type raw_signature, input %s", i, wc)
111                         }
112                         si.WitnessComponents = append(si.WitnessComponents, &s)
113
114                 default:
115                         return errors.WithDetailf(ErrBadWitnessComponent, "witness component %d has unknown type '%s'", i, t.Type)
116                 }
117         }
118         return nil
119 }