difftreelog
Merge pull request #654 from UniqueNetwork/feature/solidity_methods_renaming
in: master
Feature/solidity methods renaming
21 files changed
pallets/common/src/erc.rsdiffbeforeafterboth--- a/pallets/common/src/erc.rs
+++ b/pallets/common/src/erc.rs
@@ -592,6 +592,7 @@
///
/// @dev Owner can be changed only by current owner
/// @param newOwner new owner account
+ #[solidity(rename_selector = "changeCollectionOwner")]
fn set_owner(&mut self, caller: caller, new_owner: address) -> Result<void> {
self.consume_store_writes(1)?;
pallets/evm-contract-helpers/src/stubs/ContractHelpers.rawdiffbeforeafterbothbinary blob — no preview
pallets/fungible/src/stubs/UniqueFungible.rawdiffbeforeafterbothbinary blob — no preview
pallets/fungible/src/stubs/UniqueFungible.soldiffbeforeafterboth--- a/pallets/fungible/src/stubs/UniqueFungible.sol
+++ b/pallets/fungible/src/stubs/UniqueFungible.sol
@@ -18,7 +18,7 @@
}
/// @title A contract that allows you to work with collections.
-/// @dev the ERC-165 identifier for this interface is 0x3e1e8083
+/// @dev the ERC-165 identifier for this interface is 0x62e22290
contract Collection is Dummy, ERC165 {
/// Set collection property.
///
@@ -296,9 +296,9 @@
///
/// @dev Owner can be changed only by current owner
/// @param newOwner new owner account
- /// @dev EVM selector for this function is: 0x13af4035,
- /// or in textual repr: setOwner(address)
- function setOwner(address newOwner) public {
+ /// @dev EVM selector for this function is: 0x4f53e226,
+ /// or in textual repr: changeCollectionOwner(address)
+ function changeCollectionOwner(address newOwner) public {
require(false, stub_error);
newOwner;
dummy = 0;
pallets/nonfungible/src/stubs/UniqueNFT.rawdiffbeforeafterbothbinary blob — no preview
pallets/nonfungible/src/stubs/UniqueNFT.soldiffbeforeafterboth--- a/pallets/nonfungible/src/stubs/UniqueNFT.sol
+++ b/pallets/nonfungible/src/stubs/UniqueNFT.sol
@@ -91,7 +91,7 @@
}
/// @title A contract that allows you to work with collections.
-/// @dev the ERC-165 identifier for this interface is 0x3e1e8083
+/// @dev the ERC-165 identifier for this interface is 0x62e22290
contract Collection is Dummy, ERC165 {
/// Set collection property.
///
@@ -369,9 +369,9 @@
///
/// @dev Owner can be changed only by current owner
/// @param newOwner new owner account
- /// @dev EVM selector for this function is: 0x13af4035,
- /// or in textual repr: setOwner(address)
- function setOwner(address newOwner) public {
+ /// @dev EVM selector for this function is: 0x4f53e226,
+ /// or in textual repr: changeCollectionOwner(address)
+ function changeCollectionOwner(address newOwner) public {
require(false, stub_error);
newOwner;
dummy = 0;
pallets/refungible/src/stubs/UniqueRefungible.rawdiffbeforeafterbothbinary blob — no preview
pallets/refungible/src/stubs/UniqueRefungible.soldiffbeforeafterboth--- a/pallets/refungible/src/stubs/UniqueRefungible.sol
+++ b/pallets/refungible/src/stubs/UniqueRefungible.sol
@@ -91,7 +91,7 @@
}
/// @title A contract that allows you to work with collections.
-/// @dev the ERC-165 identifier for this interface is 0x3e1e8083
+/// @dev the ERC-165 identifier for this interface is 0x62e22290
contract Collection is Dummy, ERC165 {
/// Set collection property.
///
@@ -369,9 +369,9 @@
///
/// @dev Owner can be changed only by current owner
/// @param newOwner new owner account
- /// @dev EVM selector for this function is: 0x13af4035,
- /// or in textual repr: setOwner(address)
- function setOwner(address newOwner) public {
+ /// @dev EVM selector for this function is: 0x4f53e226,
+ /// or in textual repr: changeCollectionOwner(address)
+ function changeCollectionOwner(address newOwner) public {
require(false, stub_error);
newOwner;
dummy = 0;
pallets/refungible/src/stubs/UniqueRefungibleToken.rawdiffbeforeafterbothbinary blob — no preview
pallets/unique/src/eth/mod.rsdiffbeforeafterboth1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617//! Implementation of CollectionHelpers contract.1819use core::marker::PhantomData;20use ethereum as _;21use evm_coder::{execution::*, generate_stubgen, solidity_interface, solidity, weight, types::*};22use frame_support::traits::Get;23use pallet_common::{24 CollectionById,25 dispatch::CollectionDispatch,26 erc::{27 CollectionHelpersEvents,28 static_property::{key},29 },30 Pallet as PalletCommon,31};32use pallet_evm_coder_substrate::{dispatch_to_evm, SubstrateRecorder, WithRecorder};33use pallet_evm::{account::CrossAccountId, OnMethodCall, PrecompileHandle, PrecompileResult};34use sp_std::vec;35use up_data_structs::{36 CollectionName, CollectionDescription, CollectionTokenPrefix, CreateCollectionData,37 CollectionMode, PropertyValue, CollectionFlags,38};3940use crate::{Config, SelfWeightOf, weights::WeightInfo};4142use sp_std::vec::Vec;43use alloc::format;4445/// See [`CollectionHelpersCall`]46pub struct EvmCollectionHelpers<T: Config>(SubstrateRecorder<T>);47impl<T: Config> WithRecorder<T> for EvmCollectionHelpers<T> {48 fn recorder(&self) -> &SubstrateRecorder<T> {49 &self.050 }5152 fn into_recorder(self) -> SubstrateRecorder<T> {53 self.054 }55}5657fn convert_data<T: Config>(58 caller: caller,59 name: string,60 description: string,61 token_prefix: string,62) -> Result<(63 T::CrossAccountId,64 CollectionName,65 CollectionDescription,66 CollectionTokenPrefix,67)> {68 let caller = T::CrossAccountId::from_eth(caller);69 let name = name70 .encode_utf16()71 .collect::<Vec<u16>>()72 .try_into()73 .map_err(|_| error_field_too_long(stringify!(name), CollectionName::bound()))?;74 let description = description75 .encode_utf16()76 .collect::<Vec<u16>>()77 .try_into()78 .map_err(|_| {79 error_field_too_long(stringify!(description), CollectionDescription::bound())80 })?;81 let token_prefix = token_prefix.into_bytes().try_into().map_err(|_| {82 error_field_too_long(stringify!(token_prefix), CollectionTokenPrefix::bound())83 })?;84 Ok((caller, name, description, token_prefix))85}8687fn create_refungible_collection_internal<88 T: Config + pallet_nonfungible::Config + pallet_refungible::Config,89>(90 caller: caller,91 value: value,92 name: string,93 description: string,94 token_prefix: string,95) -> Result<address> {96 let (caller, name, description, token_prefix) =97 convert_data::<T>(caller, name, description, token_prefix)?;98 let data = CreateCollectionData {99 name,100 mode: CollectionMode::ReFungible,101 description,102 token_prefix,103 ..Default::default()104 };105 check_sent_amount_equals_collection_creation_price::<T>(value)?;106 let collection_helpers_address =107 T::CrossAccountId::from_eth(<T as pallet_common::Config>::ContractAddress::get());108109 let collection_id = T::CollectionDispatch::create(110 caller.clone(),111 collection_helpers_address,112 data,113 Default::default(),114 )115 .map_err(pallet_evm_coder_substrate::dispatch_to_evm::<T>)?;116 let address = pallet_common::eth::collection_id_to_address(collection_id);117 Ok(address)118}119120fn check_sent_amount_equals_collection_creation_price<T: Config>(value: value) -> Result<()> {121 let value = value.as_u128();122 let creation_price: u128 = T::CollectionCreationPrice::get()123 .try_into()124 .map_err(|_| ()) // workaround for `expect` requiring `Debug` trait125 .expect("Collection creation price should be convertible to u128");126 if value != creation_price {127 return Err(format!(128 "Sent amount not equals to collection creation price ({0})",129 creation_price130 )131 .into());132 }133 Ok(())134}135136/// @title Contract, which allows users to operate with collections137#[solidity_interface(name = CollectionHelpers, events(CollectionHelpersEvents))]138impl<T> EvmCollectionHelpers<T>139where140 T: Config + pallet_common::Config + pallet_nonfungible::Config + pallet_refungible::Config,141{142 /// Create an NFT collection143 /// @param name Name of the collection144 /// @param description Informative description of the collection145 /// @param tokenPrefix Token prefix to represent the collection tokens in UI and user applications146 /// @return address Address of the newly created collection147 #[weight(<SelfWeightOf<T>>::create_collection())]148 #[solidity(rename_selector = "createNFTCollection")]149 fn create_nft_collection(150 &mut self,151 caller: caller,152 value: value,153 name: string,154 description: string,155 token_prefix: string,156 ) -> Result<address> {157 let (caller, name, description, token_prefix) =158 convert_data::<T>(caller, name, description, token_prefix)?;159 let data = CreateCollectionData {160 name,161 mode: CollectionMode::NFT,162 description,163 token_prefix,164 ..Default::default()165 };166 check_sent_amount_equals_collection_creation_price::<T>(value)?;167 let collection_helpers_address =168 T::CrossAccountId::from_eth(<T as pallet_common::Config>::ContractAddress::get());169 let collection_id = T::CollectionDispatch::create(170 caller,171 collection_helpers_address,172 data,173 Default::default(),174 )175 .map_err(dispatch_to_evm::<T>)?;176177 let address = pallet_common::eth::collection_id_to_address(collection_id);178 Ok(address)179 }180 /// Create an NFT collection181 /// @param name Name of the collection182 /// @param description Informative description of the collection183 /// @param tokenPrefix Token prefix to represent the collection tokens in UI and user applications184 /// @return address Address of the newly created collection185 #[weight(<SelfWeightOf<T>>::create_collection())]186 #[deprecated(note = "mathod was renamed to `create_nft_collection`, prefer it instead")]187 fn create_nonfungible_collection(188 &mut self,189 caller: caller,190 value: value,191 name: string,192 description: string,193 token_prefix: string,194 ) -> Result<address> {195 self.create_nft_collection(caller, value, name, description, token_prefix)196 }197198 #[weight(<SelfWeightOf<T>>::create_collection())]199 #[solidity(rename_selector = "createRFTCollection")]200 fn create_rft_collection(201 &mut self,202 caller: caller,203 value: value,204 name: string,205 description: string,206 token_prefix: string,207 ) -> Result<address> {208 create_refungible_collection_internal::<T>(caller, value, name, description, token_prefix)209 }210211 #[solidity(rename_selector = "makeCollectionERC721MetadataCompatible")]212 fn make_collection_metadata_compatible(213 &mut self,214 caller: caller,215 collection: address,216 base_uri: string,217 ) -> Result<()> {218 let caller = T::CrossAccountId::from_eth(caller);219 let collection =220 pallet_common::eth::map_eth_to_id(&collection).ok_or("not a collection address")?;221 let mut collection =222 <crate::CollectionHandle<T>>::new(collection).ok_or("collection not found")?;223224 if !matches!(225 collection.mode,226 CollectionMode::NFT | CollectionMode::ReFungible227 ) {228 return Err("target collection should be either NFT or Refungible".into());229 }230231 self.recorder().consume_sstore()?;232 collection233 .check_is_owner_or_admin(&caller)234 .map_err(dispatch_to_evm::<T>)?;235236 if collection.flags.erc721metadata {237 return Err("target collection is already Erc721Metadata compatible".into());238 }239 collection.flags.erc721metadata = true;240241 let all_permissions = <pallet_common::CollectionPropertyPermissions<T>>::get(collection.id);242 if all_permissions.get(&key::url()).is_none() {243 self.recorder().consume_sstore()?;244 <PalletCommon<T>>::set_property_permission(245 &collection,246 &caller,247 up_data_structs::PropertyKeyPermission {248 key: key::url(),249 permission: up_data_structs::PropertyPermission {250 mutable: true,251 collection_admin: true,252 token_owner: false,253 },254 },255 )256 .map_err(dispatch_to_evm::<T>)?;257 }258 if all_permissions.get(&key::suffix()).is_none() {259 self.recorder().consume_sstore()?;260 <PalletCommon<T>>::set_property_permission(261 &collection,262 &caller,263 up_data_structs::PropertyKeyPermission {264 key: key::suffix(),265 permission: up_data_structs::PropertyPermission {266 mutable: true,267 collection_admin: true,268 token_owner: false,269 },270 },271 )272 .map_err(dispatch_to_evm::<T>)?;273 }274275 let all_properties = <pallet_common::CollectionProperties<T>>::get(collection.id);276 if all_properties.get(&key::base_uri()).is_none() && !base_uri.is_empty() {277 self.recorder().consume_sstore()?;278 <PalletCommon<T>>::set_collection_properties(279 &collection,280 &caller,281 vec![up_data_structs::Property {282 key: key::base_uri(),283 value: base_uri284 .into_bytes()285 .try_into()286 .map_err(|_| "base uri is too large")?,287 }],288 )289 .map_err(dispatch_to_evm::<T>)?;290 }291292 self.recorder().consume_sstore()?;293 collection.save().map_err(dispatch_to_evm::<T>)?;294295 Ok(())296 }297298 /// Check if a collection exists299 /// @param collectionAddress Address of the collection in question300 /// @return bool Does the collection exist?301 fn is_collection_exist(&self, _caller: caller, collection_address: address) -> Result<bool> {302 if let Some(id) = pallet_common::eth::map_eth_to_id(&collection_address) {303 let collection_id = id;304 return Ok(<CollectionById<T>>::contains_key(collection_id));305 }306307 Ok(false)308 }309310 fn collection_creation_fee(&self) -> Result<value> {311 let price: u128 = T::CollectionCreationPrice::get()312 .try_into()313 .map_err(|_| ()) // workaround for `expect` requiring `Debug` trait314 .expect("Collection creation price should be convertible to u128");315 Ok(price.into())316 }317}318319/// Implements [`OnMethodCall`], which delegates call to [`EvmCollectionHelpers`]320pub struct CollectionHelpersOnMethodCall<T: Config>(PhantomData<*const T>);321impl<T: Config + pallet_nonfungible::Config + pallet_refungible::Config> OnMethodCall<T>322 for CollectionHelpersOnMethodCall<T>323{324 fn is_reserved(contract: &sp_core::H160) -> bool {325 contract == &T::ContractAddress::get()326 }327328 fn is_used(contract: &sp_core::H160) -> bool {329 contract == &T::ContractAddress::get()330 }331332 fn call(handle: &mut impl PrecompileHandle) -> Option<PrecompileResult> {333 if handle.code_address() != T::ContractAddress::get() {334 return None;335 }336337 let helpers =338 EvmCollectionHelpers::<T>(SubstrateRecorder::<T>::new(handle.remaining_gas()));339 pallet_evm_coder_substrate::call(handle, helpers)340 }341342 fn get_code(contract: &sp_core::H160) -> Option<Vec<u8>> {343 (contract == &T::ContractAddress::get())344 .then(|| include_bytes!("./stubs/CollectionHelpers.raw").to_vec())345 }346}347348generate_stubgen!(collection_helper_impl, CollectionHelpersCall<()>, true);349generate_stubgen!(collection_helper_iface, CollectionHelpersCall<()>, false);350351fn error_field_too_long(feild: &str, bound: usize) -> Error {352 Error::Revert(format!("{} is too long. Max length is {}.", feild, bound))353}1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617//! Implementation of CollectionHelpers contract.1819use core::marker::PhantomData;20use ethereum as _;21use evm_coder::{execution::*, generate_stubgen, solidity_interface, solidity, weight, types::*};22use frame_support::traits::Get;23use pallet_common::{24 CollectionById,25 dispatch::CollectionDispatch,26 erc::{27 CollectionHelpersEvents,28 static_property::{key},29 },30 Pallet as PalletCommon,31};32use pallet_evm_coder_substrate::{dispatch_to_evm, SubstrateRecorder, WithRecorder};33use pallet_evm::{account::CrossAccountId, OnMethodCall, PrecompileHandle, PrecompileResult};34use sp_std::vec;35use up_data_structs::{36 CollectionName, CollectionDescription, CollectionTokenPrefix, CreateCollectionData,37 CollectionMode, PropertyValue, CollectionFlags,38};3940use crate::{Config, SelfWeightOf, weights::WeightInfo};4142use sp_std::vec::Vec;43use alloc::format;4445/// See [`CollectionHelpersCall`]46pub struct EvmCollectionHelpers<T: Config>(SubstrateRecorder<T>);47impl<T: Config> WithRecorder<T> for EvmCollectionHelpers<T> {48 fn recorder(&self) -> &SubstrateRecorder<T> {49 &self.050 }5152 fn into_recorder(self) -> SubstrateRecorder<T> {53 self.054 }55}5657fn convert_data<T: Config>(58 caller: caller,59 name: string,60 description: string,61 token_prefix: string,62) -> Result<(63 T::CrossAccountId,64 CollectionName,65 CollectionDescription,66 CollectionTokenPrefix,67)> {68 let caller = T::CrossAccountId::from_eth(caller);69 let name = name70 .encode_utf16()71 .collect::<Vec<u16>>()72 .try_into()73 .map_err(|_| error_field_too_long(stringify!(name), CollectionName::bound()))?;74 let description = description75 .encode_utf16()76 .collect::<Vec<u16>>()77 .try_into()78 .map_err(|_| {79 error_field_too_long(stringify!(description), CollectionDescription::bound())80 })?;81 let token_prefix = token_prefix.into_bytes().try_into().map_err(|_| {82 error_field_too_long(stringify!(token_prefix), CollectionTokenPrefix::bound())83 })?;84 Ok((caller, name, description, token_prefix))85}8687fn create_refungible_collection_internal<88 T: Config + pallet_nonfungible::Config + pallet_refungible::Config,89>(90 caller: caller,91 value: value,92 name: string,93 description: string,94 token_prefix: string,95) -> Result<address> {96 let (caller, name, description, token_prefix) =97 convert_data::<T>(caller, name, description, token_prefix)?;98 let data = CreateCollectionData {99 name,100 mode: CollectionMode::ReFungible,101 description,102 token_prefix,103 ..Default::default()104 };105 check_sent_amount_equals_collection_creation_price::<T>(value)?;106 let collection_helpers_address =107 T::CrossAccountId::from_eth(<T as pallet_common::Config>::ContractAddress::get());108109 let collection_id = T::CollectionDispatch::create(110 caller.clone(),111 collection_helpers_address,112 data,113 Default::default(),114 )115 .map_err(pallet_evm_coder_substrate::dispatch_to_evm::<T>)?;116 let address = pallet_common::eth::collection_id_to_address(collection_id);117 Ok(address)118}119120fn check_sent_amount_equals_collection_creation_price<T: Config>(value: value) -> Result<()> {121 let value = value.as_u128();122 let creation_price: u128 = T::CollectionCreationPrice::get()123 .try_into()124 .map_err(|_| ()) // workaround for `expect` requiring `Debug` trait125 .expect("Collection creation price should be convertible to u128");126 if value != creation_price {127 return Err(format!(128 "Sent amount not equals to collection creation price ({0})",129 creation_price130 )131 .into());132 }133 Ok(())134}135136/// @title Contract, which allows users to operate with collections137#[solidity_interface(name = CollectionHelpers, events(CollectionHelpersEvents))]138impl<T> EvmCollectionHelpers<T>139where140 T: Config + pallet_common::Config + pallet_nonfungible::Config + pallet_refungible::Config,141{142 /// Create an NFT collection143 /// @param name Name of the collection144 /// @param description Informative description of the collection145 /// @param tokenPrefix Token prefix to represent the collection tokens in UI and user applications146 /// @return address Address of the newly created collection147 #[weight(<SelfWeightOf<T>>::create_collection())]148 #[solidity(rename_selector = "createNFTCollection")]149 fn create_nft_collection(150 &mut self,151 caller: caller,152 value: value,153 name: string,154 description: string,155 token_prefix: string,156 ) -> Result<address> {157 let (caller, name, description, token_prefix) =158 convert_data::<T>(caller, name, description, token_prefix)?;159 let data = CreateCollectionData {160 name,161 mode: CollectionMode::NFT,162 description,163 token_prefix,164 ..Default::default()165 };166 check_sent_amount_equals_collection_creation_price::<T>(value)?;167 let collection_helpers_address =168 T::CrossAccountId::from_eth(<T as pallet_common::Config>::ContractAddress::get());169 let collection_id = T::CollectionDispatch::create(170 caller,171 collection_helpers_address,172 data,173 Default::default(),174 )175 .map_err(dispatch_to_evm::<T>)?;176177 let address = pallet_common::eth::collection_id_to_address(collection_id);178 Ok(address)179 }180 /// Create an NFT collection181 /// @param name Name of the collection182 /// @param description Informative description of the collection183 /// @param tokenPrefix Token prefix to represent the collection tokens in UI and user applications184 /// @return address Address of the newly created collection185 #[weight(<SelfWeightOf<T>>::create_collection())]186 #[deprecated(note = "mathod was renamed to `create_nft_collection`, prefer it instead")]187 #[solidity(hide)]188 fn create_nonfungible_collection(189 &mut self,190 caller: caller,191 value: value,192 name: string,193 description: string,194 token_prefix: string,195 ) -> Result<address> {196 self.create_nft_collection(caller, value, name, description, token_prefix)197 }198199 #[weight(<SelfWeightOf<T>>::create_collection())]200 #[solidity(rename_selector = "createRFTCollection")]201 fn create_rft_collection(202 &mut self,203 caller: caller,204 value: value,205 name: string,206 description: string,207 token_prefix: string,208 ) -> Result<address> {209 create_refungible_collection_internal::<T>(caller, value, name, description, token_prefix)210 }211212 #[solidity(rename_selector = "makeCollectionERC721MetadataCompatible")]213 fn make_collection_metadata_compatible(214 &mut self,215 caller: caller,216 collection: address,217 base_uri: string,218 ) -> Result<()> {219 let caller = T::CrossAccountId::from_eth(caller);220 let collection =221 pallet_common::eth::map_eth_to_id(&collection).ok_or("not a collection address")?;222 let mut collection =223 <crate::CollectionHandle<T>>::new(collection).ok_or("collection not found")?;224225 if !matches!(226 collection.mode,227 CollectionMode::NFT | CollectionMode::ReFungible228 ) {229 return Err("target collection should be either NFT or Refungible".into());230 }231232 self.recorder().consume_sstore()?;233 collection234 .check_is_owner_or_admin(&caller)235 .map_err(dispatch_to_evm::<T>)?;236237 if collection.flags.erc721metadata {238 return Err("target collection is already Erc721Metadata compatible".into());239 }240 collection.flags.erc721metadata = true;241242 let all_permissions = <pallet_common::CollectionPropertyPermissions<T>>::get(collection.id);243 if all_permissions.get(&key::url()).is_none() {244 self.recorder().consume_sstore()?;245 <PalletCommon<T>>::set_property_permission(246 &collection,247 &caller,248 up_data_structs::PropertyKeyPermission {249 key: key::url(),250 permission: up_data_structs::PropertyPermission {251 mutable: true,252 collection_admin: true,253 token_owner: false,254 },255 },256 )257 .map_err(dispatch_to_evm::<T>)?;258 }259 if all_permissions.get(&key::suffix()).is_none() {260 self.recorder().consume_sstore()?;261 <PalletCommon<T>>::set_property_permission(262 &collection,263 &caller,264 up_data_structs::PropertyKeyPermission {265 key: key::suffix(),266 permission: up_data_structs::PropertyPermission {267 mutable: true,268 collection_admin: true,269 token_owner: false,270 },271 },272 )273 .map_err(dispatch_to_evm::<T>)?;274 }275276 let all_properties = <pallet_common::CollectionProperties<T>>::get(collection.id);277 if all_properties.get(&key::base_uri()).is_none() && !base_uri.is_empty() {278 self.recorder().consume_sstore()?;279 <PalletCommon<T>>::set_collection_properties(280 &collection,281 &caller,282 vec![up_data_structs::Property {283 key: key::base_uri(),284 value: base_uri285 .into_bytes()286 .try_into()287 .map_err(|_| "base uri is too large")?,288 }],289 )290 .map_err(dispatch_to_evm::<T>)?;291 }292293 self.recorder().consume_sstore()?;294 collection.save().map_err(dispatch_to_evm::<T>)?;295296 Ok(())297 }298299 /// Check if a collection exists300 /// @param collectionAddress Address of the collection in question301 /// @return bool Does the collection exist?302 fn is_collection_exist(&self, _caller: caller, collection_address: address) -> Result<bool> {303 if let Some(id) = pallet_common::eth::map_eth_to_id(&collection_address) {304 let collection_id = id;305 return Ok(<CollectionById<T>>::contains_key(collection_id));306 }307308 Ok(false)309 }310311 fn collection_creation_fee(&self) -> Result<value> {312 let price: u128 = T::CollectionCreationPrice::get()313 .try_into()314 .map_err(|_| ()) // workaround for `expect` requiring `Debug` trait315 .expect("Collection creation price should be convertible to u128");316 Ok(price.into())317 }318}319320/// Implements [`OnMethodCall`], which delegates call to [`EvmCollectionHelpers`]321pub struct CollectionHelpersOnMethodCall<T: Config>(PhantomData<*const T>);322impl<T: Config + pallet_nonfungible::Config + pallet_refungible::Config> OnMethodCall<T>323 for CollectionHelpersOnMethodCall<T>324{325 fn is_reserved(contract: &sp_core::H160) -> bool {326 contract == &T::ContractAddress::get()327 }328329 fn is_used(contract: &sp_core::H160) -> bool {330 contract == &T::ContractAddress::get()331 }332333 fn call(handle: &mut impl PrecompileHandle) -> Option<PrecompileResult> {334 if handle.code_address() != T::ContractAddress::get() {335 return None;336 }337338 let helpers =339 EvmCollectionHelpers::<T>(SubstrateRecorder::<T>::new(handle.remaining_gas()));340 pallet_evm_coder_substrate::call(handle, helpers)341 }342343 fn get_code(contract: &sp_core::H160) -> Option<Vec<u8>> {344 (contract == &T::ContractAddress::get())345 .then(|| include_bytes!("./stubs/CollectionHelpers.raw").to_vec())346 }347}348349generate_stubgen!(collection_helper_impl, CollectionHelpersCall<()>, true);350generate_stubgen!(collection_helper_iface, CollectionHelpersCall<()>, false);351352fn error_field_too_long(feild: &str, bound: usize) -> Error {353 Error::Revert(format!("{} is too long. Max length is {}.", feild, bound))354}pallets/unique/src/eth/stubs/CollectionHelpers.rawdiffbeforeafterbothbinary blob — no preview
pallets/unique/src/eth/stubs/CollectionHelpers.soldiffbeforeafterboth--- a/pallets/unique/src/eth/stubs/CollectionHelpers.sol
+++ b/pallets/unique/src/eth/stubs/CollectionHelpers.sol
@@ -45,25 +45,21 @@
return 0x0000000000000000000000000000000000000000;
}
- /// Create an NFT collection
- /// @param name Name of the collection
- /// @param description Informative description of the collection
- /// @param tokenPrefix Token prefix to represent the collection tokens in UI and user applications
- /// @return address Address of the newly created collection
- /// @dev EVM selector for this function is: 0xe34a6844,
- /// or in textual repr: createNonfungibleCollection(string,string,string)
- function createNonfungibleCollection(
- string memory name,
- string memory description,
- string memory tokenPrefix
- ) public payable returns (address) {
- require(false, stub_error);
- name;
- description;
- tokenPrefix;
- dummy = 0;
- return 0x0000000000000000000000000000000000000000;
- }
+ // /// Create an NFT collection
+ // /// @param name Name of the collection
+ // /// @param description Informative description of the collection
+ // /// @param tokenPrefix Token prefix to represent the collection tokens in UI and user applications
+ // /// @return address Address of the newly created collection
+ // /// @dev EVM selector for this function is: 0xe34a6844,
+ // /// or in textual repr: createNonfungibleCollection(string,string,string)
+ // function createNonfungibleCollection(string memory name, string memory description, string memory tokenPrefix) public payable returns (address) {
+ // require(false, stub_error);
+ // name;
+ // description;
+ // tokenPrefix;
+ // dummy = 0;
+ // return 0x0000000000000000000000000000000000000000;
+ // }
/// @dev EVM selector for this function is: 0xab173450,
/// or in textual repr: createRFTCollection(string,string,string)
tests/src/eth/api/CollectionHelpers.soldiffbeforeafterboth--- a/tests/src/eth/api/CollectionHelpers.sol
+++ b/tests/src/eth/api/CollectionHelpers.sol
@@ -33,18 +33,14 @@
string memory tokenPrefix
) external payable returns (address);
- /// Create an NFT collection
- /// @param name Name of the collection
- /// @param description Informative description of the collection
- /// @param tokenPrefix Token prefix to represent the collection tokens in UI and user applications
- /// @return address Address of the newly created collection
- /// @dev EVM selector for this function is: 0xe34a6844,
- /// or in textual repr: createNonfungibleCollection(string,string,string)
- function createNonfungibleCollection(
- string memory name,
- string memory description,
- string memory tokenPrefix
- ) external payable returns (address);
+ // /// Create an NFT collection
+ // /// @param name Name of the collection
+ // /// @param description Informative description of the collection
+ // /// @param tokenPrefix Token prefix to represent the collection tokens in UI and user applications
+ // /// @return address Address of the newly created collection
+ // /// @dev EVM selector for this function is: 0xe34a6844,
+ // /// or in textual repr: createNonfungibleCollection(string,string,string)
+ // function createNonfungibleCollection(string memory name, string memory description, string memory tokenPrefix) external payable returns (address);
/// @dev EVM selector for this function is: 0xab173450,
/// or in textual repr: createRFTCollection(string,string,string)
tests/src/eth/api/UniqueFungible.soldiffbeforeafterboth--- a/tests/src/eth/api/UniqueFungible.sol
+++ b/tests/src/eth/api/UniqueFungible.sol
@@ -13,7 +13,7 @@
}
/// @title A contract that allows you to work with collections.
-/// @dev the ERC-165 identifier for this interface is 0x3e1e8083
+/// @dev the ERC-165 identifier for this interface is 0x62e22290
interface Collection is Dummy, ERC165 {
/// Set collection property.
///
@@ -194,9 +194,9 @@
///
/// @dev Owner can be changed only by current owner
/// @param newOwner new owner account
- /// @dev EVM selector for this function is: 0x13af4035,
- /// or in textual repr: setOwner(address)
- function setOwner(address newOwner) external;
+ /// @dev EVM selector for this function is: 0x4f53e226,
+ /// or in textual repr: changeCollectionOwner(address)
+ function changeCollectionOwner(address newOwner) external;
}
/// @dev the ERC-165 identifier for this interface is 0x63034ac5
tests/src/eth/api/UniqueNFT.soldiffbeforeafterboth--- a/tests/src/eth/api/UniqueNFT.sol
+++ b/tests/src/eth/api/UniqueNFT.sol
@@ -62,7 +62,7 @@
}
/// @title A contract that allows you to work with collections.
-/// @dev the ERC-165 identifier for this interface is 0x3e1e8083
+/// @dev the ERC-165 identifier for this interface is 0x62e22290
interface Collection is Dummy, ERC165 {
/// Set collection property.
///
@@ -243,9 +243,9 @@
///
/// @dev Owner can be changed only by current owner
/// @param newOwner new owner account
- /// @dev EVM selector for this function is: 0x13af4035,
- /// or in textual repr: setOwner(address)
- function setOwner(address newOwner) external;
+ /// @dev EVM selector for this function is: 0x4f53e226,
+ /// or in textual repr: changeCollectionOwner(address)
+ function changeCollectionOwner(address newOwner) external;
}
/// @dev anonymous struct
tests/src/eth/api/UniqueRefungible.soldiffbeforeafterboth--- a/tests/src/eth/api/UniqueRefungible.sol
+++ b/tests/src/eth/api/UniqueRefungible.sol
@@ -62,7 +62,7 @@
}
/// @title A contract that allows you to work with collections.
-/// @dev the ERC-165 identifier for this interface is 0x3e1e8083
+/// @dev the ERC-165 identifier for this interface is 0x62e22290
interface Collection is Dummy, ERC165 {
/// Set collection property.
///
@@ -243,9 +243,9 @@
///
/// @dev Owner can be changed only by current owner
/// @param newOwner new owner account
- /// @dev EVM selector for this function is: 0x13af4035,
- /// or in textual repr: setOwner(address)
- function setOwner(address newOwner) external;
+ /// @dev EVM selector for this function is: 0x4f53e226,
+ /// or in textual repr: changeCollectionOwner(address)
+ function changeCollectionOwner(address newOwner) external;
}
/// @dev anonymous struct
tests/src/eth/collectionAdmin.test.tsdiffbeforeafterboth--- a/tests/src/eth/collectionAdmin.test.ts
+++ b/tests/src/eth/collectionAdmin.test.ts
@@ -282,7 +282,7 @@
const {collectionAddress} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');
const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
- await collectionEvm.methods.setOwner(newOwner).send();
+ await collectionEvm.methods.changeCollectionOwner(newOwner).send();
expect(await collectionEvm.methods.isOwnerOrAdmin(owner).call()).to.be.false;
expect(await collectionEvm.methods.isOwnerOrAdmin(newOwner).call()).to.be.true;
@@ -293,7 +293,7 @@
const newOwner = await helper.eth.createAccountWithBalance(donor);
const {collectionAddress} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');
const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
- const cost = await recordEthFee(helper, owner, () => collectionEvm.methods.setOwner(newOwner).send());
+ const cost = await recordEthFee(helper, owner, () => collectionEvm.methods.changeCollectionOwner(newOwner).send());
expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));
expect(cost > 0);
});
@@ -304,7 +304,7 @@
const {collectionAddress} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');
const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
- await expect(collectionEvm.methods.setOwner(newOwner).send({from: newOwner})).to.be.rejected;
+ await expect(collectionEvm.methods.changeCollectionOwner(newOwner).send({from: newOwner})).to.be.rejected;
expect(await collectionEvm.methods.isOwnerOrAdmin(newOwner).call()).to.be.false;
});
});
tests/src/eth/collectionHelpersAbi.jsondiffbeforeafterboth--- a/tests/src/eth/collectionHelpersAbi.json
+++ b/tests/src/eth/collectionHelpersAbi.json
@@ -42,17 +42,6 @@
{ "internalType": "string", "name": "description", "type": "string" },
{ "internalType": "string", "name": "tokenPrefix", "type": "string" }
],
- "name": "createNonfungibleCollection",
- "outputs": [{ "internalType": "address", "name": "", "type": "address" }],
- "stateMutability": "payable",
- "type": "function"
- },
- {
- "inputs": [
- { "internalType": "string", "name": "name", "type": "string" },
- { "internalType": "string", "name": "description", "type": "string" },
- { "internalType": "string", "name": "tokenPrefix", "type": "string" }
- ],
"name": "createRFTCollection",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "payable",
tests/src/eth/fungibleAbi.jsondiffbeforeafterboth--- a/tests/src/eth/fungibleAbi.json
+++ b/tests/src/eth/fungibleAbi.json
@@ -116,6 +116,15 @@
"type": "function"
},
{
+ "inputs": [
+ { "internalType": "address", "name": "newOwner", "type": "address" }
+ ],
+ "name": "changeCollectionOwner",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
"inputs": [],
"name": "collectionOwner",
"outputs": [
@@ -329,15 +338,6 @@
{ "internalType": "address", "name": "sponsor", "type": "address" }
],
"name": "setCollectionSponsor",
- "outputs": [],
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "inputs": [
- { "internalType": "address", "name": "newOwner", "type": "address" }
- ],
- "name": "setOwner",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
tests/src/eth/nonFungibleAbi.jsondiffbeforeafterboth--- a/tests/src/eth/nonFungibleAbi.json
+++ b/tests/src/eth/nonFungibleAbi.json
@@ -146,6 +146,15 @@
"type": "function"
},
{
+ "inputs": [
+ { "internalType": "address", "name": "newOwner", "type": "address" }
+ ],
+ "name": "changeCollectionOwner",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
"inputs": [],
"name": "collectionOwner",
"outputs": [
@@ -472,15 +481,6 @@
{ "internalType": "address", "name": "sponsor", "type": "address" }
],
"name": "setCollectionSponsor",
- "outputs": [],
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "inputs": [
- { "internalType": "address", "name": "newOwner", "type": "address" }
- ],
- "name": "setOwner",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
tests/src/eth/reFungibleAbi.jsondiffbeforeafterboth--- a/tests/src/eth/reFungibleAbi.json
+++ b/tests/src/eth/reFungibleAbi.json
@@ -146,6 +146,15 @@
"type": "function"
},
{
+ "inputs": [
+ { "internalType": "address", "name": "newOwner", "type": "address" }
+ ],
+ "name": "changeCollectionOwner",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
"inputs": [],
"name": "collectionOwner",
"outputs": [
@@ -472,15 +481,6 @@
{ "internalType": "address", "name": "sponsor", "type": "address" }
],
"name": "setCollectionSponsor",
- "outputs": [],
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "inputs": [
- { "internalType": "address", "name": "newOwner", "type": "address" }
- ],
- "name": "setOwner",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"