OSDN Git Service

Modify the dependency on path
[bytom/vapor.git] / blockchain / txbuilder / mainchain / rawtxsig_witness.go
1 package mainchain
2
3 import (
4         "encoding/json"
5         "fmt"
6
7         "github.com/vapor/crypto/ed25519/chainkd"
8         chainjson "github.com/vapor/encoding/json"
9 )
10
11 // TODO(bobg): most of the code here is duplicated from
12 // signature_witness.go and needs refactoring.
13
14 // RawTxSigWitness is like SignatureWitness but doesn't involve
15 // signature programs.
16 type RawTxSigWitness struct {
17         Quorum int                  `json:"quorum"`
18         Keys   []keyID              `json:"keys"`
19         Sigs   []chainjson.HexBytes `json:"signatures"`
20 }
21
22 func (sw *RawTxSigWitness) Sign(tpl *Template, index uint32, xprv chainkd.XPrv) error {
23         if len(sw.Sigs) < len(sw.Keys) {
24                 // Each key in sw.Keys may produce a signature in sw.Sigs. Make
25                 // sure there are enough slots in sw.Sigs and that we preserve any
26                 // sigs already present.
27                 newSigs := make([]chainjson.HexBytes, len(sw.Keys))
28                 copy(newSigs, sw.Sigs)
29                 sw.Sigs = newSigs
30         }
31         for i, keyID := range sw.Keys {
32                 if len(sw.Sigs[i]) > 0 {
33                         // Already have a signature for this key
34                         continue
35                 }
36                 fmt.Println(keyID.XPub.String())
37                 fmt.Println(xprv.XPub().String())
38                 if keyID.XPub.String() != xprv.XPub().String() {
39                         continue
40                 }
41                 data := tpl.Hash(index).Byte32()
42                 sigBytes := xprv.Sign(data[:])
43
44                 // This break is ordered to avoid signing transaction successfully only once for a multiple-sign account
45                 // that consist of different keys by the same password. Exit immediately when the signature is success,
46                 // it means that only one signature will be successful in the loop for this multiple-sign account.
47                 sw.Sigs[i] = sigBytes
48                 break
49         }
50         return nil
51 }
52
53 func (sw RawTxSigWitness) Materialize(args *[][]byte) error {
54         var nsigs int
55         for i := 0; i < len(sw.Sigs) && nsigs < sw.Quorum; i++ {
56                 if len(sw.Sigs[i]) > 0 {
57                         *args = append(*args, sw.Sigs[i])
58                         nsigs++
59                 }
60         }
61         return nil
62 }
63
64 // MarshalJSON convert struct to json
65 func (sw RawTxSigWitness) MarshalJSON() ([]byte, error) {
66         obj := struct {
67                 Type   string               `json:"type"`
68                 Quorum int                  `json:"quorum"`
69                 Keys   []keyID              `json:"keys"`
70                 Sigs   []chainjson.HexBytes `json:"signatures"`
71         }{
72                 Type:   "raw_tx_signature",
73                 Quorum: sw.Quorum,
74                 Keys:   sw.Keys,
75                 Sigs:   sw.Sigs,
76         }
77         return json.Marshal(obj)
78 }