// spendNestedWitnessPubKey generates both a sigScript, and valid witness for // spending the passed pkScript with the specified input amount. The generated // sigScript is the version 0 p2wkh witness program corresponding to the queried // key. The witness stack is identical to that of one which spends a regular // p2wkh output. The input amount *must* correspond to the output value of the // previous pkScript, or else verification will fail since the new sighash // digest algorithm defined in BIP0143 includes the input value in the sighash. func spendNestedWitnessPubKeyHash(txIn *wire.TxIn, pkScript []byte, inputValue int64, chainParams *chaincfg.Params, secrets SecretsSource, tx *wire.MsgTx, hashCache *txscript.TxSigHashes, idx int) error { // First we need to obtain the key pair related to this p2sh output. _, addrs, _, err := txscript.ExtractPkScriptAddrs(pkScript, chainParams) if err != nil { return err } privKey, compressed, err := secrets.GetKey(addrs[0]) if err != nil { return err } pubKey := privKey.PubKey() var pubKeyHash []byte if compressed { pubKeyHash = btcutil.Hash160(pubKey.SerializeCompressed()) } else { pubKeyHash = btcutil.Hash160(pubKey.SerializeUncompressed()) } // Next, we'll generate a valid sigScript that'll allow us to spend // the p2sh output. The sigScript will contain only a single push of // the p2wkh witness program corresponding to the matching public key // of this address. p2wkhAddr, err := btcutil.NewAddressWitnessPubKeyHash(pubKeyHash, chainParams) if err != nil { return err } witnessProgram, err := txscript.PayToAddrScript(p2wkhAddr) if err != nil { return err } bldr := txscript.NewScriptBuilder() bldr.AddData(witnessProgram) sigScript, err := bldr.Script() if err != nil { return err } txIn.SignatureScript = sigScript // With the sigScript in place, we'll next generate the proper witness // that'll allow us to spend the p2wkh output. witnessScript, err := txscript.WitnessScript(tx, hashCache, idx, inputValue, witnessProgram, txscript.SigHashAll, privKey, compressed) if err != nil { return err } txIn.Witness = witnessScript return nil }
// spendWitnessKeyHash generates, and sets a valid witness for spending the // passed pkScript with the specified input amount. The input amount *must* // correspond to the output value of the previous pkScript, or else verification // will fail since the new sighash digest algorithm defined in BIP0143 includes // the input value in the sighash. func spendWitnessKeyHash(txIn *wire.TxIn, pkScript []byte, inputValue int64, chainParams *chaincfg.Params, secrets SecretsSource, tx *wire.MsgTx, hashCache *txscript.TxSigHashes, idx int) error { // First obtain the key pair associated with this p2wkh address. _, addrs, _, err := txscript.ExtractPkScriptAddrs(pkScript, chainParams) if err != nil { return err } privKey, compressed, err := secrets.GetKey(addrs[0]) if err != nil { return err } pubKey := privKey.PubKey() // Once we have the key pair, generate a p2wkh address type, respecting // the compression type of the generated key. var pubKeyHash []byte if compressed { pubKeyHash = btcutil.Hash160(pubKey.SerializeCompressed()) } else { pubKeyHash = btcutil.Hash160(pubKey.SerializeUncompressed()) } p2wkhAddr, err := btcutil.NewAddressWitnessPubKeyHash(pubKeyHash, chainParams) if err != nil { return err } // With the concrete address type, we can now generate the // corresponding witness program to be used to generate a valid witness // which will allow us to spend this output. witnessProgram, err := txscript.PayToAddrScript(p2wkhAddr) if err != nil { return err } witnessScript, err := txscript.WitnessScript(tx, hashCache, idx, inputValue, witnessProgram, txscript.SigHashAll, privKey, true) if err != nil { return err } txIn.Witness = witnessScript return nil }