7 log "github.com/sirupsen/logrus"
9 chainjson "github.com/vapor/encoding/json"
12 // TODO(bobg): most of the code here is duplicated from
13 // signature_witness.go and needs refactoring.
15 // RawTxSigWitness is like SignatureWitness but doesn't involve
16 // signature programs.
17 type RawTxSigWitness struct {
18 Quorum int `json:"quorum"`
19 Keys []keyID `json:"keys"`
20 Sigs []chainjson.HexBytes `json:"signatures"`
23 func (sw *RawTxSigWitness) sign(ctx context.Context, tpl *Template, index uint32, auth string, signFn SignFunc) error {
24 if len(sw.Sigs) < len(sw.Keys) {
25 // Each key in sw.Keys may produce a signature in sw.Sigs. Make
26 // sure there are enough slots in sw.Sigs and that we preserve any
27 // sigs already present.
28 newSigs := make([]chainjson.HexBytes, len(sw.Keys))
29 copy(newSigs, sw.Sigs)
32 for i, keyID := range sw.Keys {
33 if len(sw.Sigs[i]) > 0 {
34 // Already have a signature for this key
37 path := make([][]byte, len(keyID.DerivationPath))
38 for i, p := range keyID.DerivationPath {
41 sigBytes, err := signFn(ctx, keyID.XPub, path, tpl.Hash(index).Byte32(), auth)
43 log.WithFields(log.Fields{"module": logModule, "err": err}).Warningf("computing signature %d", i)
47 // This break is ordered to avoid signing transaction successfully only once for a multiple-sign account
48 // that consist of different keys by the same password. Exit immediately when the signature is success,
49 // it means that only one signature will be successful in the loop for this multiple-sign account.
56 func (sw RawTxSigWitness) materialize(args *[][]byte) error {
58 for i := 0; i < len(sw.Sigs) && nsigs < sw.Quorum; i++ {
59 if len(sw.Sigs[i]) > 0 {
60 *args = append(*args, sw.Sigs[i])
67 // MarshalJSON convert struct to json
68 func (sw RawTxSigWitness) MarshalJSON() ([]byte, error) {
70 Type string `json:"type"`
71 Quorum int `json:"quorum"`
72 Keys []keyID `json:"keys"`
73 Sigs []chainjson.HexBytes `json:"signatures"`
75 Type: "raw_tx_signature",
80 return json.Marshal(obj)