package txbuilder import ( "encoding/json" "github.com/vapor/crypto/ed25519/chainkd" chainjson "github.com/vapor/encoding/json" "github.com/vapor/errors" ) 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 }