use rust_bitcoin::secp256k1::PublicKey; use tiny_keccak::Hasher; use web3::types::Address; pub trait ToEthereumAddress { fn to_ethereum_address(&self) -> Address; } impl ToEthereumAddress for PublicKey { fn to_ethereum_address(&self) -> Address { let serialized_public_key = self.serialize_uncompressed(); // Remove the silly openssl 0x04 byte from the front of the // serialized public key. This is a bitcoin thing that // ethereum doesn't want. Eth pubkey should be 32 + 32 = 64 bytes. let actual_public_key = &serialized_public_key[1..]; let mut keccak = tiny_keccak::Keccak::v256(); keccak.update(actual_public_key); let mut hash = [0u8; 32]; keccak.finalize(&mut hash); // Ethereum address is the last twenty bytes of the keccak256 hash let ethereum_address_bytes = &hash[12..]; let mut address = Address::default(); address.assign_from_slice(ethereum_address_bytes); address } }