// AddAllInputScripts modifies transaction a transaction by adding inputs // scripts for each input. Previous output scripts being redeemed by each input // are passed in prevPkScripts and the slice length must match the number of // inputs. Private keys and redeem scripts are looked up using a SecretsSource // based on the previous output script. func AddAllInputScripts(tx *wire.MsgTx, prevPkScripts [][]byte, inputValues []btcutil.Amount, secrets SecretsSource) error { inputs := tx.TxIn hashCache := txscript.NewTxSigHashes(tx) chainParams := secrets.ChainParams() if len(inputs) != len(prevPkScripts) { return errors.New("tx.TxIn and prevPkScripts slices must " + "have equal length") } for i := range inputs { pkScript := prevPkScripts[i] switch { // If this is a p2sh output, who's script hash pre-image is a // witness program, then we'll need to use a modified signing // function which generates both the sigScript, and the witness // script. case txscript.IsPayToScriptHash(pkScript): err := spendNestedWitnessPubKeyHash(inputs[i], pkScript, int64(inputValues[i]), chainParams, secrets, tx, hashCache, i) if err != nil { return err } case txscript.IsPayToWitnessPubKeyHash(pkScript): err := spendWitnessKeyHash(inputs[i], pkScript, int64(inputValues[i]), chainParams, secrets, tx, hashCache, i) if err != nil { return err } default: sigScript := inputs[i].SignatureScript script, err := txscript.SignTxOutput(chainParams, tx, i, pkScript, txscript.SigHashAll, secrets, secrets, sigScript) if err != nil { return err } inputs[i].SignatureScript = script } } return nil }
// ListUnspentWitness returns a slice of all the unspent outputs the wallet // controls which pay to witness programs either directly or indirectly. // // This is a part of the WalletController interface. func (b *BtcWallet) ListUnspentWitness(minConfs int32) ([]*lnwallet.Utxo, error) { // First, grab all the unfiltered currently unspent outputs. maxConfs := int32(math.MaxInt32) unspentOutputs, err := b.wallet.ListUnspent(minConfs, maxConfs, nil) if err != nil { return nil, err } // Next, we'll run through all the regular outputs, only saving those // which are p2wkh outputs or a p2wsh output nested within a p2sh output. witnessOutputs := make([]*lnwallet.Utxo, 0, len(unspentOutputs)) for _, output := range unspentOutputs { pkScript, err := hex.DecodeString(output.ScriptPubKey) if err != nil { return nil, err } // TODO(roasbeef): this assumes all p2sh outputs returned by // the wallet are nested p2sh... if txscript.IsPayToWitnessPubKeyHash(pkScript) || txscript.IsPayToScriptHash(pkScript) { txid, err := wire.NewShaHashFromStr(output.TxID) if err != nil { return nil, err } utxo := &lnwallet.Utxo{ Value: btcutil.Amount(output.Amount * 1e8), OutPoint: wire.OutPoint{ Hash: *txid, Index: output.Vout, }, } witnessOutputs = append(witnessOutputs, utxo) } } return witnessOutputs, nil }