1use crate::Config;2use evm_coder::{abi::AbiType, AbiCoder, ToLog, generate_stubgen, solidity_interface, types::*};3use frame_support::traits::Currency;4use pallet_common::erc::{CommonEvmHandler, CrossAccountId, PrecompileHandle, PrecompileResult};5use pallet_evm_coder_substrate::{6 call, dispatch_to_evm,7 execution::{PreDispatch, Result},8 frontier_contract, WithRecorder, SubstrateRecorder,9};10use sp_core::{U256, Get};11use sp_std::vec::Vec;1213frontier_contract! {14 macro_rules! NativeFungibleHandle_result {...}15 impl<T: Config> Contract for NativeFungibleHandle<T> {...}16}1718#[derive(ToLog)]19pub enum ERC20Events {20 Transfer {21 #[indexed]22 from: Address,23 #[indexed]24 to: Address,25 value: U256,26 },27 Approval {28 #[indexed]29 owner: Address,30 #[indexed]31 spender: Address,32 value: U256,33 },34}3536pub struct NativeFungibleHandle<T: Config>(SubstrateRecorder<T>);3738impl<T: Config> WithRecorder<T> for NativeFungibleHandle<T> {39 fn recorder(&self) -> &pallet_evm_coder_substrate::SubstrateRecorder<T> {40 &self.041 }42 fn into_recorder(self) -> pallet_evm_coder_substrate::SubstrateRecorder<T> {43 self.044 }45}4647#[solidity_interface(name = ERC20, events(ERC20Events), enum(derive(PreDispatch)), enum_attr(weight), expect_selector = 0x942e8b22)]48impl<T: Config> NativeFungibleHandle<T> {49 fn allowance(&self, owner: Address, spender: Address) -> Result<U256> {50 Ok(U256::zero())51 }5253 54 fn approve(&mut self, caller: Caller, spender: Address, amount: U256) -> Result<bool> {55 56 Err("Approve not supported now".into())57 }58 fn balance_of(&self, owner: Address) -> Result<U256> {59 60 let owner = T::CrossAccountId::from_eth(owner);61 let balance = <T as Config>::Currency::free_balance(owner.as_sub());62 Ok(balance.into())63 }6465 fn decimals(&self) -> Result<u8> {66 Ok(T::Decimals::get())67 }6869 fn name(&self) -> Result<String> {70 Ok(T::Name::get())71 }7273 fn symbol(&self) -> Result<String> {74 Ok(T::Symbol::get())75 }7677 fn total_supply(&self) -> Result<U256> {78 79 let total = <T as Config>::Currency::total_issuance();80 Ok(total.into())81 }8283 84 fn transfer(&mut self, caller: Caller, to: Address, amount: U256) -> Result<bool> {85 86 87 88 89 90 9192 93 94 todo!()95 }9697 98 fn transfer_from(99 &mut self,100 caller: Caller,101 from: Address,102 to: Address,103 amount: U256,104 ) -> Result<bool> {105 106 107 108 109 110 111 112113 114 115 116 todo!()117 }118}119120#[solidity_interface(121 name = UniqueNativeFungible,122 is(ERC20),123 enum(derive(PreDispatch))124)]125impl<T: Config> NativeFungibleHandle<T> where T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]> {}126127generate_stubgen!(gen_impl, UniqueNativeFungibleCall<()>, true);128generate_stubgen!(gen_iface, UniqueNativeFungibleCall<()>, false);129130impl<T: Config> CommonEvmHandler for NativeFungibleHandle<T>131where132 T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]>,133{134 const CODE: &'static [u8] = include_bytes!("./stubs/UniqueNativeFungible.raw");135136 fn call(self, handle: &mut impl PrecompileHandle) -> Option<PrecompileResult> {137 call::<T, UniqueNativeFungibleCall<T>, _, _>(handle, self)138 }139}