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