Rename EcdsaSigHashType -> EcdsaSighashType
Our usage of `SigHash` implies that 'sighash' is _two_ words; 'sighash' is a well known word in the Bitcoin ecosystem it should appear in identifiers as `Sighash`. Rename `EcdsaSigHashType` to `EcdsaSighashType`.
This commit is contained in:
parent
58a958e3f7
commit
5522454583
|
@ -319,10 +319,10 @@ impl Transaction {
|
||||||
/// sighash flag can be computed.
|
/// sighash flag can be computed.
|
||||||
///
|
///
|
||||||
/// To actually produce a scriptSig, this hash needs to be run through an ECDSA signer, the
|
/// 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
|
/// [`EcdsaSighashType`] appended to the resulting sig, and a script written around this, but
|
||||||
/// this is the general (and hard) part.
|
/// this is the general (and hard) part.
|
||||||
///
|
///
|
||||||
/// The `sighash_type` supports an arbitrary `u32` value, instead of just [`EcdsaSigHashType`],
|
/// 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
|
/// because internally 4 bytes are being hashed, even though only the lowest byte is appended to
|
||||||
/// signature in a transaction.
|
/// signature in a transaction.
|
||||||
///
|
///
|
||||||
|
@ -356,7 +356,7 @@ impl Transaction {
|
||||||
return Ok(())
|
return Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
let (sighash, anyone_can_pay) = EcdsaSigHashType::from_consensus(sighash_type).split_anyonecanpay_flag();
|
let (sighash, anyone_can_pay) = EcdsaSighashType::from_consensus(sighash_type).split_anyonecanpay_flag();
|
||||||
|
|
||||||
// Build tx to sign
|
// Build tx to sign
|
||||||
let mut tx = Transaction {
|
let mut tx = Transaction {
|
||||||
|
@ -379,22 +379,22 @@ impl Transaction {
|
||||||
tx.input.push(TxIn {
|
tx.input.push(TxIn {
|
||||||
previous_output: input.previous_output,
|
previous_output: input.previous_output,
|
||||||
script_sig: if n == input_index { script_pubkey.clone() } else { Script::new() },
|
script_sig: if n == input_index { script_pubkey.clone() } else { Script::new() },
|
||||||
sequence: if n != input_index && (sighash == EcdsaSigHashType::Single || sighash == EcdsaSigHashType::None) { 0 } else { input.sequence },
|
sequence: if n != input_index && (sighash == EcdsaSighashType::Single || sighash == EcdsaSighashType::None) { 0 } else { input.sequence },
|
||||||
witness: Witness::default(),
|
witness: Witness::default(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// ..then all outputs
|
// ..then all outputs
|
||||||
tx.output = match sighash {
|
tx.output = match sighash {
|
||||||
EcdsaSigHashType::All => self.output.clone(),
|
EcdsaSighashType::All => self.output.clone(),
|
||||||
EcdsaSigHashType::Single => {
|
EcdsaSighashType::Single => {
|
||||||
let output_iter = self.output.iter()
|
let output_iter = self.output.iter()
|
||||||
.take(input_index + 1) // sign all outputs up to and including this one, but erase
|
.take(input_index + 1) // sign all outputs up to and including this one, but erase
|
||||||
.enumerate() // all of them except for this one
|
.enumerate() // all of them except for this one
|
||||||
.map(|(n, out)| if n == input_index { out.clone() } else { TxOut::default() });
|
.map(|(n, out)| if n == input_index { out.clone() } else { TxOut::default() });
|
||||||
output_iter.collect()
|
output_iter.collect()
|
||||||
}
|
}
|
||||||
EcdsaSigHashType::None => vec![],
|
EcdsaSighashType::None => vec![],
|
||||||
_ => unreachable!()
|
_ => unreachable!()
|
||||||
};
|
};
|
||||||
// hash the result
|
// hash the result
|
||||||
|
@ -407,10 +407,10 @@ impl Transaction {
|
||||||
/// Computes a signature hash for a given input index with a given sighash flag.
|
/// Computes a 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
|
/// 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
|
/// [`EcdsaSighashType`] appended to the resulting sig, and a script written around this, but
|
||||||
/// this is the general (and hard) part.
|
/// this is the general (and hard) part.
|
||||||
///
|
///
|
||||||
/// The `sighash_type` supports an arbitrary `u32` value, instead of just [`EcdsaSigHashType`],
|
/// 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
|
/// because internally 4 bytes are being hashed, even though only the lowest byte is appended to
|
||||||
/// signature in a transaction.
|
/// signature in a transaction.
|
||||||
///
|
///
|
||||||
|
@ -444,8 +444,8 @@ impl Transaction {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_invalid_use_of_sighash_single(&self, sighash: u32, input_index: usize) -> bool {
|
fn is_invalid_use_of_sighash_single(&self, sighash: u32, input_index: usize) -> bool {
|
||||||
let ty = EcdsaSigHashType::from_consensus(sighash);
|
let ty = EcdsaSighashType::from_consensus(sighash);
|
||||||
ty == EcdsaSigHashType::Single && input_index >= self.output.len()
|
ty == EcdsaSighashType::Single && input_index >= self.output.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the "weight" of this transaction, as defined by BIP141.
|
/// Returns the "weight" of this transaction, as defined by BIP141.
|
||||||
|
@ -736,15 +736,15 @@ impl fmt::Display for NonStandardSigHashType {
|
||||||
impl error::Error for NonStandardSigHashType {}
|
impl error::Error for NonStandardSigHashType {}
|
||||||
|
|
||||||
/// Legacy Hashtype of an input's signature
|
/// Legacy Hashtype of an input's signature
|
||||||
#[deprecated(since = "0.28.0", note = "Please use [`EcdsaSigHashType`] instead")]
|
#[deprecated(since = "0.28.0", note = "Please use [`EcdsaSighashType`] instead")]
|
||||||
pub type SigHashType = EcdsaSigHashType;
|
pub type SigHashType = EcdsaSighashType;
|
||||||
|
|
||||||
/// 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 cast as integer types for encoding (see also
|
/// Fixed values so they can be cast as integer types for encoding (see also
|
||||||
/// [`SchnorrSigHashType`]).
|
/// [`SchnorrSigHashType`]).
|
||||||
#[derive(PartialEq, Eq, Debug, Copy, Clone)]
|
#[derive(PartialEq, Eq, Debug, Copy, Clone)]
|
||||||
pub enum EcdsaSigHashType {
|
pub enum EcdsaSighashType {
|
||||||
/// 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.
|
||||||
|
@ -761,67 +761,67 @@ pub enum EcdsaSigHashType {
|
||||||
/// 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
|
||||||
}
|
}
|
||||||
serde_string_impl!(EcdsaSigHashType, "a EcdsaSigHashType data");
|
serde_string_impl!(EcdsaSighashType, "a EcdsaSighashType data");
|
||||||
|
|
||||||
impl fmt::Display for EcdsaSigHashType {
|
impl fmt::Display for EcdsaSighashType {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
let s = match self {
|
let s = match self {
|
||||||
EcdsaSigHashType::All => "SIGHASH_ALL",
|
EcdsaSighashType::All => "SIGHASH_ALL",
|
||||||
EcdsaSigHashType::None => "SIGHASH_NONE",
|
EcdsaSighashType::None => "SIGHASH_NONE",
|
||||||
EcdsaSigHashType::Single => "SIGHASH_SINGLE",
|
EcdsaSighashType::Single => "SIGHASH_SINGLE",
|
||||||
EcdsaSigHashType::AllPlusAnyoneCanPay => "SIGHASH_ALL|SIGHASH_ANYONECANPAY",
|
EcdsaSighashType::AllPlusAnyoneCanPay => "SIGHASH_ALL|SIGHASH_ANYONECANPAY",
|
||||||
EcdsaSigHashType::NonePlusAnyoneCanPay => "SIGHASH_NONE|SIGHASH_ANYONECANPAY",
|
EcdsaSighashType::NonePlusAnyoneCanPay => "SIGHASH_NONE|SIGHASH_ANYONECANPAY",
|
||||||
EcdsaSigHashType::SinglePlusAnyoneCanPay => "SIGHASH_SINGLE|SIGHASH_ANYONECANPAY",
|
EcdsaSighashType::SinglePlusAnyoneCanPay => "SIGHASH_SINGLE|SIGHASH_ANYONECANPAY",
|
||||||
};
|
};
|
||||||
f.write_str(s)
|
f.write_str(s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl str::FromStr for EcdsaSigHashType {
|
impl str::FromStr for EcdsaSighashType {
|
||||||
type Err = SigHashTypeParseError;
|
type Err = SigHashTypeParseError;
|
||||||
|
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
match s {
|
match s {
|
||||||
"SIGHASH_ALL" => Ok(EcdsaSigHashType::All),
|
"SIGHASH_ALL" => Ok(EcdsaSighashType::All),
|
||||||
"SIGHASH_NONE" => Ok(EcdsaSigHashType::None),
|
"SIGHASH_NONE" => Ok(EcdsaSighashType::None),
|
||||||
"SIGHASH_SINGLE" => Ok(EcdsaSigHashType::Single),
|
"SIGHASH_SINGLE" => Ok(EcdsaSighashType::Single),
|
||||||
"SIGHASH_ALL|SIGHASH_ANYONECANPAY" => Ok(EcdsaSigHashType::AllPlusAnyoneCanPay),
|
"SIGHASH_ALL|SIGHASH_ANYONECANPAY" => Ok(EcdsaSighashType::AllPlusAnyoneCanPay),
|
||||||
"SIGHASH_NONE|SIGHASH_ANYONECANPAY" => Ok(EcdsaSigHashType::NonePlusAnyoneCanPay),
|
"SIGHASH_NONE|SIGHASH_ANYONECANPAY" => Ok(EcdsaSighashType::NonePlusAnyoneCanPay),
|
||||||
"SIGHASH_SINGLE|SIGHASH_ANYONECANPAY" => Ok(EcdsaSigHashType::SinglePlusAnyoneCanPay),
|
"SIGHASH_SINGLE|SIGHASH_ANYONECANPAY" => Ok(EcdsaSighashType::SinglePlusAnyoneCanPay),
|
||||||
_ => Err(SigHashTypeParseError { unrecognized: s.to_owned() }),
|
_ => Err(SigHashTypeParseError { unrecognized: s.to_owned() }),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EcdsaSigHashType {
|
impl EcdsaSighashType {
|
||||||
/// Splits the sighash flag into the "real" sighash flag and the ANYONECANPAY boolean.
|
/// Splits the sighash flag into the "real" sighash flag and the ANYONECANPAY boolean.
|
||||||
pub(crate) fn split_anyonecanpay_flag(self) -> (EcdsaSigHashType, bool) {
|
pub(crate) fn split_anyonecanpay_flag(self) -> (EcdsaSighashType, bool) {
|
||||||
match self {
|
match self {
|
||||||
EcdsaSigHashType::All => (EcdsaSigHashType::All, false),
|
EcdsaSighashType::All => (EcdsaSighashType::All, false),
|
||||||
EcdsaSigHashType::None => (EcdsaSigHashType::None, false),
|
EcdsaSighashType::None => (EcdsaSighashType::None, false),
|
||||||
EcdsaSigHashType::Single => (EcdsaSigHashType::Single, false),
|
EcdsaSighashType::Single => (EcdsaSighashType::Single, false),
|
||||||
EcdsaSigHashType::AllPlusAnyoneCanPay => (EcdsaSigHashType::All, true),
|
EcdsaSighashType::AllPlusAnyoneCanPay => (EcdsaSighashType::All, true),
|
||||||
EcdsaSigHashType::NonePlusAnyoneCanPay => (EcdsaSigHashType::None, true),
|
EcdsaSighashType::NonePlusAnyoneCanPay => (EcdsaSighashType::None, true),
|
||||||
EcdsaSigHashType::SinglePlusAnyoneCanPay => (EcdsaSigHashType::Single, true)
|
EcdsaSighashType::SinglePlusAnyoneCanPay => (EcdsaSighashType::Single, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a [`EcdsaSigHashType`] from a raw `u32`.
|
/// Creates a [`EcdsaSighashType`] from a raw `u32`.
|
||||||
#[deprecated(since="0.28.0", note="please use `from_consensus`")]
|
#[deprecated(since="0.28.0", note="please use `from_consensus`")]
|
||||||
pub fn from_u32_consensus(n: u32) -> EcdsaSigHashType {
|
pub fn from_u32_consensus(n: u32) -> EcdsaSighashType {
|
||||||
EcdsaSigHashType::from_consensus(n)
|
EcdsaSighashType::from_consensus(n)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a [`EcdsaSigHashType`] from a raw `u32`.
|
/// Creates a [`EcdsaSighashType`] from a raw `u32`.
|
||||||
///
|
///
|
||||||
/// **Note**: this replicates consensus behaviour, for current standardness rules correctness
|
/// **Note**: this replicates consensus behaviour, for current standardness rules correctness
|
||||||
/// you probably want [`Self::from_standard`].
|
/// you probably want [`Self::from_standard`].
|
||||||
///
|
///
|
||||||
/// This might cause unexpected behavior because it does not roundtrip. That is,
|
/// This might cause unexpected behavior because it does not roundtrip. That is,
|
||||||
/// `EcdsaSigHashType::from_consensus(n) as u32 != n` for non-standard values of `n`. While
|
/// `EcdsaSighashType::from_consensus(n) as u32 != n` for non-standard values of `n`. While
|
||||||
/// verifying signatures, the user should retain the `n` and use it compute the signature hash
|
/// verifying signatures, the user should retain the `n` and use it compute the signature hash
|
||||||
/// message.
|
/// message.
|
||||||
pub fn from_consensus(n: u32) -> EcdsaSigHashType {
|
pub fn from_consensus(n: u32) -> EcdsaSighashType {
|
||||||
// In Bitcoin Core, the SignatureHash function will mask the (int32) value with
|
// In Bitcoin Core, the SignatureHash function will mask the (int32) value with
|
||||||
// 0x1f to (apparently) deactivate ACP when checking for SINGLE and NONE bits.
|
// 0x1f to (apparently) deactivate ACP when checking for SINGLE and NONE bits.
|
||||||
// We however want to be matching also against on ACP-masked ALL, SINGLE, and NONE.
|
// We however want to be matching also against on ACP-masked ALL, SINGLE, and NONE.
|
||||||
|
@ -829,43 +829,43 @@ impl EcdsaSigHashType {
|
||||||
let mask = 0x1f | 0x80;
|
let mask = 0x1f | 0x80;
|
||||||
match n & mask {
|
match n & mask {
|
||||||
// "real" sighashes
|
// "real" sighashes
|
||||||
0x01 => EcdsaSigHashType::All,
|
0x01 => EcdsaSighashType::All,
|
||||||
0x02 => EcdsaSigHashType::None,
|
0x02 => EcdsaSighashType::None,
|
||||||
0x03 => EcdsaSigHashType::Single,
|
0x03 => EcdsaSighashType::Single,
|
||||||
0x81 => EcdsaSigHashType::AllPlusAnyoneCanPay,
|
0x81 => EcdsaSighashType::AllPlusAnyoneCanPay,
|
||||||
0x82 => EcdsaSigHashType::NonePlusAnyoneCanPay,
|
0x82 => EcdsaSighashType::NonePlusAnyoneCanPay,
|
||||||
0x83 => EcdsaSigHashType::SinglePlusAnyoneCanPay,
|
0x83 => EcdsaSighashType::SinglePlusAnyoneCanPay,
|
||||||
// catchalls
|
// catchalls
|
||||||
x if x & 0x80 == 0x80 => EcdsaSigHashType::AllPlusAnyoneCanPay,
|
x if x & 0x80 == 0x80 => EcdsaSighashType::AllPlusAnyoneCanPay,
|
||||||
_ => EcdsaSigHashType::All
|
_ => EcdsaSighashType::All
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a [`EcdsaSigHashType`] from a raw `u32`.
|
/// Creates a [`EcdsaSighashType`] from a raw `u32`.
|
||||||
#[deprecated(since="0.28.0", note="please use `from_standard`")]
|
#[deprecated(since="0.28.0", note="please use `from_standard`")]
|
||||||
pub fn from_u32_standard(n: u32) -> Result<EcdsaSigHashType, NonStandardSigHashType> {
|
pub fn from_u32_standard(n: u32) -> Result<EcdsaSighashType, NonStandardSigHashType> {
|
||||||
EcdsaSigHashType::from_standard(n)
|
EcdsaSighashType::from_standard(n)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a [`EcdsaSigHashType`] from a raw `u32`.
|
/// Creates a [`EcdsaSighashType`] from a raw `u32`.
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
///
|
///
|
||||||
/// If `n` is a non-standard sighash value.
|
/// If `n` is a non-standard sighash value.
|
||||||
pub fn from_standard(n: u32) -> Result<EcdsaSigHashType, NonStandardSigHashType> {
|
pub fn from_standard(n: u32) -> Result<EcdsaSighashType, NonStandardSigHashType> {
|
||||||
match n {
|
match n {
|
||||||
// Standard sighashes, see https://github.com/bitcoin/bitcoin/blob/b805dbb0b9c90dadef0424e5b3bf86ac308e103e/src/script/interpreter.cpp#L189-L198
|
// Standard sighashes, see https://github.com/bitcoin/bitcoin/blob/b805dbb0b9c90dadef0424e5b3bf86ac308e103e/src/script/interpreter.cpp#L189-L198
|
||||||
0x01 => Ok(EcdsaSigHashType::All),
|
0x01 => Ok(EcdsaSighashType::All),
|
||||||
0x02 => Ok(EcdsaSigHashType::None),
|
0x02 => Ok(EcdsaSighashType::None),
|
||||||
0x03 => Ok(EcdsaSigHashType::Single),
|
0x03 => Ok(EcdsaSighashType::Single),
|
||||||
0x81 => Ok(EcdsaSigHashType::AllPlusAnyoneCanPay),
|
0x81 => Ok(EcdsaSighashType::AllPlusAnyoneCanPay),
|
||||||
0x82 => Ok(EcdsaSigHashType::NonePlusAnyoneCanPay),
|
0x82 => Ok(EcdsaSighashType::NonePlusAnyoneCanPay),
|
||||||
0x83 => Ok(EcdsaSigHashType::SinglePlusAnyoneCanPay),
|
0x83 => Ok(EcdsaSighashType::SinglePlusAnyoneCanPay),
|
||||||
non_standard => Err(NonStandardSigHashType(non_standard))
|
non_standard => Err(NonStandardSigHashType(non_standard))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts [`EcdsaSigHashType`] to a `u32` sighash flag.
|
/// Converts [`EcdsaSighashType`] to a `u32` sighash flag.
|
||||||
///
|
///
|
||||||
/// The returned value is guaranteed to be a valid according to standardness rules.
|
/// The returned value is guaranteed to be a valid according to standardness rules.
|
||||||
pub fn to_u32(self) -> u32 { self as u32 }
|
pub fn to_u32(self) -> u32 { self as u32 }
|
||||||
|
@ -904,7 +904,7 @@ mod tests {
|
||||||
use hashes::hex::FromHex;
|
use hashes::hex::FromHex;
|
||||||
|
|
||||||
use hash_types::*;
|
use hash_types::*;
|
||||||
use super::EcdsaSigHashType;
|
use super::EcdsaSighashType;
|
||||||
use util::sighash::SigHashCache;
|
use util::sighash::SigHashCache;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -1167,16 +1167,16 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_sighashtype_fromstr_display() {
|
fn test_sighashtype_fromstr_display() {
|
||||||
let sighashtypes = vec![
|
let sighashtypes = vec![
|
||||||
("SIGHASH_ALL", EcdsaSigHashType::All),
|
("SIGHASH_ALL", EcdsaSighashType::All),
|
||||||
("SIGHASH_NONE", EcdsaSigHashType::None),
|
("SIGHASH_NONE", EcdsaSighashType::None),
|
||||||
("SIGHASH_SINGLE", EcdsaSigHashType::Single),
|
("SIGHASH_SINGLE", EcdsaSighashType::Single),
|
||||||
("SIGHASH_ALL|SIGHASH_ANYONECANPAY", EcdsaSigHashType::AllPlusAnyoneCanPay),
|
("SIGHASH_ALL|SIGHASH_ANYONECANPAY", EcdsaSighashType::AllPlusAnyoneCanPay),
|
||||||
("SIGHASH_NONE|SIGHASH_ANYONECANPAY", EcdsaSigHashType::NonePlusAnyoneCanPay),
|
("SIGHASH_NONE|SIGHASH_ANYONECANPAY", EcdsaSighashType::NonePlusAnyoneCanPay),
|
||||||
("SIGHASH_SINGLE|SIGHASH_ANYONECANPAY", EcdsaSigHashType::SinglePlusAnyoneCanPay)
|
("SIGHASH_SINGLE|SIGHASH_ANYONECANPAY", EcdsaSighashType::SinglePlusAnyoneCanPay)
|
||||||
];
|
];
|
||||||
for (s, sht) in sighashtypes {
|
for (s, sht) in sighashtypes {
|
||||||
assert_eq!(sht.to_string(), s);
|
assert_eq!(sht.to_string(), s);
|
||||||
assert_eq!(EcdsaSigHashType::from_str(s).unwrap(), sht);
|
assert_eq!(EcdsaSighashType::from_str(s).unwrap(), sht);
|
||||||
}
|
}
|
||||||
let sht_mistakes = vec![
|
let sht_mistakes = vec![
|
||||||
"SIGHASH_ALL | SIGHASH_ANYONECANPAY",
|
"SIGHASH_ALL | SIGHASH_ANYONECANPAY",
|
||||||
|
@ -1191,7 +1191,7 @@ mod tests {
|
||||||
"SigHash_NONE",
|
"SigHash_NONE",
|
||||||
];
|
];
|
||||||
for s in sht_mistakes {
|
for s in sht_mistakes {
|
||||||
assert_eq!(EcdsaSigHashType::from_str(s).unwrap_err().to_string(), format!("Unrecognized SIGHASH string '{}'", s));
|
assert_eq!(EcdsaSighashType::from_str(s).unwrap_err().to_string(), format!("Unrecognized SIGHASH string '{}'", s));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1200,9 +1200,9 @@ mod tests {
|
||||||
fn test_sighashtype_standard() {
|
fn test_sighashtype_standard() {
|
||||||
let nonstandard_hashtype = 0x04;
|
let nonstandard_hashtype = 0x04;
|
||||||
// This type is not well defined, by consensus it becomes ALL
|
// This type is not well defined, by consensus it becomes ALL
|
||||||
assert_eq!(EcdsaSigHashType::from_u32_consensus(nonstandard_hashtype), EcdsaSigHashType::All);
|
assert_eq!(EcdsaSighashType::from_u32_consensus(nonstandard_hashtype), EcdsaSighashType::All);
|
||||||
// But it's policy-invalid to use it!
|
// But it's policy-invalid to use it!
|
||||||
assert_eq!(EcdsaSigHashType::from_u32_standard(nonstandard_hashtype), Err(NonStandardSigHashType(0x04)));
|
assert_eq!(EcdsaSighashType::from_u32_standard(nonstandard_hashtype), Err(NonStandardSigHashType(0x04)));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -123,7 +123,7 @@ pub use blockdata::transaction::Transaction;
|
||||||
pub use blockdata::transaction::TxIn;
|
pub use blockdata::transaction::TxIn;
|
||||||
pub use blockdata::transaction::TxOut;
|
pub use blockdata::transaction::TxOut;
|
||||||
pub use blockdata::transaction::OutPoint;
|
pub use blockdata::transaction::OutPoint;
|
||||||
pub use blockdata::transaction::EcdsaSigHashType;
|
pub use blockdata::transaction::EcdsaSighashType;
|
||||||
pub use blockdata::witness::Witness;
|
pub use blockdata::witness::Witness;
|
||||||
pub use consensus::encode::VarInt;
|
pub use consensus::encode::VarInt;
|
||||||
pub use network::constants::Network;
|
pub use network::constants::Network;
|
||||||
|
|
|
@ -23,7 +23,7 @@ use hashes::Hash;
|
||||||
use hash_types::SigHash;
|
use hash_types::SigHash;
|
||||||
use blockdata::script::Script;
|
use blockdata::script::Script;
|
||||||
use blockdata::witness::Witness;
|
use blockdata::witness::Witness;
|
||||||
use blockdata::transaction::{Transaction, TxIn, EcdsaSigHashType};
|
use blockdata::transaction::{Transaction, TxIn, EcdsaSighashType};
|
||||||
use consensus::{encode, Encodable};
|
use consensus::{encode, Encodable};
|
||||||
|
|
||||||
use io;
|
use io;
|
||||||
|
@ -130,7 +130,7 @@ impl<R: Deref<Target = Transaction>> SigHashCache<R> {
|
||||||
input_index: usize,
|
input_index: usize,
|
||||||
script_code: &Script,
|
script_code: &Script,
|
||||||
value: u64,
|
value: u64,
|
||||||
sighash_type: EcdsaSigHashType,
|
sighash_type: EcdsaSighashType,
|
||||||
) -> Result<(), encode::Error> {
|
) -> Result<(), encode::Error> {
|
||||||
self.cache
|
self.cache
|
||||||
.segwit_encode_signing_data_to(writer, input_index, script_code, value, sighash_type)
|
.segwit_encode_signing_data_to(writer, input_index, script_code, value, sighash_type)
|
||||||
|
@ -145,7 +145,7 @@ impl<R: Deref<Target = Transaction>> SigHashCache<R> {
|
||||||
input_index: usize,
|
input_index: usize,
|
||||||
script_code: &Script,
|
script_code: &Script,
|
||||||
value: u64,
|
value: u64,
|
||||||
sighash_type: EcdsaSigHashType
|
sighash_type: EcdsaSighashType
|
||||||
) -> SigHash {
|
) -> SigHash {
|
||||||
let mut enc = SigHash::engine();
|
let mut enc = SigHash::engine();
|
||||||
self.encode_signing_data_to(&mut enc, input_index, script_code, value, sighash_type)
|
self.encode_signing_data_to(&mut enc, input_index, script_code, value, sighash_type)
|
||||||
|
@ -164,7 +164,7 @@ impl<R: DerefMut<Target = Transaction>> SigHashCache<R> {
|
||||||
/// panics if `input_index` is out of bounds with respect of the number of inputs
|
/// panics if `input_index` is out of bounds with respect of the number of inputs
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// use bitcoin::blockdata::transaction::{Transaction, EcdsaSigHashType};
|
/// use bitcoin::blockdata::transaction::{Transaction, EcdsaSighashType};
|
||||||
/// use bitcoin::util::bip143::SigHashCache;
|
/// use bitcoin::util::bip143::SigHashCache;
|
||||||
/// use bitcoin::Script;
|
/// use bitcoin::Script;
|
||||||
///
|
///
|
||||||
|
@ -174,7 +174,7 @@ impl<R: DerefMut<Target = Transaction>> SigHashCache<R> {
|
||||||
/// let mut sig_hasher = SigHashCache::new(&mut tx_to_sign);
|
/// let mut sig_hasher = SigHashCache::new(&mut tx_to_sign);
|
||||||
/// for inp in 0..input_count {
|
/// for inp in 0..input_count {
|
||||||
/// let prevout_script = Script::new();
|
/// let prevout_script = Script::new();
|
||||||
/// let _sighash = sig_hasher.signature_hash(inp, &prevout_script, 42, EcdsaSigHashType::All);
|
/// let _sighash = sig_hasher.signature_hash(inp, &prevout_script, 42, EcdsaSighashType::All);
|
||||||
/// // ... sign the sighash
|
/// // ... sign the sighash
|
||||||
/// sig_hasher.access_witness(inp).push(&[]);
|
/// sig_hasher.access_witness(inp).push(&[]);
|
||||||
/// }
|
/// }
|
||||||
|
@ -211,7 +211,7 @@ mod tests {
|
||||||
let raw_expected = SigHash::from_hex(expected_result).unwrap();
|
let raw_expected = SigHash::from_hex(expected_result).unwrap();
|
||||||
let expected_result = SigHash::from_slice(&raw_expected[..]).unwrap();
|
let expected_result = SigHash::from_slice(&raw_expected[..]).unwrap();
|
||||||
let mut cache = SigHashCache::new(&tx);
|
let mut cache = SigHashCache::new(&tx);
|
||||||
let sighash_type = EcdsaSigHashType::from_u32_consensus(hash_type);
|
let sighash_type = EcdsaSighashType::from_u32_consensus(hash_type);
|
||||||
let actual_result = cache.signature_hash(input_index, &script, value, sighash_type);
|
let actual_result = cache.signature_hash(input_index, &script, value, sighash_type);
|
||||||
assert_eq!(actual_result, expected_result);
|
assert_eq!(actual_result, expected_result);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ use core::{fmt, iter};
|
||||||
use hashes::hex::{self, FromHex};
|
use hashes::hex::{self, FromHex};
|
||||||
use blockdata::transaction::NonStandardSigHashType;
|
use blockdata::transaction::NonStandardSigHashType;
|
||||||
use secp256k1;
|
use secp256k1;
|
||||||
use EcdsaSigHashType;
|
use EcdsaSighashType;
|
||||||
|
|
||||||
/// An ECDSA signature with the corresponding hash type.
|
/// An ECDSA signature with the corresponding hash type.
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
|
@ -31,23 +31,23 @@ pub struct EcdsaSig {
|
||||||
/// The underlying ECDSA Signature
|
/// The underlying ECDSA Signature
|
||||||
pub sig: secp256k1::ecdsa::Signature,
|
pub sig: secp256k1::ecdsa::Signature,
|
||||||
/// The corresponding hash type
|
/// The corresponding hash type
|
||||||
pub hash_ty: EcdsaSigHashType,
|
pub hash_ty: EcdsaSighashType,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EcdsaSig {
|
impl EcdsaSig {
|
||||||
/// Constructs ECDSA bitcoin signature for [`EcdsaSigHashType::All`]
|
/// Constructs ECDSA bitcoin signature for [`EcdsaSighashType::All`]
|
||||||
pub fn sighash_all(sig: secp256k1::ecdsa::Signature) -> EcdsaSig {
|
pub fn sighash_all(sig: secp256k1::ecdsa::Signature) -> EcdsaSig {
|
||||||
EcdsaSig {
|
EcdsaSig {
|
||||||
sig,
|
sig,
|
||||||
hash_ty: EcdsaSigHashType::All
|
hash_ty: EcdsaSighashType::All
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Deserialize from slice following the standardness rules for [`EcdsaSigHashType`]
|
/// Deserialize from slice following the standardness rules for [`EcdsaSighashType`]
|
||||||
pub fn from_slice(sl: &[u8]) -> Result<Self, EcdsaSigError> {
|
pub fn from_slice(sl: &[u8]) -> Result<Self, EcdsaSigError> {
|
||||||
let (hash_ty, sig) = sl.split_last()
|
let (hash_ty, sig) = sl.split_last()
|
||||||
.ok_or(EcdsaSigError::EmptySignature)?;
|
.ok_or(EcdsaSigError::EmptySignature)?;
|
||||||
let hash_ty = EcdsaSigHashType::from_standard(*hash_ty as u32)
|
let hash_ty = EcdsaSighashType::from_standard(*hash_ty as u32)
|
||||||
.map_err(|_| EcdsaSigError::NonStandardSigHashType(*hash_ty as u32))?;
|
.map_err(|_| EcdsaSigError::NonStandardSigHashType(*hash_ty as u32))?;
|
||||||
let sig = secp256k1::ecdsa::Signature::from_der(sig)
|
let sig = secp256k1::ecdsa::Signature::from_der(sig)
|
||||||
.map_err(EcdsaSigError::Secp256k1)?;
|
.map_err(EcdsaSigError::Secp256k1)?;
|
||||||
|
@ -80,7 +80,7 @@ impl FromStr for EcdsaSig {
|
||||||
.ok_or(EcdsaSigError::EmptySignature)?;
|
.ok_or(EcdsaSigError::EmptySignature)?;
|
||||||
Ok(EcdsaSig {
|
Ok(EcdsaSig {
|
||||||
sig: secp256k1::ecdsa::Signature::from_der(signature)?,
|
sig: secp256k1::ecdsa::Signature::from_der(signature)?,
|
||||||
hash_ty: EcdsaSigHashType::from_standard(*sighash_byte as u32)?
|
hash_ty: EcdsaSighashType::from_standard(*sighash_byte as u32)?
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@ use util::key::PublicKey;
|
||||||
|
|
||||||
use util::taproot::{ControlBlock, LeafVersion, TapLeafHash, TapBranchHash};
|
use util::taproot::{ControlBlock, LeafVersion, TapLeafHash, TapBranchHash};
|
||||||
use util::sighash;
|
use util::sighash;
|
||||||
use {EcdsaSigHashType, SchnorrSigHashType, EcdsaSig, SchnorrSig};
|
use {EcdsaSighashType, SchnorrSigHashType, EcdsaSig, SchnorrSig};
|
||||||
|
|
||||||
/// Type: Non-Witness UTXO PSBT_IN_NON_WITNESS_UTXO = 0x00
|
/// Type: Non-Witness UTXO PSBT_IN_NON_WITNESS_UTXO = 0x00
|
||||||
const PSBT_IN_NON_WITNESS_UTXO: u8 = 0x00;
|
const PSBT_IN_NON_WITNESS_UTXO: u8 = 0x00;
|
||||||
|
@ -148,7 +148,7 @@ pub struct Input {
|
||||||
|
|
||||||
|
|
||||||
/// A Signature hash type for the corresponding input. As of taproot upgrade, the signature hash
|
/// A Signature hash type for the corresponding input. As of taproot upgrade, the signature hash
|
||||||
/// type can be either [`EcdsaSigHashType`] or [`SchnorrSigHashType`] but it is not possible to know
|
/// type can be either [`EcdsaSighashType`] or [`SchnorrSigHashType`] but it is not possible to know
|
||||||
/// directly which signature hash type the user is dealing with. Therefore, the user is responsible
|
/// directly which signature hash type the user is dealing with. Therefore, the user is responsible
|
||||||
/// for converting to/from [`PsbtSigHashType`] from/to the desired signature hash type they need.
|
/// for converting to/from [`PsbtSigHashType`] from/to the desired signature hash type they need.
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
@ -191,8 +191,8 @@ impl FromStr for PsbtSigHashType {
|
||||||
Err(SigHashTypeParseError{ unrecognized: s.to_owned() })
|
Err(SigHashTypeParseError{ unrecognized: s.to_owned() })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl From<EcdsaSigHashType> for PsbtSigHashType {
|
impl From<EcdsaSighashType> for PsbtSigHashType {
|
||||||
fn from(ecdsa_hash_ty: EcdsaSigHashType) -> Self {
|
fn from(ecdsa_hash_ty: EcdsaSighashType) -> Self {
|
||||||
PsbtSigHashType { inner: ecdsa_hash_ty as u32 }
|
PsbtSigHashType { inner: ecdsa_hash_ty as u32 }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -204,10 +204,10 @@ impl From<SchnorrSigHashType> for PsbtSigHashType {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PsbtSigHashType {
|
impl PsbtSigHashType {
|
||||||
/// Returns the [`EcdsaSigHashType`] if the [`PsbtSigHashType`] can be
|
/// Returns the [`EcdsaSighashType`] if the [`PsbtSigHashType`] can be
|
||||||
/// converted to one.
|
/// converted to one.
|
||||||
pub fn ecdsa_hash_ty(self) -> Result<EcdsaSigHashType, NonStandardSigHashType> {
|
pub fn ecdsa_hash_ty(self) -> Result<EcdsaSighashType, NonStandardSigHashType> {
|
||||||
EcdsaSigHashType::from_standard(self.inner)
|
EcdsaSighashType::from_standard(self.inner)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the [`SchnorrSigHashType`] if the [`PsbtSigHashType`] can be
|
/// Returns the [`SchnorrSigHashType`] if the [`PsbtSigHashType`] can be
|
||||||
|
@ -223,7 +223,7 @@ impl PsbtSigHashType {
|
||||||
/// Creates a [`PsbtSigHashType`] from a raw `u32`.
|
/// Creates a [`PsbtSigHashType`] from a raw `u32`.
|
||||||
///
|
///
|
||||||
/// Allows construction of a non-standard or non-valid sighash flag
|
/// Allows construction of a non-standard or non-valid sighash flag
|
||||||
/// ([`EcdsaSigHashType`], [`SchnorrSigHashType`] respectively).
|
/// ([`EcdsaSighashType`], [`SchnorrSigHashType`] respectively).
|
||||||
pub fn from_u32(n: u32) -> PsbtSigHashType {
|
pub fn from_u32(n: u32) -> PsbtSigHashType {
|
||||||
PsbtSigHashType { inner: n }
|
PsbtSigHashType { inner: n }
|
||||||
}
|
}
|
||||||
|
@ -238,16 +238,16 @@ impl PsbtSigHashType {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Input {
|
impl Input {
|
||||||
/// Obtains the [`EcdsaSigHashType`] for this input if one is specified. If no sighash type is
|
/// Obtains the [`EcdsaSighashType`] for this input if one is specified. If no sighash type is
|
||||||
/// specified, returns [`EcdsaSigHashType::All`].
|
/// specified, returns [`EcdsaSighashType::All`].
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
///
|
///
|
||||||
/// If the `sighash_type` field is set to a non-standard ECDSA sighash value.
|
/// If the `sighash_type` field is set to a non-standard ECDSA sighash value.
|
||||||
pub fn ecdsa_hash_ty(&self) -> Result<EcdsaSigHashType, NonStandardSigHashType> {
|
pub fn ecdsa_hash_ty(&self) -> Result<EcdsaSighashType, NonStandardSigHashType> {
|
||||||
self.sighash_type
|
self.sighash_type
|
||||||
.map(|sighash_type| sighash_type.ecdsa_hash_ty())
|
.map(|sighash_type| sighash_type.ecdsa_hash_ty())
|
||||||
.unwrap_or(Ok(EcdsaSigHashType::All))
|
.unwrap_or(Ok(EcdsaSighashType::All))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Obtains the [`SchnorrSigHashType`] for this input if one is specified. If no sighash type is
|
/// Obtains the [`SchnorrSigHashType`] for this input if one is specified. If no sighash type is
|
||||||
|
@ -544,12 +544,12 @@ mod test {
|
||||||
#[test]
|
#[test]
|
||||||
fn psbt_sighash_type_ecdsa() {
|
fn psbt_sighash_type_ecdsa() {
|
||||||
for ecdsa in &[
|
for ecdsa in &[
|
||||||
EcdsaSigHashType::All,
|
EcdsaSighashType::All,
|
||||||
EcdsaSigHashType::None,
|
EcdsaSighashType::None,
|
||||||
EcdsaSigHashType::Single,
|
EcdsaSighashType::Single,
|
||||||
EcdsaSigHashType::AllPlusAnyoneCanPay,
|
EcdsaSighashType::AllPlusAnyoneCanPay,
|
||||||
EcdsaSigHashType::NonePlusAnyoneCanPay,
|
EcdsaSighashType::NonePlusAnyoneCanPay,
|
||||||
EcdsaSigHashType::SinglePlusAnyoneCanPay,
|
EcdsaSighashType::SinglePlusAnyoneCanPay,
|
||||||
] {
|
] {
|
||||||
let sighash = PsbtSigHashType::from(*ecdsa);
|
let sighash = PsbtSigHashType::from(*ecdsa);
|
||||||
let s = format!("{}", sighash);
|
let s = format!("{}", sighash);
|
||||||
|
|
|
@ -468,7 +468,7 @@ mod tests {
|
||||||
//! Create a full PSBT value with various fields filled and make sure it can be JSONized.
|
//! Create a full PSBT value with various fields filled and make sure it can be JSONized.
|
||||||
use hashes::sha256d;
|
use hashes::sha256d;
|
||||||
use util::psbt::map::Input;
|
use util::psbt::map::Input;
|
||||||
use EcdsaSigHashType;
|
use EcdsaSighashType;
|
||||||
|
|
||||||
// create some values to use in the PSBT
|
// create some values to use in the PSBT
|
||||||
let tx = Transaction {
|
let tx = Transaction {
|
||||||
|
@ -532,7 +532,7 @@ mod tests {
|
||||||
value: 190303501938,
|
value: 190303501938,
|
||||||
script_pubkey: hex_script!("a914339725ba21efd62ac753a9bcd067d6c7a6a39d0587"),
|
script_pubkey: hex_script!("a914339725ba21efd62ac753a9bcd067d6c7a6a39d0587"),
|
||||||
}),
|
}),
|
||||||
sighash_type: Some("SIGHASH_SINGLE|SIGHASH_ANYONECANPAY".parse::<EcdsaSigHashType>().unwrap().into()),
|
sighash_type: Some("SIGHASH_SINGLE|SIGHASH_ANYONECANPAY".parse::<EcdsaSighashType>().unwrap().into()),
|
||||||
redeem_script: Some(vec![0x51].into()),
|
redeem_script: Some(vec![0x51].into()),
|
||||||
witness_script: None,
|
witness_script: None,
|
||||||
partial_sigs: vec![(
|
partial_sigs: vec![(
|
||||||
|
@ -569,7 +569,7 @@ mod tests {
|
||||||
use hash_types::Txid;
|
use hash_types::Txid;
|
||||||
|
|
||||||
use blockdata::script::Script;
|
use blockdata::script::Script;
|
||||||
use blockdata::transaction::{EcdsaSigHashType, Transaction, TxIn, TxOut, OutPoint};
|
use blockdata::transaction::{EcdsaSighashType, Transaction, TxIn, TxOut, OutPoint};
|
||||||
use consensus::encode::serialize_hex;
|
use consensus::encode::serialize_hex;
|
||||||
use util::psbt::map::{Map, Input, Output};
|
use util::psbt::map::{Map, Input, Output};
|
||||||
use util::psbt::raw;
|
use util::psbt::raw;
|
||||||
|
@ -795,7 +795,7 @@ mod tests {
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
(&psbt.inputs[0].sighash_type).as_ref().unwrap().ecdsa_hash_ty().unwrap(),
|
(&psbt.inputs[0].sighash_type).as_ref().unwrap().ecdsa_hash_ty().unwrap(),
|
||||||
EcdsaSigHashType::All
|
EcdsaSighashType::All
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -118,7 +118,7 @@ impl Deserialize for EcdsaSig {
|
||||||
//
|
//
|
||||||
// 1) the current implementation of from_u32_consensus(`flag`) does not preserve
|
// 1) the current implementation of from_u32_consensus(`flag`) does not preserve
|
||||||
// the sighash byte `flag` mapping all unknown values to EcdsaSighashType::All or
|
// the sighash byte `flag` mapping all unknown values to EcdsaSighashType::All or
|
||||||
// EcdsaSigHashType::AllPlusAnyOneCanPay. Therefore, break the invariant
|
// EcdsaSighashType::AllPlusAnyOneCanPay. Therefore, break the invariant
|
||||||
// EcdsaSig::from_slice(&sl[..]).to_vec = sl.
|
// EcdsaSig::from_slice(&sl[..]).to_vec = sl.
|
||||||
//
|
//
|
||||||
// 2) This would cause to have invalid signatures because the sighash message
|
// 2) This would cause to have invalid signatures because the sighash message
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
|
|
||||||
use prelude::*;
|
use prelude::*;
|
||||||
|
|
||||||
pub use blockdata::transaction::{EcdsaSigHashType, SigHashTypeParseError};
|
pub use blockdata::transaction::{EcdsaSighashType, SigHashTypeParseError};
|
||||||
use blockdata::witness::Witness;
|
use blockdata::witness::Witness;
|
||||||
use consensus::{encode, Encodable};
|
use consensus::{encode, Encodable};
|
||||||
use core::{str, fmt};
|
use core::{str, fmt};
|
||||||
|
@ -288,15 +288,15 @@ impl<'s> From<ScriptPath<'s>> for TapLeafHash {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<EcdsaSigHashType> for SchnorrSigHashType {
|
impl From<EcdsaSighashType> for SchnorrSigHashType {
|
||||||
fn from(s: EcdsaSigHashType) -> Self {
|
fn from(s: EcdsaSighashType) -> Self {
|
||||||
match s {
|
match s {
|
||||||
EcdsaSigHashType::All => SchnorrSigHashType::All,
|
EcdsaSighashType::All => SchnorrSigHashType::All,
|
||||||
EcdsaSigHashType::None => SchnorrSigHashType::None,
|
EcdsaSighashType::None => SchnorrSigHashType::None,
|
||||||
EcdsaSigHashType::Single => SchnorrSigHashType::Single,
|
EcdsaSighashType::Single => SchnorrSigHashType::Single,
|
||||||
EcdsaSigHashType::AllPlusAnyoneCanPay => SchnorrSigHashType::AllPlusAnyoneCanPay,
|
EcdsaSighashType::AllPlusAnyoneCanPay => SchnorrSigHashType::AllPlusAnyoneCanPay,
|
||||||
EcdsaSigHashType::NonePlusAnyoneCanPay => SchnorrSigHashType::NonePlusAnyoneCanPay,
|
EcdsaSighashType::NonePlusAnyoneCanPay => SchnorrSigHashType::NonePlusAnyoneCanPay,
|
||||||
EcdsaSigHashType::SinglePlusAnyoneCanPay => SchnorrSigHashType::SinglePlusAnyoneCanPay,
|
EcdsaSighashType::SinglePlusAnyoneCanPay => SchnorrSigHashType::SinglePlusAnyoneCanPay,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -548,7 +548,7 @@ impl<R: Deref<Target=Transaction>> SigHashCache<R> {
|
||||||
input_index: usize,
|
input_index: usize,
|
||||||
script_code: &Script,
|
script_code: &Script,
|
||||||
value: u64,
|
value: u64,
|
||||||
sighash_type: EcdsaSigHashType,
|
sighash_type: EcdsaSighashType,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let zero_hash = sha256d::Hash::default();
|
let zero_hash = sha256d::Hash::default();
|
||||||
|
|
||||||
|
@ -563,8 +563,8 @@ impl<R: Deref<Target=Transaction>> SigHashCache<R> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if !anyone_can_pay
|
if !anyone_can_pay
|
||||||
&& sighash != EcdsaSigHashType::Single
|
&& sighash != EcdsaSighashType::Single
|
||||||
&& sighash != EcdsaSigHashType::None
|
&& sighash != EcdsaSighashType::None
|
||||||
{
|
{
|
||||||
self.segwit_cache()
|
self.segwit_cache()
|
||||||
.sequences
|
.sequences
|
||||||
|
@ -590,9 +590,9 @@ impl<R: Deref<Target=Transaction>> SigHashCache<R> {
|
||||||
txin.sequence.consensus_encode(&mut writer)?;
|
txin.sequence.consensus_encode(&mut writer)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if sighash != EcdsaSigHashType::Single && sighash != EcdsaSigHashType::None {
|
if sighash != EcdsaSighashType::Single && sighash != EcdsaSighashType::None {
|
||||||
self.segwit_cache().outputs.consensus_encode(&mut writer)?;
|
self.segwit_cache().outputs.consensus_encode(&mut writer)?;
|
||||||
} else if sighash == EcdsaSigHashType::Single && input_index < self.tx.output.len() {
|
} else if sighash == EcdsaSighashType::Single && input_index < self.tx.output.len() {
|
||||||
let mut single_enc = SigHash::engine();
|
let mut single_enc = SigHash::engine();
|
||||||
self.tx.output[input_index].consensus_encode(&mut single_enc)?;
|
self.tx.output[input_index].consensus_encode(&mut single_enc)?;
|
||||||
SigHash::from_engine(single_enc).consensus_encode(&mut writer)?;
|
SigHash::from_engine(single_enc).consensus_encode(&mut writer)?;
|
||||||
|
@ -611,7 +611,7 @@ impl<R: Deref<Target=Transaction>> SigHashCache<R> {
|
||||||
input_index: usize,
|
input_index: usize,
|
||||||
script_code: &Script,
|
script_code: &Script,
|
||||||
value: u64,
|
value: u64,
|
||||||
sighash_type: EcdsaSigHashType,
|
sighash_type: EcdsaSighashType,
|
||||||
) -> Result<SigHash, Error> {
|
) -> Result<SigHash, Error> {
|
||||||
let mut enc = SigHash::engine();
|
let mut enc = SigHash::engine();
|
||||||
self.segwit_encode_signing_data_to(
|
self.segwit_encode_signing_data_to(
|
||||||
|
@ -735,7 +735,7 @@ impl<R: DerefMut<Target=Transaction>> SigHashCache<R> {
|
||||||
///
|
///
|
||||||
/// This allows in-line signing such as
|
/// This allows in-line signing such as
|
||||||
/// ```
|
/// ```
|
||||||
/// use bitcoin::blockdata::transaction::{Transaction, EcdsaSigHashType};
|
/// use bitcoin::blockdata::transaction::{Transaction, EcdsaSighashType};
|
||||||
/// use bitcoin::util::sighash::SigHashCache;
|
/// use bitcoin::util::sighash::SigHashCache;
|
||||||
/// use bitcoin::Script;
|
/// use bitcoin::Script;
|
||||||
///
|
///
|
||||||
|
@ -745,7 +745,7 @@ impl<R: DerefMut<Target=Transaction>> SigHashCache<R> {
|
||||||
/// let mut sig_hasher = SigHashCache::new(&mut tx_to_sign);
|
/// let mut sig_hasher = SigHashCache::new(&mut tx_to_sign);
|
||||||
/// for inp in 0..input_count {
|
/// for inp in 0..input_count {
|
||||||
/// let prevout_script = Script::new();
|
/// let prevout_script = Script::new();
|
||||||
/// let _sighash = sig_hasher.segwit_signature_hash(inp, &prevout_script, 42, EcdsaSigHashType::All);
|
/// let _sighash = sig_hasher.segwit_signature_hash(inp, &prevout_script, 42, EcdsaSighashType::All);
|
||||||
/// // ... sign the sighash
|
/// // ... sign the sighash
|
||||||
/// sig_hasher.witness_mut(inp).unwrap().push(&Vec::new());
|
/// sig_hasher.witness_mut(inp).unwrap().push(&Vec::new());
|
||||||
/// }
|
/// }
|
||||||
|
|
Loading…
Reference in New Issue