use ex3_crypto::{keccak256, secp256k1::Pubkey};
pub struct EthAddressParser;
impl EthAddressParser {
pub fn to_address<T: AsRef<[u8]>>(pub_key: T) -> super::Result<String> {
let original_pub_key: Pubkey = Pubkey::from_slice(pub_key.as_ref())?;
let uncompressed: Vec<u8> = original_pub_key.serialize(false);
let pub_key = &uncompressed.as_slice()[1..];
let hash = keccak256(pub_key);
let mut address = vec![0u8; 20];
address.copy_from_slice(&hash[12..]);
Ok(hex::encode(address))
}
}
#[cfg(test)]
mod tests {
use super::*;
use ex3_crypto::secp256k1::Pubkey;
use k256::ecdsa::VerifyingKey;
use k256::elliptic_curve::sec1::ToEncodedPoint;
use std::ops::Deref;
#[test]
fn test_eth_address_generation() {
let private_str = "aab62dc0f7ecef14d37206898b7afb7bc00a508664e1b44607a3697873f79cc9";
let pub_key = get_pub_key_from_private_key(private_str);
let address_1 = "7a29794050c805140e840a04ca8a51f25ac181b7";
let address_2 = EthAddressParser::to_address(pub_key.deref()).unwrap();
assert_eq!(address_1, address_2)
}
#[test]
fn test_eth_address_generation_2() {
let private_str = "DC38EE117CAE37750EB1ECC5CFD3DE8E85963B481B93E732C5D0CB66EE6B0C9D";
let pub_key = get_pub_key_from_private_key(private_str);
let address_1 = "c5ed5d9b9c957be2baa01c16310aa4d1f8bc8e6f";
let address_2 = EthAddressParser::to_address(*pub_key).unwrap();
assert_eq!(address_1, address_2)
}
pub fn get_pub_key_from_private_key(private_str: &str) -> Pubkey {
let secret_key = k256::SecretKey::from_slice(&hex::decode(private_str).unwrap()).unwrap();
let pub_key = k256::PublicKey::from_secret_scalar(&secret_key.into());
VerifyingKey::from_encoded_point(&pub_key.to_encoded_point(false))
.unwrap()
.into()
}
}