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  }