6 "github.com/vapor/crypto/ed25519/chainkd"
7 chainjson "github.com/vapor/encoding/json"
10 // TODO(bobg): most of the code here is duplicated from
11 // signature_witness.go and needs refactoring.
13 // RawTxSigWitness is like SignatureWitness but doesn't involve
14 // signature programs.
15 type RawTxSigWitness struct {
16 Quorum int `json:"quorum"`
17 Keys []keyID `json:"keys"`
18 Sigs []chainjson.HexBytes `json:"signatures"`
21 func (sw *RawTxSigWitness) Sign(tpl *Template, index uint32, xprv chainkd.XPrv) error {
22 if len(sw.Sigs) < len(sw.Keys) {
23 // Each key in sw.Keys may produce a signature in sw.Sigs. Make
24 // sure there are enough slots in sw.Sigs and that we preserve any
25 // sigs already present.
26 newSigs := make([]chainjson.HexBytes, len(sw.Keys))
27 copy(newSigs, sw.Sigs)
30 for i, keyID := range sw.Keys {
31 if len(sw.Sigs[i]) > 0 {
32 // Already have a signature for this key
35 path := make([][]byte, len(keyID.DerivationPath))
36 for i, p := range keyID.DerivationPath {
39 if keyID.XPub.String() != xprv.XPub().String() {
42 data := tpl.Hash(index).Byte32()
43 sigBytes := xprv.Sign(data[:])
45 // This break is ordered to avoid signing transaction successfully only once for a multiple-sign account
46 // that consist of different keys by the same password. Exit immediately when the signature is success,
47 // it means that only one signature will be successful in the loop for this multiple-sign account.
54 func (sw RawTxSigWitness) Materialize(args *[][]byte) error {
56 for i := 0; i < len(sw.Sigs) && nsigs < sw.Quorum; i++ {
57 if len(sw.Sigs[i]) > 0 {
58 *args = append(*args, sw.Sigs[i])
65 // MarshalJSON convert struct to json
66 func (sw RawTxSigWitness) MarshalJSON() ([]byte, error) {
68 Type string `json:"type"`
69 Quorum int `json:"quorum"`
70 Keys []keyID `json:"keys"`
71 Sigs []chainjson.HexBytes `json:"signatures"`
73 Type: "raw_tx_signature",
78 return json.Marshal(obj)