OSDN Git Service

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