frequency_runtime/
ethereum.rs1use common_primitives::signatures::{AccountAddressMapper, EthereumAddressMapper};
2use core::{fmt::Debug, marker::PhantomData};
3use parity_scale_codec::Codec;
4use scale_info::StaticTypeInfo;
5use sp_core::hexdisplay::HexDisplay;
6use sp_runtime::{
7 traits::{LookupError, StaticLookup},
8 MultiAddress,
9};
10
11pub struct EthereumCompatibleAccountIdLookup<AccountId, AccountIndex>(
13 PhantomData<(AccountId, AccountIndex)>,
14);
15impl<AccountId, AccountIndex> StaticLookup
16 for EthereumCompatibleAccountIdLookup<AccountId, AccountIndex>
17where
18 AccountId: Codec + Clone + PartialEq + Debug,
19 AccountIndex: Codec + Clone + PartialEq + Debug,
20 MultiAddress<AccountId, AccountIndex>: Codec + StaticTypeInfo,
21{
22 type Source = MultiAddress<AccountId, AccountIndex>;
23 type Target = AccountId;
24 fn lookup(x: Self::Source) -> Result<Self::Target, LookupError> {
25 match x {
26 MultiAddress::Id(i) => Ok(i),
27 MultiAddress::Address20(acc20) => {
28 log::debug!(target: "ETHEREUM", "lookup 0x{:?}", HexDisplay::from(&acc20));
29 let account_id_bytes = EthereumAddressMapper::to_bytes32(&acc20);
30 let decoded =
31 Self::Target::decode(&mut &account_id_bytes[..]).map_err(|_| LookupError)?;
32 Ok(decoded)
33 },
34 _ => Err(LookupError),
35 }
36 }
37 fn unlookup(x: Self::Target) -> Self::Source {
38 MultiAddress::Id(x)
40 }
41}
42
43#[cfg(test)]
44mod tests {
45 use crate::ethereum::EthereumCompatibleAccountIdLookup;
46 use sp_core::{bytes::from_hex, crypto::AccountId32};
47 use sp_runtime::{traits::StaticLookup, MultiAddress};
48
49 #[test]
50 fn address20_should_get_decoded_correctly() {
51 let lookup =
52 EthereumCompatibleAccountIdLookup::<AccountId32, ()>::lookup(MultiAddress::Address20(
53 from_hex("0x19a701d23f0ee1748b5d5f883cb833943096c6c4")
54 .expect("should convert")
55 .try_into()
56 .expect("invalid size"),
57 ));
58 assert!(lookup.is_ok());
59
60 let converted = lookup.unwrap();
61 let expected = AccountId32::new(
62 from_hex("0x19a701d23f0ee1748b5d5f883cb833943096c6c4eeeeeeeeeeeeeeeeeeeeeeee")
63 .expect("should convert")
64 .try_into()
65 .expect("invalid size"),
66 );
67 assert_eq!(converted, expected)
68 }
69}