git.delta.rocks / unique-network / refs/commits / 6994f61a23f1

difftreelog

Merge pull request #822 from UniqueNetwork/feature/AbiCoder_option

Yaroslav Bolyukin2023-01-12parents: #32d4fdc #fd1e50b.patch.diff
in: master
Feature/AbiCoder_option

26 files changed

modifiedCargo.lockdiffbeforeafterboth
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2321,7 +2321,7 @@
 
 [[package]]
 name = "evm-coder"
-version = "0.1.5"
+version = "0.1.6"
 dependencies = [
  "ethereum 0.14.0",
  "evm-coder-procedural",
modifiedcrates/evm-coder/CHANGELOG.mddiffbeforeafterboth
--- a/crates/evm-coder/CHANGELOG.md
+++ b/crates/evm-coder/CHANGELOG.md
@@ -3,6 +3,13 @@
 All notable changes to this project will be documented in this file.
 
 <!-- bureaucrate goes here -->
+## [v0.1.6] - 2023-01-12
+
+### Added
+- Support Option<T> type.
+### Removed
+- Frontier dependency.
+
 ## [v0.1.5] - 2022-11-30
 
 ### Added
modifiedcrates/evm-coder/Cargo.tomldiffbeforeafterboth
--- a/crates/evm-coder/Cargo.toml
+++ b/crates/evm-coder/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "evm-coder"
-version = "0.1.5"
+version = "0.1.6"
 license = "GPLv3"
 edition = "2021"
 
modifiedcrates/evm-coder/src/abi/impls.rsdiffbeforeafterboth
--- a/crates/evm-coder/src/abi/impls.rs
+++ b/crates/evm-coder/src/abi/impls.rs
@@ -258,3 +258,39 @@
 impl_tuples! {A B C D E F G H}
 impl_tuples! {A B C D E F G H I}
 impl_tuples! {A B C D E F G H I J}
+
+//----- impls for Option -----
+impl<T: AbiType> AbiType for Option<T> {
+	const SIGNATURE: SignatureUnit = <(bool, T)>::SIGNATURE;
+
+	fn is_dynamic() -> bool {
+		<(bool, T)>::is_dynamic()
+	}
+
+	fn size() -> usize {
+		<(bool, T)>::size()
+	}
+}
+
+impl<T: AbiWrite + AbiType + Default> AbiWrite for Option<T> {
+	fn abi_write(&self, writer: &mut AbiWriter) {
+		match self {
+			Some(value) => (true, value).abi_write(writer),
+			None => (false, T::default()).abi_write(writer),
+		}
+	}
+}
+
+impl<T> AbiRead for Option<T>
+where
+	Self: AbiType,
+	T: AbiRead + AbiType,
+{
+	fn abi_read(reader: &mut AbiReader) -> Result<Self>
+	where
+		Self: Sized,
+	{
+		let (status, value) = <(bool, T)>::abi_read(reader)?;
+		Ok(if status { Some(value) } else { None })
+	}
+}
modifiedcrates/evm-coder/src/abi/test.rsdiffbeforeafterboth
--- a/crates/evm-coder/src/abi/test.rs
+++ b/crates/evm-coder/src/abi/test.rs
@@ -538,3 +538,68 @@
 	assert_eq!(p1, 0x0a);
 	assert_eq!(p2, 0x0b);
 }
+
+#[test]
+fn encode_decode_option_uint8_some() {
+	test_impl::<Option<u8>>(
+		0xdeadbeef,
+		Some(44),
+		&hex!(
+			"
+                deadbeef
+                0000000000000000000000000000000000000000000000000000000000000001
+                000000000000000000000000000000000000000000000000000000000000002c
+            "
+		),
+	);
+}
+
+#[test]
+fn encode_decode_option_uint8_none() {
+	test_impl::<Option<u8>>(
+		0xdeadbeef,
+		None,
+		&hex!(
+			"
+                deadbeef
+                0000000000000000000000000000000000000000000000000000000000000000
+                0000000000000000000000000000000000000000000000000000000000000000
+            "
+		),
+	);
+}
+
+#[test]
+fn encode_decode_option_string_some() {
+	test_impl::<Option<String>>(
+		0xdeadbeef,
+		Some("some string".to_string()),
+		&hex!(
+			"
+                deadbeef
+                0000000000000000000000000000000000000000000000000000000000000020
+                0000000000000000000000000000000000000000000000000000000000000001
+                0000000000000000000000000000000000000000000000000000000000000040
+                000000000000000000000000000000000000000000000000000000000000000b
+                736f6d6520737472696e67000000000000000000000000000000000000000000
+            "
+		),
+	);
+}
+
+#[test]
+fn encode_decode_option_string_none() {
+	test_impl::<Option<String>>(
+		0xdeadbeef,
+		None,
+		&hex!(
+			"
+                deadbeef
+                0000000000000000000000000000000000000000000000000000000000000020
+                0000000000000000000000000000000000000000000000000000000000000000
+                0000000000000000000000000000000000000000000000000000000000000040
+                0000000000000000000000000000000000000000000000000000000000000000
+            "
+		),
+	);
+}
modifiedcrates/evm-coder/src/solidity/impls.rsdiffbeforeafterboth
--- a/crates/evm-coder/src/solidity/impls.rs
+++ b/crates/evm-coder/src/solidity/impls.rs
@@ -121,3 +121,59 @@
 impl_tuples! {A B C D E F G H}
 impl_tuples! {A B C D E F G H I}
 impl_tuples! {A B C D E F G H I J}
+
+//----- impls for Option -----
+impl<T: SolidityTypeName + 'static> SolidityTypeName for Option<T> {
+	fn solidity_name(writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {
+		write!(writer, "{}", tc.collect_struct::<Self>())
+	}
+	fn is_simple() -> bool {
+		false
+	}
+	fn solidity_default(writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {
+		write!(writer, "{}(", tc.collect_struct::<Self>())?;
+		bool::solidity_default(writer, tc)?;
+		write!(writer, ", ");
+		T::solidity_default(writer, tc)?;
+		write!(writer, ")")
+	}
+}
+
+impl<T: SolidityTypeName> super::SolidityStructTy for Option<T> {
+	fn generate_solidity_interface(tc: &TypeCollector) -> String {
+		let mut solidity_name = "Option".to_string();
+		let mut generic_name = String::new();
+		T::solidity_name(&mut generic_name, tc);
+		solidity_name.push(
+			generic_name
+				.chars()
+				.next()
+				.expect("Generic name is empty")
+				.to_ascii_uppercase(),
+		);
+		solidity_name.push_str(&generic_name[1..]);
+
+		let interface = super::SolidityStruct {
+			docs: &[" Optional value"],
+			name: solidity_name.as_str(),
+			fields: (
+				super::SolidityStructField::<bool> {
+					docs: &[" Shows the status of accessibility of value"],
+					name: "status",
+					ty: ::core::marker::PhantomData,
+				},
+				super::SolidityStructField::<T> {
+					docs: &[" Actual value if `status` is true"],
+					name: "value",
+					ty: ::core::marker::PhantomData,
+				},
+			),
+		};
+
+		let mut out = String::new();
+		let _ = interface.format(&mut out, tc);
+		tc.collect(out);
+
+		solidity_name.to_string()
+	}
+}
modifiedcrates/evm-coder/src/solidity/mod.rsdiffbeforeafterboth
--- a/crates/evm-coder/src/solidity/mod.rs
+++ b/crates/evm-coder/src/solidity/mod.rs
@@ -456,13 +456,13 @@
 		Ok(())
 	}
 }
-pub struct SolidityStruct<F> {
-	pub docs: &'static [&'static str],
+pub struct SolidityStruct<'a, F> {
+	pub docs: &'a [&'a str],
 	// pub generics:
-	pub name: &'static str,
+	pub name: &'a str,
 	pub fields: F,
 }
