difftreelog
build update frontier
in: master
14 files changed
crates/evm-coder/Cargo.tomldiffbeforeafterboth--- a/crates/evm-coder/Cargo.toml
+++ b/crates/evm-coder/Cargo.toml
@@ -7,8 +7,8 @@
evm-coder-macros = { path = "../evm-coder-macros" }
primitive-types = { version = "0.10.1", default-features = false }
hex-literal = "0.3.3"
-ethereum = { version = "0.9", git = "https://github.com/purestake/ethereum", branch = "joshy-scale-info", default-features = false }
-evm-core = { default-features = false, git = "https://github.com/uniquenetwork/evm.git", branch="precompile-output-parachain" }
+ethereum = { version = "0.10.0", default-features = false }
+evm-core = { default-features = false, git = "https://github.com/uniquenetwork/evm.git", branch = "unique-weights" }
impl-trait-for-tuples = "0.2.1"
[dev-dependencies]
pallets/common/src/erc.rsdiffbeforeafterboth--- a/pallets/common/src/erc.rs
+++ b/pallets/common/src/erc.rs
@@ -1,4 +1,5 @@
pub use pallet_evm::PrecompileOutput;
+pub use pallet_evm::PrecompileResult;
use sp_core::{H160, U256};
/// Does not always represent a full collection, for RFT it is either
@@ -6,5 +7,5 @@
pub trait CommonEvmHandler {
const CODE: &'static [u8];
- fn call(self, source: &H160, input: &[u8], value: U256) -> Option<PrecompileOutput>;
+ fn call(self, source: &H160, input: &[u8], value: U256) -> Option<PrecompileResult>;
}
pallets/evm-coder-substrate/Cargo.tomldiffbeforeafterboth--- a/pallets/evm-coder-substrate/Cargo.toml
+++ b/pallets/evm-coder-substrate/Cargo.toml
@@ -9,7 +9,7 @@
] }
sp-std = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.12' }
sp-core = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.12' }
-ethereum = { version = "0.9", git = "https://github.com/purestake/ethereum", branch = "joshy-scale-info", default-features = false }
+ethereum = { version = "0.10.0", default-features = false }
evm-coder = { default-features = false, path = "../../crates/evm-coder" }
pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12-weights" }
pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12-weights" }
pallets/evm-coder-substrate/src/lib.rsdiffbeforeafterboth--- a/pallets/evm-coder-substrate/src/lib.rs
+++ b/pallets/evm-coder-substrate/src/lib.rs
@@ -20,7 +20,8 @@
};
use frame_support::{ensure};
use pallet_evm::{
- ExitError, ExitReason, ExitRevert, ExitSucceed, PrecompileOutput, GasWeightMapping,
+ ExitError, ExitRevert, ExitSucceed, GasWeightMapping, PrecompileFailure, PrecompileOutput,
+ PrecompileResult,
};
use frame_system::ensure_signed;
pub use frame_support::dispatch::DispatchResult;
@@ -158,26 +159,28 @@
pub fn evm_to_precompile_output(
self,
result: evm_coder::execution::Result<Option<AbiWriter>>,
- ) -> Option<PrecompileOutput> {
+ ) -> Option<PrecompileResult> {
use evm_coder::execution::Error;
- let (writer, reason) = match result {
- Ok(Some(v)) => (v, ExitReason::Succeed(ExitSucceed::Returned)),
+ Some(match result {
+ Ok(Some(v)) => Ok(PrecompileOutput {
+ exit_status: ExitSucceed::Returned,
+ cost: self.initial_gas - self.gas_left(),
+ logs: self.retrieve_logs(),
+ output: v.finish(),
+ }),
Ok(None) => return None,
Err(Error::Revert(e)) => {
let mut writer = AbiWriter::new_call(evm_coder::fn_selector!(Error(string)));
(&e as &str).abi_write(&mut writer);
- (writer, ExitReason::Revert(ExitRevert::Reverted))
+ Err(PrecompileFailure::Revert {
+ exit_status: ExitRevert::Reverted,
+ cost: self.initial_gas - self.gas_left(),
+ output: writer.finish(),
+ })
}
- Err(Error::Fatal(f)) => (AbiWriter::new(), ExitReason::Fatal(f)),
- Err(Error::Error(e)) => (AbiWriter::new(), ExitReason::Error(e)),
- };
-
- Some(PrecompileOutput {
- cost: self.initial_gas - self.gas_left(),
- exit_status: reason,
- logs: self.retrieve_logs(),
- output: writer.finish(),
+ Err(Error::Fatal(f)) => Err(f.into()),
+ Err(Error::Error(e)) => Err(e.into()),
})
}
@@ -234,7 +237,7 @@
mut e: E,
value: value,
input: &[u8],
- ) -> Option<PrecompileOutput> {
+ ) -> Option<PrecompileResult> {
let result = call_internal(caller, &mut e, value, input);
e.into_recorder().evm_to_precompile_output(result)
}
pallets/evm-contract-helpers/src/eth.rsdiffbeforeafterboth--- a/pallets/evm-contract-helpers/src/eth.rs
+++ b/pallets/evm-contract-helpers/src/eth.rs
@@ -1,7 +1,10 @@
use core::marker::PhantomData;
use evm_coder::{abi::AbiWriter, execution::Result, generate_stubgen, solidity_interface, types::*};
use pallet_evm_coder_substrate::{SubstrateRecorder, WithRecorder};
-use pallet_evm::{ExitReason, ExitRevert, OnCreate, OnMethodCall, PrecompileOutput};
+use pallet_evm::{
+ ExitReason, ExitRevert, OnCreate, OnMethodCall, PrecompileOutput, PrecompileResult,
+ PrecompileFailure,
+};
use sp_core::H160;
use crate::{
AllowlistEnabled, Config, Owner, Pallet, SelfSponsoring, SponsorBasket, SponsoringRateLimit,
@@ -109,19 +112,18 @@
gas_left: u64,
input: &[u8],
value: sp_core::U256,
- ) -> Option<PrecompileOutput> {
+ ) -> Option<PrecompileResult> {
// TODO: Extract to another OnMethodCall handler
if <AllowlistEnabled<T>>::get(target) && !<Pallet<T>>::allowed(*target, *source) {
- return Some(PrecompileOutput {
- exit_status: ExitReason::Revert(ExitRevert::Reverted),
+ return Some(Err(PrecompileFailure::Revert {
+ exit_status: ExitRevert::Reverted,
cost: 0,
output: {
let mut writer = AbiWriter::new_call(evm_coder::fn_selector!(Error(string)));
writer.string("Target contract is allowlisted");
writer.finish()
},
- logs: sp_std::vec![],
- });
+ }));
}
if target != &T::ContractAddress::get() {
pallets/evm-migration/src/lib.rsdiffbeforeafterboth--- a/pallets/evm-migration/src/lib.rs
+++ b/pallets/evm-migration/src/lib.rs
@@ -98,7 +98,7 @@
_gas_left: u64,
_input: &[u8],
_value: sp_core::U256,
- ) -> Option<pallet_evm::PrecompileOutput> {
+ ) -> Option<pallet_evm::PrecompileResult> {
None
}
pallets/fungible/Cargo.tomldiffbeforeafterboth--- a/pallets/fungible/Cargo.toml
+++ b/pallets/fungible/Cargo.toml
@@ -19,7 +19,7 @@
nft-data-structs = { default-features = false, path = '../../primitives/nft' }
evm-coder = { default-features = false, path = '../../crates/evm-coder' }
pallet-evm-coder-substrate = { default-features = false, path = '../evm-coder-substrate' }
-ethereum = { git = "https://github.com/purestake/ethereum", branch = "joshy-scale-info", default-features = false }
+ethereum = { version = "0.10.0", default-features = false }
frame-benchmarking = { default-features = false, optional = true, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.12' }
scale-info = { version = "1.0.0", default-features = false, features = [
"derive",
pallets/fungible/src/erc.rsdiffbeforeafterboth--- a/pallets/fungible/src/erc.rs
+++ b/pallets/fungible/src/erc.rs
@@ -2,7 +2,7 @@
use core::convert::TryInto;
use evm_coder::{ToLog, execution::*, generate_stubgen, solidity_interface, types::*, weight};
use nft_data_structs::CollectionMode;
-use pallet_common::erc::CommonEvmHandler;
+use pallet_common::erc::{CommonEvmHandler, PrecompileResult};
use sp_core::{H160, U256};
use sp_std::vec::Vec;
use pallet_common::account::CrossAccountId;
@@ -127,7 +127,7 @@
impl<T: Config> CommonEvmHandler for FungibleHandle<T> {
const CODE: &'static [u8] = include_bytes!("./stubs/UniqueFungible.raw");
- fn call(self, source: &H160, input: &[u8], value: U256) -> Option<PrecompileOutput> {
+ fn call(self, source: &H160, input: &[u8], value: U256) -> Option<PrecompileResult> {
call::<T, UniqueFungibleCall<T>, _>(*source, self, value, input)
}
}
pallets/nft/Cargo.tomldiffbeforeafterboth--- a/pallets/nft/Cargo.toml
+++ b/pallets/nft/Cargo.toml
@@ -131,7 +131,7 @@
scale-info = { version = "1.0.0", default-features = false, features = [
"derive",
] }
-ethereum = { version = "0.9", git = "https://github.com/purestake/ethereum", branch = "joshy-scale-info", default-features = false }
+ethereum = { version = "0.10.0", default-features = false }
rlp = { default-features = false, version = "0.5.0" }
sp-api = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.12" }
pallets/nft/src/eth/mod.rsdiffbeforeafterboth--- a/pallets/nft/src/eth/mod.rs
+++ b/pallets/nft/src/eth/mod.rs
@@ -1,5 +1,6 @@
pub mod sponsoring;
+use fp_evm::PrecompileResult;
use pallet_common::{
CollectionById,
erc::CommonEvmHandler,
@@ -10,7 +11,6 @@
use pallet_refungible::{RefungibleHandle, erc::RefungibleTokenHandle};
use sp_std::borrow::ToOwned;
use sp_std::vec::Vec;
-use pallet_evm::{PrecompileOutput};
use sp_core::{H160, U256};
use crate::{CollectionMode, Config, dispatch::Dispatched};
use pallet_common::CollectionHandle;
@@ -54,7 +54,7 @@
gas_limit: u64,
input: &[u8],
value: U256,
- ) -> Option<PrecompileOutput> {
+ ) -> Option<PrecompileResult> {
if let Some(collection_id) = map_eth_to_id(target) {
let collection = <CollectionHandle<T>>::new_with_gas_limit(collection_id, gas_limit)?;
let dispatched = Dispatched::dispatch(collection);
pallets/nft/src/eth/sponsoring.rsdiffbeforeafterboth--- a/pallets/nft/src/eth/sponsoring.rs
+++ b/pallets/nft/src/eth/sponsoring.rs
@@ -27,7 +27,7 @@
let (method_id, mut reader) = AbiReader::new_call(&call.1).ok()?;
match &collection.mode {
crate::CollectionMode::NFT => {
- let call = UniqueNFTCall::parse(method_id, &mut reader).ok()??;
+ let call = <UniqueNFTCall<T>>::parse(method_id, &mut reader).ok()??;
match call {
UniqueNFTCall::ERC721UniqueExtensions(
ERC721UniqueExtensionsCall::Transfer { token_id, .. },
@@ -49,7 +49,7 @@
}
}
crate::CollectionMode::Fungible(_) => {
- let call = UniqueFungibleCall::parse(method_id, &mut reader).ok()??;
+ let call = <UniqueFungibleCall<T>>::parse(method_id, &mut reader).ok()??;
#[allow(clippy::single_match)]
match call {
UniqueFungibleCall::ERC20(ERC20Call::Transfer { .. }) => {
pallets/nonfungible/Cargo.tomldiffbeforeafterboth--- a/pallets/nonfungible/Cargo.toml
+++ b/pallets/nonfungible/Cargo.toml
@@ -19,7 +19,7 @@
nft-data-structs = { default-features = false, path = '../../primitives/nft' }
evm-coder = { default-features = false, path = '../../crates/evm-coder' }
pallet-evm-coder-substrate = { default-features = false, path = '../evm-coder-substrate' }
-ethereum = { git = "https://github.com/purestake/ethereum", branch = "joshy-scale-info", default-features = false }
+ethereum = { version = "0.10.0", default-features = false }
frame-benchmarking = { default-features = false, optional = true, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.12' }
scale-info = { version = "1.0.0", default-features = false, features = [
"derive",
pallets/nonfungible/src/erc.rsdiffbeforeafterboth1use core::{2 char::{REPLACEMENT_CHARACTER, decode_utf16},3 convert::TryInto,4};5use evm_coder::{ToLog, execution::*, generate_stubgen, solidity, solidity_interface, types::*, weight};6use frame_support::BoundedVec;7use nft_data_structs::TokenId;8use pallet_evm_coder_substrate::dispatch_to_evm;9use sp_core::{H160, U256};10use sp_std::{vec::Vec, vec};11use pallet_common::{12 account::CrossAccountId,13 erc::{CommonEvmHandler, PrecompileResult},14};15use pallet_evm_coder_substrate::call;16use pallet_common::erc::PrecompileOutput;1718use crate::{19 AccountBalance, Config, CreateItemData, NonfungibleHandle, Pallet, TokenData, TokensMinted,20 SelfWeightOf, weights::WeightInfo,21};2223#[derive(ToLog)]24pub enum ERC721Events {25 Transfer {26 #[indexed]27 from: address,28 #[indexed]29 to: address,30 #[indexed]31 token_id: uint256,32 },33 Approval {34 #[indexed]35 owner: address,36 #[indexed]37 approved: address,38 #[indexed]39 token_id: uint256,40 },41 #[allow(dead_code)]42 ApprovalForAll {43 #[indexed]44 owner: address,45 #[indexed]46 operator: address,47 approved: bool,48 },49}5051#[derive(ToLog)]52pub enum ERC721MintableEvents {53 #[allow(dead_code)]54 MintingFinished {},55}5657#[solidity_interface(name = "ERC721Metadata")]58impl<T: Config> NonfungibleHandle<T> {59 fn name(&self) -> Result<string> {60 Ok(decode_utf16(self.name.iter().copied())61 .map(|r| r.unwrap_or(REPLACEMENT_CHARACTER))62 .collect::<string>())63 }64 fn symbol(&self) -> Result<string> {65 Ok(string::from_utf8_lossy(&self.token_prefix).into())66 }6768 /// Returns token's const_metadata69 #[solidity(rename_selector = "tokenURI")]70 fn token_uri(&self, token_id: uint256) -> Result<string> {71 self.consume_store_reads(1)?;72 let token_id: u32 = token_id.try_into().map_err(|_| "token id overflow")?;73 Ok(string::from_utf8_lossy(74 &<TokenData<T>>::get((self.id, token_id))75 .ok_or("token not found")?76 .const_data,77 )78 .into())79 }80}8182#[solidity_interface(name = "ERC721Enumerable")]83impl<T: Config> NonfungibleHandle<T> {84 fn token_by_index(&self, index: uint256) -> Result<uint256> {85 Ok(index)86 }8788 /// Not implemented89 fn token_of_owner_by_index(&self, _owner: address, _index: uint256) -> Result<uint256> {90 // TODO: Not implemetable91 Err("not implemented".into())92 }9394 fn total_supply(&self) -> Result<uint256> {95 self.consume_store_reads(1)?;96 Ok(<Pallet<T>>::total_supply(self).into())97 }98}99100#[solidity_interface(name = "ERC721", events(ERC721Events))]101impl<T: Config> NonfungibleHandle<T> {102 fn balance_of(&self, owner: address) -> Result<uint256> {103 self.consume_store_reads(1)?;104 let owner = T::CrossAccountId::from_eth(owner);105 let balance = <AccountBalance<T>>::get((self.id, owner));106 Ok(balance.into())107 }108 fn owner_of(&self, token_id: uint256) -> Result<address> {109 self.consume_store_reads(1)?;110 let token: TokenId = token_id.try_into()?;111 Ok(*<TokenData<T>>::get((self.id, token))112 .ok_or("token not found")?113 .owner114 .as_eth())115 }116 /// Not implemented117 fn safe_transfer_from_with_data(118 &mut self,119 _from: address,120 _to: address,121 _token_id: uint256,122 _data: bytes,123 _value: value,124 ) -> Result<void> {125 // TODO: Not implemetable126 Err("not implemented".into())127 }128 /// Not implemented129 fn safe_transfer_from(130 &mut self,131 _from: address,132 _to: address,133 _token_id: uint256,134 _value: value,135 ) -> Result<void> {136 // TODO: Not implemetable137 Err("not implemented".into())138 }139140 #[weight(<SelfWeightOf<T>>::transfer_from())]141 fn transfer_from(142 &mut self,143 caller: caller,144 from: address,145 to: address,146 token_id: uint256,147 _value: value,148 ) -> Result<void> {149 let caller = T::CrossAccountId::from_eth(caller);150 let from = T::CrossAccountId::from_eth(from);151 let to = T::CrossAccountId::from_eth(to);152 let token = token_id.try_into()?;153154 <Pallet<T>>::transfer_from(self, &caller, &from, &to, token)155 .map_err(dispatch_to_evm::<T>)?;156 Ok(())157 }158159 #[weight(<SelfWeightOf<T>>::approve())]160 fn approve(161 &mut self,162 caller: caller,163 approved: address,164 token_id: uint256,165 _value: value,166 ) -> Result<void> {167 let caller = T::CrossAccountId::from_eth(caller);168 let approved = T::CrossAccountId::from_eth(approved);169 let token = token_id.try_into()?;170171 <Pallet<T>>::set_allowance(self, &caller, token, Some(&approved))172 .map_err(dispatch_to_evm::<T>)?;173 Ok(())174 }175176 /// Not implemented177 fn set_approval_for_all(178 &mut self,179 _caller: caller,180 _operator: address,181 _approved: bool,182 ) -> Result<void> {183 // TODO: Not implemetable184 Err("not implemented".into())185 }186187 /// Not implemented188 fn get_approved(&self, _token_id: uint256) -> Result<address> {189 // TODO: Not implemetable190 Err("not implemented".into())191 }192193 /// Not implemented194 fn is_approved_for_all(&self, _owner: address, _operator: address) -> Result<address> {195 // TODO: Not implemetable196 Err("not implemented".into())197 }198}199200#[solidity_interface(name = "ERC721Burnable")]201impl<T: Config> NonfungibleHandle<T> {202 #[weight(<SelfWeightOf<T>>::burn_item())]203 fn burn(&mut self, caller: caller, token_id: uint256) -> Result<void> {204 let caller = T::CrossAccountId::from_eth(caller);205 let token = token_id.try_into()?;206207 <Pallet<T>>::burn(self, &caller, token).map_err(dispatch_to_evm::<T>)?;208 Ok(())209 }210}211212#[solidity_interface(name = "ERC721Mintable", events(ERC721MintableEvents))]213impl<T: Config> NonfungibleHandle<T> {214 fn minting_finished(&self) -> Result<bool> {215 Ok(false)216 }217218 /// `token_id` should be obtained with `next_token_id` method,219 /// unlike standard, you can't specify it manually220 #[weight(<SelfWeightOf<T>>::create_item())]221 fn mint(&mut self, caller: caller, to: address, token_id: uint256) -> Result<bool> {222 let caller = T::CrossAccountId::from_eth(caller);223 let to = T::CrossAccountId::from_eth(to);224 let token_id: u32 = token_id.try_into()?;225 if <TokensMinted<T>>::get(self.id)226 .checked_add(1)227 .ok_or("item id overflow")?228 != token_id229 {230 return Err("item id should be next".into());231 }232233 <Pallet<T>>::create_item(234 self,235 &caller,236 CreateItemData {237 const_data: BoundedVec::default(),238 variable_data: BoundedVec::default(),239 owner: to,240 },241 )242 .map_err(dispatch_to_evm::<T>)?;243244 Ok(true)245 }246247 /// `token_id` should be obtained with `next_token_id` method,248 /// unlike standard, you can't specify it manually249 #[solidity(rename_selector = "mintWithTokenURI")]250 #[weight(<SelfWeightOf<T>>::create_item())]251 fn mint_with_token_uri(252 &mut self,253 caller: caller,254 to: address,255 token_id: uint256,256 token_uri: string,257 ) -> Result<bool> {258 let caller = T::CrossAccountId::from_eth(caller);259 let to = T::CrossAccountId::from_eth(to);260 let token_id: u32 = token_id.try_into().map_err(|_| "amount overflow")?;261 if <TokensMinted<T>>::get(self.id)262 .checked_add(1)263 .ok_or("item id overflow")?264 != token_id265 {266 return Err("item id should be next".into());267 }268269 <Pallet<T>>::create_item(270 self,271 &caller,272 CreateItemData {273 const_data: Vec::<u8>::from(token_uri)274 .try_into()275 .map_err(|_| "token uri is too long")?,276 variable_data: BoundedVec::default(),277 owner: to,278 },279 )280 .map_err(dispatch_to_evm::<T>)?;281 Ok(true)282 }283284 /// Not implemented285 fn finish_minting(&mut self, _caller: caller) -> Result<bool> {286 Err("not implementable".into())287 }288}289290#[solidity_interface(name = "ERC721UniqueExtensions")]291impl<T: Config> NonfungibleHandle<T> {292 #[weight(<SelfWeightOf<T>>::transfer())]293 fn transfer(294 &mut self,295 caller: caller,296 to: address,297 token_id: uint256,298 _value: value,299 ) -> Result<void> {300 let caller = T::CrossAccountId::from_eth(caller);301 let to = T::CrossAccountId::from_eth(to);302 let token = token_id.try_into()?;303304 <Pallet<T>>::transfer(self, &caller, &to, token).map_err(dispatch_to_evm::<T>)?;305 Ok(())306 }307308 #[weight(<SelfWeightOf<T>>::burn_from())]309 fn burn_from(310 &mut self,311 caller: caller,312 from: address,313 token_id: uint256,314 _value: value,315 ) -> Result<void> {316 let caller = T::CrossAccountId::from_eth(caller);317 let from = T::CrossAccountId::from_eth(from);318 let token = token_id.try_into()?;319320 <Pallet<T>>::burn_from(self, &caller, &from, token).map_err(dispatch_to_evm::<T>)?;321 Ok(())322 }323324 fn next_token_id(&self) -> Result<uint256> {325 self.consume_store_reads(1)?;326 Ok(<TokensMinted<T>>::get(self.id)327 .checked_add(1)328 .ok_or("item id overflow")?329 .into())330 }331332 #[weight(<SelfWeightOf<T>>::set_variable_metadata(data.len() as u32))]333 fn set_variable_metadata(334 &mut self,335 caller: caller,336 token_id: uint256,337 data: bytes,338 ) -> Result<void> {339 let caller = T::CrossAccountId::from_eth(caller);340 let token = token_id.try_into()?;341342 <Pallet<T>>::set_variable_metadata(self, &caller, token, data)343 .map_err(dispatch_to_evm::<T>)?;344 Ok(())345 }346347 fn get_variable_metadata(&self, token_id: uint256) -> Result<bytes> {348 self.consume_store_reads(1)?;349 let token: TokenId = token_id.try_into()?;350351 Ok(<TokenData<T>>::get((self.id, token))352 .ok_or("token not found")?353 .variable_data)354 }355356 #[weight(<SelfWeightOf<T>>::create_multiple_items(token_ids.len() as u32))]357 fn mint_bulk(&mut self, caller: caller, to: address, token_ids: Vec<uint256>) -> Result<bool> {358 let caller = T::CrossAccountId::from_eth(caller);359 let to = T::CrossAccountId::from_eth(to);360 let mut expected_index = <TokensMinted<T>>::get(self.id)361 .checked_add(1)362 .ok_or("item id overflow")?;363364 let total_tokens = token_ids.len();365 for id in token_ids.into_iter() {366 let id: u32 = id.try_into().map_err(|_| "token id overflow")?;367 if id != expected_index {368 return Err("item id should be next".into());369 }370 expected_index = expected_index.checked_add(1).ok_or("item id overflow")?;371 }372 let data = (0..total_tokens)373 .map(|_| CreateItemData {374 const_data: BoundedVec::default(),375 variable_data: BoundedVec::default(),376 owner: to.clone(),377 })378 .collect();379380 <Pallet<T>>::create_multiple_items(self, &caller, data).map_err(dispatch_to_evm::<T>)?;381 Ok(true)382 }383384 #[solidity(rename_selector = "mintBulkWithTokenURI")]385 #[weight(<SelfWeightOf<T>>::create_multiple_items(tokens.len() as u32))]386 fn mint_bulk_with_token_uri(387 &mut self,388 caller: caller,389 to: address,390 tokens: Vec<(uint256, string)>,391 ) -> Result<bool> {392 let caller = T::CrossAccountId::from_eth(caller);393 let to = T::CrossAccountId::from_eth(to);394 let mut expected_index = <TokensMinted<T>>::get(self.id)395 .checked_add(1)396 .ok_or("item id overflow")?;397398 let mut data = Vec::with_capacity(tokens.len());399 for (id, token_uri) in tokens {400 let id: u32 = id.try_into().map_err(|_| "token id overflow")?;401 if id != expected_index {402 panic!("item id should be next ({}) but got {}", expected_index, id);403 }404 expected_index = expected_index.checked_add(1).ok_or("item id overflow")?;405406 data.push(CreateItemData {407 const_data: Vec::<u8>::from(token_uri)408 .try_into()409 .map_err(|_| "token uri is too long")?,410 variable_data: vec![].try_into().unwrap(),411 owner: to.clone(),412 });413 }414415 <Pallet<T>>::create_multiple_items(self, &caller, data).map_err(dispatch_to_evm::<T>)?;416 Ok(true)417 }418}419420#[solidity_interface(421 name = "UniqueNFT",422 is(423 ERC721,424 ERC721Metadata,425 ERC721Enumerable,426 ERC721UniqueExtensions,427 ERC721Mintable,428 ERC721Burnable,429 )430)]431impl<T: Config> NonfungibleHandle<T> {}432433// Not a tests, but code generators434generate_stubgen!(gen_impl, UniqueNFTCall<()>, true);435generate_stubgen!(gen_iface, UniqueNFTCall<()>, false);436437impl<T: Config> CommonEvmHandler for NonfungibleHandle<T> {438 const CODE: &'static [u8] = include_bytes!("./stubs/UniqueNFT.raw");439440 fn call(self, source: &H160, input: &[u8], value: U256) -> Option<PrecompileResult> {441 call::<T, UniqueNFTCall<T>, _>(*source, self, value, input)442 }443}pallets/refungible/src/erc.rsdiffbeforeafterboth--- a/pallets/refungible/src/erc.rs
+++ b/pallets/refungible/src/erc.rs
@@ -11,7 +11,7 @@
_source: &sp_core::H160,
_input: &[u8],
_value: sp_core::U256,
- ) -> Option<pallet_common::erc::PrecompileOutput> {
+ ) -> Option<pallet_common::erc::PrecompileResult> {
// TODO: Implement RFT variant of ERC721
None
}
@@ -27,7 +27,7 @@
_source: &sp_core::H160,
_input: &[u8],
_value: sp_core::U256,
- ) -> Option<pallet_common::erc::PrecompileOutput> {
+ ) -> Option<pallet_common::erc::PrecompileResult> {
// TODO: Implement RFT variant of ERC20
None
}