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::{account::CrossAccountId, erc::CommonEvmHandler};12use pallet_evm_coder_substrate::call;13use pallet_common::erc::PrecompileOutput;1415use crate::{16 AccountBalance, Config, CreateItemData, NonfungibleHandle, Pallet, TokenData, TokensMinted,17 SelfWeightOf, weights::WeightInfo,18};1920#[derive(ToLog)]21pub enum ERC721Events {22 Transfer {23 #[indexed]24 from: address,25 #[indexed]26 to: address,27 #[indexed]28 token_id: uint256,29 },30 Approval {31 #[indexed]32 owner: address,33 #[indexed]34 approved: address,35 #[indexed]36 token_id: uint256,37 },38 #[allow(dead_code)]39 ApprovalForAll {40 #[indexed]41 owner: address,42 #[indexed]43 operator: address,44 approved: bool,45 },46}4748#[derive(ToLog)]49pub enum ERC721MintableEvents {50 #[allow(dead_code)]51 MintingFinished {},52}5354#[solidity_interface(name = "ERC721Metadata")]55impl<T: Config> NonfungibleHandle<T> {56 fn name(&self) -> Result<string> {57 Ok(decode_utf16(self.name.iter().copied())58 .map(|r| r.unwrap_or(REPLACEMENT_CHARACTER))59 .collect::<string>())60 }61 fn symbol(&self) -> Result<string> {62 Ok(string::from_utf8_lossy(&self.token_prefix).into())63 }6465 /// Returns token's const_metadata66 #[solidity(rename_selector = "tokenURI")]67 fn token_uri(&self, token_id: uint256) -> Result<string> {68 self.consume_store_reads(1)?;69 let token_id: u32 = token_id.try_into().map_err(|_| "token id overflow")?;70 Ok(string::from_utf8_lossy(71 &<TokenData<T>>::get((self.id, token_id))72 .ok_or("token not found")?73 .const_data,74 )75 .into())76 }77}7879#[solidity_interface(name = "ERC721Enumerable")]80impl<T: Config> NonfungibleHandle<T> {81 fn token_by_index(&self, index: uint256) -> Result<uint256> {82 Ok(index)83 }8485 /// Not implemented86 fn token_of_owner_by_index(&self, _owner: address, _index: uint256) -> Result<uint256> {87 // TODO: Not implemetable88 Err("not implemented".into())89 }9091 fn total_supply(&self) -> Result<uint256> {92 self.consume_store_reads(1)?;93 Ok(<Pallet<T>>::total_supply(self).into())94 }95}9697#[solidity_interface(name = "ERC721", events(ERC721Events))]98impl<T: Config> NonfungibleHandle<T> {99 fn balance_of(&self, owner: address) -> Result<uint256> {100 self.consume_store_reads(1)?;101 let owner = T::CrossAccountId::from_eth(owner);102 let balance = <AccountBalance<T>>::get((self.id, owner));103 Ok(balance.into())104 }105 fn owner_of(&self, token_id: uint256) -> Result<address> {106 self.consume_store_reads(1)?;107 let token: TokenId = token_id.try_into()?;108 Ok(*<TokenData<T>>::get((self.id, token))109 .ok_or("token not found")?110 .owner111 .as_eth())112 }113 /// Not implemented114 fn safe_transfer_from_with_data(115 &mut self,116 _from: address,117 _to: address,118 _token_id: uint256,119 _data: bytes,120 _value: value,121 ) -> Result<void> {122 // TODO: Not implemetable123 Err("not implemented".into())124 }125 /// Not implemented126 fn safe_transfer_from(127 &mut self,128 _from: address,129 _to: address,130 _token_id: uint256,131 _value: value,132 ) -> Result<void> {133 // TODO: Not implemetable134 Err("not implemented".into())135 }136137 #[weight(<SelfWeightOf<T>>::transfer_from())]138 fn transfer_from(139 &mut self,140 caller: caller,141 from: address,142 to: address,143 token_id: uint256,144 _value: value,145 ) -> Result<void> {146 let caller = T::CrossAccountId::from_eth(caller);147 let from = T::CrossAccountId::from_eth(from);148 let to = T::CrossAccountId::from_eth(to);149 let token = token_id.try_into()?;150151 <Pallet<T>>::transfer_from(self, &caller, &from, &to, token)152 .map_err(dispatch_to_evm::<T>)?;153 Ok(())154 }155156 #[weight(<SelfWeightOf<T>>::approve())]157 fn approve(158 &mut self,159 caller: caller,160 approved: address,161 token_id: uint256,162 _value: value,163 ) -> Result<void> {164 let caller = T::CrossAccountId::from_eth(caller);165 let approved = T::CrossAccountId::from_eth(approved);166 let token = token_id.try_into()?;167168 <Pallet<T>>::set_allowance(self, &caller, token, Some(&approved))169 .map_err(dispatch_to_evm::<T>)?;170 Ok(())171 }172173 /// Not implemented174 fn set_approval_for_all(175 &mut self,176 _caller: caller,177 _operator: address,178 _approved: bool,179 ) -> Result<void> {180 // TODO: Not implemetable181 Err("not implemented".into())182 }183184 /// Not implemented185 fn get_approved(&self, _token_id: uint256) -> Result<address> {186 // TODO: Not implemetable187 Err("not implemented".into())188 }189190 /// Not implemented191 fn is_approved_for_all(&self, _owner: address, _operator: address) -> Result<address> {192 // TODO: Not implemetable193 Err("not implemented".into())194 }195}196197#[solidity_interface(name = "ERC721Burnable")]198impl<T: Config> NonfungibleHandle<T> {199 #[weight(<SelfWeightOf<T>>::burn_item())]200 fn burn(&mut self, caller: caller, token_id: uint256) -> Result<void> {201 let caller = T::CrossAccountId::from_eth(caller);202 let token = token_id.try_into()?;203204 <Pallet<T>>::burn(self, &caller, token).map_err(dispatch_to_evm::<T>)?;205 Ok(())206 }207}208209#[solidity_interface(name = "ERC721Mintable", events(ERC721MintableEvents))]210impl<T: Config> NonfungibleHandle<T> {211 fn minting_finished(&self) -> Result<bool> {212 Ok(false)213 }214215 /// `token_id` should be obtained with `next_token_id` method,216 /// unlike standard, you can't specify it manually217 #[weight(<SelfWeightOf<T>>::create_item())]218 fn mint(&mut self, caller: caller, to: address, token_id: uint256) -> Result<bool> {219 let caller = T::CrossAccountId::from_eth(caller);220 let to = T::CrossAccountId::from_eth(to);221 let token_id: u32 = token_id.try_into()?;222 if <TokensMinted<T>>::get(self.id)223 .checked_add(1)224 .ok_or("item id overflow")?225 != token_id226 {227 return Err("item id should be next".into());228 }229230 <Pallet<T>>::create_item(231 self,232 &caller,233 CreateItemData {234 const_data: BoundedVec::default(),235 variable_data: BoundedVec::default(),236 owner: to,237 },238 )239 .map_err(dispatch_to_evm::<T>)?;240241 Ok(true)242 }243244 /// `token_id` should be obtained with `next_token_id` method,245 /// unlike standard, you can't specify it manually246 #[solidity(rename_selector = "mintWithTokenURI")]247 #[weight(<SelfWeightOf<T>>::create_item())]248 fn mint_with_token_uri(249 &mut self,250 caller: caller,251 to: address,252 token_id: uint256,253 token_uri: string,254 ) -> Result<bool> {255 let caller = T::CrossAccountId::from_eth(caller);256 let to = T::CrossAccountId::from_eth(to);257 let token_id: u32 = token_id.try_into().map_err(|_| "amount overflow")?;258 if <TokensMinted<T>>::get(self.id)259 .checked_add(1)260 .ok_or("item id overflow")?261 != token_id262 {263 return Err("item id should be next".into());264 }265266 <Pallet<T>>::create_item(267 self,268 &caller,269 CreateItemData {270 const_data: Vec::<u8>::from(token_uri)271 .try_into()272 .map_err(|_| "token uri is too long")?,273 variable_data: BoundedVec::default(),274 owner: to,275 },276 )277 .map_err(dispatch_to_evm::<T>)?;278 Ok(true)279 }280281 /// Not implemented282 fn finish_minting(&mut self, _caller: caller) -> Result<bool> {283 Err("not implementable".into())284 }285}286287#[solidity_interface(name = "ERC721UniqueExtensions")]288impl<T: Config> NonfungibleHandle<T> {289 #[weight(<SelfWeightOf<T>>::transfer())]290 fn transfer(291 &mut self,292 caller: caller,293 to: address,294 token_id: uint256,295 _value: value,296 ) -> Result<void> {297 let caller = T::CrossAccountId::from_eth(caller);298 let to = T::CrossAccountId::from_eth(to);299 let token = token_id.try_into()?;300301 <Pallet<T>>::transfer(self, &caller, &to, token).map_err(dispatch_to_evm::<T>)?;302 Ok(())303 }304305 #[weight(<SelfWeightOf<T>>::burn_from())]306 fn burn_from(307 &mut self,308 caller: caller,309 from: address,310 token_id: uint256,311 _value: value,312 ) -> Result<void> {313 let caller = T::CrossAccountId::from_eth(caller);314 let from = T::CrossAccountId::from_eth(from);315 let token = token_id.try_into()?;316317 <Pallet<T>>::burn_from(self, &caller, &from, token).map_err(dispatch_to_evm::<T>)?;318 Ok(())319 }320321 fn next_token_id(&self) -> Result<uint256> {322 self.consume_store_reads(1)?;323 Ok(<TokensMinted<T>>::get(self.id)324 .checked_add(1)325 .ok_or("item id overflow")?326 .into())327 }328329 #[weight(<SelfWeightOf<T>>::set_variable_metadata(data.len() as u32))]330 fn set_variable_metadata(331 &mut self,332 caller: caller,333 token_id: uint256,334 data: bytes,335 ) -> Result<void> {336 let caller = T::CrossAccountId::from_eth(caller);337 let token = token_id.try_into()?;338339 <Pallet<T>>::set_variable_metadata(self, &caller, token, data)340 .map_err(dispatch_to_evm::<T>)?;341 Ok(())342 }343344 fn get_variable_metadata(&self, token_id: uint256) -> Result<bytes> {345 self.consume_store_reads(1)?;346 let token: TokenId = token_id.try_into()?;347348 Ok(<TokenData<T>>::get((self.id, token))349 .ok_or("token not found")?350 .variable_data)351 }352353 #[weight(<SelfWeightOf<T>>::create_multiple_items(token_ids.len() as u32))]354 fn mint_bulk(&mut self, caller: caller, to: address, token_ids: Vec<uint256>) -> Result<bool> {355 let caller = T::CrossAccountId::from_eth(caller);356 let to = T::CrossAccountId::from_eth(to);357 let mut expected_index = <TokensMinted<T>>::get(self.id)358 .checked_add(1)359 .ok_or("item id overflow")?;360361 let total_tokens = token_ids.len();362 for id in token_ids.into_iter() {363 let id: u32 = id.try_into().map_err(|_| "token id overflow")?;364 if id != expected_index {365 return Err("item id should be next".into());366 }367 expected_index = expected_index.checked_add(1).ok_or("item id overflow")?;368 }369 let data = (0..total_tokens)370 .map(|_| CreateItemData {371 const_data: BoundedVec::default(),372 variable_data: BoundedVec::default(),373 owner: to.clone(),374 })375 .collect();376377 <Pallet<T>>::create_multiple_items(self, &caller, data).map_err(dispatch_to_evm::<T>)?;378 Ok(true)379 }380381 #[solidity(rename_selector = "mintBulkWithTokenURI")]382 #[weight(<SelfWeightOf<T>>::create_multiple_items(tokens.len() as u32))]383 fn mint_bulk_with_token_uri(384 &mut self,385 caller: caller,386 to: address,387 tokens: Vec<(uint256, string)>,388 ) -> Result<bool> {389 let caller = T::CrossAccountId::from_eth(caller);390 let to = T::CrossAccountId::from_eth(to);391 let mut expected_index = <TokensMinted<T>>::get(self.id)392 .checked_add(1)393 .ok_or("item id overflow")?;394395 let mut data = Vec::with_capacity(tokens.len());396 for (id, token_uri) in tokens {397 let id: u32 = id.try_into().map_err(|_| "token id overflow")?;398 if id != expected_index {399 panic!("item id should be next ({}) but got {}", expected_index, id);400 }401 expected_index = expected_index.checked_add(1).ok_or("item id overflow")?;402403 data.push(CreateItemData {404 const_data: Vec::<u8>::from(token_uri)405 .try_into()406 .map_err(|_| "token uri is too long")?,407 variable_data: vec![].try_into().unwrap(),408 owner: to.clone(),409 });410 }411412 <Pallet<T>>::create_multiple_items(self, &caller, data).map_err(dispatch_to_evm::<T>)?;413 Ok(true)414 }415}416417#[solidity_interface(418 name = "UniqueNFT",419 is(420 ERC721,421 ERC721Metadata,422 ERC721Enumerable,423 ERC721UniqueExtensions,424 ERC721Mintable,425 ERC721Burnable,426 )427)]428impl<T: Config> NonfungibleHandle<T> {}429430// Not a tests, but code generators431generate_stubgen!(gen_impl, UniqueNFTCall<()>, true);432generate_stubgen!(gen_iface, UniqueNFTCall<()>, false);433434impl<T: Config> CommonEvmHandler for NonfungibleHandle<T> {435 const CODE: &'static [u8] = include_bytes!("./stubs/UniqueNFT.raw");436437 fn call(self, source: &H160, input: &[u8], value: U256) -> Option<PrecompileOutput> {438 call::<T, UniqueNFTCall<T>, _>(*source, self, value, input)439 }440}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
}