-impl<F> SolidityStruct<F>
+impl<F> SolidityStruct<'_, F>
 where
 	F: SolidityItems,
 {
modifiedpallets/common/src/erc.rsdiffbeforeafterboth
--- a/pallets/common/src/erc.rs
+++ b/pallets/common/src/erc.rs
@@ -284,6 +284,11 @@
 	fn collection_limits(&self) -> Result<Vec<eth::CollectionLimit>> {
 		let limits = &self.collection.limits;
 
+		let convert_value_from_bool = |ob: Option<bool>| match ob {
+			Some(b) => Some(b as u32),
+			None => None,
+		};
+
 		Ok(vec![
 			eth::CollectionLimit::new(
 				eth::CollectionLimitField::AccountTokenOwnership,
@@ -297,15 +302,15 @@
 				.sponsored_data_rate_limit
 				.and_then(|limit| {
 					if let SponsoringRateLimit::Blocks(blocks) = limit {
-						Some(eth::CollectionLimit::new::<u32>(
+						Some(eth::CollectionLimit::new(
 							eth::CollectionLimitField::SponsoredDataRateLimit,
-							blocks,
+							Some(blocks),
 						))
 					} else {
 						None
 					}
 				})
-				.unwrap_or(eth::CollectionLimit::new::<u32>(
+				.unwrap_or(eth::CollectionLimit::new(
 					eth::CollectionLimitField::SponsoredDataRateLimit,
 					Default::default(),
 				)),
@@ -320,15 +325,15 @@
 			),
 			eth::CollectionLimit::new(
 				eth::CollectionLimitField::OwnerCanTransfer,
-				limits.owner_can_transfer,
+				convert_value_from_bool(limits.owner_can_transfer),
 			),
 			eth::CollectionLimit::new(
 				eth::CollectionLimitField::OwnerCanDestroy,
-				limits.owner_can_destroy,
+				convert_value_from_bool(limits.owner_can_destroy),
 			),
 			eth::CollectionLimit::new(
 				eth::CollectionLimitField::TransferEnabled,
-				limits.transfers_enabled,
+				convert_value_from_bool(limits.transfers_enabled),
 			),
 		])
 	}
modifiedpallets/common/src/eth.rsdiffbeforeafterboth
--- a/pallets/common/src/eth.rs
+++ b/pallets/common/src/eth.rs
@@ -66,71 +66,6 @@
 	T::CrossAccountId::from_sub(account_id)
 }
 
-/// Ethereum representation of Optional value with uint256.
-#[derive(Debug, Default, AbiCoder)]
-pub struct OptionUint {
-	status: bool,
-	value: uint256,
-}
-
-impl From<u32> for OptionUint {
-	fn from(value: u32) -> Self {
-		Self {
-			status: true,
-			value: uint256::from(value),
-		}
-	}
-}
-
-impl From<Option<u32>> for OptionUint {
-	fn from(value: Option<u32>) -> Self {
-		match value {
-			Some(value) => Self {
-				status: true,
-				value: value.into(),
-			},
-			None => Self {
-				status: false,
-				value: Default::default(),
-			},
-		}
-	}
-}
-
-impl From<bool> for OptionUint {
-	fn from(value: bool) -> Self {
-		Self {
-			status: true,
-			value: if value {
-				uint256::from(1)
-			} else {
-				Default::default()
-			},
-		}
-	}
-}
-
-impl From<Option<bool>> for OptionUint {
-	fn from(value: Option<bool>) -> Self {
-		match value {
-			Some(value) => Self::from(value),
-			None => Self {
-				status: false,
-				value: Default::default(),
-			},
-		}
-	}
-}
-
-/// Ethereum representation of Optional value with CrossAddress.
-#[derive(Debug, Default, AbiCoder)]
-pub struct OptionCrossAddress {
-	/// Whether or not this CrossAdress is valid and has meaning.
-	pub status: bool,
-	/// The underlying CrossAddress value. If the status is false, can be set to whatever.
-	pub value: CrossAddress,
-}
-
 /// Cross account struct
 #[derive(Debug, Default, AbiCoder)]
 pub struct CrossAddress {
@@ -252,23 +187,23 @@
 #[derive(Debug, Default, AbiCoder)]
 pub struct CollectionLimit {
 	field: CollectionLimitField,
-	value: OptionUint,
+	value: Option<uint256>,
 }
 
 impl CollectionLimit {
 	/// Create [`CollectionLimit`] from field and value.
-	pub fn new<T>(field: CollectionLimitField, value: T) -> Self
-	where
-		OptionUint: From<T>,
-	{
+	pub fn new(field: CollectionLimitField, value: Option<u32>) -> Self {
 		Self {
 			field,
-			value: value.into(),
+			value: match value {
+				Some(value) => Some(value.into()),
+				None => None,
+			},
 		}
 	}
 	/// Whether the field contains a value.
 	pub fn has_value(&self) -> bool {
-		self.value.status
+		self.value.is_some()
 	}
 }
 
@@ -276,52 +211,60 @@
 	type Error = evm_coder::execution::Error;
 
 	fn try_into(self) -> Result<up_data_structs::CollectionLimits, Self::Error> {
-		let value = self.value.value.try_into().map_err(|error| {
+		let value = self
+			.value
+			.ok_or::<Self::Error>("can't convert `None` value to boolean".into())?;
+		let value = Some(value.try_into().map_err(|error| {
 			Self::Error::Revert(format!(
 				"can't convert value to u32 \"{}\" because: \"{error}\"",
-				self.value.value
+				value
 			))
-		})?;
+		})?);
 
 		let convert_value_to_bool = || match value {
-			0 => Ok(false),
-			1 => Ok(true),
-			_ => {
-				return Err(Self::Error::Revert(format!(
-					"can't convert value to boolean \"{value}\""
-				)))
-			}
+			Some(value) => match value {
+				0 => Ok(Some(false)),
+				1 => Ok(Some(true)),
+				_ => {
+					return Err(Self::Error::Revert(format!(
+						"can't convert value to boolean \"{value}\""
+					)))
+				}
+			},
+			None => Ok(None),
 		};
 
 		let mut limits = up_data_structs::CollectionLimits::default();
 		match self.field {
 			CollectionLimitField::AccountTokenOwnership => {
-				limits.account_token_ownership_limit = Some(value);
+				limits.account_token_ownership_limit = value;
 			}
 			CollectionLimitField::SponsoredDataSize => {
-				limits.sponsored_data_size = Some(value);
+				limits.sponsored_data_size = value;
 			}
 			CollectionLimitField::SponsoredDataRateLimit => {
-				limits.sponsored_data_rate_limit =
-					Some(up_data_structs::SponsoringRateLimit::Blocks(value));
+				limits.sponsored_data_rate_limit = match value {
+					Some(value) => Some(up_data_structs::SponsoringRateLimit::Blocks(value)),
+					None => None,
+				};
 			}
 			CollectionLimitField::TokenLimit => {
-				limits.token_limit = Some(value);
+				limits.token_limit = value;
 			}
 			CollectionLimitField::SponsorTransferTimeout => {
-				limits.sponsor_transfer_timeout = Some(value);
+				limits.sponsor_transfer_timeout = value;
 			}
 			CollectionLimitField::SponsorApproveTimeout => {
-				limits.sponsor_approve_timeout = Some(value);
+				limits.sponsor_approve_timeout = value;
 			}
 			CollectionLimitField::OwnerCanTransfer => {
-				limits.owner_can_transfer = Some(convert_value_to_bool()?);
+				limits.owner_can_transfer = convert_value_to_bool()?;
 			}
 			CollectionLimitField::OwnerCanDestroy => {
-				limits.owner_can_destroy = Some(convert_value_to_bool()?);
+				limits.owner_can_destroy = convert_value_to_bool()?;
 			}
 			CollectionLimitField::TransferEnabled => {
-				limits.transfers_enabled = Some(convert_value_to_bool()?);
+				limits.transfers_enabled = convert_value_to_bool()?;
 			}
 		};
 		Ok(limits)
modifiedpallets/evm-contract-helpers/src/eth.rsdiffbeforeafterboth
--- a/pallets/evm-contract-helpers/src/eth.rs
+++ b/pallets/evm-contract-helpers/src/eth.rs
@@ -175,16 +175,10 @@
 	///
 	/// @param contractAddress The contract for which a sponsor is requested.
 	/// @return Tuble with sponsor address and his substrate mirror. If there is no confirmed sponsor error "Contract has no sponsor" throw.
-	fn sponsor(&self, contract_address: address) -> Result<eth::OptionCrossAddress> {
+	fn sponsor(&self, contract_address: address) -> Result<Option<eth::CrossAddress>> {
 		Ok(match Pallet::<T>::get_sponsor(contract_address) {
-			Some(ref value) => eth::OptionCrossAddress {
-				status: true,
-				value: eth::CrossAddress::from_sub_cross_account::<T>(value),
-			},
-			None => eth::OptionCrossAddress {
-				status: false,
-				value: Default::default(),
-			},
+			Some(ref value) => Some(eth::CrossAddress::from_sub_cross_account::<T>(value)),
+			None => None,
 		})
 	}
 
modifiedpallets/evm-contract-helpers/src/stubs/ContractHelpers.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/evm-contract-helpers/src/stubs/ContractHelpers.soldiffbeforeafterboth
--- a/pallets/evm-contract-helpers/src/stubs/ContractHelpers.sol
+++ b/pallets/evm-contract-helpers/src/stubs/ContractHelpers.sol
@@ -281,10 +281,10 @@
 	uint256 sub;
 }
 
-/// Ethereum representation of Optional value with CrossAddress.
+/// Optional value
 struct OptionCrossAddress {
-	/// Whether or not this CrossAdress is valid and has meaning.
+	/// Shows the status of accessibility of value
 	bool status;
-	/// The underlying CrossAddress value. If the status is false, can be set to whatever.
+	/// Actual value if `status` is true
 	CrossAddress value;
 }
modifiedpallets/fungible/src/stubs/UniqueFungible.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/fungible/src/stubs/UniqueFungible.soldiffbeforeafterboth
--- a/pallets/fungible/src/stubs/UniqueFungible.sol
+++ b/pallets/fungible/src/stubs/UniqueFungible.sol
@@ -466,12 +466,14 @@
 /// [`CollectionLimits`](up_data_structs::CollectionLimits) field representation for EVM.
 struct CollectionLimit {
 	CollectionLimitField field;
-	OptionUint value;
+	OptionUint256 value;
 }
 
-/// Ethereum representation of Optional value with uint256.
-struct OptionUint {
+/// Optional value
+struct OptionUint256 {
+	/// Shows the status of accessibility of value
 	bool status;
+	/// Actual value if `status` is true
 	uint256 value;
 }
 
modifiedpallets/nonfungible/src/stubs/UniqueNFT.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/nonfungible/src/stubs/UniqueNFT.soldiffbeforeafterboth
--- a/pallets/nonfungible/src/stubs/UniqueNFT.sol
+++ b/pallets/nonfungible/src/stubs/UniqueNFT.sol
@@ -608,12 +608,14 @@
 /// [`CollectionLimits`](up_data_structs::CollectionLimits) field representation for EVM.
 struct CollectionLimit {
 	CollectionLimitField field;
-	OptionUint value;
+	OptionUint256 value;
 }
 
-/// Ethereum representation of Optional value with uint256.
-struct OptionUint {
+/// Optional value
+struct OptionUint256 {
+	/// Shows the status of accessibility of value
 	bool status;
+	/// Actual value if `status` is true
 	uint256 value;
 }
 
modifiedpallets/refungible/src/stubs/UniqueRefungible.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/refungible/src/stubs/UniqueRefungible.soldiffbeforeafterboth
--- a/pallets/refungible/src/stubs/UniqueRefungible.sol
+++ b/pallets/refungible/src/stubs/UniqueRefungible.sol
@@ -608,12 +608,14 @@
 /// [`CollectionLimits`](up_data_structs::CollectionLimits) field representation for EVM.
 struct CollectionLimit {
 	CollectionLimitField field;
-	OptionUint value;
+	OptionUint256 value;
 }
 
-/// Ethereum representation of Optional value with uint256.
-struct OptionUint {
+/// Optional value
+struct OptionUint256 {
+	/// Shows the status of accessibility of value
 	bool status;
+	/// Actual value if `status` is true
 	uint256 value;
 }
 
modifiedruntime/common/identity.rsdiffbeforeafterboth
--- a/runtime/common/identity.rs
+++ b/runtime/common/identity.rs
@@ -24,9 +24,6 @@
 	transaction_validity::{TransactionValidity, ValidTransaction, TransactionValidityError},
 };
 
-#[cfg(feature = "collator-selection")]
-use sp_runtime::transaction_validity::InvalidTransaction;
-
 #[derive(Debug, Encode, Decode, PartialEq, Eq, Clone, TypeInfo)]
 pub struct DisableIdentityCalls;
 
modifiedtests/src/eth/abi/fungible.jsondiffbeforeafterboth
--- a/tests/src/eth/abi/fungible.json
+++ b/tests/src/eth/abi/fungible.json
@@ -222,7 +222,7 @@
               { "internalType": "bool", "name": "status", "type": "bool" },
               { "internalType": "uint256", "name": "value", "type": "uint256" }
             ],
-            "internalType": "struct OptionUint",
+            "internalType": "struct OptionUint256",
             "name": "value",
             "type": "tuple"
           }
@@ -508,7 +508,7 @@
               { "internalType": "bool", "name": "status", "type": "bool" },
               { "internalType": "uint256", "name": "value", "type": "uint256" }
             ],
-            "internalType": "struct OptionUint",
+            "internalType": "struct OptionUint256",
             "name": "value",
             "type": "tuple"
           }
modifiedtests/src/eth/abi/nonFungible.jsondiffbeforeafterboth
--- a/tests/src/eth/abi/nonFungible.json
+++ b/tests/src/eth/abi/nonFungible.json
@@ -252,7 +252,7 @@
               { "internalType": "bool", "name": "status", "type": "bool" },
               { "internalType": "uint256", "name": "value", "type": "uint256" }
             ],
-            "internalType": "struct OptionUint",
+            "internalType": "struct OptionUint256",
             "name": "value",
             "type": "tuple"
           }
@@ -670,7 +670,7 @@
               { "internalType": "bool", "name": "status", "type": "bool" },
               { "internalType": "uint256", "name": "value", "type": "uint256" }
             ],
-            "internalType": "struct OptionUint",
+            "internalType": "struct OptionUint256",
             "name": "value",
             "type": "tuple"
           }
modifiedtests/src/eth/abi/reFungible.jsondiffbeforeafterboth
before · tests/src/eth/abi/reFungible.json
1[2  {3    "anonymous": false,4    "inputs": [5      {6        "indexed": true,7        "internalType": "address",8        "name": "owner",9        "type": "address"10      },11      {12        "indexed": true,13        "internalType": "address",14        "name": "approved",15        "type": "address"16      },17      {18        "indexed": true,19        "internalType": "uint256",20        "name": "tokenId",21        "type": "uint256"22      }23    ],24    "name": "Approval",25    "type": "event"26  },27  {28    "anonymous": false,29    "inputs": [30      {31        "indexed": true,32        "internalType": "address",33        "name": "owner",34        "type": "address"35      },36      {37        "indexed": true,38        "internalType": "address",39        "name": "operator",40        "type": "address"41      },42      {43        "indexed": false,44        "internalType": "bool",45        "name": "approved",46        "type": "bool"47      }48    ],49    "name": "ApprovalForAll",50    "type": "event"51  },52  {53    "anonymous": false,54    "inputs": [],55    "name": "MintingFinished",56    "type": "event"57  },58  {59    "anonymous": false,60    "inputs": [61      {62        "indexed": true,63        "internalType": "address",64        "name": "from",65        "type": "address"66      },67      {68        "indexed": true,69        "internalType": "address",70        "name": "to",71        "type": "address"72      },73      {74        "indexed": true,75        "internalType": "uint256",76        "name": "tokenId",77        "type": "uint256"78      }79    ],80    "name": "Transfer",81    "type": "event"82  },83  {84    "inputs": [85      {86        "components": [87          { "internalType": "address", "name": "eth", "type": "address" },88          { "internalType": "uint256", "name": "sub", "type": "uint256" }89        ],90        "internalType": "struct CrossAddress",91        "name": "newAdmin",92        "type": "tuple"93      }94    ],95    "name": "addCollectionAdminCross",96    "outputs": [],97    "stateMutability": "nonpayable",98    "type": "function"99  },100  {101    "inputs": [102      {103        "components": [104          { "internalType": "address", "name": "eth", "type": "address" },105          { "internalType": "uint256", "name": "sub", "type": "uint256" }106        ],107        "internalType": "struct CrossAddress",108        "name": "user",109        "type": "tuple"110      }111    ],112    "name": "addToCollectionAllowListCross",113    "outputs": [],114    "stateMutability": "nonpayable",115    "type": "function"116  },117  {118    "inputs": [119      {120        "components": [121          { "internalType": "address", "name": "eth", "type": "address" },122          { "internalType": "uint256", "name": "sub", "type": "uint256" }123        ],124        "internalType": "struct CrossAddress",125        "name": "user",126        "type": "tuple"127      }128    ],129    "name": "allowlistedCross",130    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],131    "stateMutability": "view",132    "type": "function"133  },134  {135    "inputs": [136      { "internalType": "address", "name": "approved", "type": "address" },137      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }138    ],139    "name": "approve",140    "outputs": [],141    "stateMutability": "nonpayable",142    "type": "function"143  },144  {145    "inputs": [146      { "internalType": "address", "name": "owner", "type": "address" }147    ],148    "name": "balanceOf",149    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],150    "stateMutability": "view",151    "type": "function"152  },153  {154    "inputs": [155      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }156    ],157    "name": "burn",158    "outputs": [],159    "stateMutability": "nonpayable",160    "type": "function"161  },162  {163    "inputs": [164      {165        "components": [166          { "internalType": "address", "name": "eth", "type": "address" },167          { "internalType": "uint256", "name": "sub", "type": "uint256" }168        ],169        "internalType": "struct CrossAddress",170        "name": "from",171        "type": "tuple"172      },173      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }174    ],175    "name": "burnFromCross",176    "outputs": [],177    "stateMutability": "nonpayable",178    "type": "function"179  },180  {181    "inputs": [182      {183        "components": [184          { "internalType": "address", "name": "eth", "type": "address" },185          { "internalType": "uint256", "name": "sub", "type": "uint256" }186        ],187        "internalType": "struct CrossAddress",188        "name": "newOwner",189        "type": "tuple"190      }191    ],192    "name": "changeCollectionOwnerCross",193    "outputs": [],194    "stateMutability": "nonpayable",195    "type": "function"196  },197  {198    "inputs": [],199    "name": "collectionAdmins",200    "outputs": [201      {202        "components": [203          { "internalType": "address", "name": "eth", "type": "address" },204          { "internalType": "uint256", "name": "sub", "type": "uint256" }205        ],206        "internalType": "struct CrossAddress[]",207        "name": "",208        "type": "tuple[]"209      }210    ],211    "stateMutability": "view",212    "type": "function"213  },214  {215    "inputs": [],216    "name": "collectionHelperAddress",217    "outputs": [{ "internalType": "address", "name": "", "type": "address" }],218    "stateMutability": "view",219    "type": "function"220  },221  {222    "inputs": [],223    "name": "collectionLimits",224    "outputs": [225      {226        "components": [227          {228            "internalType": "enum CollectionLimitField",229            "name": "field",230            "type": "uint8"231          },232          {233            "components": [234              { "internalType": "bool", "name": "status", "type": "bool" },235              { "internalType": "uint256", "name": "value", "type": "uint256" }236            ],237            "internalType": "struct OptionUint",238            "name": "value",239            "type": "tuple"240          }241        ],242        "internalType": "struct CollectionLimit[]",243        "name": "",244        "type": "tuple[]"245      }246    ],247    "stateMutability": "view",248    "type": "function"249  },250  {251    "inputs": [],252    "name": "collectionNestingPermissions",253    "outputs": [254      {255        "components": [256          {257            "internalType": "enum CollectionPermissionField",258            "name": "field",259            "type": "uint8"260          },261          { "internalType": "bool", "name": "value", "type": "bool" }262        ],263        "internalType": "struct CollectionNestingPermission[]",264        "name": "",265        "type": "tuple[]"266      }267    ],268    "stateMutability": "view",269    "type": "function"270  },271  {272    "inputs": [],273    "name": "collectionNestingRestrictedCollectionIds",274    "outputs": [275      {276        "components": [277          { "internalType": "bool", "name": "token_owner", "type": "bool" },278          { "internalType": "uint256[]", "name": "ids", "type": "uint256[]" }279        ],280        "internalType": "struct CollectionNesting",281        "name": "",282        "type": "tuple"283      }284    ],285    "stateMutability": "view",286    "type": "function"287  },288  {289    "inputs": [],290    "name": "collectionOwner",291    "outputs": [292      {293        "components": [294          { "internalType": "address", "name": "eth", "type": "address" },295          { "internalType": "uint256", "name": "sub", "type": "uint256" }296        ],297        "internalType": "struct CrossAddress",298        "name": "",299        "type": "tuple"300      }301    ],302    "stateMutability": "view",303    "type": "function"304  },305  {306    "inputs": [307      { "internalType": "string[]", "name": "keys", "type": "string[]" }308    ],309    "name": "collectionProperties",310    "outputs": [311      {312        "components": [313          { "internalType": "string", "name": "key", "type": "string" },314          { "internalType": "bytes", "name": "value", "type": "bytes" }315        ],316        "internalType": "struct Property[]",317        "name": "",318        "type": "tuple[]"319      }320    ],321    "stateMutability": "view",322    "type": "function"323  },324  {325    "inputs": [{ "internalType": "string", "name": "key", "type": "string" }],326    "name": "collectionProperty",327    "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }],328    "stateMutability": "view",329    "type": "function"330  },331  {332    "inputs": [],333    "name": "collectionSponsor",334    "outputs": [335      {336        "components": [337          { "internalType": "address", "name": "eth", "type": "address" },338          { "internalType": "uint256", "name": "sub", "type": "uint256" }339        ],340        "internalType": "struct CrossAddress",341        "name": "",342        "type": "tuple"343      }344    ],345    "stateMutability": "view",346    "type": "function"347  },348  {349    "inputs": [],350    "name": "confirmCollectionSponsorship",351    "outputs": [],352    "stateMutability": "nonpayable",353    "type": "function"354  },355  {356    "inputs": [],357    "name": "contractAddress",358    "outputs": [{ "internalType": "address", "name": "", "type": "address" }],359    "stateMutability": "view",360    "type": "function"361  },362  {363    "inputs": [364      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }365    ],366    "name": "crossOwnerOf",367    "outputs": [368      {369        "components": [370          { "internalType": "address", "name": "eth", "type": "address" },371          { "internalType": "uint256", "name": "sub", "type": "uint256" }372        ],373        "internalType": "struct CrossAddress",374        "name": "",375        "type": "tuple"376      }377    ],378    "stateMutability": "view",379    "type": "function"380  },381  {382    "inputs": [383      { "internalType": "string[]", "name": "keys", "type": "string[]" }384    ],385    "name": "deleteCollectionProperties",386    "outputs": [],387    "stateMutability": "nonpayable",388    "type": "function"389  },390  {391    "inputs": [392      { "internalType": "uint256", "name": "tokenId", "type": "uint256" },393      { "internalType": "string[]", "name": "keys", "type": "string[]" }394    ],395    "name": "deleteProperties",396    "outputs": [],397    "stateMutability": "nonpayable",398    "type": "function"399  },400  {401    "inputs": [],402    "name": "description",403    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],404    "stateMutability": "view",405    "type": "function"406  },407  {408    "inputs": [],409    "name": "finishMinting",410    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],411    "stateMutability": "nonpayable",412    "type": "function"413  },414  {415    "inputs": [416      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }417    ],418    "name": "getApproved",419    "outputs": [{ "internalType": "address", "name": "", "type": "address" }],420    "stateMutability": "view",421    "type": "function"422  },423  {424    "inputs": [],425    "name": "hasCollectionPendingSponsor",426    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],427    "stateMutability": "view",428    "type": "function"429  },430  {431    "inputs": [432      { "internalType": "address", "name": "owner", "type": "address" },433      { "internalType": "address", "name": "operator", "type": "address" }434    ],435    "name": "isApprovedForAll",436    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],437    "stateMutability": "view",438    "type": "function"439  },440  {441    "inputs": [442      {443        "components": [444          { "internalType": "address", "name": "eth", "type": "address" },445          { "internalType": "uint256", "name": "sub", "type": "uint256" }446        ],447        "internalType": "struct CrossAddress",448        "name": "user",449        "type": "tuple"450      }451    ],452    "name": "isOwnerOrAdminCross",453    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],454    "stateMutability": "view",455    "type": "function"456  },457  {458    "inputs": [{ "internalType": "address", "name": "to", "type": "address" }],459    "name": "mint",460    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],461    "stateMutability": "nonpayable",462    "type": "function"463  },464  {465    "inputs": [466      {467        "components": [468          { "internalType": "address", "name": "eth", "type": "address" },469          { "internalType": "uint256", "name": "sub", "type": "uint256" }470        ],471        "internalType": "struct CrossAddress",472        "name": "to",473        "type": "tuple"474      },475      {476        "components": [477          { "internalType": "string", "name": "key", "type": "string" },478          { "internalType": "bytes", "name": "value", "type": "bytes" }479        ],480        "internalType": "struct Property[]",481        "name": "properties",482        "type": "tuple[]"483      }484    ],485    "name": "mintCross",486    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],487    "stateMutability": "nonpayable",488    "type": "function"489  },490  {491    "inputs": [492      { "internalType": "address", "name": "to", "type": "address" },493      { "internalType": "string", "name": "tokenUri", "type": "string" }494    ],495    "name": "mintWithTokenURI",496    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],497    "stateMutability": "nonpayable",498    "type": "function"499  },500  {501    "inputs": [],502    "name": "mintingFinished",503    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],504    "stateMutability": "view",505    "type": "function"506  },507  {508    "inputs": [],509    "name": "name",510    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],511    "stateMutability": "view",512    "type": "function"513  },514  {515    "inputs": [],516    "name": "nextTokenId",517    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],518    "stateMutability": "view",519    "type": "function"520  },521  {522    "inputs": [523      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }524    ],525    "name": "ownerOf",526    "outputs": [{ "internalType": "address", "name": "", "type": "address" }],527    "stateMutability": "view",528    "type": "function"529  },530  {531    "inputs": [532      { "internalType": "uint256", "name": "tokenId", "type": "uint256" },533      { "internalType": "string[]", "name": "keys", "type": "string[]" }534    ],535    "name": "properties",536    "outputs": [537      {538        "components": [539          { "internalType": "string", "name": "key", "type": "string" },540          { "internalType": "bytes", "name": "value", "type": "bytes" }541        ],542        "internalType": "struct Property[]",543        "name": "",544        "type": "tuple[]"545      }546    ],547    "stateMutability": "view",548    "type": "function"549  },550  {551    "inputs": [552      { "internalType": "uint256", "name": "tokenId", "type": "uint256" },553      { "internalType": "string", "name": "key", "type": "string" }554    ],555    "name": "property",556    "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }],557    "stateMutability": "view",558    "type": "function"559  },560  {561    "inputs": [562      {563        "components": [564          { "internalType": "address", "name": "eth", "type": "address" },565          { "internalType": "uint256", "name": "sub", "type": "uint256" }566        ],567        "internalType": "struct CrossAddress",568        "name": "admin",569        "type": "tuple"570      }571    ],572    "name": "removeCollectionAdminCross",573    "outputs": [],574    "stateMutability": "nonpayable",575    "type": "function"576  },577  {578    "inputs": [],579    "name": "removeCollectionSponsor",580    "outputs": [],581    "stateMutability": "nonpayable",582    "type": "function"583  },584  {585    "inputs": [586      {587        "components": [588          { "internalType": "address", "name": "eth", "type": "address" },589          { "internalType": "uint256", "name": "sub", "type": "uint256" }590        ],591        "internalType": "struct CrossAddress",592        "name": "user",593        "type": "tuple"594      }595    ],596    "name": "removeFromCollectionAllowListCross",597    "outputs": [],598    "stateMutability": "nonpayable",599    "type": "function"600  },601  {602    "inputs": [603      { "internalType": "address", "name": "from", "type": "address" },604      { "internalType": "address", "name": "to", "type": "address" },605      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }606    ],607    "name": "safeTransferFrom",608    "outputs": [],609    "stateMutability": "nonpayable",610    "type": "function"611  },612  {613    "inputs": [614      { "internalType": "address", "name": "from", "type": "address" },615      { "internalType": "address", "name": "to", "type": "address" },616      { "internalType": "uint256", "name": "tokenId", "type": "uint256" },617      { "internalType": "bytes", "name": "data", "type": "bytes" }618    ],619    "name": "safeTransferFromWithData",620    "outputs": [],621    "stateMutability": "nonpayable",622    "type": "function"623  },624  {625    "inputs": [626      { "internalType": "address", "name": "operator", "type": "address" },627      { "internalType": "bool", "name": "approved", "type": "bool" }628    ],629    "name": "setApprovalForAll",630    "outputs": [],631    "stateMutability": "nonpayable",632    "type": "function"633  },634  {635    "inputs": [{ "internalType": "uint8", "name": "mode", "type": "uint8" }],636    "name": "setCollectionAccess",637    "outputs": [],638    "stateMutability": "nonpayable",639    "type": "function"640  },641  {642    "inputs": [643      {644        "components": [645          {646            "internalType": "enum CollectionLimitField",647            "name": "field",648            "type": "uint8"649          },650          {651            "components": [652              { "internalType": "bool", "name": "status", "type": "bool" },653              { "internalType": "uint256", "name": "value", "type": "uint256" }654            ],655            "internalType": "struct OptionUint",656            "name": "value",657            "type": "tuple"658          }659        ],660        "internalType": "struct CollectionLimit",661        "name": "limit",662        "type": "tuple"663      }664    ],665    "name": "setCollectionLimit",666    "outputs": [],667    "stateMutability": "nonpayable",668    "type": "function"669  },670  {671    "inputs": [{ "internalType": "bool", "name": "mode", "type": "bool" }],672    "name": "setCollectionMintMode",673    "outputs": [],674    "stateMutability": "nonpayable",675    "type": "function"676  },677  {678    "inputs": [{ "internalType": "bool", "name": "enable", "type": "bool" }],679    "name": "setCollectionNesting",680    "outputs": [],681    "stateMutability": "nonpayable",682    "type": "function"683  },684  {685    "inputs": [686      { "internalType": "bool", "name": "enable", "type": "bool" },687      {688        "internalType": "address[]",689        "name": "collections",690        "type": "address[]"691      }692    ],693    "name": "setCollectionNesting",694    "outputs": [],695    "stateMutability": "nonpayable",696    "type": "function"697  },698  {699    "inputs": [700      {701        "components": [702          { "internalType": "string", "name": "key", "type": "string" },703          { "internalType": "bytes", "name": "value", "type": "bytes" }704        ],705        "internalType": "struct Property[]",706        "name": "properties",707        "type": "tuple[]"708      }709    ],710    "name": "setCollectionProperties",711    "outputs": [],712    "stateMutability": "nonpayable",713    "type": "function"714  },715  {716    "inputs": [717      {718        "components": [719          { "internalType": "address", "name": "eth", "type": "address" },720          { "internalType": "uint256", "name": "sub", "type": "uint256" }721        ],722        "internalType": "struct CrossAddress",723        "name": "sponsor",724        "type": "tuple"725      }726    ],727    "name": "setCollectionSponsorCross",728    "outputs": [],729    "stateMutability": "nonpayable",730    "type": "function"731  },732  {733    "inputs": [734      { "internalType": "uint256", "name": "tokenId", "type": "uint256" },735      {736        "components": [737          { "internalType": "string", "name": "key", "type": "string" },738          { "internalType": "bytes", "name": "value", "type": "bytes" }739        ],740        "internalType": "struct Property[]",741        "name": "properties",742        "type": "tuple[]"743      }744    ],745    "name": "setProperties",746    "outputs": [],747    "stateMutability": "nonpayable",748    "type": "function"749  },750  {751    "inputs": [752      {753        "components": [754          { "internalType": "string", "name": "key", "type": "string" },755          {756            "components": [757              {758                "internalType": "enum TokenPermissionField",759                "name": "code",760                "type": "uint8"761              },762              { "internalType": "bool", "name": "value", "type": "bool" }763            ],764            "internalType": "struct PropertyPermission[]",765            "name": "permissions",766            "type": "tuple[]"767          }768        ],769        "internalType": "struct TokenPropertyPermission[]",770        "name": "permissions",771        "type": "tuple[]"772      }773    ],774    "name": "setTokenPropertyPermissions",775    "outputs": [],776    "stateMutability": "nonpayable",777    "type": "function"778  },779  {780    "inputs": [781      { "internalType": "bytes4", "name": "interfaceID", "type": "bytes4" }782    ],783    "name": "supportsInterface",784    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],785    "stateMutability": "view",786    "type": "function"787  },788  {789    "inputs": [],790    "name": "symbol",791    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],792    "stateMutability": "view",793    "type": "function"794  },795  {796    "inputs": [797      { "internalType": "uint256", "name": "index", "type": "uint256" }798    ],799    "name": "tokenByIndex",800    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],801    "stateMutability": "view",802    "type": "function"803  },804  {805    "inputs": [806      { "internalType": "uint256", "name": "token", "type": "uint256" }807    ],808    "name": "tokenContractAddress",809    "outputs": [{ "internalType": "address", "name": "", "type": "address" }],810    "stateMutability": "view",811    "type": "function"812  },813  {814    "inputs": [815      { "internalType": "address", "name": "owner", "type": "address" },816      { "internalType": "uint256", "name": "index", "type": "uint256" }817    ],818    "name": "tokenOfOwnerByIndex",819    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],820    "stateMutability": "view",821    "type": "function"822  },823  {824    "inputs": [],825    "name": "tokenPropertyPermissions",826    "outputs": [827      {828        "components": [829          { "internalType": "string", "name": "key", "type": "string" },830          {831            "components": [832              {833                "internalType": "enum TokenPermissionField",834                "name": "code",835                "type": "uint8"836              },837              { "internalType": "bool", "name": "value", "type": "bool" }838            ],839            "internalType": "struct PropertyPermission[]",840            "name": "permissions",841            "type": "tuple[]"842          }843        ],844        "internalType": "struct TokenPropertyPermission[]",845        "name": "",846        "type": "tuple[]"847      }848    ],849    "stateMutability": "view",850    "type": "function"851  },852  {853    "inputs": [854      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }855    ],856    "name": "tokenURI",857    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],858    "stateMutability": "view",859    "type": "function"860  },861  {862    "inputs": [],863    "name": "totalSupply",864    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],865    "stateMutability": "view",866    "type": "function"867  },868  {869    "inputs": [870      { "internalType": "address", "name": "to", "type": "address" },871      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }872    ],873    "name": "transfer",874    "outputs": [],875    "stateMutability": "nonpayable",876    "type": "function"877  },878  {879    "inputs": [880      {881        "components": [882          { "internalType": "address", "name": "eth", "type": "address" },883          { "internalType": "uint256", "name": "sub", "type": "uint256" }884        ],885        "internalType": "struct CrossAddress",886        "name": "to",887        "type": "tuple"888      },889      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }890    ],891    "name": "transferCross",892    "outputs": [],893    "stateMutability": "nonpayable",894    "type": "function"895  },896  {897    "inputs": [898      { "internalType": "address", "name": "from", "type": "address" },899      { "internalType": "address", "name": "to", "type": "address" },900      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }901    ],902    "name": "transferFrom",903    "outputs": [],904    "stateMutability": "nonpayable",905    "type": "function"906  },907  {908    "inputs": [909      {910        "components": [911          { "internalType": "address", "name": "eth", "type": "address" },912          { "internalType": "uint256", "name": "sub", "type": "uint256" }913        ],914        "internalType": "struct CrossAddress",915        "name": "from",916        "type": "tuple"917      },918      {919        "components": [920          { "internalType": "address", "name": "eth", "type": "address" },921          { "internalType": "uint256", "name": "sub", "type": "uint256" }922        ],923        "internalType": "struct CrossAddress",924        "name": "to",925        "type": "tuple"926      },927      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }928    ],929    "name": "transferFromCross",930    "outputs": [],931    "stateMutability": "nonpayable",932    "type": "function"933  },934  {935    "inputs": [],936    "name": "uniqueCollectionType",937    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],938    "stateMutability": "view",939    "type": "function"940  }941]
after · tests/src/eth/abi/reFungible.json
1[2  {3    "anonymous": false,4    "inputs": [5      {6        "indexed": true,7        "internalType": "address",8        "name": "owner",9        "type": "address"10      },11      {12        "indexed": true,13        "internalType": "address",14        "name": "approved",15        "type": "address"16      },17      {18        "indexed": true,19        "internalType": "uint256",20        "name": "tokenId",21        "type": "uint256"22      }23    ],24    "name": "Approval",25    "type": "event"26  },27  {28    "anonymous": false,29    "inputs": [30      {31        "indexed": true,32        "internalType": "address",33        "name": "owner",34        "type": "address"35      },36      {37        "indexed": true,38        "internalType": "address",39        "name": "operator",40        "type": "address"41      },42      {43        "indexed": false,44        "internalType": "bool",45        "name": "approved",46        "type": "bool"47      }48    ],49    "name": "ApprovalForAll",50    "type": "event"51  },52  {53    "anonymous": false,54    "inputs": [],55    "name": "MintingFinished",56    "type": "event"57  },58  {59    "anonymous": false,60    "inputs": [61      {62        "indexed": true,63        "internalType": "address",64        "name": "from",65        "type": "address"66      },67      {68        "indexed": true,69        "internalType": "address",70        "name": "to",71        "type": "address"72      },73      {74        "indexed": true,75        "internalType": "uint256",76        "name": "tokenId",77        "type": "uint256"78      }79    ],80    "name": "Transfer",81    "type": "event"82  },83  {84    "inputs": [85      {86        "components": [87          { "internalType": "address", "name": "eth", "type": "address" },88          { "internalType": "uint256", "name": "sub", "type": "uint256" }89        ],90        "internalType": "struct CrossAddress",91        "name": "newAdmin",92        "type": "tuple"93      }94    ],95    "name": "addCollectionAdminCross",96    "outputs": [],97    "stateMutability": "nonpayable",98    "type": "function"99  },100  {101    "inputs": [102      {103        "components": [104          { "internalType": "address", "name": "eth", "type": "address" },105          { "internalType": "uint256", "name": "sub", "type": "uint256" }106        ],107        "internalType": "struct CrossAddress",108        "name": "user",109        "type": "tuple"110      }111    ],112    "name": "addToCollectionAllowListCross",113    "outputs": [],114    "stateMutability": "nonpayable",115    "type": "function"116  },117  {118    "inputs": [119      {120        "components": [121          { "internalType": "address", "name": "eth", "type": "address" },122          { "internalType": "uint256", "name": "sub", "type": "uint256" }123        ],124        "internalType": "struct CrossAddress",125        "name": "user",126        "type": "tuple"127      }128    ],129    "name": "allowlistedCross",130    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],131    "stateMutability": "view",132    "type": "function"133  },134  {135    "inputs": [136      { "internalType": "address", "name": "approved", "type": "address" },137      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }138    ],139    "name": "approve",140    "outputs": [],141    "stateMutability": "nonpayable",142    "type": "function"143  },144  {145    "inputs": [146      { "internalType": "address", "name": "owner", "type": "address" }147    ],148    "name": "balanceOf",149    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],150    "stateMutability": "view",151    "type": "function"152  },153  {154    "inputs": [155      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }156    ],157    "name": "burn",158    "outputs": [],159    "stateMutability": "nonpayable",160    "type": "function"161  },162  {163    "inputs": [164      {165        "components": [166          { "internalType": "address", "name": "eth", "type": "address" },167          { "internalType": "uint256", "name": "sub", "type": "uint256" }168        ],169        "internalType": "struct CrossAddress",170        "name": "from",171        "type": "tuple"172      },173      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }174    ],175    "name": "burnFromCross",176    "outputs": [],177    "stateMutability": "nonpayable",178    "type": "function"179  },180  {181    "inputs": [182      {183        "components": [184          { "internalType": "address", "name": "eth", "type": "address" },185          { "internalType": "uint256", "name": "sub", "type": "uint256" }186        ],187        "internalType": "struct CrossAddress",188        "name": "newOwner",189        "type": "tuple"190      }191    ],192    "name": "changeCollectionOwnerCross",193    "outputs": [],194    "stateMutability": "nonpayable",195    "type": "function"196  },197  {198    "inputs": [],199    "name": "collectionAdmins",200    "outputs": [201      {202        "components": [203          { "internalType": "address", "name": "eth", "type": "address" },204          { "internalType": "uint256", "name": "sub", "type": "uint256" }205        ],206        "internalType": "struct CrossAddress[]",207        "name": "",208        "type": "tuple[]"209      }210    ],211    "stateMutability": "view",212    "type": "function"213  },214  {215    "inputs": [],216    "name": "collectionHelperAddress",217    "outputs": [{ "internalType": "address", "name": "", "type": "address" }],218    "stateMutability": "view",219    "type": "function"220  },221  {222    "inputs": [],223    "name": "collectionLimits",224    "outputs": [225      {226        "components": [227          {228            "internalType": "enum CollectionLimitField",229            "name": "field",230            "type": "uint8"231          },232          {233            "components": [234              { "internalType": "bool", "name": "status", "type": "bool" },235              { "internalType": "uint256", "name": "value", "type": "uint256" }236            ],237            "internalType": "struct OptionUint256",238            "name": "value",239            "type": "tuple"240          }241        ],242        "internalType": "struct CollectionLimit[]",243        "name": "",244        "type": "tuple[]"245      }246    ],247    "stateMutability": "view",248    "type": "function"249  },250  {251    "inputs": [],252    "name": "collectionNestingPermissions",253    "outputs": [254      {255        "components": [256          {257            "internalType": "enum CollectionPermissionField",258            "name": "field",259            "type": "uint8"260          },261          { "internalType": "bool", "name": "value", "type": "bool" }262        ],263        "internalType": "struct CollectionNestingPermission[]",264        "name": "",265        "type": "tuple[]"266      }267    ],268    "stateMutability": "view",269    "type": "function"270  },271  {272    "inputs": [],273    "name": "collectionNestingRestrictedCollectionIds",274    "outputs": [275      {276        "components": [277          { "internalType": "bool", "name": "token_owner", "type": "bool" },278          { "internalType": "uint256[]", "name": "ids", "type": "uint256[]" }279        ],280        "internalType": "struct CollectionNesting",281        "name": "",282        "type": "tuple"283      }284    ],285    "stateMutability": "view",286    "type": "function"287  },288  {289    "inputs": [],290    "name": "collectionOwner",291    "outputs": [292      {293        "components": [294          { "internalType": "address", "name": "eth", "type": "address" },295          { "internalType": "uint256", "name": "sub", "type": "uint256" }296        ],297        "internalType": "struct CrossAddress",298        "name": "",299        "type": "tuple"300      }301    ],302    "stateMutability": "view",303    "type": "function"304  },305  {306    "inputs": [307      { "internalType": "string[]", "name": "keys", "type": "string[]" }308    ],309    "name": "collectionProperties",310    "outputs": [311      {312        "components": [313          { "internalType": "string", "name": "key", "type": "string" },314          { "internalType": "bytes", "name": "value", "type": "bytes" }315        ],316        "internalType": "struct Property[]",317        "name": "",318        "type": "tuple[]"319      }320    ],321    "stateMutability": "view",322    "type": "function"323  },324  {325    "inputs": [{ "internalType": "string", "name": "key", "type": "string" }],326    "name": "collectionProperty",327    "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }],328    "stateMutability": "view",329    "type": "function"330  },331  {332    "inputs": [],333    "name": "collectionSponsor",334    "outputs": [335      {336        "components": [337          { "internalType": "address", "name": "eth", "type": "address" },338          { "internalType": "uint256", "name": "sub", "type": "uint256" }339        ],340        "internalType": "struct CrossAddress",341        "name": "",342        "type": "tuple"343      }344    ],345    "stateMutability": "view",346    "type": "function"347  },348  {349    "inputs": [],350    "name": "confirmCollectionSponsorship",351    "outputs": [],352    "stateMutability": "nonpayable",353    "type": "function"354  },355  {356    "inputs": [],357    "name": "contractAddress",358    "outputs": [{ "internalType": "address", "name": "", "type": "address" }],359    "stateMutability": "view",360    "type": "function"361  },362  {363    "inputs": [364      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }365    ],366    "name": "crossOwnerOf",367    "outputs": [368      {369        "components": [370          { "internalType": "address", "name": "eth", "type": "address" },371          { "internalType": "uint256", "name": "sub", "type": "uint256" }372        ],373        "internalType": "struct CrossAddress",374        "name": "",375        "type": "tuple"376      }377    ],378    "stateMutability": "view",379    "type": "function"380  },381  {382    "inputs": [383      { "internalType": "string[]", "name": "keys", "type": "string[]" }384    ],385    "name": "deleteCollectionProperties",386    "outputs": [],387    "stateMutability": "nonpayable",388    "type": "function"389  },390  {391    "inputs": [392      { "internalType": "uint256", "name": "tokenId", "type": "uint256" },393      { "internalType": "string[]", "name": "keys", "type": "string[]" }394    ],395    "name": "deleteProperties",396    "outputs": [],397    "stateMutability": "nonpayable",398    "type": "function"399  },400  {401    "inputs": [],402    "name": "description",403    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],404    "stateMutability": "view",405    "type": "function"406  },407  {408    "inputs": [],409    "name": "finishMinting",410    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],411    "stateMutability": "nonpayable",412    "type": "function"413  },414  {415    "inputs": [416      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }417    ],418    "name": "getApproved",419    "outputs": [{ "internalType": "address", "name": "", "type": "address" }],420    "stateMutability": "view",421    "type": "function"422  },423  {424    "inputs": [],425    "name": "hasCollectionPendingSponsor",426    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],427    "stateMutability": "view",428    "type": "function"429  },430  {431    "inputs": [432      { "internalType": "address", "name": "owner", "type": "address" },433      { "internalType": "address", "name": "operator", "type": "address" }434    ],435    "name": "isApprovedForAll",436    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],437    "stateMutability": "view",438    "type": "function"439  },440  {441    "inputs": [442      {443        "components": [444          { "internalType": "address", "name": "eth", "type": "address" },445          { "internalType": "uint256", "name": "sub", "type": "uint256" }446        ],447        "internalType": "struct CrossAddress",448        "name": "user",449        "type": "tuple"450      }451    ],452    "name": "isOwnerOrAdminCross",453    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],454    "stateMutability": "view",455    "type": "function"456  },457  {458    "inputs": [{ "internalType": "address", "name": "to", "type": "address" }],459    "name": "mint",460    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],461    "stateMutability": "nonpayable",462    "type": "function"463  },464  {465    "inputs": [466      {467        "components": [468          { "internalType": "address", "name": "eth", "type": "address" },469          { "internalType": "uint256", "name": "sub", "type": "uint256" }470        ],471        "internalType": "struct CrossAddress",472        "name": "to",473        "type": "tuple"474      },475      {476        "components": [477          { "internalType": "string", "name": "key", "type": "string" },478          { "internalType": "bytes", "name": "value", "type": "bytes" }479        ],480        "internalType": "struct Property[]",481        "name": "properties",482        "type": "tuple[]"483      }484    ],485    "name": "mintCross",486    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],487    "stateMutability": "nonpayable",488    "type": "function"489  },490  {491    "inputs": [492      { "internalType": "address", "name": "to", "type": "address" },493      { "internalType": "string", "name": "tokenUri", "type": "string" }494    ],495    "name": "mintWithTokenURI",496    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],497    "stateMutability": "nonpayable",498    "type": "function"499  },500  {501    "inputs": [],502    "name": "mintingFinished",503    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],504    "stateMutability": "view",505    "type": "function"506  },507  {508    "inputs": [],509    "name": "name",510    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],511    "stateMutability": "view",512    "type": "function"513  },514  {515    "inputs": [],516    "name": "nextTokenId",517    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],518    "stateMutability": "view",519    "type": "function"520  },521  {522    "inputs": [523      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }524    ],525    "name": "ownerOf",526    "outputs": [{ "internalType": "address", "name": "", "type": "address" }],527    "stateMutability": "view",528    "type": "function"529  },530  {531    "inputs": [532      { "internalType": "uint256", "name": "tokenId", "type": "uint256" },533      { "internalType": "string[]", "name": "keys", "type": "string[]" }534    ],535    "name": "properties",536    "outputs": [537      {538        "components": [539          { "internalType": "string", "name": "key", "type": "string" },540          { "internalType": "bytes", "name": "value", "type": "bytes" }541        ],542        "internalType": "struct Property[]",543        "name": "",544        "type": "tuple[]"545      }546    ],547    "stateMutability": "view",548    "type": "function"549  },550  {551    "inputs": [552      { "internalType": "uint256", "name": "tokenId", "type": "uint256" },553      { "internalType": "string", "name": "key", "type": "string" }554    ],555    "name": "property",556    "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }],557    "stateMutability": "view",558    "type": "function"559  },560  {561    "inputs": [562      {563        "components": [564          { "internalType": "address", "name": "eth", "type": "address" },565          { "internalType": "uint256", "name": "sub", "type": "uint256" }566        ],567        "internalType": "struct CrossAddress",568        "name": "admin",569        "type": "tuple"570      }571    ],572    "name": "removeCollectionAdminCross",573    "outputs": [],574    "stateMutability": "nonpayable",575    "type": "function"576  },577  {578    "inputs": [],579    "name": "removeCollectionSponsor",580    "outputs": [],581    "stateMutability": "nonpayable",582    "type": "function"583  },584  {585    "inputs": [586      {587        "components": [588          { "internalType": "address", "name": "eth", "type": "address" },589          { "internalType": "uint256", "name": "sub", "type": "uint256" }590        ],591        "internalType": "struct CrossAddress",592        "name": "user",593        "type": "tuple"594      }595    ],596    "name": "removeFromCollectionAllowListCross",597    "outputs": [],598    "stateMutability": "nonpayable",599    "type": "function"600  },601  {602    "inputs": [603      { "internalType": "address", "name": "from", "type": "address" },604      { "internalType": "address", "name": "to", "type": "address" },605      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }606    ],607    "name": "safeTransferFrom",608    "outputs": [],609    "stateMutability": "nonpayable",610    "type": "function"611  },612  {613    "inputs": [614      { "internalType": "address", "name": "from", "type": "address" },615      { "internalType": "address", "name": "to", "type": "address" },616      { "internalType": "uint256", "name": "tokenId", "type": "uint256" },617      { "internalType": "bytes", "name": "data", "type": "bytes" }618    ],619    "name": "safeTransferFromWithData",620    "outputs": [],621    "stateMutability": "nonpayable",622    "type": "function"623  },624  {625    "inputs": [626      { "internalType": "address", "name": "operator", "type": "address" },627      { "internalType": "bool", "name": "approved", "type": "bool" }628    ],629    "name": "setApprovalForAll",630    "outputs": [],631    "stateMutability": "nonpayable",632    "type": "function"633  },634  {635    "inputs": [{ "internalType": "uint8", "name": "mode", "type": "uint8" }],636    "name": "setCollectionAccess",637    "outputs": [],638    "stateMutability": "nonpayable",639    "type": "function"640  },641  {642    "inputs": [643      {644        "components": [645          {646            "internalType": "enum CollectionLimitField",647            "name": "field",648            "type": "uint8"649          },650          {651            "components": [652              { "internalType": "bool", "name": "status", "type": "bool" },653              { "internalType": "uint256", "name": "value", "type": "uint256" }654            ],655            "internalType": "struct OptionUint256",656            "name": "value",657            "type": "tuple"658          }659        ],660        "internalType": "struct CollectionLimit",661        "name": "limit",662        "type": "tuple"663      }664    ],665    "name": "setCollectionLimit",666    "outputs": [],667    "stateMutability": "nonpayable",668    "type": "function"669  },670  {671    "inputs": [{ "internalType": "bool", "name": "mode", "type": "bool" }],672    "name": "setCollectionMintMode",673    "outputs": [],674    "stateMutability": "nonpayable",675    "type": "function"676  },677  {678    "inputs": [{ "internalType": "bool", "name": "enable", "type": "bool" }],679    "name": "setCollectionNesting",680    "outputs": [],681    "stateMutability": "nonpayable",682    "type": "function"683  },684  {685    "inputs": [686      { "internalType": "bool", "name": "enable", "type": "bool" },687      {688        "internalType": "address[]",689        "name": "collections",690        "type": "address[]"691      }692    ],693    "name": "setCollectionNesting",694    "outputs": [],695    "stateMutability": "nonpayable",696    "type": "function"697  },698  {699    "inputs": [700      {701        "components": [702          { "internalType": "string", "name": "key", "type": "string" },703          { "internalType": "bytes", "name": "value", "type": "bytes" }704        ],705        "internalType": "struct Property[]",706        "name": "properties",707        "type": "tuple[]"708      }709    ],710    "name": "setCollectionProperties",711    "outputs": [],712    "stateMutability": "nonpayable",713    "type": "function"714  },715  {716    "inputs": [717      {718        "components": [719          { "internalType": "address", "name": "eth", "type": "address" },720          { "internalType": "uint256", "name": "sub", "type": "uint256" }721        ],722        "internalType": "struct CrossAddress",723        "name": "sponsor",724        "type": "tuple"725      }726    ],727    "name": "setCollectionSponsorCross",728    "outputs": [],729    "stateMutability": "nonpayable",730    "type": "function"731  },732  {733    "inputs": [734      { "internalType": "uint256", "name": "tokenId", "type": "uint256" },735      {736        "components": [737          { "internalType": "string", "name": "key", "type": "string" },738          { "internalType": "bytes", "name": "value", "type": "bytes" }739        ],740        "internalType": "struct Property[]",741        "name": "properties",742        "type": "tuple[]"743      }744    ],745    "name": "setProperties",746    "outputs": [],747    "stateMutability": "nonpayable",748    "type": "function"749  },750  {751    "inputs": [752      {753        "components": [754          { "internalType": "string", "name": "key", "type": "string" },755          {756            "components": [757              {758                "internalType": "enum TokenPermissionField",759                "name": "code",760                "type": "uint8"761              },762              { "internalType": "bool", "name": "value", "type": "bool" }763            ],764            "internalType": "struct PropertyPermission[]",765            "name": "permissions",766            "type": "tuple[]"767          }768        ],769        "internalType": "struct TokenPropertyPermission[]",770        "name": "permissions",771        "type": "tuple[]"772      }773    ],774    "name": "setTokenPropertyPermissions",775    "outputs": [],776    "stateMutability": "nonpayable",777    "type": "function"778  },779  {780    "inputs": [781      { "internalType": "bytes4", "name": "interfaceID", "type": "bytes4" }782    ],783    "name": "supportsInterface",784    "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }],785    "stateMutability": "view",786    "type": "function"787  },788  {789    "inputs": [],790    "name": "symbol",791    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],792    "stateMutability": "view",793    "type": "function"794  },795  {796    "inputs": [797      { "internalType": "uint256", "name": "index", "type": "uint256" }798    ],799    "name": "tokenByIndex",800    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],801    "stateMutability": "view",802    "type": "function"803  },804  {805    "inputs": [806      { "internalType": "uint256", "name": "token", "type": "uint256" }807    ],808    "name": "tokenContractAddress",809    "outputs": [{ "internalType": "address", "name": "", "type": "address" }],810    "stateMutability": "view",811    "type": "function"812  },813  {814    "inputs": [815      { "internalType": "address", "name": "owner", "type": "address" },816      { "internalType": "uint256", "name": "index", "type": "uint256" }817    ],818    "name": "tokenOfOwnerByIndex",819    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],820    "stateMutability": "view",821    "type": "function"822  },823  {824    "inputs": [],825    "name": "tokenPropertyPermissions",826    "outputs": [827      {828        "components": [829          { "internalType": "string", "name": "key", "type": "string" },830          {831            "components": [832              {833                "internalType": "enum TokenPermissionField",834                "name": "code",835                "type": "uint8"836              },837              { "internalType": "bool", "name": "value", "type": "bool" }838            ],839            "internalType": "struct PropertyPermission[]",840            "name": "permissions",841            "type": "tuple[]"842          }843        ],844        "internalType": "struct TokenPropertyPermission[]",845        "name": "",846        "type": "tuple[]"847      }848    ],849    "stateMutability": "view",850    "type": "function"851  },852  {853    "inputs": [854      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }855    ],856    "name": "tokenURI",857    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],858    "stateMutability": "view",859    "type": "function"860  },861  {862    "inputs": [],863    "name": "totalSupply",864    "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],865    "stateMutability": "view",866    "type": "function"867  },868  {869    "inputs": [870      { "internalType": "address", "name": "to", "type": "address" },871      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }872    ],873    "name": "transfer",874    "outputs": [],875    "stateMutability": "nonpayable",876    "type": "function"877  },878  {879    "inputs": [880      {881        "components": [882          { "internalType": "address", "name": "eth", "type": "address" },883          { "internalType": "uint256", "name": "sub", "type": "uint256" }884        ],885        "internalType": "struct CrossAddress",886        "name": "to",887        "type": "tuple"888      },889      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }890    ],891    "name": "transferCross",892    "outputs": [],893    "stateMutability": "nonpayable",894    "type": "function"895  },896  {897    "inputs": [898      { "internalType": "address", "name": "from", "type": "address" },899      { "internalType": "address", "name": "to", "type": "address" },900      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }901    ],902    "name": "transferFrom",903    "outputs": [],904    "stateMutability": "nonpayable",905    "type": "function"906  },907  {908    "inputs": [909      {910        "components": [911          { "internalType": "address", "name": "eth", "type": "address" },912          { "internalType": "uint256", "name": "sub", "type": "uint256" }913        ],914        "internalType": "struct CrossAddress",915        "name": "from",916        "type": "tuple"917      },918      {919        "components": [920          { "internalType": "address", "name": "eth", "type": "address" },921          { "internalType": "uint256", "name": "sub", "type": "uint256" }922        ],923        "internalType": "struct CrossAddress",924        "name": "to",925        "type": "tuple"926      },927      { "internalType": "uint256", "name": "tokenId", "type": "uint256" }928    ],929    "name": "transferFromCross",930    "outputs": [],931    "stateMutability": "nonpayable",932    "type": "function"933  },934  {935    "inputs": [],936    "name": "uniqueCollectionType",937    "outputs": [{ "internalType": "string", "name": "", "type": "string" }],938    "stateMutability": "view",939    "type": "function"940  }941]
modifiedtests/src/eth/api/ContractHelpers.soldiffbeforeafterboth
--- a/tests/src/eth/api/ContractHelpers.sol
+++ b/tests/src/eth/api/ContractHelpers.sol
@@ -181,11 +181,11 @@
 	Generous
 }
 
