Merge rust-bitcoin/rust-bitcoin#956: Improve docs in `sighash` and `psbt/mod.rs`
9896f27eae
psbt: Improve documentation (Tobin C. Harding)33a50831ce
sighash: Improve documentation (Tobin Harding) Pull request description: Done while working on sighash and PSBT signing. Just the usual docs fixes. Note, does not do the whole `psbt` module just the file mentioned. ACKs for top commit: apoelstra: ACK9896f27eae
Tree-SHA512: 5fbfa258cdb216189922a49a42b7ab9fb78faeee72d82f8cb99a1b3d930d170074013e317b0e7af259a404ac4db93841b4d2b525e933c5e145da71e7522800fd
This commit is contained in:
commit
fcb035fb4f
|
@ -53,13 +53,12 @@ pub type Psbt = PartiallySignedTransaction;
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
pub struct PartiallySignedTransaction {
|
pub struct PartiallySignedTransaction {
|
||||||
/// The unsigned transaction, scriptSigs and witnesses for each input must be
|
/// The unsigned transaction, scriptSigs and witnesses for each input must be empty.
|
||||||
/// empty.
|
|
||||||
pub unsigned_tx: Transaction,
|
pub unsigned_tx: Transaction,
|
||||||
/// The version number of this PSBT. If omitted, the version number is 0.
|
/// The version number of this PSBT. If omitted, the version number is 0.
|
||||||
pub version: u32,
|
pub version: u32,
|
||||||
/// A global map from extended public keys to the used key fingerprint and
|
/// A global map from extended public keys to the used key fingerprint and
|
||||||
/// derivation path as defined by BIP 32
|
/// derivation path as defined by BIP 32.
|
||||||
pub xpub: BTreeMap<ExtendedPubKey, KeySource>,
|
pub xpub: BTreeMap<ExtendedPubKey, KeySource>,
|
||||||
/// Global proprietary key-value pairs.
|
/// Global proprietary key-value pairs.
|
||||||
#[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_as_seq_byte_values"))]
|
#[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_as_seq_byte_values"))]
|
||||||
|
@ -68,11 +67,9 @@ pub struct PartiallySignedTransaction {
|
||||||
#[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_as_seq_byte_values"))]
|
#[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_as_seq_byte_values"))]
|
||||||
pub unknown: BTreeMap<raw::Key, Vec<u8>>,
|
pub unknown: BTreeMap<raw::Key, Vec<u8>>,
|
||||||
|
|
||||||
/// The corresponding key-value map for each input in the unsigned
|
/// The corresponding key-value map for each input in the unsigned transaction.
|
||||||
/// transaction.
|
|
||||||
pub inputs: Vec<Input>,
|
pub inputs: Vec<Input>,
|
||||||
/// The corresponding key-value map for each output in the unsigned
|
/// The corresponding key-value map for each output in the unsigned transaction.
|
||||||
/// transaction.
|
|
||||||
pub outputs: Vec<Output>,
|
pub outputs: Vec<Output>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,8 +100,7 @@ impl PartiallySignedTransaction {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks that unsigned transaction does not have scriptSig's or witness
|
/// Checks that unsigned transaction does not have scriptSig's or witness data.
|
||||||
/// data
|
|
||||||
fn unsigned_tx_checks(&self) -> Result<(), Error> {
|
fn unsigned_tx_checks(&self) -> Result<(), Error> {
|
||||||
for txin in &self.unsigned_tx.input {
|
for txin in &self.unsigned_tx.input {
|
||||||
if !txin.script_sig.is_empty() {
|
if !txin.script_sig.is_empty() {
|
||||||
|
@ -119,8 +115,11 @@ impl PartiallySignedTransaction {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a PartiallySignedTransaction from an unsigned transaction, error
|
/// Creates a PSBT from an unsigned transaction.
|
||||||
/// if not unsigned
|
///
|
||||||
|
/// # Errors
|
||||||
|
///
|
||||||
|
/// If transactions is not unsigned.
|
||||||
pub fn from_unsigned_tx(tx: Transaction) -> Result<Self, Error> {
|
pub fn from_unsigned_tx(tx: Transaction) -> Result<Self, Error> {
|
||||||
let psbt = PartiallySignedTransaction {
|
let psbt = PartiallySignedTransaction {
|
||||||
inputs: vec![Default::default(); tx.input.len()],
|
inputs: vec![Default::default(); tx.input.len()],
|
||||||
|
@ -136,8 +135,7 @@ impl PartiallySignedTransaction {
|
||||||
Ok(psbt)
|
Ok(psbt)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extract the Transaction from a PartiallySignedTransaction by filling in
|
/// Extracts the `Transaction` from a PSBT by filling in the available signature information.
|
||||||
/// the available signature information in place.
|
|
||||||
pub fn extract_tx(self) -> Transaction {
|
pub fn extract_tx(self) -> Transaction {
|
||||||
let mut tx: Transaction = self.unsigned_tx;
|
let mut tx: Transaction = self.unsigned_tx;
|
||||||
|
|
||||||
|
@ -222,13 +220,13 @@ mod display_from_str {
|
||||||
use crate::consensus::encode::{Error, self};
|
use crate::consensus::encode::{Error, self};
|
||||||
use base64::display::Base64Display;
|
use base64::display::Base64Display;
|
||||||
|
|
||||||
/// Error happening during PSBT decoding from Base64 string
|
/// Error encountered during PSBT decoding from Base64 string.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "base64")))]
|
#[cfg_attr(docsrs, doc(cfg(feature = "base64")))]
|
||||||
pub enum PsbtParseError {
|
pub enum PsbtParseError {
|
||||||
/// Error in internal PSBT data structure
|
/// Error in internal PSBT data structure.
|
||||||
PsbtEncoding(Error),
|
PsbtEncoding(Error),
|
||||||
/// Error in PSBT Base64 encoding
|
/// Error in PSBT Base64 encoding.
|
||||||
Base64Encoding(::base64::DecodeError)
|
Base64Encoding(::base64::DecodeError)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,33 +39,33 @@ use super::taproot::LeafVersion;
|
||||||
/// Efficiently calculates signature hash message for legacy, segwit and taproot inputs.
|
/// Efficiently calculates signature hash message for legacy, segwit and taproot inputs.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct SighashCache<T: Deref<Target=Transaction>> {
|
pub struct SighashCache<T: Deref<Target=Transaction>> {
|
||||||
/// Access to transaction required for various introspection, moreover type
|
/// Access to transaction required for transaction introspection. Moreover, type
|
||||||
/// `T: Deref<Target=Transaction>` allows to accept borrow and mutable borrow, the
|
/// `T: Deref<Target=Transaction>` allows us to use borrowed and mutable borrowed types,
|
||||||
/// latter in particular is necessary for [`SighashCache::witness_mut`]
|
/// the latter in particular is necessary for [`SighashCache::witness_mut`].
|
||||||
tx: T,
|
tx: T,
|
||||||
|
|
||||||
/// Common cache for taproot and segwit inputs. It's an option because it's not needed for legacy inputs
|
/// Common cache for taproot and segwit inputs, `None` for legacy inputs.
|
||||||
common_cache: Option<CommonCache>,
|
common_cache: Option<CommonCache>,
|
||||||
|
|
||||||
/// Cache for segwit v0 inputs, it's the result of another round of sha256 on `common_cache`
|
/// Cache for segwit v0 inputs (the result of another round of sha256 on `common_cache`).
|
||||||
segwit_cache: Option<SegwitCache>,
|
segwit_cache: Option<SegwitCache>,
|
||||||
|
|
||||||
/// Cache for taproot v1 inputs
|
/// Cache for taproot v1 inputs.
|
||||||
taproot_cache: Option<TaprootCache>,
|
taproot_cache: Option<TaprootCache>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Values cached common between segwit and taproot inputs
|
/// Common values cached between segwit and taproot inputs.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct CommonCache {
|
struct CommonCache {
|
||||||
prevouts: sha256::Hash,
|
prevouts: sha256::Hash,
|
||||||
sequences: sha256::Hash,
|
sequences: sha256::Hash,
|
||||||
|
|
||||||
/// in theory, `outputs` could be `Option` since `NONE` and `SINGLE` doesn't need it, but since
|
/// In theory `outputs` could be an `Option` since `SIGHASH_NONE` and `SIGHASH_SINGLE` do not
|
||||||
/// `ALL` is the mostly used variant by large, we don't bother
|
/// need it, but since `SIGHASH_ALL` is by far the most used variant we don't bother.
|
||||||
outputs: sha256::Hash,
|
outputs: sha256::Hash,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Values cached for segwit inputs, it's equal to [`CommonCache`] plus another round of `sha256`
|
/// Values cached for segwit inputs, equivalent to [`CommonCache`] plus another round of `sha256`.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct SegwitCache {
|
struct SegwitCache {
|
||||||
prevouts: sha256d::Hash,
|
prevouts: sha256d::Hash,
|
||||||
|
@ -73,29 +73,29 @@ struct SegwitCache {
|
||||||
outputs: sha256d::Hash,
|
outputs: sha256d::Hash,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Values cached for taproot inputs
|
/// Values cached for taproot inputs.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct TaprootCache {
|
struct TaprootCache {
|
||||||
amounts: sha256::Hash,
|
amounts: sha256::Hash,
|
||||||
script_pubkeys: sha256::Hash,
|
script_pubkeys: sha256::Hash,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Contains outputs of previous transactions.
|
/// Contains outputs of previous transactions. In the case [`SchnorrSighashType`] variant is
|
||||||
/// In the case [`SchnorrSighashType`] variant is `ANYONECANPAY`, [`Prevouts::One`] may be provided
|
/// `SIGHASH_ANYONECANPAY`, [`Prevouts::One`] may be used.
|
||||||
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
|
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
|
||||||
pub enum Prevouts<'u, T> where T: 'u + Borrow<TxOut> {
|
pub enum Prevouts<'u, T> where T: 'u + Borrow<TxOut> {
|
||||||
/// `One` variant allows to provide the single Prevout needed. It's useful for example
|
/// `One` variant allows provision of the single prevout needed. It's useful, for example, when
|
||||||
/// when modifier `ANYONECANPAY` is provided, only prevout of the current input is needed.
|
/// modifier `SIGHASH_ANYONECANPAY` is provided, only prevout of the current input is needed.
|
||||||
/// The first `usize` argument is the input index this [`TxOut`] is referring to.
|
/// The first `usize` argument is the input index this [`TxOut`] is referring to.
|
||||||
One(usize, T),
|
One(usize, T),
|
||||||
/// When `ANYONECANPAY` is not provided, or the caller is handy giving all prevouts so the same
|
/// When `SIGHASH_ANYONECANPAY` is not provided, or when the caller is giving all prevouts so
|
||||||
/// variable can be used for multiple inputs.
|
/// the same variable can be used for multiple inputs.
|
||||||
All(&'u [T]),
|
All(&'u [T]),
|
||||||
}
|
}
|
||||||
|
|
||||||
const KEY_VERSION_0: u8 = 0u8;
|
const KEY_VERSION_0: u8 = 0u8;
|
||||||
|
|
||||||
/// Information related to the script path spending
|
/// Information related to the script path spending.
|
||||||
///
|
///
|
||||||
/// This can be hashed into a [`TapLeafHash`].
|
/// This can be hashed into a [`TapLeafHash`].
|
||||||
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
|
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
|
||||||
|
@ -104,29 +104,29 @@ pub struct ScriptPath<'s> {
|
||||||
leaf_version: LeafVersion,
|
leaf_version: LeafVersion,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Hashtype of an input's signature, encoded in the last byte of the signature
|
/// Hashtype of an input's signature, encoded in the last byte of the signature.
|
||||||
/// Fixed values so they can be casted as integer types for encoding
|
/// Fixed values so they can be cast as integer types for encoding.
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
|
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
|
||||||
pub enum SchnorrSighashType {
|
pub enum SchnorrSighashType {
|
||||||
/// 0x0: Used when not explicitly specified, defaulting to [`SchnorrSighashType::All`]
|
/// 0x0: Used when not explicitly specified, defaults to [`SchnorrSighashType::All`]
|
||||||
Default = 0x00,
|
Default = 0x00,
|
||||||
/// 0x1: Sign all outputs
|
/// 0x1: Sign all outputs.
|
||||||
All = 0x01,
|
All = 0x01,
|
||||||
/// 0x2: Sign no outputs --- anyone can choose the destination
|
/// 0x2: Sign no outputs --- anyone can choose the destination.
|
||||||
None = 0x02,
|
None = 0x02,
|
||||||
/// 0x3: Sign the output whose index matches this input's index. If none exists,
|
/// 0x3: Sign the output whose index matches this input's index. If none exists,
|
||||||
/// sign the hash `0000000000000000000000000000000000000000000000000000000000000001`.
|
/// sign the hash `0000000000000000000000000000000000000000000000000000000000000001`.
|
||||||
/// (This rule is probably an unintentional C++ism, but it's consensus so we have
|
/// (This rule is probably an unintentional C++ism, but it's consensus so we have
|
||||||
/// to follow it.)
|
/// to follow it.)
|
||||||
Single = 0x03,
|
Single = 0x03,
|
||||||
/// 0x81: Sign all outputs but only this input
|
/// 0x81: Sign all outputs but only this input.
|
||||||
AllPlusAnyoneCanPay = 0x81,
|
AllPlusAnyoneCanPay = 0x81,
|
||||||
/// 0x82: Sign no outputs and only this input
|
/// 0x82: Sign no outputs and only this input.
|
||||||
NonePlusAnyoneCanPay = 0x82,
|
NonePlusAnyoneCanPay = 0x82,
|
||||||
/// 0x83: Sign one output and only this input (see `Single` for what "one output" means)
|
/// 0x83: Sign one output and only this input (see `Single` for what "one output" means).
|
||||||
SinglePlusAnyoneCanPay = 0x83,
|
SinglePlusAnyoneCanPay = 0x83,
|
||||||
|
|
||||||
/// Reserved for future use, `#[non_exhaustive]` is not available with current MSRV
|
/// Reserved for future use, `#[non_exhaustive]` is not available with MSRV 1.29.0
|
||||||
Reserved = 0xFF,
|
Reserved = 0xFF,
|
||||||
}
|
}
|
||||||
serde_string_impl!(SchnorrSighashType, "a SchnorrSighashType data");
|
serde_string_impl!(SchnorrSighashType, "a SchnorrSighashType data");
|
||||||
|
@ -165,45 +165,46 @@ impl str::FromStr for SchnorrSighashType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Possible errors in computing the signature message
|
/// Possible errors in computing the signature message.
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
|
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
/// Could happen only by using `*_encode_signing_*` methods with custom writers, engines writers
|
/// Could happen only by using `*_encode_signing_*` methods with custom writers, engines writers
|
||||||
/// like the ones used in methods `*_signature_hash` don't error
|
/// like the ones used in methods `*_signature_hash` do not error.
|
||||||
Io(io::ErrorKind),
|
Io(io::ErrorKind),
|
||||||
|
|
||||||
/// Requested index is greater or equal than the number of inputs in the transaction
|
/// Requested index is greater or equal than the number of inputs in the transaction.
|
||||||
IndexOutOfInputsBounds {
|
IndexOutOfInputsBounds {
|
||||||
/// Requested index
|
/// Requested index.
|
||||||
index: usize,
|
index: usize,
|
||||||
/// Number of transaction inputs
|
/// Number of transaction inputs.
|
||||||
inputs_size: usize,
|
inputs_size: usize,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// Using SIGHASH_SINGLE without a "corresponding output" (an output with the same index as the
|
/// Using `SIGHASH_SINGLE` without a "corresponding output" (an output with the same index as
|
||||||
/// input being verified) is a validation failure
|
/// the input being verified) is a validation failure.
|
||||||
SingleWithoutCorrespondingOutput {
|
SingleWithoutCorrespondingOutput {
|
||||||
/// Requested index
|
/// Requested index.
|
||||||
index: usize,
|
index: usize,
|
||||||
/// Number of transaction outputs
|
/// Number of transaction outputs.
|
||||||
outputs_size: usize,
|
outputs_size: usize,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// There are mismatches in the number of prevouts provided compared with the number of
|
/// There are mismatches in the number of prevouts provided compared to the number of inputs in
|
||||||
/// inputs in the transaction
|
/// the transaction.
|
||||||
PrevoutsSize,
|
PrevoutsSize,
|
||||||
|
|
||||||
/// Requested a prevout index which is greater than the number of prevouts provided or a
|
/// Requested a prevout index which is greater than the number of prevouts provided or a
|
||||||
/// [`Prevouts::One`] with different index
|
/// [`Prevouts::One`] with different index.
|
||||||
PrevoutIndex,
|
PrevoutIndex,
|
||||||
|
|
||||||
/// A single prevout has been provided but all prevouts are needed without `ANYONECANPAY`
|
/// A single prevout has been provided but all prevouts are needed unless using
|
||||||
|
/// `SIGHASH_ANYONECANPAY`.
|
||||||
PrevoutKind,
|
PrevoutKind,
|
||||||
|
|
||||||
/// Annex must be at least one byte long and the first bytes must be `0x50`
|
/// Annex must be at least one byte long and the first bytes must be `0x50`.
|
||||||
WrongAnnex,
|
WrongAnnex,
|
||||||
|
|
||||||
/// Invalid Sighash type
|
/// Invalid Sighash type.
|
||||||
InvalidSighashType(u32),
|
InvalidSighashType(u32),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -260,18 +261,18 @@ impl<'u, T> Prevouts<'u, T> where T: Borrow<TxOut> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'s> ScriptPath<'s> {
|
impl<'s> ScriptPath<'s> {
|
||||||
/// Create a new ScriptPath structure
|
/// Creates a new `ScriptPath` structure.
|
||||||
pub fn new(script: &'s Script, leaf_version: LeafVersion) -> Self {
|
pub fn new(script: &'s Script, leaf_version: LeafVersion) -> Self {
|
||||||
ScriptPath {
|
ScriptPath {
|
||||||
script,
|
script,
|
||||||
leaf_version,
|
leaf_version,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Create a new ScriptPath structure using default leaf version value
|
/// Creates a new `ScriptPath` structure using default leaf version value.
|
||||||
pub fn with_defaults(script: &'s Script) -> Self {
|
pub fn with_defaults(script: &'s Script) -> Self {
|
||||||
Self::new(script, LeafVersion::TapScript)
|
Self::new(script, LeafVersion::TapScript)
|
||||||
}
|
}
|
||||||
/// Compute the leaf hash
|
/// Computes the leaf hash for this `ScriptPath`.
|
||||||
pub fn leaf_hash(&self) -> TapLeafHash {
|
pub fn leaf_hash(&self) -> TapLeafHash {
|
||||||
let mut enc = TapLeafHash::engine();
|
let mut enc = TapLeafHash::engine();
|
||||||
|
|
||||||
|
@ -302,7 +303,7 @@ impl From<EcdsaSighashType> for SchnorrSighashType {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SchnorrSighashType {
|
impl SchnorrSighashType {
|
||||||
/// Break the sighash flag into the "real" sighash flag and the ANYONECANPAY boolean
|
/// Breaks the sighash flag into the "real" sighash flag and the `SIGHASH_ANYONECANPAY` boolean.
|
||||||
pub(crate) fn split_anyonecanpay_flag(self) -> (SchnorrSighashType, bool) {
|
pub(crate) fn split_anyonecanpay_flag(self) -> (SchnorrSighashType, bool) {
|
||||||
match self {
|
match self {
|
||||||
SchnorrSighashType::Default => (SchnorrSighashType::Default, false),
|
SchnorrSighashType::Default => (SchnorrSighashType::Default, false),
|
||||||
|
@ -316,7 +317,7 @@ impl SchnorrSighashType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a [`SchnorrSighashType`] from raw `u8`
|
/// Creates a [`SchnorrSighashType`] from raw `u8`.
|
||||||
pub fn from_u8(hash_ty: u8) -> Result<Self, Error> {
|
pub fn from_u8(hash_ty: u8) -> Result<Self, Error> {
|
||||||
match hash_ty {
|
match hash_ty {
|
||||||
0x00 => Ok(SchnorrSighashType::Default),
|
0x00 => Ok(SchnorrSighashType::Default),
|
||||||
|
@ -333,10 +334,11 @@ impl SchnorrSighashType {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: Deref<Target = Transaction>> SighashCache<R> {
|
impl<R: Deref<Target = Transaction>> SighashCache<R> {
|
||||||
/// Compute the sighash components from an unsigned transaction and auxiliary
|
/// Constructs a new `SighashCache` from an unsigned transaction.
|
||||||
/// in a lazy manner when required.
|
///
|
||||||
/// For the generated sighashes to be valid, no fields in the transaction may change except for
|
/// The sighash components are computed in a lazy manner when required. For the generated
|
||||||
/// script_sig and witnesses.
|
/// sighashes to be valid, no fields in the transaction may change except for script_sig and
|
||||||
|
/// witness.
|
||||||
pub fn new(tx: R) -> Self {
|
pub fn new(tx: R) -> Self {
|
||||||
SighashCache {
|
SighashCache {
|
||||||
tx,
|
tx,
|
||||||
|
@ -346,8 +348,8 @@ impl<R: Deref<Target=Transaction>> SighashCache<R> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Encode the BIP341 signing data for any flag type into a given object implementing a
|
/// Encodes the BIP341 signing data for any flag type into a given object implementing a
|
||||||
/// io::Write trait.
|
/// [`io::Write`] trait.
|
||||||
pub fn taproot_encode_signing_data_to<Write: io::Write, T: Borrow<TxOut>>(
|
pub fn taproot_encode_signing_data_to<Write: io::Write, T: Borrow<TxOut>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
mut writer: Write,
|
mut writer: Write,
|
||||||
|
@ -477,7 +479,7 @@ impl<R: Deref<Target=Transaction>> SighashCache<R> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Compute the BIP341 sighash for any flag type.
|
/// Computes the BIP341 sighash for any flag type.
|
||||||
pub fn taproot_signature_hash<T: Borrow<TxOut>>(
|
pub fn taproot_signature_hash<T: Borrow<TxOut>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
input_index: usize,
|
input_index: usize,
|
||||||
|
@ -498,7 +500,7 @@ impl<R: Deref<Target=Transaction>> SighashCache<R> {
|
||||||
Ok(TapSighashHash::from_engine(enc))
|
Ok(TapSighashHash::from_engine(enc))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Compute the BIP341 sighash for a key spend
|
/// Computes the BIP341 sighash for a key spend.
|
||||||
pub fn taproot_key_spend_signature_hash<T: Borrow<TxOut>>(
|
pub fn taproot_key_spend_signature_hash<T: Borrow<TxOut>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
input_index: usize,
|
input_index: usize,
|
||||||
|
@ -517,7 +519,7 @@ impl<R: Deref<Target=Transaction>> SighashCache<R> {
|
||||||
Ok(TapSighashHash::from_engine(enc))
|
Ok(TapSighashHash::from_engine(enc))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Compute the BIP341 sighash for a script spend
|
/// Computes the BIP341 sighash for a script spend.
|
||||||
///
|
///
|
||||||
/// Assumes the default `OP_CODESEPARATOR` position of `0xFFFFFFFF`. Custom values can be
|
/// 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`].
|
/// provided through the more fine-grained API of [`SighashCache::taproot_encode_signing_data_to`].
|
||||||
|
@ -540,7 +542,7 @@ impl<R: Deref<Target=Transaction>> SighashCache<R> {
|
||||||
Ok(TapSighashHash::from_engine(enc))
|
Ok(TapSighashHash::from_engine(enc))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Encode the BIP143 signing data for any flag type into a given object implementing a
|
/// Encodes the BIP143 signing data for any flag type into a given object implementing a
|
||||||
/// [`std::io::Write`] trait.
|
/// [`std::io::Write`] trait.
|
||||||
pub fn segwit_encode_signing_data_to<Write: io::Write>(
|
pub fn segwit_encode_signing_data_to<Write: io::Write>(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
@ -605,7 +607,7 @@ impl<R: Deref<Target=Transaction>> SighashCache<R> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Compute the BIP143 sighash for any flag type.
|
/// Computes the BIP143 sighash for any flag type.
|
||||||
pub fn segwit_signature_hash(
|
pub fn segwit_signature_hash(
|
||||||
&mut self,
|
&mut self,
|
||||||
input_index: usize,
|
input_index: usize,
|
||||||
|
@ -624,8 +626,8 @@ impl<R: Deref<Target=Transaction>> SighashCache<R> {
|
||||||
Ok(Sighash::from_engine(enc))
|
Ok(Sighash::from_engine(enc))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Encode the legacy signing data for any flag type into a given object implementing a
|
/// Encodes the legacy signing data for any flag type into a given object implementing a
|
||||||
/// [`std::io::Write`] trait. Internally calls [`Transaction::encode_signing_data_to`]
|
/// [`std::io::Write`] trait. Internally calls [`Transaction::encode_signing_data_to`].
|
||||||
pub fn legacy_encode_signing_data_to<Write: io::Write, U: Into<u32>>(
|
pub fn legacy_encode_signing_data_to<Write: io::Write, U: Into<u32>>(
|
||||||
&self,
|
&self,
|
||||||
mut writer: Write,
|
mut writer: Write,
|
||||||
|
@ -645,7 +647,7 @@ impl<R: Deref<Target=Transaction>> SighashCache<R> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the legacy sighash for any sighash type.
|
/// Computes the legacy sighash for any `sighash_type`.
|
||||||
pub fn legacy_signature_hash(
|
pub fn legacy_signature_hash(
|
||||||
&self,
|
&self,
|
||||||
input_index: usize,
|
input_index: usize,
|
||||||
|
@ -730,8 +732,8 @@ impl<R: Deref<Target=Transaction>> SighashCache<R> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: DerefMut<Target=Transaction>> SighashCache<R> {
|
impl<R: DerefMut<Target=Transaction>> SighashCache<R> {
|
||||||
/// When the SighashCache is initialized with a mutable reference to a transaction instead of a
|
/// When the `SighashCache` is initialized with a mutable reference to a transaction instead of
|
||||||
/// regular reference, this method is available to allow modification to the witnesses.
|
/// a regular reference, this method is available to allow modification to the witnesses.
|
||||||
///
|
///
|
||||||
/// This allows in-line signing such as
|
/// This allows in-line signing such as
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -761,12 +763,12 @@ impl From<io::Error> for Error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The `Annex` struct is a slice wrapper enforcing first byte to be `0x50`.
|
/// The `Annex` struct is a slice wrapper enforcing first byte is `0x50`.
|
||||||
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
|
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
|
||||||
pub struct Annex<'a>(&'a [u8]);
|
pub struct Annex<'a>(&'a [u8]);
|
||||||
|
|
||||||
impl<'a> Annex<'a> {
|
impl<'a> Annex<'a> {
|
||||||
/// Creates a new `Annex` struct checking the first byte is `0x50`
|
/// Creates a new `Annex` struct checking the first byte is `0x50`.
|
||||||
pub fn new(annex_bytes: &'a [u8]) -> Result<Self, Error> {
|
pub fn new(annex_bytes: &'a [u8]) -> Result<Self, Error> {
|
||||||
if annex_bytes.first() == Some(&TAPROOT_ANNEX_PREFIX) {
|
if annex_bytes.first() == Some(&TAPROOT_ANNEX_PREFIX) {
|
||||||
Ok(Annex(annex_bytes))
|
Ok(Annex(annex_bytes))
|
||||||
|
@ -775,7 +777,7 @@ impl<'a> Annex<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the Annex bytes data (including first byte `0x50`)
|
/// Returns the Annex bytes data (including first byte `0x50`).
|
||||||
pub fn as_bytes(&self) -> &[u8] {
|
pub fn as_bytes(&self) -> &[u8] {
|
||||||
&*self.0
|
&*self.0
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue