mirror of
https://github.com/btcsuite/btcd.git
synced 2025-03-11 01:35:29 +01:00
txscript: add new functions for signing a top-level taproot output
In this commit, we add two new functions: one for signing a raw top-level taproot keyspend, and another for generating a valid witness for a keyspend.
This commit is contained in:
parent
1ac34b75dc
commit
938c1930da
1 changed files with 54 additions and 2 deletions
|
@ -7,10 +7,11 @@ package txscript
|
|||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/btcsuite/btcd/btcec/v2/ecdsa"
|
||||
|
||||
"github.com/btcsuite/btcd/btcec/v2"
|
||||
"github.com/btcsuite/btcd/btcec/v2/schnorr"
|
||||
"github.com/btcsuite/btcd/btcutil"
|
||||
|
||||
"github.com/btcsuite/btcd/btcec/v2/ecdsa"
|
||||
"github.com/btcsuite/btcd/chaincfg"
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
)
|
||||
|
@ -62,6 +63,57 @@ func WitnessSignature(tx *wire.MsgTx, sigHashes *TxSigHashes, idx int, amt int64
|
|||
return wire.TxWitness{sig, pkData}, nil
|
||||
}
|
||||
|
||||
// RawTxInWitnessSignature returns a valid schnorr signature required to
|
||||
// perform a taproot key-spend of the specified input. An explicit sighash is
|
||||
// always attached, which can be removed by a caller if they wish to
|
||||
// implicitly use the "default" sighash with a 64-byte signature.
|
||||
//
|
||||
// TODO(roasbeef): also need a tapscript version of this as well
|
||||
func RawTxInTaprootSignature(tx *wire.MsgTx, sigHashes *TxSigHashes, idx int,
|
||||
amt int64, pkScript []byte, hashType SigHashType,
|
||||
key *btcec.PrivateKey) ([]byte, error) {
|
||||
|
||||
// First, we'll start by compute the top-level taproot sighash.
|
||||
sigHash, err := calcTaprootSignatureHashRaw(
|
||||
sigHashes, hashType, tx, idx,
|
||||
NewCannedPrevOutputFetcher(pkScript, amt),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// With the sighash constructed, we can sign it with the specified
|
||||
// private key.
|
||||
signature, err := schnorr.Sign(key, sigHash)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Finally, append the sighash type to the final sig.
|
||||
return append(signature.Serialize(), byte(hashType)), nil
|
||||
}
|
||||
|
||||
// TaprootWitnessSignature returns a valid witness stack that can be used to
|
||||
// spend the key-spend path of a taproot input as specified in BIP 342.
|
||||
//
|
||||
// TODO(roasbeef): add support for annex even tho it's non-standard?
|
||||
func TaprootWitnessSignature(tx *wire.MsgTx, sigHashes *TxSigHashes, idx int,
|
||||
amt int64, pkScript []byte, hashType SigHashType,
|
||||
key *btcec.PrivateKey) (wire.TxWitness, error) {
|
||||
|
||||
sig, err := RawTxInTaprootSignature(
|
||||
tx, sigHashes, idx, amt, pkScript, hashType, key,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// The witness script to spend a taproot input using the key-spend path
|
||||
// is just the signature itself, given the public key is
|
||||
// embedded in the previous output script.
|
||||
return wire.TxWitness{sig}, nil
|
||||
}
|
||||
|
||||
// RawTxInSignature returns the serialized ECDSA signature for the input idx of
|
||||
// the given transaction, with hashType appended to it.
|
||||
func RawTxInSignature(tx *wire.MsgTx, idx int, subScript []byte,
|
||||
|
|
Loading…
Add table
Reference in a new issue