-/// Ethereum representation of Optional value with CrossAddress.
+/// Optional value
 struct OptionCrossAddress {
-	/// Whether or not this CrossAdress is valid and has meaning.
+	/// Shows the status of accessibility of value
 	bool status;
-	/// The underlying CrossAddress value. If the status is false, can be set to whatever.
+	/// Actual value if `status` is true
 	CrossAddress value;
 }
 
modifiedtests/src/eth/api/UniqueFungible.soldiffbeforeafterboth
--- a/tests/src/eth/api/UniqueFungible.sol
+++ b/tests/src/eth/api/UniqueFungible.sol
@@ -308,12 +308,14 @@
 /// [`CollectionLimits`](up_data_structs::CollectionLimits) field representation for EVM.
 struct CollectionLimit {
 	CollectionLimitField field;
-	OptionUint value;
+	OptionUint256 value;
 }
 
-/// Ethereum representation of Optional value with uint256.
-struct OptionUint {
+/// Optional value
+struct OptionUint256 {
+	/// Shows the status of accessibility of value
 	bool status;
+	/// Actual value if `status` is true
 	uint256 value;
 }
 
modifiedtests/src/eth/api/UniqueNFT.soldiffbeforeafterboth
--- a/tests/src/eth/api/UniqueNFT.sol
+++ b/tests/src/eth/api/UniqueNFT.sol
@@ -408,12 +408,14 @@
 /// [`CollectionLimits`](up_data_structs::CollectionLimits) field representation for EVM.
 struct CollectionLimit {
 	CollectionLimitField field;
-	OptionUint value;
+	OptionUint256 value;
 }
 
-/// Ethereum representation of Optional value with uint256.
-struct OptionUint {
+/// Optional value
+struct OptionUint256 {
+	/// Shows the status of accessibility of value
 	bool status;
+	/// Actual value if `status` is true
 	uint256 value;
 }
 
modifiedtests/src/eth/api/UniqueRefungible.soldiffbeforeafterboth
--- a/tests/src/eth/api/UniqueRefungible.sol
+++ b/tests/src/eth/api/UniqueRefungible.sol
@@ -408,12 +408,14 @@
 /// [`CollectionLimits`](up_data_structs::CollectionLimits) field representation for EVM.
 struct CollectionLimit {
 	CollectionLimitField field;
-	OptionUint value;
+	OptionUint256 value;
 }
 
-/// Ethereum representation of Optional value with uint256.
-struct OptionUint {
+/// Optional value
+struct OptionUint256 {
+	/// Shows the status of accessibility of value
 	bool status;
+	/// Actual value if `status` is true
 	uint256 value;
 }