mirror of
https://github.com/btcsuite/btcd.git
synced 2025-03-11 17:57:50 +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 (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/btcec/v2/ecdsa"
|
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/btcec/v2"
|
"github.com/btcsuite/btcd/btcec/v2"
|
||||||
|
"github.com/btcsuite/btcd/btcec/v2/schnorr"
|
||||||
"github.com/btcsuite/btcd/btcutil"
|
"github.com/btcsuite/btcd/btcutil"
|
||||||
|
|
||||||
|
"github.com/btcsuite/btcd/btcec/v2/ecdsa"
|
||||||
"github.com/btcsuite/btcd/chaincfg"
|
"github.com/btcsuite/btcd/chaincfg"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"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
|
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
|
// RawTxInSignature returns the serialized ECDSA signature for the input idx of
|
||||||
// the given transaction, with hashType appended to it.
|
// the given transaction, with hashType appended to it.
|
||||||
func RawTxInSignature(tx *wire.MsgTx, idx int, subScript []byte,
|
func RawTxInSignature(tx *wire.MsgTx, idx int, subScript []byte,
|
||||||
|
|
Loading…
Add table
Reference in a new issue