pub struct SighashCache<T: Borrow<Transaction>> { /* private fields */ }
Expand description
Efficiently calculates signature hash message for legacy, segwit and taproot inputs.
Implementations§
Source§impl<R: Borrow<Transaction>> SighashCache<R>
impl<R: Borrow<Transaction>> SighashCache<R>
Sourcepub fn new(tx: R) -> Self
pub fn new(tx: R) -> Self
Constructs a new SighashCache
from an unsigned transaction.
The sighash components are computed in a lazy manner when required. For the generated sighashes to be valid, no fields in the transaction may change except for script_sig and witness.
Sourcepub fn transaction(&self) -> &Transaction
pub fn transaction(&self) -> &Transaction
Returns the reference to the cached transaction.
Sourcepub fn into_transaction(self) -> R
pub fn into_transaction(self) -> R
Destroys the cache and recovers the stored transaction.
Sourcepub fn taproot_encode_signing_data_to<W: Write + ?Sized, T: Borrow<TxOut>>(
&mut self,
writer: &mut W,
input_index: usize,
prevouts: &Prevouts<'_, T>,
annex: Option<Annex<'_>>,
leaf_hash_code_separator: Option<(TapLeafHash, u32)>,
sighash_type: TapSighashType,
) -> Result<(), SigningDataError<TaprootError>>
pub fn taproot_encode_signing_data_to<W: Write + ?Sized, T: Borrow<TxOut>>( &mut self, writer: &mut W, input_index: usize, prevouts: &Prevouts<'_, T>, annex: Option<Annex<'_>>, leaf_hash_code_separator: Option<(TapLeafHash, u32)>, sighash_type: TapSighashType, ) -> Result<(), SigningDataError<TaprootError>>
Encodes the BIP341 signing data for any flag type into a given object implementing the
io::Write
trait.
Sourcepub fn taproot_signature_hash<T: Borrow<TxOut>>(
&mut self,
input_index: usize,
prevouts: &Prevouts<'_, T>,
annex: Option<Annex<'_>>,
leaf_hash_code_separator: Option<(TapLeafHash, u32)>,
sighash_type: TapSighashType,
) -> Result<TapSighash, TaprootError>
pub fn taproot_signature_hash<T: Borrow<TxOut>>( &mut self, input_index: usize, prevouts: &Prevouts<'_, T>, annex: Option<Annex<'_>>, leaf_hash_code_separator: Option<(TapLeafHash, u32)>, sighash_type: TapSighashType, ) -> Result<TapSighash, TaprootError>
Computes the BIP341 sighash for any flag type.
Sourcepub fn taproot_key_spend_signature_hash<T: Borrow<TxOut>>(
&mut self,
input_index: usize,
prevouts: &Prevouts<'_, T>,
sighash_type: TapSighashType,
) -> Result<TapSighash, TaprootError>
pub fn taproot_key_spend_signature_hash<T: Borrow<TxOut>>( &mut self, input_index: usize, prevouts: &Prevouts<'_, T>, sighash_type: TapSighashType, ) -> Result<TapSighash, TaprootError>
Computes the BIP341 sighash for a key spend.
Sourcepub fn taproot_script_spend_signature_hash<S: Into<TapLeafHash>, T: Borrow<TxOut>>(
&mut self,
input_index: usize,
prevouts: &Prevouts<'_, T>,
leaf_hash: S,
sighash_type: TapSighashType,
) -> Result<TapSighash, TaprootError>
pub fn taproot_script_spend_signature_hash<S: Into<TapLeafHash>, T: Borrow<TxOut>>( &mut self, input_index: usize, prevouts: &Prevouts<'_, T>, leaf_hash: S, sighash_type: TapSighashType, ) -> Result<TapSighash, TaprootError>
Computes the BIP341 sighash for a script spend.
Assumes the default OP_CODESEPARATOR
position of 0xFFFFFFFF
. Custom values can be
provided through the more fine-grained API of SighashCache::taproot_encode_signing_data_to
.
Sourcepub fn segwit_v0_encode_signing_data_to<W: Write + ?Sized>(
&mut self,
writer: &mut W,
input_index: usize,
script_code: &Script,
value: Amount,
sighash_type: EcdsaSighashType,
) -> Result<(), SigningDataError<InputsIndexError>>
pub fn segwit_v0_encode_signing_data_to<W: Write + ?Sized>( &mut self, writer: &mut W, input_index: usize, script_code: &Script, value: Amount, sighash_type: EcdsaSighashType, ) -> Result<(), SigningDataError<InputsIndexError>>
Encodes the BIP143 signing data for any flag type into a given object implementing the
std::io::Write
trait.
script_code
is dependent on the type of the spend transaction. For p2wpkh use
Script::p2wpkh_script_code
, for p2wsh just pass in the witness script. (Also see
Self::p2wpkh_signature_hash
and SighashCache::p2wsh_signature_hash
.)
Sourcepub fn p2wpkh_signature_hash(
&mut self,
input_index: usize,
script_pubkey: &Script,
value: Amount,
sighash_type: EcdsaSighashType,
) -> Result<SegwitV0Sighash, P2wpkhError>
pub fn p2wpkh_signature_hash( &mut self, input_index: usize, script_pubkey: &Script, value: Amount, sighash_type: EcdsaSighashType, ) -> Result<SegwitV0Sighash, P2wpkhError>
Computes the BIP143 sighash to spend a p2wpkh transaction for any flag type.
script_pubkey
is the scriptPubkey
(native segwit) of the spend transaction
(TxOut::script_pubkey
) or the redeemScript
(wrapped segwit).
Sourcepub fn p2wsh_signature_hash(
&mut self,
input_index: usize,
witness_script: &Script,
value: Amount,
sighash_type: EcdsaSighashType,
) -> Result<SegwitV0Sighash, InputsIndexError>
pub fn p2wsh_signature_hash( &mut self, input_index: usize, witness_script: &Script, value: Amount, sighash_type: EcdsaSighashType, ) -> Result<SegwitV0Sighash, InputsIndexError>
Computes the BIP143 sighash to spend a p2wsh transaction for any flag type.
Sourcepub fn legacy_encode_signing_data_to<W: Write + ?Sized, U: Into<u32>>(
&self,
writer: &mut W,
input_index: usize,
script_pubkey: &Script,
sighash_type: U,
) -> EncodeSigningDataResult<SigningDataError<InputsIndexError>>
pub fn legacy_encode_signing_data_to<W: Write + ?Sized, U: Into<u32>>( &self, writer: &mut W, input_index: usize, script_pubkey: &Script, sighash_type: U, ) -> EncodeSigningDataResult<SigningDataError<InputsIndexError>>
Encodes the legacy signing data from which a signature hash for a given input index with a given sighash flag can be computed.
To actually produce a scriptSig, this hash needs to be run through an ECDSA signer, the
EcdsaSighashType
appended to the resulting sig, and a script written around this, but
this is the general (and hard) part.
The sighash_type
supports an arbitrary u32
value, instead of just EcdsaSighashType
,
because internally 4 bytes are being hashed, even though only the lowest byte is appended to
signature in a transaction.
§Warning
- Does NOT attempt to support OP_CODESEPARATOR. In general this would require evaluating
script_pubkey
to determine which separators get evaluated and which don’t, which we don’t have the information to determine. - Does NOT handle the sighash single bug (see “Return type” section)
§Returns
This function can’t handle the SIGHASH_SINGLE bug internally, so it returns EncodeSigningDataResult
that must be handled by the caller (see EncodeSigningDataResult::is_sighash_single_bug
).
Sourcepub fn legacy_signature_hash(
&self,
input_index: usize,
script_pubkey: &Script,
sighash_type: u32,
) -> Result<LegacySighash, InputsIndexError>
pub fn legacy_signature_hash( &self, input_index: usize, script_pubkey: &Script, sighash_type: u32, ) -> Result<LegacySighash, InputsIndexError>
Computes a legacy signature hash for a given input index with a given sighash flag.
To actually produce a scriptSig, this hash needs to be run through an ECDSA signer, the
EcdsaSighashType
appended to the resulting sig, and a script written around this, but
this is the general (and hard) part.
The sighash_type
supports an arbitrary u32
value, instead of just EcdsaSighashType
,
because internally 4 bytes are being hashed, even though only the lowest byte is appended to
signature in a transaction.
This function correctly handles the sighash single bug by returning the ‘one array’. The
sighash single bug becomes exploitable when one tries to sign a transaction with
SIGHASH_SINGLE
and there is not a corresponding output with the same index as the input.
§Warning
Does NOT attempt to support OP_CODESEPARATOR. In general this would require evaluating
script_pubkey
to determine which separators get evaluated and which don’t, which we don’t
have the information to determine.
Source§impl<R: BorrowMut<Transaction>> SighashCache<R>
impl<R: BorrowMut<Transaction>> SighashCache<R>
Sourcepub fn witness_mut(&mut self, input_index: usize) -> Option<&mut Witness>
pub fn witness_mut(&mut self, input_index: usize) -> Option<&mut Witness>
Allows modification of witnesses.
As a lint against accidental changes to the transaction that would invalidate the cache and
signatures, SighashCache
borrows the Transaction so that modifying it is not possible
without hacks with UnsafeCell
(which is hopefully a strong indication that something is
wrong). However modifying witnesses never invalidates the cache and is actually useful - one
usually wants to put the signature generated for an input into the witness of that input.
This method allows doing exactly that if the transaction is owned by the SighashCache
or
borrowed mutably.
§Examples
let mut sighasher = SighashCache::new(&mut tx_to_sign);
let sighash = sighasher.p2wpkh_signature_hash(input_index, &utxo.script_pubkey, amount, sighash_type)?;
let signature = {
// Sign the sighash using secp256k1
};
*sighasher.witness_mut(input_index).unwrap() = Witness::p2wpkh(&signature, &pk);
For full signing code see the segwit v0
and taproot
signing examples.