bdk_chain::bitcoin::sighash

Struct SighashCache

pub struct SighashCache<T>
where T: Borrow<Transaction>,
{ /* private fields */ }
Expand description

Efficiently calculates signature hash message for legacy, segwit and taproot inputs.

Implementations§

§

impl<R> SighashCache<R>
where R: Borrow<Transaction>,

pub fn new(tx: R) -> SighashCache<R>

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.

pub fn transaction(&self) -> &Transaction

Returns the reference to the cached transaction.

pub fn into_transaction(self) -> R

Destroys the cache and recovers the stored transaction.

pub fn taproot_encode_signing_data_to<W, T>( &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>>
where W: Write + ?Sized, T: Borrow<TxOut>,

Encodes the BIP341 signing data for any flag type into a given object implementing the io::Write trait.

pub fn taproot_signature_hash<T>( &mut self, input_index: usize, prevouts: &Prevouts<'_, T>, annex: Option<Annex<'_>>, leaf_hash_code_separator: Option<(TapLeafHash, u32)>, sighash_type: TapSighashType, ) -> Result<TapSighash, TaprootError>
where T: Borrow<TxOut>,

Computes the BIP341 sighash for any flag type.

pub fn taproot_key_spend_signature_hash<T>( &mut self, input_index: usize, prevouts: &Prevouts<'_, T>, sighash_type: TapSighashType, ) -> Result<TapSighash, TaprootError>
where T: Borrow<TxOut>,

Computes the BIP341 sighash for a key spend.

pub fn taproot_script_spend_signature_hash<S, T>( &mut self, input_index: usize, prevouts: &Prevouts<'_, T>, leaf_hash: S, sighash_type: TapSighashType, ) -> Result<TapSighash, TaprootError>
where S: Into<TapLeafHash>, T: Borrow<TxOut>,

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.

pub fn segwit_v0_encode_signing_data_to<W>( &mut self, writer: &mut W, input_index: usize, script_code: &Script, value: Amount, sighash_type: EcdsaSighashType, ) -> Result<(), SigningDataError<InputsIndexError>>
where W: Write + ?Sized,

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.)

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).

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.

pub fn legacy_encode_signing_data_to<W, U>( &self, writer: &mut W, input_index: usize, script_pubkey: &Script, sighash_type: U, ) -> EncodeSigningDataResult<SigningDataError<InputsIndexError>>
where W: Write + ?Sized, U: Into<u32>,

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).

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.

§

impl<R> SighashCache<R>

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.

Trait Implementations§

§

impl<T> Debug for SighashCache<T>
where T: Debug + Borrow<Transaction>,

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<T> Freeze for SighashCache<T>
where T: Freeze,

§

impl<T> RefUnwindSafe for SighashCache<T>
where T: RefUnwindSafe,

§

impl<T> Send for SighashCache<T>
where T: Send,

§

impl<T> Sync for SighashCache<T>
where T: Sync,

§

impl<T> Unpin for SighashCache<T>
where T: Unpin,

§

impl<T> UnwindSafe for SighashCache<T>
where T: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V