use std::io::{Cursor, Read, Result, Write};
use sha2::Digest;
pub fn sha256(data: &[u8]) -> [u8; 32] {
let mut hasher = sha2::Sha256::new();
hasher.update(data);
hasher.finalize().into()
}
pub fn sha256d(data: &[u8]) -> [u8; 32] {
sha256(&sha256(data))
}
pub fn rmd160(data: &[u8]) -> [u8; 20] {
let mut hasher = ripemd::Ripemd160::new();
hasher.update(data);
hasher.finalize().into()
}
pub fn hash160(data: &[u8]) -> [u8; 20] {
rmd160(&sha256(data))
}
pub enum AddrType {
P2PKH([u8; 20]), P2SH([u8; 20]), P2PK([u8; 20]), P2WPKH([u8; 20]), P2WSH([u8; 20]), Unknown,
}
impl AddrType {
pub fn hex(&self) -> String {
match self {
AddrType::P2PKH(h) => hex::encode(h),
AddrType::P2SH(h) => hex::encode(h),
AddrType::P2PK(h) => hex::encode(h),
AddrType::P2WPKH(h) => hex::encode(h),
AddrType::P2WSH(h) => hex::encode(h),
AddrType::Unknown => "".to_string(),
}
}
pub fn load(s: &[u8]) -> AddrType {
match s {
s if s.len() == 25 && s[0] == 0x76 && s[1] == 0xA9 && s[2] == 0x14 && s[24] == 0xAC => {
AddrType::P2PKH(s[3..23].try_into().unwrap())
}
s if s.len() == 23 && s[0] == 0xA9 && s[1] == 0x14 && s[22] == 0x87 => {
AddrType::P2SH(s[2..22].try_into().unwrap())
}
s if s.len() == 67 && s[0] == 0x41 && s[66] == 0xAC => {
AddrType::P2PK(hash160(s[1..66].as_ref()))
}
s if s.len() == 22 && s[0] == 0x00 && s[1] == 0x14 => {
AddrType::P2WPKH(s[2..22].try_into().unwrap())
}
s if s.len() == 34 && s[0] == 0x00 && s[1] == 0x20 => AddrType::P2WSH(rmd160(&s[2..34])),
_ => AddrType::Unknown,
}
}
}