use sha2::{Digest, Sha256};
use ripemd::Ripemd160;
use secp256k1::{Secp256k1, SecretKey, PublicKey};
use secp256k1::rand::rngs::OsRng;
use bs58;
const MAINNET_ADDRESS_PREFIX: u8 = 0x00;
pub fn sha256(data: &[u8]) -> Vec<u8> {
let mut hasher = Sha256::new();
hasher.update(data);
hasher.finalize().as_slice().to_vec()
}
pub fn ripemd160(data: &[u8]) -> Vec<u8> {
let mut hasher = Ripemd160::new();
hasher.update(data);
hasher.finalize().as_slice().to_vec()
}
pub fn hash160(data: &[u8]) -> Vec<u8> {
let sha_result = sha256(data);
ripemd160(&sha_result)
}
pub fn generate_private_key() -> SecretKey {
let secp = Secp256k1::new();
let mut rng = OsRng::default();
SecretKey::new(&mut rng)
}
pub fn derive_public_key(private_key: &SecretKey) -> PublicKey {
let secp = Secp256k1::new();
PublicKey::from_secret_key(&secp, private_key)
}
pub fn derive_address(public_key: &PublicKey) -> String {
let pk_bytes = public_key.serialize();
let hash160_result = hash160(&pk_bytes);
let mut payload: Vec<u8> = vec![MAINNET_ADDRESS_PREFIX];
payload.extend_from_slice(&hash160_result);
let checksum_full = sha256(&sha256(&payload));
let checksum = &checksum_full[0..4];
payload.extend_from_slice(checksum);
bs58::encode(payload).into_string()
}