difftreelog
refactor rewrite nft pallet to evm helpers
in: master
7 files changed
pallets/nft/Cargo.tomldiffbeforeafterboth--- a/pallets/nft/Cargo.toml
+++ b/pallets/nft/Cargo.toml
@@ -39,7 +39,7 @@
'primitive-types/std',
'evm-coder/std',
- 'evm-coder-substrate/std',
+ 'pallet-evm-coder-substrate/std',
]
################################################################################
@@ -144,10 +144,12 @@
sp-api = { default-features = false, version = '3.0.0', git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.8" }
evm-coder = { default-features = false, path = "../../crates/evm-coder" }
-evm-coder-substrate = { default-features = false, path = "../../crates/evm-coder-substrate" }
-primitive-types = { version = "0.9.0", default-features = false, features = ["serde_no_std"] }
+pallet-evm-coder-substrate = { default-features = false, path = "../../pallets/evm-coder-substrate" }
+primitive-types = { version = "0.9.0", default-features = false, features = [
+ "serde_no_std",
+] }
pallet-evm = { default-features = false, version = "5.0.0-dev", git = "https://github.com/uniquenetwork/frontier.git", branch = "injected-transactions-parachain" }
pallet-ethereum = { default-features = false, version = "3.0.0-dev", git = "https://github.com/uniquenetwork/frontier.git", branch = "injected-transactions-parachain" }
fp-evm = { default-features = false, version = '2.0.0', git = "https://github.com/uniquenetwork/frontier.git", branch = "injected-transactions-parachain" }
-hex-literal = "0.3.1"
\ No newline at end of file
+hex-literal = "0.3.1"
pallets/nft/src/eth/erc.rsdiffbeforeafterboth--- a/pallets/nft/src/eth/erc.rs
+++ b/pallets/nft/src/eth/erc.rs
@@ -1,46 +1,63 @@
-use evm_coder::{solidity_interface, solidity, types::*, ToLog};
+use core::char::{decode_utf16, REPLACEMENT_CHARACTER};
+use evm_coder::{ToLog, execution::Result, solidity, solidity_interface, types::*};
+use core::convert::TryInto;
+use alloc::format;
+use crate::{Allowances, Module, Balance, CollectionHandle, CollectionMode, Config, NftItemList};
+use frame_support::storage::StorageDoubleMap;
+use pallet_evm::AddressMapping;
+use super::account::CrossAccountId;
use sp_std::vec::Vec;
-#[solidity_interface]
-pub trait InlineNameSymbol {
- type Error;
-
- fn name(&self) -> Result<string, Self::Error>;
- fn symbol(&self) -> Result<string, Self::Error>;
+#[solidity_interface(name = "ERC165")]
+impl<T: Config> CollectionHandle<T> {
+ fn supports_interface(&self, interface_id: bytes4) -> Result<bool> {
+ Ok(match self.mode {
+ CollectionMode::Fungible(_) => UniqueFungibleCall::supports_interface(interface_id),
+ CollectionMode::NFT => UniqueNFTCall::supports_interface(interface_id),
+ _ => false,
+ })
+ }
}
-#[solidity_interface]
-pub trait InlineTotalSupply {
- type Error;
+#[solidity_interface(name = "InlineNameSymbol")]
+impl<T: Config> CollectionHandle<T> {
+ fn name(&self) -> Result<string> {
+ Ok(decode_utf16(self.name.iter().copied())
+ .map(|r| r.unwrap_or(REPLACEMENT_CHARACTER))
+ .collect::<string>())
+ }
- fn total_supply(&self) -> Result<uint256, Self::Error>;
+ fn symbol(&self) -> Result<string> {
+ Ok(string::from_utf8_lossy(&self.token_prefix).into())
+ }
}
-#[solidity_interface]
-pub trait ERC165 {
- type Error;
-
- fn supports_interface(&self, interface_id: bytes4) -> Result<bool, Self::Error>;
+#[solidity_interface(name = "InlineTotalSupply")]
+impl<T: Config> CollectionHandle<T> {
+ fn total_supply(&self) -> Result<uint256> {
+ // TODO: we do not track total amount of all tokens
+ Ok(0.into())
+ }
}
-#[solidity_interface(inline_is(InlineNameSymbol))]
-pub trait ERC721Metadata {
- type Error;
-
- #[solidity(rename_selector = "tokenURI")]
- fn token_uri(&self, token_id: uint256) -> Result<string, Self::Error>;
+#[solidity_interface(name = "ERC721Metadata", inline_is(InlineNameSymbol))]
+impl<T: Config> CollectionHandle<T> {
+ fn token_uri(&self, token_id: uint256) -> Result<string> {
+ // TODO: We should standartize url prefix, maybe via offchain schema?
+ Ok(format!("unique.network/{}/{}", self.id, token_id))
+ }
}
-#[solidity_interface(inline_is(InlineTotalSupply))]
-pub trait ERC721Enumerable {
- type Error;
+#[solidity_interface(name = "ERC721Enumerable", inline_is(InlineTotalSupply))]
+impl<T: Config> CollectionHandle<T> {
+ fn token_by_index(&self, index: uint256) -> Result<uint256> {
+ Ok(index)
+ }
- fn token_by_index(&self, index: uint256) -> Result<uint256, Self::Error>;
- fn token_of_owner_by_index(
- &self,
- owner: address,
- index: uint256,
- ) -> Result<uint256, Self::Error>;
+ fn token_of_owner_by_index(&self, _owner: address, _index: uint256) -> Result<uint256> {
+ // TODO: Not implemetable
+ Err("not implemented".into())
+ }
}
#[derive(ToLog)]
@@ -71,29 +88,40 @@
},
}
-#[solidity_interface(is(ERC165), events(ERC721Events))]
-pub trait ERC721 {
- type Error;
-
- fn balance_of(&self, owner: address) -> Result<uint256, Self::Error>;
- fn owner_of(&self, token_id: uint256) -> Result<address, Self::Error>;
-
- #[solidity(rename_selector = "safeTransferFrom")]
+#[solidity_interface(name = "ERC721", is(ERC165), events(ERC721Events))]
+impl<T: Config> CollectionHandle<T> {
+ #[solidity(rename_selector = "balanceOf")]
+ fn balance_of_nft(&self, owner: address) -> Result<uint256> {
+ let owner = T::EvmAddressMapping::into_account_id(owner);
+ let balance = <Balance<T>>::get(self.id, owner);
+ Ok(balance.into())
+ }
+ fn owner_of(&self, token_id: uint256) -> Result<address> {
+ let token_id: u32 = token_id.try_into().map_err(|_| "token id overflow")?;
+ let token = <NftItemList<T>>::get(self.id, token_id).ok_or("unknown token")?;
+ Ok(*token.owner.as_eth())
+ }
fn safe_transfer_from_with_data(
&mut self,
- from: address,
- to: address,
- token_id: uint256,
- data: bytes,
- value: value,
- ) -> Result<void, Self::Error>;
+ _from: address,
+ _to: address,
+ _token_id: uint256,
+ _data: bytes,
+ _value: value,
+ ) -> Result<void> {
+ // TODO: Not implemetable
+ Err("not implemented".into())
+ }
fn safe_transfer_from(
&mut self,
- from: address,
- to: address,
- token_id: uint256,
- value: value,
- ) -> Result<void, Self::Error>;
+ _from: address,
+ _to: address,
+ _token_id: uint256,
+ _value: value,
+ ) -> Result<void> {
+ // TODO: Not implemetable
+ Err("not implemented".into())
+ }
fn transfer_from(
&mut self,
@@ -101,53 +129,86 @@
from: address,
to: address,
token_id: uint256,
- value: value,
- ) -> Result<void, Self::Error>;
+ _value: value,
+ ) -> Result<void> {
+ let caller = T::CrossAccountId::from_eth(caller);
+ let from = T::CrossAccountId::from_eth(from);
+ let to = T::CrossAccountId::from_eth(to);
+ let token_id = token_id.try_into().map_err(|_| "token_id overflow")?;
+
+ <Module<T>>::transfer_from_internal(&caller, &from, &to, self, token_id, 1)
+ .map_err(|_| "transferFrom error")?;
+ Ok(())
+ }
+
fn approve(
&mut self,
caller: caller,
approved: address,
token_id: uint256,
- value: value,
- ) -> Result<void, Self::Error>;
+ _value: value,
+ ) -> Result<void> {
+ let caller = T::CrossAccountId::from_eth(caller);
+ let approved = T::CrossAccountId::from_eth(approved);
+ let token_id = token_id.try_into().map_err(|_| "token_id overflow")?;
+
+ <Module<T>>::approve_internal(&caller, &approved, self, token_id, 1)
+ .map_err(|_| "approve internal")?;
+ Ok(())
+ }
+
fn set_approval_for_all(
&mut self,
- caller: caller,
- operator: address,
- approved: bool,
- ) -> Result<void, Self::Error>;
+ _caller: caller,
+ _operator: address,
+ _approved: bool,
+ ) -> Result<void> {
+ // TODO: Not implemetable
+ Err("not implemented".into())
+ }
+
+ fn get_approved(&self, _token_id: uint256) -> Result<address> {
+ // TODO: Not implemetable
+ Err("not implemented".into())
+ }
- fn get_approved(&self, token_id: uint256) -> Result<address, Self::Error>;
- fn is_approved_for_all(
- &self,
- owner: address,
- operator: address,
- ) -> Result<address, Self::Error>;
+ fn is_approved_for_all(&self, _owner: address, _operator: address) -> Result<address> {
+ // TODO: Not implemetable
+ Err("not implemented".into())
+ }
}
-#[solidity_interface]
-pub trait ERC721UniqueExtensions {
- type Error;
-
- fn transfer(
+#[solidity_interface(name = "ERC721UniqueExtensions")]
+impl<T: Config> CollectionHandle<T> {
+ #[solidity(rename_selector = "transfer")]
+ fn transfer_nft(
&mut self,
caller: caller,
to: address,
token_id: uint256,
- value: value,
- ) -> Result<void, Self::Error>;
+ _value: value,
+ ) -> Result<void> {
+ let caller = T::CrossAccountId::from_eth(caller);
+ let to = T::CrossAccountId::from_eth(to);
+ let token_id = token_id.try_into().map_err(|_| "amount overflow")?;
+
+ <Module<T>>::transfer_internal(&caller, &to, self, token_id, 1)
+ .map_err(|_| "transfer error")?;
+ Ok(())
+ }
}
-#[solidity_interface(is(
- ERC165,
- ERC721,
- ERC721Metadata,
- ERC721Enumerable,
- ERC721UniqueExtensions
-))]
-pub trait UniqueNFT {
- type Error;
-}
+#[solidity_interface(
+ name = "UniqueNFT",
+ is(
+ ERC165,
+ ERC721,
+ ERC721Metadata,
+ ERC721Enumerable,
+ ERC721UniqueExtensions
+ )
+)]
+impl<T: Config> CollectionHandle<T> {}
#[derive(ToLog)]
pub enum ERC20Events {
@@ -167,35 +228,72 @@
},
}
-#[solidity_interface(inline_is(InlineNameSymbol, InlineTotalSupply), events(ERC20Events))]
-pub trait ERC20 {
- type Error;
+#[solidity_interface(
+ name = "ERC20",
+ inline_is(InlineNameSymbol, InlineTotalSupply),
+ events(ERC20Events)
+)]
+impl<T: Config> CollectionHandle<T> {
+ fn decimals(&self) -> Result<uint8> {
+ Ok(if let CollectionMode::Fungible(decimals) = &self.mode {
+ *decimals
+ } else {
+ unreachable!()
+ })
+ }
+ fn balance_of(&self, owner: address) -> Result<uint256> {
+ let owner = T::EvmAddressMapping::into_account_id(owner);
+ let balance = <Balance<T>>::get(self.id, owner);
+ Ok(balance.into())
+ }
+ fn transfer(&mut self, caller: caller, to: address, amount: uint256) -> Result<bool> {
+ let caller = T::CrossAccountId::from_eth(caller);
+ let to = T::CrossAccountId::from_eth(to);
+ let amount = amount.try_into().map_err(|_| "amount overflow")?;
- fn decimals(&self) -> Result<uint8, Self::Error>;
- fn balance_of(&self, owner: address) -> Result<uint256, Self::Error>;
- fn transfer(
- &mut self,
- caller: caller,
- to: address,
- value: uint256,
- ) -> Result<bool, Self::Error>;
- fn transfer_from(
+ <Module<T>>::transfer_internal(&caller, &to, self, 1, amount)
+ .map_err(|_| "transfer error")?;
+ Ok(true)
+ }
+ #[solidity(rename_selector = "transferFrom")]
+ fn transfer_from_fungible(
&mut self,
caller: caller,
from: address,
to: address,
- value: uint256,
- ) -> Result<bool, Self::Error>;
- fn approve(
+ amount: uint256,
+ ) -> Result<bool> {
+ let caller = T::CrossAccountId::from_eth(caller);
+ let from = T::CrossAccountId::from_eth(from);
+ let to = T::CrossAccountId::from_eth(to);
+ let amount = amount.try_into().map_err(|_| "amount overflow")?;
+
+ <Module<T>>::transfer_from_internal(&caller, &from, &to, self, 1, amount)
+ .map_err(|_| "transferFrom error")?;
+ Ok(true)
+ }
+ #[solidity(rename_selector = "approve")]
+ fn approve_fungible(
&mut self,
caller: caller,
spender: address,
- value: uint256,
- ) -> Result<bool, Self::Error>;
- fn allowance(&self, owner: address, spender: address) -> Result<uint256, Self::Error>;
-}
+ amount: uint256,
+ ) -> Result<bool> {
+ let caller = T::CrossAccountId::from_eth(caller);
+ let spender = T::CrossAccountId::from_eth(spender);
+ let amount = amount.try_into().map_err(|_| "amount overflow")?;
+
+ <Module<T>>::approve_internal(&caller, &spender, self, 1, amount)
+ .map_err(|_| "approve internal")?;
+ Ok(true)
+ }
+ fn allowance(&self, owner: address, spender: address) -> Result<uint256> {
+ let owner = T::CrossAccountId::from_eth(owner);
+ let spender = T::CrossAccountId::from_eth(spender);
-#[solidity_interface(is(ERC165, ERC20))]
-pub trait UniqueFungible {
- type Error;
+ Ok(<Allowances<T>>::get(self.id, (1, owner.as_sub(), spender.as_sub())).into())
+ }
}
+
+#[solidity_interface(name = "UniqueFungible", is(ERC165, ERC20))]
+impl<T: Config> CollectionHandle<T> {}
pallets/nft/src/eth/erc_impl.rsdiffbeforeafterboth--- a/pallets/nft/src/eth/erc_impl.rs
+++ /dev/null
@@ -1,283 +0,0 @@
-use core::char::{decode_utf16, REPLACEMENT_CHARACTER};
-use evm_coder::{
- abi::{AbiWriter, StringError},
- types::*,
-};
-use core::convert::TryInto;
-use alloc::format;
-use crate::{Allowances, Module, Balance, CollectionHandle, CollectionMode, Config, NftItemList};
-use frame_support::storage::StorageDoubleMap;
-use pallet_evm::AddressMapping;
-use super::erc::*;
-use super::account::CrossAccountId;
-
-type Result<T> = core::result::Result<T, StringError>;
-
-impl<T: Config> InlineNameSymbol for CollectionHandle<T> {
- type Error = StringError;
-
- fn name(&self) -> Result<string> {
- Ok(decode_utf16(self.name.iter().copied())
- .map(|r| r.unwrap_or(REPLACEMENT_CHARACTER))
- .collect::<string>())
- }
-
- fn symbol(&self) -> Result<string> {
- Ok(string::from_utf8_lossy(&self.token_prefix).into())
- }
-}
-
-impl<T: Config> InlineTotalSupply for CollectionHandle<T> {
- type Error = StringError;
-
- fn total_supply(&self) -> Result<uint256> {
- // TODO: we do not track total amount of all tokens
- Ok(0.into())
- }
-}
-
-impl<T: Config> ERC721Metadata for CollectionHandle<T> {
- type Error = StringError;
-
- fn token_uri(&self, token_id: uint256) -> Result<string> {
- // TODO: We should standartize url prefix, maybe via offchain schema?
- Ok(format!("unique.network/{}/{}", self.id, token_id))
- }
-
- fn call_inline_name_symbol(&mut self, c: Msg<InlineNameSymbolCall>) -> Result<AbiWriter> {
- <Self as InlineNameSymbol>::call(self, c)
- }
-}
-
-impl<T: Config> ERC721Enumerable for CollectionHandle<T> {
- type Error = StringError;
-
- fn token_by_index(&self, index: uint256) -> Result<uint256> {
- Ok(index)
- }
-
- fn token_of_owner_by_index(&self, _owner: address, _index: uint256) -> Result<uint256> {
- // TODO: Not implemetable
- Err("not implemented".into())
- }
-
- fn call_inline_total_supply(&mut self, c: Msg<InlineTotalSupplyCall>) -> Result<AbiWriter> {
- <Self as InlineTotalSupply>::call(self, c)
- }
-}
-
-impl<T: Config> ERC721 for CollectionHandle<T> {
- type Error = StringError;
-
- fn balance_of(&self, owner: address) -> Result<uint256> {
- let owner = T::EvmAddressMapping::into_account_id(owner);
- let balance = <Balance<T>>::get(self.id, owner);
- Ok(balance.into())
- }
- fn owner_of(&self, token_id: uint256) -> Result<address> {
- let token_id: u32 = token_id.try_into().map_err(|_| "token id overflow")?;
- let token = <NftItemList<T>>::get(self.id, token_id).ok_or("unknown token")?;
- Ok(*token.owner.as_eth())
- }
- fn safe_transfer_from_with_data(
- &mut self,
- _from: address,
- _to: address,
- _token_id: uint256,
- _data: bytes,
- _value: value,
- ) -> Result<void> {
- // TODO: Not implemetable
- Err("not implemented".into())
- }
- fn safe_transfer_from(
- &mut self,
- _from: address,
- _to: address,
- _token_id: uint256,
- _value: value,
- ) -> Result<void> {
- // TODO: Not implemetable
- Err("not implemented".into())
- }
-
- fn transfer_from(
- &mut self,
- caller: caller,
- from: address,
- to: address,
- token_id: uint256,
- _value: value,
- ) -> Result<void> {
- let caller = T::CrossAccountId::from_eth(caller);
- let from = T::CrossAccountId::from_eth(from);
- let to = T::CrossAccountId::from_eth(to);
- let token_id = token_id.try_into().map_err(|_| "token_id overflow")?;
-
- <Module<T>>::transfer_from_internal(&caller, &from, &to, self, token_id, 1)
- .map_err(|_| "transferFrom error")?;
- Ok(())
- }
-
- fn approve(
- &mut self,
- caller: caller,
- approved: address,
- token_id: uint256,
- _value: value,
- ) -> Result<void> {
- let caller = T::CrossAccountId::from_eth(caller);
- let approved = T::CrossAccountId::from_eth(approved);
- let token_id = token_id.try_into().map_err(|_| "token_id overflow")?;
-
- <Module<T>>::approve_internal(&caller, &approved, self, token_id, 1)
- .map_err(|_| "approve internal")?;
- Ok(())
- }
-
- fn set_approval_for_all(
- &mut self,
- _caller: caller,
- _operator: address,
- _approved: bool,
- ) -> Result<void> {
- // TODO: Not implemetable
- Err("not implemented".into())
- }
-
- fn get_approved(&self, _token_id: uint256) -> Result<address> {
- // TODO: Not implemetable
- Err("not implemented".into())
- }
-
- fn is_approved_for_all(&self, _owner: address, _operator: address) -> Result<address> {
- // TODO: Not implemetable
- Err("not implemented".into())
- }
-
- fn call_erc165(&mut self, c: Msg<ERC165Call>) -> Result<AbiWriter> {
- let ERC165Call::SupportsInterface { interface_id } = c.call;
- Ok(evm_coder::abi_encode!(bool(
- &ERC721Call::supports_interface(interface_id)
- )))
- }
-}
-
-impl<T: Config> ERC721UniqueExtensions for CollectionHandle<T> {
- type Error = StringError;
- fn transfer(
- &mut self,
- caller: caller,
- to: address,
- token_id: uint256,
- _value: value,
- ) -> Result<void> {
- let caller = T::CrossAccountId::from_eth(caller);
- let to = T::CrossAccountId::from_eth(to);
- let token_id = token_id.try_into().map_err(|_| "amount overflow")?;
-
- <Module<T>>::transfer_internal(&caller, &to, self, token_id, 1)
- .map_err(|_| "transfer error")?;
- Ok(())
- }
-}
-
-impl<T: Config> UniqueNFT for CollectionHandle<T> {
- type Error = StringError;
- fn call_erc165(&mut self, c: Msg<ERC165Call>) -> Result<AbiWriter> {
- let ERC165Call::SupportsInterface { interface_id } = c.call;
- Ok(evm_coder::abi_encode!(bool(
- &UniqueNFTCall::supports_interface(interface_id)
- )))
- }
- fn call_erc721(&mut self, c: Msg<ERC721Call>) -> Result<AbiWriter> {
- <Self as ERC721>::call(self, c)
- }
- fn call_erc721_metadata(&mut self, c: Msg<ERC721MetadataCall>) -> Result<AbiWriter> {
- <Self as ERC721Metadata>::call(self, c)
- }
- fn call_erc721_enumerable(&mut self, c: Msg<ERC721EnumerableCall>) -> Result<AbiWriter> {
- <Self as ERC721Enumerable>::call(self, c)
- }
- fn call_erc721_unique_extensions(
- &mut self,
- c: Msg<ERC721UniqueExtensionsCall>,
- ) -> Result<AbiWriter> {
- <Self as ERC721UniqueExtensions>::call(self, c)
- }
-}
-
-impl<T: Config> ERC20 for CollectionHandle<T> {
- type Error = StringError;
- fn decimals(&self) -> Result<uint8> {
- Ok(if let CollectionMode::Fungible(decimals) = &self.mode {
- *decimals
- } else {
- unreachable!()
- })
- }
- fn balance_of(&self, owner: address) -> Result<uint256> {
- let owner = T::EvmAddressMapping::into_account_id(owner);
- let balance = <Balance<T>>::get(self.id, owner);
- Ok(balance.into())
- }
- fn transfer(&mut self, caller: caller, to: address, amount: uint256) -> Result<bool> {
- let caller = T::CrossAccountId::from_eth(caller);
- let to = T::CrossAccountId::from_eth(to);
- let amount = amount.try_into().map_err(|_| "amount overflow")?;
-
- <Module<T>>::transfer_internal(&caller, &to, self, 1, amount)
- .map_err(|_| "transfer error")?;
- Ok(true)
- }
- fn transfer_from(
- &mut self,
- caller: caller,
- from: address,
- to: address,
- amount: uint256,
- ) -> Result<bool> {
- let caller = T::CrossAccountId::from_eth(caller);
- let from = T::CrossAccountId::from_eth(from);
- let to = T::CrossAccountId::from_eth(to);
- let amount = amount.try_into().map_err(|_| "amount overflow")?;
-
- <Module<T>>::transfer_from_internal(&caller, &from, &to, self, 1, amount)
- .map_err(|_| "transferFrom error")?;
- Ok(true)
- }
- fn approve(&mut self, caller: caller, spender: address, amount: uint256) -> Result<bool> {
- let caller = T::CrossAccountId::from_eth(caller);
- let spender = T::CrossAccountId::from_eth(spender);
- let amount = amount.try_into().map_err(|_| "amount overflow")?;
-
- <Module<T>>::approve_internal(&caller, &spender, self, 1, amount)
- .map_err(|_| "approve internal")?;
- Ok(true)
- }
- fn allowance(&self, owner: address, spender: address) -> Result<uint256> {
- let owner = T::CrossAccountId::from_eth(owner);
- let spender = T::CrossAccountId::from_eth(spender);
-
- Ok(<Allowances<T>>::get(self.id, (1, owner.as_sub(), spender.as_sub())).into())
- }
- fn call_inline_name_symbol(&mut self, c: Msg<InlineNameSymbolCall>) -> Result<AbiWriter> {
- <Self as InlineNameSymbol>::call(self, c)
- }
- fn call_inline_total_supply(&mut self, c: Msg<InlineTotalSupplyCall>) -> Result<AbiWriter> {
- <Self as InlineTotalSupply>::call(self, c)
- }
-}
-
-impl<T: Config> UniqueFungible for CollectionHandle<T> {
- type Error = StringError;
- fn call_erc165(&mut self, c: Msg<ERC165Call>) -> Result<AbiWriter> {
- let ERC165Call::SupportsInterface { interface_id } = c.call;
- Ok(evm_coder::abi_encode!(bool(
- &UniqueNFTCall::supports_interface(interface_id)
- )))
- }
- fn call_erc20(&mut self, c: Msg<ERC20Call>) -> Result<AbiWriter> {
- <Self as ERC20>::call(self, c)
- }
-}
pallets/nft/src/eth/log.rsdiffbeforeafterboth--- a/pallets/nft/src/eth/log.rs
+++ /dev/null
@@ -1,19 +0,0 @@
-use sp_std::cell::RefCell;
-use sp_std::vec::Vec;
-
-use ethereum::Log;
-
-#[derive(Default)]
-pub struct LogRecorder(RefCell<Vec<Log>>);
-
-impl LogRecorder {
- pub fn is_empty(&self) -> bool {
- self.0.borrow().is_empty()
- }
- pub fn log(&self, log: Log) {
- self.0.borrow_mut().push(log);
- }
- pub fn retrieve_logs(self) -> Vec<Log> {
- self.0.into_inner()
- }
-}
pallets/nft/src/eth/mod.rsdiffbeforeafterboth--- a/pallets/nft/src/eth/mod.rs
+++ b/pallets/nft/src/eth/mod.rs
@@ -1,23 +1,15 @@
pub mod account;
pub mod erc;
-mod erc_impl;
-pub mod log;
pub mod sponsoring;
-use evm_coder::abi::AbiWriter;
-use evm_coder::abi::StringError;
-use sp_std::prelude::*;
+use pallet_evm_coder_substrate::call_internal;
use sp_std::borrow::ToOwned;
use sp_std::vec::Vec;
-
-use pallet_evm::{PrecompileOutput, ExitReason, ExitRevert, ExitSucceed};
+use pallet_evm::{PrecompileOutput};
use sp_core::{H160, U256};
use frame_support::storage::StorageMap;
-
use crate::{Config, CollectionById, CollectionHandle, CollectionId, CollectionMode};
-
-use erc::{UniqueFungible, UniqueFungibleCall, UniqueNFT, UniqueNFTCall};
-use evm_coder::{types::*, abi::AbiReader};
+use erc::{UniqueFungibleCall, UniqueNFTCall};
pub struct NftErcSupport<T: Config>(core::marker::PhantomData<T>);
@@ -42,19 +34,17 @@
H160(out)
}
+/*
fn call_internal<T: Config>(
collection: &mut CollectionHandle<T>,
caller: caller,
method_id: u32,
mut input: AbiReader,
value: U256,
-) -> Result<Option<AbiWriter>, evm_coder::abi::StringError> {
+) -> Result<Option<AbiWriter>> {
match collection.mode.clone() {
CollectionMode::Fungible(_) => {
- #[cfg(feature = "std")]
- {
- println!("Parse fungible call {:x}", method_id);
- }
+ call_internal();
let call = match UniqueFungibleCall::parse(method_id, &mut input)? {
Some(v) => v,
None => {
@@ -65,10 +55,6 @@
return Ok(None);
}
};
- #[cfg(feature = "std")]
- {
- dbg!(&call);
- }
Ok(Some(<CollectionHandle<T> as UniqueFungible>::call(
collection,
Msg {
@@ -92,11 +78,9 @@
},
)?))
}
- _ => Err(StringError::from(
- "erc calls only supported to fungible and nft collections for now",
- )),
+ _ => Err("erc calls only supported to fungible and nft collections for now".into()),
}
-}
+}*/
impl<T: Config> pallet_evm::OnMethodCall<T> for NftErcSupport<T> {
fn is_reserved(target: &H160) -> bool {
@@ -129,56 +113,15 @@
) -> Option<PrecompileOutput> {
let mut collection = map_eth_to_id(target)
.and_then(|id| <CollectionHandle<T>>::get_with_gas_limit(id, gas_limit))?;
- let (method_id, input) = AbiReader::new_call(input).unwrap();
- let result = call_internal(&mut collection, *source, method_id, input, value);
- let cost = gas_limit - collection.gas_left();
- let logs = collection.logs.retrieve_logs();
- match result {
- Ok(Some(v)) => Some(PrecompileOutput {
- exit_status: ExitReason::Succeed(ExitSucceed::Returned),
- cost,
- logs,
- output: v.finish(),
- }),
- Ok(None) => None,
- Err(e) => Some(PrecompileOutput {
- exit_status: ExitReason::Revert(ExitRevert::Reverted),
- cost: 0,
- logs: Default::default(),
- output: AbiWriter::from(e).finish(),
- }),
- }
- }
-}
-
-// TODO: This function is slow, and output can be memoized
-pub fn generate_transaction(collection_id: u32, chain_id: u64) -> ethereum::Transaction {
- // FIXME: Can be done on wasm runtime with https://github.com/paritytech/substrate/pull/8728
- #[cfg(feature = "std")]
- {
- let contract = collection_id_to_address(collection_id);
- let signed = ethereum_tx_sign::RawTransaction {
- nonce: 0.into(),
- to: Some(contract.0.into()),
- value: 0.into(),
- gas_price: 0.into(),
- gas: 0.into(),
- // zero selector, this transaction always have same sender, so all data should be acquired from logs
- data: Vec::from([0, 0, 0, 0]),
- }
- .sign(
- // TODO: move to pallet config
- // 0xF70631E55faff9f3FD3681545aa6c724226a3853
- // 9dbaef9b3ebc00e53f67c6a77bcfbf2c4f2aebe4d70d94af4f2df01744b7a91a
- &hex_literal::hex!("9dbaef9b3ebc00e53f67c6a77bcfbf2c4f2aebe4d70d94af4f2df01744b7a91a")
- .into(),
- &chain_id,
- );
- rlp::decode::<ethereum::Transaction>(&signed)
- .expect("transaction is just created, it can't be broken")
- }
- #[cfg(not(feature = "std"))]
- {
- panic!("transaction generation not yet supported by wasm runtime while generating transaction for collection_id {}, chain_id {}", collection_id, chain_id)
+ let result = match collection.mode {
+ CollectionMode::NFT => {
+ call_internal::<UniqueNFTCall, _>(*source, &mut collection, value, input)
+ }
+ CollectionMode::Fungible(_) => {
+ call_internal::<UniqueFungibleCall, _>(*source, &mut collection, value, input)
+ }
+ _ => return None,
+ };
+ collection.recorder.evm_to_precompile_output(result)
}
}
pallets/nft/src/lib.rsdiffbeforeafterboth36use sp_std::vec;36use sp_std::vec;37use sp_runtime::sp_std::prelude::Vec;37use sp_runtime::sp_std::prelude::Vec;38use core::ops::{Deref, DerefMut};38use core::ops::{Deref, DerefMut};39use core::cell::RefCell;40use nft_data_structs::{39use nft_data_structs::{41 MAX_DECIMAL_POINTS, MAX_SPONSOR_TIMEOUT, MAX_TOKEN_OWNERSHIP, MAX_REFUNGIBLE_PIECES,40 MAX_DECIMAL_POINTS, MAX_SPONSOR_TIMEOUT, MAX_TOKEN_OWNERSHIP, MAX_REFUNGIBLE_PIECES,42 AccessMode, ChainLimits, Collection, CreateItemData, CollectionLimits, CollectionId,41 AccessMode, ChainLimits, Collection, CreateItemData, CollectionLimits, CollectionId,43 CollectionMode, TokenId, SchemaVersion, SponsorshipState, Ownership, NftItemType,42 CollectionMode, TokenId, SchemaVersion, SponsorshipState, Ownership, NftItemType,44 FungibleItemType, ReFungibleItemType,43 FungibleItemType, ReFungibleItemType,45};44};46use pallet_ethereum::EthereumTransactionSender;474548#[cfg(test)]46#[cfg(test)]49mod mock;47mod mock;55mod eth;53mod eth;56mod sponsorship;54mod sponsorship;57pub use sponsorship::NftSponsorshipHandler;55pub use sponsorship::NftSponsorshipHandler;56pub use eth::sponsoring::NftEthSponsorshipHandler;585759pub use eth::NftErcSupport;58pub use eth::NftErcSupport;60pub use eth::account::*;59pub use eth::account::*;178 }177 }179}178}180179180#[must_use = "Should call submit_logs or save, otherwise some data will be lost for evm side"]181pub struct CollectionHandle<T: Config> {181pub struct CollectionHandle<T: Config> {182 pub id: CollectionId,182 pub id: CollectionId,183 collection: Collection<T>,183 collection: Collection<T>,184 logs: eth::log::LogRecorder,184 recorder: pallet_evm_coder_substrate::SubstrateRecorder<T>,185 evm_address: H160,186 gas_limit: RefCell<u64>,187}185}188impl<T: Config> CollectionHandle<T> {186impl<T: Config> CollectionHandle<T> {189 pub fn get_with_gas_limit(id: CollectionId, gas_limit: u64) -> Option<Self> {187 pub fn get_with_gas_limit(id: CollectionId, gas_limit: u64) -> Option<Self> {190 <CollectionById<T>>::get(id).map(|collection| Self {188 <CollectionById<T>>::get(id).map(|collection| Self {191 id,189 id,192 collection,190 collection,193 logs: eth::log::LogRecorder::default(),194 evm_address: eth::collection_id_to_address(id),191 recorder: pallet_evm_coder_substrate::SubstrateRecorder::new(195 gas_limit: RefCell::new(gas_limit),192 eth::collection_id_to_address(id),193 gas_limit,194 ),196 })195 })197 }196 }198 pub fn get(id: CollectionId) -> Option<Self> {197 pub fn get(id: CollectionId) -> Option<Self> {199 Self::get_with_gas_limit(id, u64::MAX)198 Self::get_with_gas_limit(id, u64::MAX)200 }199 }201 pub fn gas_left(&self) -> u64 {200 pub fn log(&self, log: impl evm_coder::ToLog) -> DispatchResult {202 *self.gas_limit.borrow()201 self.recorder.log_sub(log)203 }202 }204 pub fn consume_gas(&self, gas: u64) -> DispatchResult {203 fn consume_gas(&self, gas: u64) -> DispatchResult {205 let mut gas_limit = self.gas_limit.borrow_mut();204 self.recorder.consume_gas_sub(gas)206 if *gas_limit < gas {207 fail!(Error::<T>::OutOfGas);208 }209 *gas_limit -= gas;210 Ok(())211 }205 }212 pub fn log(&self, log: impl evm_coder::ToLog) {206 pub fn submit_logs(self) -> DispatchResult {213 self.logs.log(log.to_log(self.evm_address))207 self.recorder.submit_logs()214 }208 }215 pub fn into_inner(self) -> Collection<T> {209 pub fn save(self) -> DispatchResult {210 self.recorder.submit_logs()?;216 self.collection211 <CollectionById<T>>::insert(self.id, self.collection);217 }212 Ok(())213 }218}214}219impl<T: Config> Deref for CollectionHandle<T> {215impl<T: Config> Deref for CollectionHandle<T> {220 type Target = Collection<T>;216 type Target = Collection<T>;230 }226 }231}227}232228233pub trait Config: system::Config + Sized {229pub trait Config: system::Config + pallet_evm_coder_substrate::Config + Sized {234 type Event: From<Event<Self>> + Into<<Self as system::Config>::Event>;230 type Event: From<Event<Self>> + Into<<Self as system::Config>::Event>;235231236 /// Weight information for extrinsics in this pallet.232 /// Weight information for extrinsics in this pallet.246 >;242 >;247 type TreasuryAccountId: Get<Self::AccountId>;243 type TreasuryAccountId: Get<Self::AccountId>;248249 type EthereumChainId: Get<u64>;250 type EthereumTransactionSender: pallet_ethereum::EthereumTransactionSender;251}244}252245253// # Used definitions246// # Used definitions564 fail!(Error::<T>::NoPermission);557 fail!(Error::<T>::NoPermission);565 }558 }566559567 <AddressTokens<T>>::remove_prefix(collection_id);560 <AddressTokens<T>>::remove_prefix(collection_id, None);568 <Allowances<T>>::remove_prefix(collection_id);561 <Allowances<T>>::remove_prefix(collection_id, None);569 <Balance<T>>::remove_prefix(collection_id);562 <Balance<T>>::remove_prefix(collection_id, None);570 <ItemListIndex>::remove(collection_id);563 <ItemListIndex>::remove(collection_id);571 <AdminList<T>>::remove(collection_id);564 <AdminList<T>>::remove(collection_id);572 <CollectionById<T>>::remove(collection_id);565 <CollectionById<T>>::remove(collection_id);573 <WhiteList<T>>::remove_prefix(collection_id);566 <WhiteList<T>>::remove_prefix(collection_id, None);574567575 <NftItemList<T>>::remove_prefix(collection_id);568 <NftItemList<T>>::remove_prefix(collection_id, None);576 <FungibleItemList<T>>::remove_prefix(collection_id);569 <FungibleItemList<T>>::remove_prefix(collection_id, None);577 <ReFungibleItemList<T>>::remove_prefix(collection_id);570 <ReFungibleItemList<T>>::remove_prefix(collection_id, None);578571579 <NftTransferBasket<T>>::remove_prefix(collection_id);572 <NftTransferBasket<T>>::remove_prefix(collection_id, None);580 <FungibleTransferBasket<T>>::remove_prefix(collection_id);573 <FungibleTransferBasket<T>>::remove_prefix(collection_id, None);581 <ReFungibleTransferBasket<T>>::remove_prefix(collection_id);574 <ReFungibleTransferBasket<T>>::remove_prefix(collection_id, None);582575583 <VariableMetaDataBasket<T>>::remove_prefix(collection_id);576 <VariableMetaDataBasket<T>>::remove_prefix(collection_id, None);584577585 DestroyedCollectionCount::put(DestroyedCollectionCount::get()578 DestroyedCollectionCount::put(DestroyedCollectionCount::get()586 .checked_add(1)579 .checked_add(1)667 let mut target_collection = Self::get_collection(collection_id)?;660 let mut target_collection = Self::get_collection(collection_id)?;668 Self::check_owner_permissions(&target_collection, &sender)?;661 Self::check_owner_permissions(&target_collection, &sender)?;669 target_collection.access = mode;662 target_collection.access = mode;670 Self::save_collection(target_collection);663 target_collection.save()671672 Ok(())673 }664 }674665675 /// Allows Anyone to create tokens if:666 /// Allows Anyone to create tokens if:694 let mut target_collection = Self::get_collection(collection_id)?;685 let mut target_collection = Self::get_collection(collection_id)?;695 Self::check_owner_permissions(&target_collection, &sender)?;686 Self::check_owner_permissions(&target_collection, &sender)?;696 target_collection.mint_mode = mint_permission;687 target_collection.mint_mode = mint_permission;697 Self::save_collection(target_collection);688 target_collection.save()698699 Ok(())700 }689 }701690702 /// Change the owner of the collection.691 /// Change the owner of the collection.718 let mut target_collection = Self::get_collection(collection_id)?;707 let mut target_collection = Self::get_collection(collection_id)?;719 Self::check_owner_permissions(&target_collection, &sender)?;708 Self::check_owner_permissions(&target_collection, &sender)?;720 target_collection.owner = new_owner;709 target_collection.owner = new_owner;721 Self::save_collection(target_collection);710 target_collection.save()722723 Ok(())724 }711 }725712726 /// Adds an admin of the Collection.713 /// Adds an admin of the Collection.800 Self::check_owner_permissions(&target_collection, &sender)?;787 Self::check_owner_permissions(&target_collection, &sender)?;801788802 target_collection.sponsorship = SponsorshipState::Unconfirmed(new_sponsor);789 target_collection.sponsorship = SponsorshipState::Unconfirmed(new_sponsor);803 Self::save_collection(target_collection);790 target_collection.save()804805 Ok(())806 }791 }807792808 /// # Permissions793 /// # Permissions824 );809 );825810826 target_collection.sponsorship = SponsorshipState::Confirmed(sender);811 target_collection.sponsorship = SponsorshipState::Confirmed(sender);827 Self::save_collection(target_collection);812 target_collection.save()828829 Ok(())830 }813 }831814832 /// Switch back to pay-per-own-transaction model.815 /// Switch back to pay-per-own-transaction model.847 Self::check_owner_permissions(&target_collection, &sender)?;830 Self::check_owner_permissions(&target_collection, &sender)?;848831849 target_collection.sponsorship = SponsorshipState::Disabled;832 target_collection.sponsorship = SponsorshipState::Disabled;850 Self::save_collection(target_collection);833 target_collection.save()851852 Ok(())853 }834 }854835855 /// This method creates a concrete instance of NFT Collection created with CreateCollection method.836 /// This method creates a concrete instance of NFT Collection created with CreateCollection method.884865885 Self::create_item_internal(&sender, &collection, &owner, data)?;866 Self::create_item_internal(&sender, &collection, &owner, data)?;886867887 Self::submit_logs(collection)?;868 collection.submit_logs()888 Ok(())889 }869 }890870891 /// This method creates multiple items in a collection created with CreateCollection method.871 /// This method creates multiple items in a collection created with CreateCollection method.918898919 Self::create_multiple_items_internal(&sender, &collection, &owner, items_data)?;899 Self::create_multiple_items_internal(&sender, &collection, &owner, items_data)?;920900921 Self::submit_logs(collection)?;901 collection.submit_logs()922 Ok(())923 }902 }924903925 /// Destroys a concrete instance of NFT.904 /// Destroys a concrete instance of NFT.944923945 Self::burn_item_internal(&sender, &target_collection, item_id, value)?;924 Self::burn_item_internal(&sender, &target_collection, item_id, value)?;946925947 Self::submit_logs(target_collection)?;926 target_collection.submit_logs()948 Ok(())949 }927 }950928951 /// Change ownership of the token.929 /// Change ownership of the token.979957980 Self::transfer_internal(&sender, &recipient, &collection, item_id, value)?;958 Self::transfer_internal(&sender, &recipient, &collection, item_id, value)?;981959982 Self::submit_logs(collection)?;960 collection.submit_logs()983 Ok(())984 }961 }985962986 /// Set, change, or remove approved address to transfer the ownership of the NFT.963 /// Set, change, or remove approved address to transfer the ownership of the NFT.10069831007 Self::approve_internal(&sender, &spender, &collection, item_id, amount)?;984 Self::approve_internal(&sender, &spender, &collection, item_id, amount)?;10089851009 Self::submit_logs(collection)?;986 collection.submit_logs()1010 Ok(())1011 }987 }10129881013 /// Change ownership of a NFT on behalf of the owner. See Approve method for additional information. After this method executes, the approval is removed so that the approved address will not be able to transfer this NFT again from this owner.989 /// Change ownership of a NFT on behalf of the owner. See Approve method for additional information. After this method executes, the approval is removed so that the approved address will not be able to transfer this NFT again from this owner.103710131038 Self::transfer_from_internal(&sender, &from, &recipient, &collection, item_id, value)?;1014 Self::transfer_from_internal(&sender, &from, &recipient, &collection, item_id, value)?;103910151040 Self::submit_logs(collection)?;1016 collection.submit_logs()1041 Ok(())1042 }1017 }1043 // #[weight = 0]1018 // #[weight = 0]1044 // // let no_perm_mes = "You do not have permissions to modify this collection";1019 // // let no_perm_mes = "You do not have permissions to modify this collection";1107 let mut target_collection = Self::get_collection(collection_id)?;1082 let mut target_collection = Self::get_collection(collection_id)?;1108 Self::check_owner_or_admin_permissions(&target_collection, &sender)?;1083 Self::check_owner_or_admin_permissions(&target_collection, &sender)?;1109 target_collection.schema_version = version;1084 target_collection.schema_version = version;1110 Self::save_collection(target_collection);1085 target_collection.save()11111112 Ok(())1113 }1086 }111410871115 /// Set off-chain data schema.1088 /// Set off-chain data schema.1139 ensure!(schema.len() as u32 <= ChainLimit::get().offchain_schema_limit, "");1112 ensure!(schema.len() as u32 <= ChainLimit::get().offchain_schema_limit, "");114011131141 target_collection.offchain_schema = schema;1114 target_collection.offchain_schema = schema;1142 Self::save_collection(target_collection);1115 target_collection.save()11431144 Ok(())1145 }1116 }114611171147 /// Set const on-chain data schema.1118 /// Set const on-chain data schema.1171 ensure!(schema.len() as u32 <= ChainLimit::get().const_on_chain_schema_limit, "");1142 ensure!(schema.len() as u32 <= ChainLimit::get().const_on_chain_schema_limit, "");117211431173 target_collection.const_on_chain_schema = schema;1144 target_collection.const_on_chain_schema = schema;1174 Self::save_collection(target_collection);1145 target_collection.save()11751176 Ok(())1177 }1146 }117811471179 /// Set variable on-chain data schema.1148 /// Set variable on-chain data schema.1203 ensure!(schema.len() as u32 <= ChainLimit::get().variable_on_chain_schema_limit, "");1172 ensure!(schema.len() as u32 <= ChainLimit::get().variable_on_chain_schema_limit, "");120411731205 target_collection.variable_on_chain_schema = schema;1174 target_collection.variable_on_chain_schema = schema;1206 Self::save_collection(target_collection);1175 target_collection.save()12071208 Ok(())1209 }1176 }121011771211 // Sudo permissions function1178 // Sudo permissions function125412211255 target_collection.limits = new_limits;1222 target_collection.limits = new_limits;12231256 Self::save_collection(target_collection);1224 target_collection.save()12571258 Ok(())1259 }1225 }1260 }1226 }1261}1227}1376 owner: *sender.as_eth(),1342 owner: *sender.as_eth(),1377 approved: *spender.as_eth(),1343 approved: *spender.as_eth(),1378 token_id: item_id.into(),1344 token_id: item_id.into(),1379 });1345 })?;1380 }1346 }138113471382 if matches!(collection.mode, CollectionMode::Fungible(_)) {1348 if matches!(collection.mode, CollectionMode::Fungible(_)) {1385 owner: *sender.as_eth(),1351 owner: *sender.as_eth(),1386 spender: *spender.as_eth(),1352 spender: *spender.as_eth(),1387 value: allowance.into(),1353 value: allowance.into(),1388 });1354 })?;1389 }1355 }139013561391 Self::deposit_event(RawEvent::Approved(1357 Self::deposit_event(RawEvent::Approved(1461 owner: *from.as_eth(),1427 owner: *from.as_eth(),1462 spender: *sender.as_eth(),1428 spender: *sender.as_eth(),1463 value: allowance.into(),1429 value: allowance.into(),1464 });1430 })?;1465 }1431 }146614321467 Ok(())1433 Ok(())1789 from: H160::default(),1755 from: H160::default(),1790 to: *item_owner.as_eth(),1756 to: *item_owner.as_eth(),1791 token_id: current_index.into(),1757 token_id: current_index.into(),1792 });1758 })?;1793 Self::deposit_event(RawEvent::ItemCreated(1759 Self::deposit_event(RawEvent::ItemCreated(1794 collection_id,1760 collection_id,1795 current_index,1761 current_index,1886 from: *owner.as_eth(),1852 from: *owner.as_eth(),1887 to: H160::default(),1853 to: H160::default(),1888 value: value.into(),1854 value: value.into(),1889 });1855 })?;1890 Ok(())1856 Ok(())1891 }1857 }189218581896 Ok(<CollectionHandle<T>>::get(collection_id).ok_or(Error::<T>::CollectionNotFound)?)1862 Ok(<CollectionHandle<T>>::get(collection_id).ok_or(Error::<T>::CollectionNotFound)?)1897 }1863 }18981899 fn save_collection(collection: CollectionHandle<T>) {1900 <CollectionById<T>>::insert(collection.id, collection.into_inner());1901 }19021903 pub fn submit_logs(collection: CollectionHandle<T>) -> DispatchResult {1904 if collection.logs.is_empty() {1905 return Ok(());1906 }1907 T::EthereumTransactionSender::submit_logs_transaction(1908 eth::generate_transaction(collection.id, T::EthereumChainId::get()),1909 collection.logs.retrieve_logs(),1910 )1911 }191218641913 fn check_owner_permissions(1865 fn check_owner_permissions(1914 target_collection: &CollectionHandle<T>,1866 target_collection: &CollectionHandle<T>,2037 from: *owner.as_eth(),1989 from: *owner.as_eth(),2038 to: *recipient.as_eth(),1990 to: *recipient.as_eth(),2039 value: value.into(),1991 value: value.into(),2040 });1992 })?;2041 Self::deposit_event(RawEvent::Transfer(1993 Self::deposit_event(RawEvent::Transfer(2042 collection.id,1994 collection.id,2043 1,1995 1,2173 from: *sender.as_eth(),2125 from: *sender.as_eth(),2174 to: *new_owner.as_eth(),2126 to: *new_owner.as_eth(),2175 token_id: item_id.into(),2127 token_id: item_id.into(),2176 });2128 })?;2177 Self::deposit_event(RawEvent::Transfer(2129 Self::deposit_event(RawEvent::Transfer(2178 collection.id,2130 collection.id,2179 item_id,2131 item_id,pallets/nft/src/mock.rsdiffbeforeafterboth--- a/pallets/nft/src/mock.rs
+++ b/pallets/nft/src/mock.rs
@@ -193,7 +193,6 @@
type EvmAddressMapping = TestEvmAddressMapping;
type EvmBackwardsAddressMapping = TestEvmBackwardsAddressMapping;
type CrossAccountId = TestCrossAccountId;
- type EthereumChainId = EthereumChainId;
type EthereumTransactionSender = TestEtheremTransactionSender;
}