Add eth_address

This commit is contained in:
pgherveou
2024-09-11 13:37:19 +02:00
parent 9739a1682c
commit 6b874e993c
+23 -2
View File
@@ -3,13 +3,14 @@
// see LICENSE for license details.
//! An ecdsa keypair implementation.
use codec::Encode;
use crate::crypto::{seed_from_entropy, DeriveJunction, SecretUri};
use codec::Encode;
use core::{fmt::Display, str::FromStr};
use hex::FromHex;
use secp256k1::{ecdsa::RecoverableSignature, Message, Secp256k1, SecretKey};
use secrecy::ExposeSecret;
use sp_crypto_hashing::keccak_256;
use subxt_core::utils::H160;
const SECRET_KEY_LENGTH: usize = 32;
@@ -150,6 +151,13 @@ impl Keypair {
Self::from_secret_key(acc)
}
/// Get the Ethereum address for this key pair.
/// See https://ethereum.org/en/developers/docs/accounts/#account-creation
pub fn eth_address(&self) -> H160 {
let pk = self.0.public_key().serialize_uncompressed();
H160::from_slice(&keccak_256(&pk[1..])[12..])
}
/// Obtain the [`PublicKey`] part of this key pair, which can be used in calls to [`verify()`].
/// or otherwise converted into an address. In case of ECDSA, the public key bytes are not
/// equivalent to a Substrate `AccountId32`. They have to be hashed to obtain `AccountId32`.
@@ -453,4 +461,17 @@ mod test {
assert_eq!(pair.public_key().0, sp_pair.public().0);
}
#[test]
fn check_eth_address() {
// See https://goethereumbook.org/wallet-generate
let private_key =
hex_literal::hex!("fad9c8855b740a0b7ed4c221dbad0f33a83a49cad6b3fe8d5817ac83d38b6a19");
let pair = Keypair::from_secret_key(private_key).unwrap();
assert_eq!(
pair.eth_address(),
H160::from_str("0x96216849c49358B10257cb55b28eA603c874b05E").unwrap()
);
}
}