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