input: add GenTaprootFundingScript based on musig2
In this commit, we add GenTaprootFundingScript, which'll return the taproot pkScript and output for a taproot+musig2 channel. This uses musig2 key aggregation with sorting activated. The final key produced uses a bip86 tweak, meaning that the output key provably doesn't commit to any script path. In the future, we may want to permit this, as then it allows for a greater degree of programmability of the funding output.
This commit is contained in:
1 file changed
+35
@@ -6,6 +6,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/btcec/v2"
|
"github.com/btcsuite/btcd/btcec/v2"
|
||||||
|
"github.com/btcsuite/btcd/btcec/v2/schnorr/musig2"
|
||||||
"github.com/btcsuite/btcd/btcutil"
|
"github.com/btcsuite/btcd/btcutil"
|
||||||
"github.com/btcsuite/btcd/txscript"
|
"github.com/btcsuite/btcd/txscript"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
@@ -152,6 +153,40 @@ func GenFundingPkScript(aPub, bPub []byte, amt int64) ([]byte, *wire.TxOut, erro
|
|||||||
return witnessScript, wire.NewTxOut(amt, pkScript), nil
|
return witnessScript, wire.NewTxOut(amt, pkScript), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GenTaprootFundingScript constructs the taproot-native funding output that
|
||||||
|
// uses musig2 to create a single aggregated key to anchor the channel.
|
||||||
|
func GenTaprootFundingScript(aPub, bPub *btcec.PublicKey,
|
||||||
|
amt int64) ([]byte, *wire.TxOut, error) {
|
||||||
|
|
||||||
|
// Similar to the existing p2wsh funding script, we'll always make sure
|
||||||
|
// we sort the keys before any major operations. In order to ensure
|
||||||
|
// that there's no other way this output can be spent, we'll use a BIP
|
||||||
|
// 86 tweak here during aggregation.
|
||||||
|
//
|
||||||
|
// TODO(roasbeef): revisit if BIP 86 is needed here?
|
||||||
|
combinedKey, _, _, err := musig2.AggregateKeys(
|
||||||
|
[]*btcec.PublicKey{aPub, bPub}, true,
|
||||||
|
musig2.WithBIP86KeyTweak(),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, fmt.Errorf("unable to combine keys: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now that we have the combined key, we can create a taproot pkScript
|
||||||
|
// from this, and then make the txout given the amount.
|
||||||
|
pkScript, err := PayToTaprootScript(combinedKey.FinalKey)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, fmt.Errorf("unable to make taproot "+
|
||||||
|
"pkscript: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
txOut := wire.NewTxOut(amt, pkScript)
|
||||||
|
|
||||||
|
// For the "witness program" we just return the raw pkScript since the
|
||||||
|
// output we create can _only_ be spent with a musig2 signature.
|
||||||
|
return pkScript, txOut, nil
|
||||||
|
}
|
||||||
|
|
||||||
// SpendMultiSig generates the witness stack required to redeem the 2-of-2 p2wsh
|
// SpendMultiSig generates the witness stack required to redeem the 2-of-2 p2wsh
|
||||||
// multi-sig output.
|
// multi-sig output.
|
||||||
func SpendMultiSig(witnessScript, pubA []byte, sigA Signature,
|
func SpendMultiSig(witnessScript, pubA []byte, sigA Signature,
|
||||||
|
|||||||
Reference in new issue
Block a user