Skip to content

Commit 0af1c3f

Browse files
committed
Add Display and FromStr for EcdsaSig
1 parent daf0eac commit 0af1c3f

File tree

1 file changed

+42
-5
lines changed

1 file changed

+42
-5
lines changed

src/util/ecdsa.rs

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,12 @@ use io;
2525

2626
use secp256k1::{self, Secp256k1};
2727
use network::constants::Network;
28-
use hashes::{Hash, hash160};
28+
use hashes::{Hash, hash160, hex};
29+
use hashes::hex::FromHex;
2930
use hash_types::{PubkeyHash, WPubkeyHash};
3031
use util::base58;
3132
use util::key::Error;
32-
use blockdata::transaction::EcdsaSigHashType;
33+
use blockdata::transaction::{EcdsaSigHashType, NonStandardSigHashType};
3334

3435

3536
/// A Bitcoin ECDSA public key
@@ -426,7 +427,7 @@ pub struct EcdsaSig {
426427

427428
impl EcdsaSig {
428429
/// Constructs ECDSA bitcoin signature for [`EcdsaSigHashType::All`]
429-
pub fn sighash_all(sig: secp256k1::Signature) -> EcdsaSig {
430+
pub fn sighash_all(sig: secp256k1::ecdsa::Signature) -> EcdsaSig {
430431
EcdsaSig {
431432
sig,
432433
hash_ty: EcdsaSigHashType::All
@@ -438,7 +439,7 @@ impl EcdsaSig {
438439
let (hash_ty, sig) = sl.split_last()
439440
.ok_or(EcdsaSigError::EmptySignature)?;
440441
let hash_ty = EcdsaSigHashType::from_u32_standard(*hash_ty as u32)
441-
.map_err(|_| EcdsaSigError::NonStandardSigHashType(*hash_ty))?;
442+
.map_err(|_| EcdsaSigError::NonStandardSigHashType(*hash_ty as u32))?;
442443
let sig = secp256k1::ecdsa::Signature::from_der(sig)
443444
.map_err(EcdsaSigError::Secp256k1)?;
444445
Ok(EcdsaSig { sig, hash_ty })
@@ -453,11 +454,34 @@ impl EcdsaSig {
453454
}
454455
}
455456

457+
impl fmt::Display for EcdsaSig {
458+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
459+
hex::format_hex(&self.sig.serialize_der(), f)?;
460+
hex::format_hex(&[self.hash_ty as u8], f)
461+
}
462+
}
463+
464+
impl FromStr for EcdsaSig {
465+
type Err = EcdsaSigError;
466+
467+
fn from_str(s: &str) -> Result<Self, Self::Err> {
468+
let bytes = Vec::from_hex(s)?;
469+
let (sighash_byte, signature) = bytes.split_last()
470+
.ok_or(EcdsaSigError::EmptySignature)?;
471+
Ok(EcdsaSig {
472+
sig: secp256k1::ecdsa::Signature::from_der(signature)?,
473+
hash_ty: EcdsaSigHashType::from_u32_standard(*sighash_byte as u32)?
474+
})
475+
}
476+
}
477+
456478
/// A key-related error.
457479
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
458480
pub enum EcdsaSigError {
481+
/// Hex encoding error
482+
HexEncoding(hex::Error),
459483
/// Base58 encoding error
460-
NonStandardSigHashType(u8),
484+
NonStandardSigHashType(u32),
461485
/// Empty Signature
462486
EmptySignature,
463487
/// secp256k1-related error
@@ -474,6 +498,7 @@ impl fmt::Display for EcdsaSigError {
474498
write!(f, "Invalid Ecdsa signature: {}", e),
475499
EcdsaSigError::EmptySignature =>
476500
write!(f, "Empty ECDSA signature"),
501+
EcdsaSigError::HexEncoding(e) => write!(f, "EcdsaSig hex encoding error: {}", e)
477502
}
478503
}
479504
}
@@ -488,6 +513,18 @@ impl From<secp256k1::Error> for EcdsaSigError {
488513
}
489514
}
490515

516+
impl From<NonStandardSigHashType> for EcdsaSigError {
517+
fn from(err: NonStandardSigHashType) -> Self {
518+
EcdsaSigError::NonStandardSigHashType(err.0)
519+
}
520+
}
521+
522+
impl From<hex::Error> for EcdsaSigError {
523+
fn from(err: hex::Error) -> Self {
524+
EcdsaSigError::HexEncoding(err)
525+
}
526+
}
527+
491528
#[cfg(test)]
492529
mod tests {
493530
use io;

0 commit comments

Comments
 (0)