Update docs on witness_mut

Recently during the rust-bitcoin workshop at TABConf devs were thrown
off by the example on `witness_mut`.

Attempt to improve the docs on `witness_mut`.
This commit is contained in:
Tobin C. Harding 2023-09-20 15:39:14 +10:00
parent 931a1d0356
commit 98ce46c009
No known key found for this signature in database
GPG Key ID: 40BF9E4C269D6607
1 changed files with 24 additions and 15 deletions

View File

@ -1187,25 +1187,34 @@ impl<R: Borrow<Transaction>> SighashCache<R> {
} }
impl<R: BorrowMut<Transaction>> SighashCache<R> { impl<R: BorrowMut<Transaction>> SighashCache<R> {
/// When the `SighashCache` is initialized with a mutable reference to a transaction instead of /// Allows modification of witnesses.
/// a regular reference, this method is available to allow modification to the witnesses.
/// ///
/// This allows in-line signing such as /// 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
///
/// ```compile_fail
/// 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);
/// ``` /// ```
/// use bitcoin::{absolute, transaction, Amount, Transaction, Script};
/// use bitcoin::sighash::{EcdsaSighashType, SighashCache};
/// ///
/// let mut tx_to_sign = Transaction { version: transaction::Version::TWO, lock_time: absolute::LockTime::ZERO, input: Vec::new(), output: Vec::new() }; /// For full signing code see the [`segwit v0`] and [`taproot`] signing examples.
/// let input_count = tx_to_sign.input.len();
/// ///
/// let mut sig_hasher = SighashCache::new(&mut tx_to_sign); /// [`segwit v0`]: <https://github.com/rust-bitcoin/rust-bitcoin/blob/master/bitcoin/examples/sign-tx-segwit-v0.rs>
/// for inp in 0..input_count { /// [`taproot`]: <https://github.com/rust-bitcoin/rust-bitcoin/blob/master/bitcoin/examples/sign-tx-taproot.rs>
/// let prevout_script = Script::new();
/// let _sighash = sig_hasher.p2wpkh_signature_hash(inp, prevout_script, Amount::ONE_SAT, EcdsaSighashType::All);
/// // ... sign the sighash
/// sig_hasher.witness_mut(inp).unwrap().push(&Vec::new());
/// }
/// ```
pub fn witness_mut(&mut self, input_index: usize) -> Option<&mut Witness> { pub fn witness_mut(&mut self, input_index: usize) -> Option<&mut Witness> {
self.tx.borrow_mut().input.get_mut(input_index).map(|i| &mut i.witness) self.tx.borrow_mut().input.get_mut(input_index).map(|i| &mut i.witness)
} }