From 0af1c3f320dd1b341dbf8ea722c7312df1dec593 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Thu, 6 Jan 2022 12:01:05 +0100 Subject: [PATCH] Add Display and FromStr for EcdsaSig --- src/util/ecdsa.rs | 47 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/src/util/ecdsa.rs b/src/util/ecdsa.rs index 5456cc03..54dd2692 100644 --- a/src/util/ecdsa.rs +++ b/src/util/ecdsa.rs @@ -25,11 +25,12 @@ use io; use secp256k1::{self, Secp256k1}; use network::constants::Network; -use hashes::{Hash, hash160}; +use hashes::{Hash, hash160, hex}; +use hashes::hex::FromHex; use hash_types::{PubkeyHash, WPubkeyHash}; use util::base58; use util::key::Error; -use blockdata::transaction::EcdsaSigHashType; +use blockdata::transaction::{EcdsaSigHashType, NonStandardSigHashType}; /// A Bitcoin ECDSA public key @@ -426,7 +427,7 @@ pub struct EcdsaSig { impl EcdsaSig { /// Constructs ECDSA bitcoin signature for [`EcdsaSigHashType::All`] - pub fn sighash_all(sig: secp256k1::Signature) -> EcdsaSig { + pub fn sighash_all(sig: secp256k1::ecdsa::Signature) -> EcdsaSig { EcdsaSig { sig, hash_ty: EcdsaSigHashType::All @@ -438,7 +439,7 @@ impl EcdsaSig { let (hash_ty, sig) = sl.split_last() .ok_or(EcdsaSigError::EmptySignature)?; let hash_ty = EcdsaSigHashType::from_u32_standard(*hash_ty as u32) - .map_err(|_| EcdsaSigError::NonStandardSigHashType(*hash_ty))?; + .map_err(|_| EcdsaSigError::NonStandardSigHashType(*hash_ty as u32))?; let sig = secp256k1::ecdsa::Signature::from_der(sig) .map_err(EcdsaSigError::Secp256k1)?; Ok(EcdsaSig { sig, hash_ty }) @@ -453,11 +454,34 @@ impl EcdsaSig { } } +impl fmt::Display for EcdsaSig { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + hex::format_hex(&self.sig.serialize_der(), f)?; + hex::format_hex(&[self.hash_ty as u8], f) + } +} + +impl FromStr for EcdsaSig { + type Err = EcdsaSigError; + + fn from_str(s: &str) -> Result { + let bytes = Vec::from_hex(s)?; + let (sighash_byte, signature) = bytes.split_last() + .ok_or(EcdsaSigError::EmptySignature)?; + Ok(EcdsaSig { + sig: secp256k1::ecdsa::Signature::from_der(signature)?, + hash_ty: EcdsaSigHashType::from_u32_standard(*sighash_byte as u32)? + }) + } +} + /// A key-related error. #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] pub enum EcdsaSigError { + /// Hex encoding error + HexEncoding(hex::Error), /// Base58 encoding error - NonStandardSigHashType(u8), + NonStandardSigHashType(u32), /// Empty Signature EmptySignature, /// secp256k1-related error @@ -474,6 +498,7 @@ impl fmt::Display for EcdsaSigError { write!(f, "Invalid Ecdsa signature: {}", e), EcdsaSigError::EmptySignature => write!(f, "Empty ECDSA signature"), + EcdsaSigError::HexEncoding(e) => write!(f, "EcdsaSig hex encoding error: {}", e) } } } @@ -488,6 +513,18 @@ impl From for EcdsaSigError { } } +impl From for EcdsaSigError { + fn from(err: NonStandardSigHashType) -> Self { + EcdsaSigError::NonStandardSigHashType(err.0) + } +} + +impl From for EcdsaSigError { + fn from(err: hex::Error) -> Self { + EcdsaSigError::HexEncoding(err) + } +} + #[cfg(test)] mod tests { use io;