git.delta.rocks / unique-network / refs/commits / 18f1623e4e86

difftreelog

source

pallets/nft/src/eth/mod.rs3.4 KiBsourcehistory
1pub mod account;2pub mod erc;3pub mod sponsoring;45use pallet_evm_coder_substrate::call_internal;6use sp_std::borrow::ToOwned;7use sp_std::vec::Vec;8use pallet_evm::{PrecompileOutput};9use sp_core::{H160, U256};10use frame_support::storage::StorageMap;11use crate::{Config, CollectionById, CollectionHandle, CollectionId, CollectionMode};12use erc::{UniqueFungibleCall, UniqueNFTCall};1314pub struct NftErcSupport<T: Config>(core::marker::PhantomData<T>);1516// 0x17c4e6453Cc49AAAaEACA894e6D9683e00000001 - collection17// TODO: Unhardcode prefix18const ETH_ACCOUNT_PREFIX: [u8; 16] = [19	0x17, 0xc4, 0xe6, 0x45, 0x3c, 0xc4, 0x9a, 0xaa, 0xae, 0xac, 0xa8, 0x94, 0xe6, 0xd9, 0x68, 0x3e,20];2122fn map_eth_to_id(eth: &H160) -> Option<CollectionId> {23	if eth[0..16] != ETH_ACCOUNT_PREFIX {24		return None;25	}26	let mut id_bytes = [0; 4];27	id_bytes.copy_from_slice(&eth[16..20]);28	Some(u32::from_be_bytes(id_bytes))29}30pub fn collection_id_to_address(id: u32) -> H160 {31	let mut out = [0; 20];32	out[0..16].copy_from_slice(&ETH_ACCOUNT_PREFIX);33	out[16..20].copy_from_slice(&u32::to_be_bytes(id));34	H160(out)35}3637/*38fn call_internal<T: Config>(39	collection: &mut CollectionHandle<T>,40	caller: caller,41	method_id: u32,42	mut input: AbiReader,43	value: U256,44) -> Result<Option<AbiWriter>> {45	match collection.mode.clone() {46		CollectionMode::Fungible(_) => {47			call_internal();48			let call = match UniqueFungibleCall::parse(method_id, &mut input)? {49				Some(v) => v,50				None => {51					#[cfg(feature = "std")]52					{53						println!("Method not found");54					}55					return Ok(None);56				}57			};58			Ok(Some(<CollectionHandle<T> as UniqueFungible>::call(59				collection,60				Msg {61					call,62					caller,63					value,64				},65			)?))66		}67		CollectionMode::NFT => {68			let call = match UniqueNFTCall::parse(method_id, &mut input)? {69				Some(v) => v,70				None => return Ok(None),71			};72			Ok(Some(<CollectionHandle<T> as UniqueNFT>::call(73				collection,74				Msg {75					call,76					caller,77					value,78				},79			)?))80		}81		_ => Err("erc calls only supported to fungible and nft collections for now".into()),82	}83}*/8485impl<T: Config> pallet_evm::OnMethodCall<T> for NftErcSupport<T> {86	fn is_reserved(target: &H160) -> bool {87		map_eth_to_id(target).is_some()88	}89	fn is_used(target: &H160) -> bool {90		map_eth_to_id(target)91			.map(<CollectionById<T>>::contains_key)92			.unwrap_or(false)93	}94	fn get_code(target: &H160) -> Option<Vec<u8>> {95		map_eth_to_id(target)96			.and_then(<CollectionById<T>>::get)97			.map(|collection| {98				match collection.mode {99					CollectionMode::NFT => include_bytes!("stubs/UniqueNFT.raw") as &[u8],100					CollectionMode::Fungible(_) => {101						include_bytes!("stubs/UniqueFungible.raw") as &[u8]102					}103					CollectionMode::ReFungible => {104						include_bytes!("stubs/UniqueRefungible.raw") as &[u8]105					}106					CollectionMode::Invalid => include_bytes!("stubs/UniqueInvalid.raw") as &[u8],107				}108				.to_owned()109			})110	}111	fn call(112		source: &H160,113		target: &H160,114		gas_limit: u64,115		input: &[u8],116		value: U256,117	) -> Option<PrecompileOutput> {118		let mut collection = map_eth_to_id(target)119			.and_then(|id| <CollectionHandle<T>>::get_with_gas_limit(id, gas_limit))?;120		let result = match collection.mode {121			CollectionMode::NFT => {122				call_internal::<UniqueNFTCall, _>(*source, &mut collection, value, input)123			}124			CollectionMode::Fungible(_) => {125				call_internal::<UniqueFungibleCall, _>(*source, &mut collection, value, input)126			}127			_ => return None,128		};129		collection.recorder.evm_to_precompile_output(result)130	}131}