OSDN Git Service

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