difftreelog
refac: rename bytes -> Bytes
in: master
9 files changed
crates/evm-coder/src/abi/impls.rsdiffbeforeafterboth--- a/crates/evm-coder/src/abi/impls.rs
+++ b/crates/evm-coder/src/abi/impls.rs
@@ -67,15 +67,15 @@
impl_abi_writeable!(&str, string);
-impl_abi_type!(bytes, bytes, true);
+impl_abi_type!(Bytes, bytes, true);
-impl AbiRead for bytes {
- fn abi_read(reader: &mut AbiReader) -> Result<bytes> {
- Ok(bytes(reader.bytes()?))
+impl AbiRead for Bytes {
+ fn abi_read(reader: &mut AbiReader) -> Result<Bytes> {
+ Ok(Bytes(reader.bytes()?))
}
}
-impl AbiWrite for bytes {
+impl AbiWrite for Bytes {
fn abi_write(&self, writer: &mut AbiWriter) {
writer.bytes(self.0.as_slice())
}
crates/evm-coder/src/abi/test.rsdiffbeforeafterboth--- a/crates/evm-coder/src/abi/test.rs
+++ b/crates/evm-coder/src/abi/test.rs
@@ -273,12 +273,12 @@
#[test]
fn encode_decode_vec_tuple_string_bytes() {
- test_impl::<Vec<(String, bytes)>>(
+ test_impl::<Vec<(String, Bytes)>>(
0xdeadbeef,
vec![
(
"Test URI 0".to_string(),
- bytes(vec![
+ Bytes(vec![
0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
@@ -287,14 +287,14 @@
),
(
"Test URI 1".to_string(),
- bytes(vec![
+ Bytes(vec![
0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
]),
),
- ("Test URI 2".to_string(), bytes(vec![0x33, 0x33])),
+ ("Test URI 2".to_string(), Bytes(vec![0x33, 0x33])),
],
&hex!(
"
@@ -337,10 +337,10 @@
// #[ignore = "reason"]
fn encode_decode_tuple0_tuple1_uint8_tuple1_string_bytes_tuple1_uint8_bytes() {
let int = 0xff;
- let by = bytes(vec![0x11, 0x22, 0x33]);
+ let by = Bytes(vec![0x11, 0x22, 0x33]);
let string = "some string".to_string();
- test_impl::<((u8,), (String, bytes), (u8, bytes))>(
+ test_impl::<((u8,), (String, Bytes), (u8, Bytes))>(
0xdeadbeef,
((int,), (string.clone(), by.clone()), (int, by)),
&hex!(
@@ -485,9 +485,9 @@
#[test]
fn encode_decode_tuple0_tuple1_string_bytes() {
- test_impl::<((String, bytes),)>(
+ test_impl::<((String, Bytes),)>(
0xdeadbeef,
- (("some string".to_string(), bytes(vec![1, 2, 3])),),
+ (("some string".to_string(), Bytes(vec![1, 2, 3])),),
&hex!(
"
deadbeef
crates/evm-coder/src/lib.rsdiffbeforeafterboth--- a/crates/evm-coder/src/lib.rs
+++ b/crates/evm-coder/src/lib.rs
@@ -141,7 +141,7 @@
pub type String = ::std::string::String;
#[derive(Default, Debug, PartialEq, Eq, Clone)]
- pub struct bytes(pub Vec<u8>);
+ pub struct Bytes(pub Vec<u8>);
//#region Special types
/// Makes function payable
@@ -162,20 +162,20 @@
pub value: U256,
}
- impl From<Vec<u8>> for bytes {
+ impl From<Vec<u8>> for Bytes {
fn from(src: Vec<u8>) -> Self {
Self(src)
}
}
#[allow(clippy::from_over_into)]
- impl Into<Vec<u8>> for bytes {
+ impl Into<Vec<u8>> for Bytes {
fn into(self) -> Vec<u8> {
self.0
}
}
- impl bytes {
+ impl Bytes {
#[must_use]
pub fn len(&self) -> usize {
self.0.len()
crates/evm-coder/src/solidity/impls.rsdiffbeforeafterboth--- a/crates/evm-coder/src/solidity/impls.rs
+++ b/crates/evm-coder/src/solidity/impls.rs
@@ -30,7 +30,7 @@
Bytes4 => "bytes4" true = "bytes4(0)",
H160 => "address" true = "0x0000000000000000000000000000000000000000",
String => "string" false = "\"\"",
- bytes => "bytes" false = "hex\"\"",
+ Bytes => "bytes" false = "hex\"\"",
bool => "bool" true = "false",
}
crates/evm-coder/tests/abi_derive_generation.rsdiffbeforeafterboth--- a/crates/evm-coder/tests/abi_derive_generation.rs
+++ b/crates/evm-coder/tests/abi_derive_generation.rs
@@ -1,6 +1,6 @@
mod test_struct {
use evm_coder_procedural::AbiCoder;
- use evm_coder::types::bytes;
+ use evm_coder::types::Bytes;
#[test]
fn empty_struct() {
@@ -27,13 +27,13 @@
#[derive(AbiCoder, PartialEq, Debug)]
struct TypeStruct2DynamicParam {
_a: String,
- _b: bytes,
+ _b: Bytes,
}
#[derive(AbiCoder, PartialEq, Debug)]
struct TypeStruct2MixedParam {
_a: u8,
- _b: bytes,
+ _b: Bytes,
}
#[derive(AbiCoder, PartialEq, Debug)]
@@ -236,10 +236,10 @@
struct TupleStruct2SimpleParam(u8, u32);
#[derive(AbiCoder, PartialEq, Debug)]
- struct TupleStruct2DynamicParam(String, bytes);
+ struct TupleStruct2DynamicParam(String, Bytes);
#[derive(AbiCoder, PartialEq, Debug)]
- struct TupleStruct2MixedParam(u8, bytes);
+ struct TupleStruct2MixedParam(u8, Bytes);
#[derive(AbiCoder, PartialEq, Debug)]
struct TupleStruct1DerivedSimpleParam(TupleStruct1SimpleParam);
@@ -562,8 +562,8 @@
#[test]
fn codec_struct_2_dynamic() {
let _a: String = "some string".into();
- let _b: bytes = bytes(vec![0x11, 0x22, 0x33]);
- test_impl::<(String, bytes), TupleStruct2DynamicParam, TypeStruct2DynamicParam>(
+ let _b: Bytes = Bytes(vec![0x11, 0x22, 0x33]);
+ test_impl::<(String, Bytes), TupleStruct2DynamicParam, TypeStruct2DynamicParam>(
(_a.clone(), _b.clone()),
TupleStruct2DynamicParam(_a.clone(), _b.clone()),
TypeStruct2DynamicParam { _a, _b },
@@ -573,8 +573,8 @@
#[test]
fn codec_struct_2_mixed() {
let _a: u8 = 0xff;
- let _b: bytes = bytes(vec![0x11, 0x22, 0x33]);
- test_impl::<(u8, bytes), TupleStruct2MixedParam, TypeStruct2MixedParam>(
+ let _b: Bytes = Bytes(vec![0x11, 0x22, 0x33]);
+ test_impl::<(u8, Bytes), TupleStruct2MixedParam, TypeStruct2MixedParam>(
(_a.clone(), _b.clone()),
TupleStruct2MixedParam(_a.clone(), _b.clone()),
TypeStruct2MixedParam { _a, _b },
@@ -605,9 +605,9 @@
#[test]
fn codec_struct_2_derived_dynamic() {
let _a = "some string".to_string();
- let _b = bytes(vec![0x11, 0x22, 0x33]);
+ let _b = Bytes(vec![0x11, 0x22, 0x33]);
test_impl::<
- ((String,), (String, bytes)),
+ ((String,), (String, Bytes)),
TupleStruct2DerivedDynamicParam,
TypeStruct2DerivedDynamicParam,
>(
@@ -626,10 +626,10 @@
#[test]
fn codec_struct_3_derived_mixed() {
let int = 0xff;
- let by = bytes(vec![0x11, 0x22, 0x33]);
+ let by = Bytes(vec![0x11, 0x22, 0x33]);
let string = "some string".to_string();
test_impl::<
- ((u8,), (String, bytes), (u8, bytes)),
+ ((u8,), (String, Bytes), (u8, Bytes)),
TupleStruct3DerivedMixedParam,
TypeStruct3DerivedMixedParam,
>(
pallets/common/src/erc.rsdiffbeforeafterboth--- a/pallets/common/src/erc.rs
+++ b/pallets/common/src/erc.rs
@@ -94,7 +94,7 @@
/// @param value Propery value.
#[solidity(hide)]
#[weight(<SelfWeightOf<T>>::set_collection_properties(1))]
- fn set_collection_property(&mut self, caller: caller, key: String, value: bytes) -> Result<()> {
+ fn set_collection_property(&mut self, caller: caller, key: String, value: Bytes) -> Result<()> {
let caller = T::CrossAccountId::from_eth(caller);
let key = <Vec<u8>>::from(key)
.try_into()
@@ -164,7 +164,7 @@
///
/// @param key Property key.
/// @return bytes The property corresponding to the key.
- fn collection_property(&self, key: String) -> Result<bytes> {
+ fn collection_property(&self, key: String) -> Result<Bytes> {
let key = <Vec<u8>>::from(key)
.try_into()
.map_err(|_| "key too large")?;
@@ -172,7 +172,7 @@
let props = CollectionProperties::<T>::get(self.id);
let prop = props.get(&key).ok_or("key not found")?;
- Ok(bytes(prop.to_vec()))
+ Ok(Bytes(prop.to_vec()))
}
/// Get collection properties.
pallets/common/src/eth.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//! The module contains a number of functions for converting and checking ethereum identifiers.1819use alloc::format;20use sp_std::{vec, vec::Vec};21use evm_coder::{AbiCoder, types::Address};22pub use pallet_evm::{Config, account::CrossAccountId};23use sp_core::{H160, U256};24use up_data_structs::CollectionId;2526// 0x17c4e6453Cc49AAAaEACA894e6D9683e00000001 - collection 127// TODO: Unhardcode prefix28const ETH_COLLECTION_PREFIX: [u8; 16] = [29 0x17, 0xc4, 0xe6, 0x45, 0x3c, 0xc4, 0x9a, 0xaa, 0xae, 0xac, 0xa8, 0x94, 0xe6, 0xd9, 0x68, 0x3e,30];3132/// Maps the ethereum address of the collection in substrate.33pub fn map_eth_to_id(eth: &Address) -> Option<CollectionId> {34 if eth[0..16] != ETH_COLLECTION_PREFIX {35 return None;36 }37 let mut id_bytes = [0; 4];38 id_bytes.copy_from_slice(ð[16..20]);39 Some(CollectionId(u32::from_be_bytes(id_bytes)))40}4142/// Maps the substrate collection id in ethereum.43pub fn collection_id_to_address(id: CollectionId) -> Address {44 let mut out = [0; 20];45 out[0..16].copy_from_slice(Ð_COLLECTION_PREFIX);46 out[16..20].copy_from_slice(&u32::to_be_bytes(id.0));47 H160(out)48}4950/// Check if the ethereum address is a collection.51pub fn is_collection(address: &Address) -> bool {52 address[0..16] == ETH_COLLECTION_PREFIX53}5455/// Convert `U256` to `CrossAccountId`.56pub fn convert_uint256_to_cross_account<T: Config>(from: U256) -> T::CrossAccountId57where58 T::AccountId: From<[u8; 32]>,59{60 let mut new_admin_arr = [0_u8; 32];61 from.to_big_endian(&mut new_admin_arr);62 let account_id = T::AccountId::from(new_admin_arr);63 T::CrossAccountId::from_sub(account_id)64}6566/// Cross account struct67#[derive(Debug, Default, AbiCoder)]68pub struct CrossAddress {69 pub(crate) eth: Address,70 pub(crate) sub: U256,71}7273impl CrossAddress {74 /// Converts `CrossAccountId` to [`CrossAddress`] to be correctly usable with Ethereum.75 pub fn from_sub_cross_account<T>(cross_account_id: &T::CrossAccountId) -> Self76 where77 T: pallet_evm::Config,78 T::AccountId: AsRef<[u8; 32]>,79 {80 if cross_account_id.is_canonical_substrate() {81 Self::from_sub::<T>(cross_account_id.as_sub())82 } else {83 Self {84 eth: *cross_account_id.as_eth(),85 sub: Default::default(),86 }87 }88 }89 /// Creates [`CrossAddress`] from Substrate account.90 pub fn from_sub<T>(account_id: &T::AccountId) -> Self91 where92 T: pallet_evm::Config,93 T::AccountId: AsRef<[u8; 32]>,94 {95 Self {96 eth: Default::default(),97 sub: U256::from_big_endian(account_id.as_ref()),98 }99 }100 /// Converts [`CrossAddress`] to `CrossAccountId`.101 pub fn into_sub_cross_account<T>(&self) -> evm_coder::execution::Result<T::CrossAccountId>102 where103 T: pallet_evm::Config,104 T::AccountId: From<[u8; 32]>,105 {106 if self.eth == Default::default() && self.sub == Default::default() {107 Err("All fields of cross account is zeroed".into())108 } else if self.eth == Default::default() {109 Ok(convert_uint256_to_cross_account::<T>(self.sub))110 } else if self.sub == Default::default() {111 Ok(T::CrossAccountId::from_eth(self.eth))112 } else {113 Err("All fields of cross account is non zeroed".into())114 }115 }116}117118/// Ethereum representation of collection [`PropertyKey`](up_data_structs::PropertyKey) and [`PropertyValue`](up_data_structs::PropertyValue).119#[derive(Debug, Default, AbiCoder)]120pub struct Property {121 key: evm_coder::types::String,122 value: evm_coder::types::bytes,123}124125impl TryFrom<up_data_structs::Property> for Property {126 type Error = evm_coder::execution::Error;127128 fn try_from(from: up_data_structs::Property) -> Result<Self, Self::Error> {129 let key = evm_coder::types::String::from_utf8(from.key.into())130 .map_err(|e| Self::Error::Revert(format!("utf8 conversion error: {}", e)))?;131 let value = evm_coder::types::bytes(from.value.to_vec());132 Ok(Property { key, value })133 }134}135136impl TryInto<up_data_structs::Property> for Property {137 type Error = evm_coder::execution::Error;138139 fn try_into(self) -> Result<up_data_structs::Property, Self::Error> {140 let key = <Vec<u8>>::from(self.key)141 .try_into()142 .map_err(|_| "key too large")?;143144 let value = self.value.0.try_into().map_err(|_| "value too large")?;145146 Ok(up_data_structs::Property { key, value })147 }148}149150/// [`CollectionLimits`](up_data_structs::CollectionLimits) fields representation for EVM.151#[derive(Debug, Default, Clone, Copy, AbiCoder)]152#[repr(u8)]153pub enum CollectionLimitField {154 /// How many tokens can a user have on one account.155 #[default]156 AccountTokenOwnership,157158 /// How many bytes of data are available for sponsorship.159 SponsoredDataSize,160161 /// In any case, chain default: [`SponsoringRateLimit::SponsoringDisabled`]162 SponsoredDataRateLimit,163164 /// How many tokens can be mined into this collection.165 TokenLimit,166167 /// Timeouts for transfer sponsoring.168 SponsorTransferTimeout,169170 /// Timeout for sponsoring an approval in passed blocks.171 SponsorApproveTimeout,172173 /// Whether the collection owner of the collection can send tokens (which belong to other users).174 OwnerCanTransfer,175176 /// Can the collection owner burn other people's tokens.177 OwnerCanDestroy,178179 /// Is it possible to send tokens from this collection between users.180 TransferEnabled,181}182183/// [`CollectionLimits`](up_data_structs::CollectionLimits) field representation for EVM.184#[derive(Debug, Default, AbiCoder)]185pub struct CollectionLimit {186 field: CollectionLimitField,187 value: Option<U256>,188}189190impl CollectionLimit {191 /// Create [`CollectionLimit`] from field and value.192 pub fn new(field: CollectionLimitField, value: Option<u32>) -> Self {193 Self {194 field,195 value: match value {196 Some(value) => Some(value.into()),197 None => None,198 },199 }200 }201 /// Whether the field contains a value.202 pub fn has_value(&self) -> bool {203 self.value.is_some()204 }205}206207impl TryInto<up_data_structs::CollectionLimits> for CollectionLimit {208 type Error = evm_coder::execution::Error;209210 fn try_into(self) -> Result<up_data_structs::CollectionLimits, Self::Error> {211 let value = self212 .value213 .ok_or::<Self::Error>("can't convert `None` value to boolean".into())?;214 let value = Some(value.try_into().map_err(|error| {215 Self::Error::Revert(format!(216 "can't convert value to u32 \"{}\" because: \"{error}\"",217 value218 ))219 })?);220221 let convert_value_to_bool = || match value {222 Some(value) => match value {223 0 => Ok(Some(false)),224 1 => Ok(Some(true)),225 _ => {226 return Err(Self::Error::Revert(format!(227 "can't convert value to boolean \"{value}\""228 )))229 }230 },231 None => Ok(None),232 };233234 let mut limits = up_data_structs::CollectionLimits::default();235 match self.field {236 CollectionLimitField::AccountTokenOwnership => {237 limits.account_token_ownership_limit = value;238 }239 CollectionLimitField::SponsoredDataSize => {240 limits.sponsored_data_size = value;241 }242 CollectionLimitField::SponsoredDataRateLimit => {243 limits.sponsored_data_rate_limit = match value {244 Some(value) => Some(up_data_structs::SponsoringRateLimit::Blocks(value)),245 None => None,246 };247 }248 CollectionLimitField::TokenLimit => {249 limits.token_limit = value;250 }251 CollectionLimitField::SponsorTransferTimeout => {252 limits.sponsor_transfer_timeout = value;253 }254 CollectionLimitField::SponsorApproveTimeout => {255 limits.sponsor_approve_timeout = value;256 }257 CollectionLimitField::OwnerCanTransfer => {258 limits.owner_can_transfer = convert_value_to_bool()?;259 }260 CollectionLimitField::OwnerCanDestroy => {261 limits.owner_can_destroy = convert_value_to_bool()?;262 }263 CollectionLimitField::TransferEnabled => {264 limits.transfers_enabled = convert_value_to_bool()?;265 }266 };267 Ok(limits)268 }269}270271/// Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) fields as an enumeration.272#[derive(Default, Debug, Clone, Copy, AbiCoder)]273#[repr(u8)]274pub enum CollectionPermissionField {275 /// Owner of token can nest tokens under it.276 #[default]277 TokenOwner,278279 /// Admin of token collection can nest tokens under token.280 CollectionAdmin,281}282283/// Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) fields as an enumeration.284#[derive(AbiCoder, Copy, Clone, Default, Debug)]285#[repr(u8)]286pub enum TokenPermissionField {287 /// Permission to change the property and property permission. See [`up_data_structs::PropertyPermission::mutable`]288 #[default]289 Mutable,290291 /// Change permission for the collection administrator. See [`up_data_structs::PropertyPermission::token_owner`]292 TokenOwner,293294 /// Permission to change the property for the owner of the token. See [`up_data_structs::PropertyPermission::collection_admin`]295 CollectionAdmin,296}297298/// Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) as an key and value.299#[derive(Debug, Default, AbiCoder)]300pub struct PropertyPermission {301 /// TokenPermission field.302 code: TokenPermissionField,303 /// TokenPermission value.304 value: bool,305}306307impl PropertyPermission {308 /// Make vector of [`PropertyPermission`] from [`up_data_structs::PropertyPermission`].309 pub fn into_vec(pp: up_data_structs::PropertyPermission) -> Vec<Self> {310 vec![311 PropertyPermission {312 code: TokenPermissionField::Mutable,313 value: pp.mutable,314 },315 PropertyPermission {316 code: TokenPermissionField::TokenOwner,317 value: pp.token_owner,318 },319 PropertyPermission {320 code: TokenPermissionField::CollectionAdmin,321 value: pp.collection_admin,322 },323 ]324 }325326 /// Make [`up_data_structs::PropertyPermission`] from vector of [`PropertyPermission`].327 pub fn from_vec(permission: Vec<Self>) -> up_data_structs::PropertyPermission {328 let mut token_permission = up_data_structs::PropertyPermission::default();329330 for PropertyPermission { code, value } in permission {331 match code {332 TokenPermissionField::Mutable => token_permission.mutable = value,333 TokenPermissionField::TokenOwner => token_permission.token_owner = value,334 TokenPermissionField::CollectionAdmin => token_permission.collection_admin = value,335 }336 }337 token_permission338 }339}340341/// Ethereum representation of Token Property Permissions.342#[derive(Debug, Default, AbiCoder)]343pub struct TokenPropertyPermission {344 /// Token property key.345 key: evm_coder::types::String,346 /// Token property permissions.347 permissions: Vec<PropertyPermission>,348}349350impl351 From<(352 up_data_structs::PropertyKey,353 up_data_structs::PropertyPermission,354 )> for TokenPropertyPermission355{356 fn from(357 value: (358 up_data_structs::PropertyKey,359 up_data_structs::PropertyPermission,360 ),361 ) -> Self {362 let (key, permission) = value;363 let key = evm_coder::types::String::from_utf8(key.into_inner())364 .expect("Stored key must be valid");365 let permissions = PropertyPermission::into_vec(permission);366 Self { key, permissions }367 }368}369370impl TokenPropertyPermission {371 /// Convert vector of [`TokenPropertyPermission`] into vector of [`up_data_structs::PropertyKeyPermission`].372 pub fn into_property_key_permissions(373 permissions: Vec<TokenPropertyPermission>,374 ) -> evm_coder::execution::Result<Vec<up_data_structs::PropertyKeyPermission>> {375 let mut perms = Vec::new();376377 for TokenPropertyPermission { key, permissions } in permissions {378 let token_permission = PropertyPermission::from_vec(permissions);379380 perms.push(up_data_structs::PropertyKeyPermission {381 key: key.into_bytes().try_into().map_err(|_| "too long key")?,382 permission: token_permission,383 });384 }385 Ok(perms)386 }387}388389/// Nested collections.390#[derive(Debug, Default, AbiCoder)]391pub struct CollectionNesting {392 token_owner: bool,393 ids: Vec<U256>,394}395396impl CollectionNesting {397 /// Create [`CollectionNesting`].398 pub fn new(token_owner: bool, ids: Vec<U256>) -> Self {399 Self { token_owner, ids }400 }401}402403/// Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) field.404#[derive(Debug, Default, AbiCoder)]405pub struct CollectionNestingPermission {406 field: CollectionPermissionField,407 value: bool,408}409410impl CollectionNestingPermission {411 /// Create [`CollectionNestingPermission`].412 pub fn new(field: CollectionPermissionField, value: bool) -> Self {413 Self { field, value }414 }415}416417/// Ethereum representation of `AccessMode` (see [`up_data_structs::AccessMode`]).418#[derive(AbiCoder, Copy, Clone, Default, Debug)]419#[repr(u8)]420pub enum AccessMode {421 /// Access grant for owner and admins. Used as default.422 #[default]423 Normal,424 /// Like a [`Normal`](AccessMode::Normal) but also users in allow list.425 AllowList,426}427428impl From<up_data_structs::AccessMode> for AccessMode {429 fn from(value: up_data_structs::AccessMode) -> Self {430 match value {431 up_data_structs::AccessMode::Normal => AccessMode::Normal,432 up_data_structs::AccessMode::AllowList => AccessMode::AllowList,433 }434 }435}436437impl Into<up_data_structs::AccessMode> for AccessMode {438 fn into(self) -> up_data_structs::AccessMode {439 match self {440 AccessMode::Normal => up_data_structs::AccessMode::Normal,441 AccessMode::AllowList => up_data_structs::AccessMode::AllowList,442 }443 }444}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//! The module contains a number of functions for converting and checking ethereum identifiers.1819use alloc::format;20use sp_std::{vec, vec::Vec};21use evm_coder::{AbiCoder, types::Address};22pub use pallet_evm::{Config, account::CrossAccountId};23use sp_core::{H160, U256};24use up_data_structs::CollectionId;2526// 0x17c4e6453Cc49AAAaEACA894e6D9683e00000001 - collection 127// TODO: Unhardcode prefix28const ETH_COLLECTION_PREFIX: [u8; 16] = [29 0x17, 0xc4, 0xe6, 0x45, 0x3c, 0xc4, 0x9a, 0xaa, 0xae, 0xac, 0xa8, 0x94, 0xe6, 0xd9, 0x68, 0x3e,30];3132/// Maps the ethereum address of the collection in substrate.33pub fn map_eth_to_id(eth: &Address) -> Option<CollectionId> {34 if eth[0..16] != ETH_COLLECTION_PREFIX {35 return None;36 }37 let mut id_bytes = [0; 4];38 id_bytes.copy_from_slice(ð[16..20]);39 Some(CollectionId(u32::from_be_bytes(id_bytes)))40}4142/// Maps the substrate collection id in ethereum.43pub fn collection_id_to_address(id: CollectionId) -> Address {44 let mut out = [0; 20];45 out[0..16].copy_from_slice(Ð_COLLECTION_PREFIX);46 out[16..20].copy_from_slice(&u32::to_be_bytes(id.0));47 H160(out)48}4950/// Check if the ethereum address is a collection.51pub fn is_collection(address: &Address) -> bool {52 address[0..16] == ETH_COLLECTION_PREFIX53}5455/// Convert `U256` to `CrossAccountId`.56pub fn convert_uint256_to_cross_account<T: Config>(from: U256) -> T::CrossAccountId57where58 T::AccountId: From<[u8; 32]>,59{60 let mut new_admin_arr = [0_u8; 32];61 from.to_big_endian(&mut new_admin_arr);62 let account_id = T::AccountId::from(new_admin_arr);63 T::CrossAccountId::from_sub(account_id)64}6566/// Cross account struct67#[derive(Debug, Default, AbiCoder)]68pub struct CrossAddress {69 pub(crate) eth: Address,70 pub(crate) sub: U256,71}7273impl CrossAddress {74 /// Converts `CrossAccountId` to [`CrossAddress`] to be correctly usable with Ethereum.75 pub fn from_sub_cross_account<T>(cross_account_id: &T::CrossAccountId) -> Self76 where77 T: pallet_evm::Config,78 T::AccountId: AsRef<[u8; 32]>,79 {80 if cross_account_id.is_canonical_substrate() {81 Self::from_sub::<T>(cross_account_id.as_sub())82 } else {83 Self {84 eth: *cross_account_id.as_eth(),85 sub: Default::default(),86 }87 }88 }89 /// Creates [`CrossAddress`] from Substrate account.90 pub fn from_sub<T>(account_id: &T::AccountId) -> Self91 where92 T: pallet_evm::Config,93 T::AccountId: AsRef<[u8; 32]>,94 {95 Self {96 eth: Default::default(),97 sub: U256::from_big_endian(account_id.as_ref()),98 }99 }100 /// Converts [`CrossAddress`] to `CrossAccountId`.101 pub fn into_sub_cross_account<T>(&self) -> evm_coder::execution::Result<T::CrossAccountId>102 where103 T: pallet_evm::Config,104 T::AccountId: From<[u8; 32]>,105 {106 if self.eth == Default::default() && self.sub == Default::default() {107 Err("All fields of cross account is zeroed".into())108 } else if self.eth == Default::default() {109 Ok(convert_uint256_to_cross_account::<T>(self.sub))110 } else if self.sub == Default::default() {111 Ok(T::CrossAccountId::from_eth(self.eth))112 } else {113 Err("All fields of cross account is non zeroed".into())114 }115 }116}117118/// Ethereum representation of collection [`PropertyKey`](up_data_structs::PropertyKey) and [`PropertyValue`](up_data_structs::PropertyValue).119#[derive(Debug, Default, AbiCoder)]120pub struct Property {121 key: evm_coder::types::String,122 value: evm_coder::types::Bytes,123}124125impl TryFrom<up_data_structs::Property> for Property {126 type Error = evm_coder::execution::Error;127128 fn try_from(from: up_data_structs::Property) -> Result<Self, Self::Error> {129 let key = evm_coder::types::String::from_utf8(from.key.into())130 .map_err(|e| Self::Error::Revert(format!("utf8 conversion error: {}", e)))?;131 let value = evm_coder::types::Bytes(from.value.to_vec());132 Ok(Property { key, value })133 }134}135136impl TryInto<up_data_structs::Property> for Property {137 type Error = evm_coder::execution::Error;138139 fn try_into(self) -> Result<up_data_structs::Property, Self::Error> {140 let key = <Vec<u8>>::from(self.key)141 .try_into()142 .map_err(|_| "key too large")?;143144 let value = self.value.0.try_into().map_err(|_| "value too large")?;145146 Ok(up_data_structs::Property { key, value })147 }148}149150/// [`CollectionLimits`](up_data_structs::CollectionLimits) fields representation for EVM.151#[derive(Debug, Default, Clone, Copy, AbiCoder)]152#[repr(u8)]153pub enum CollectionLimitField {154 /// How many tokens can a user have on one account.155 #[default]156 AccountTokenOwnership,157158 /// How many bytes of data are available for sponsorship.159 SponsoredDataSize,160161 /// In any case, chain default: [`SponsoringRateLimit::SponsoringDisabled`]162 SponsoredDataRateLimit,163164 /// How many tokens can be mined into this collection.165 TokenLimit,166167 /// Timeouts for transfer sponsoring.168 SponsorTransferTimeout,169170 /// Timeout for sponsoring an approval in passed blocks.171 SponsorApproveTimeout,172173 /// Whether the collection owner of the collection can send tokens (which belong to other users).174 OwnerCanTransfer,175176 /// Can the collection owner burn other people's tokens.177 OwnerCanDestroy,178179 /// Is it possible to send tokens from this collection between users.180 TransferEnabled,181}182183/// [`CollectionLimits`](up_data_structs::CollectionLimits) field representation for EVM.184#[derive(Debug, Default, AbiCoder)]185pub struct CollectionLimit {186 field: CollectionLimitField,187 value: Option<U256>,188}189190impl CollectionLimit {191 /// Create [`CollectionLimit`] from field and value.192 pub fn new(field: CollectionLimitField, value: Option<u32>) -> Self {193 Self {194 field,195 value: match value {196 Some(value) => Some(value.into()),197 None => None,198 },199 }200 }201 /// Whether the field contains a value.202 pub fn has_value(&self) -> bool {203 self.value.is_some()204 }205}206207impl TryInto<up_data_structs::CollectionLimits> for CollectionLimit {208 type Error = evm_coder::execution::Error;209210 fn try_into(self) -> Result<up_data_structs::CollectionLimits, Self::Error> {211 let value = self212 .value213 .ok_or::<Self::Error>("can't convert `None` value to boolean".into())?;214 let value = Some(value.try_into().map_err(|error| {215 Self::Error::Revert(format!(216 "can't convert value to u32 \"{}\" because: \"{error}\"",217 value218 ))219 })?);220221 let convert_value_to_bool = || match value {222 Some(value) => match value {223 0 => Ok(Some(false)),224 1 => Ok(Some(true)),225 _ => {226 return Err(Self::Error::Revert(format!(227 "can't convert value to boolean \"{value}\""228 )))229 }230 },231 None => Ok(None),232 };233234 let mut limits = up_data_structs::CollectionLimits::default();235 match self.field {236 CollectionLimitField::AccountTokenOwnership => {237 limits.account_token_ownership_limit = value;238 }239 CollectionLimitField::SponsoredDataSize => {240 limits.sponsored_data_size = value;241 }242 CollectionLimitField::SponsoredDataRateLimit => {243 limits.sponsored_data_rate_limit = match value {244 Some(value) => Some(up_data_structs::SponsoringRateLimit::Blocks(value)),245 None => None,246 };247 }248 CollectionLimitField::TokenLimit => {249 limits.token_limit = value;250 }251 CollectionLimitField::SponsorTransferTimeout => {252 limits.sponsor_transfer_timeout = value;253 }254 CollectionLimitField::SponsorApproveTimeout => {255 limits.sponsor_approve_timeout = value;256 }257 CollectionLimitField::OwnerCanTransfer => {258 limits.owner_can_transfer = convert_value_to_bool()?;259 }260 CollectionLimitField::OwnerCanDestroy => {261 limits.owner_can_destroy = convert_value_to_bool()?;262 }263 CollectionLimitField::TransferEnabled => {264 limits.transfers_enabled = convert_value_to_bool()?;265 }266 };267 Ok(limits)268 }269}270271/// Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) fields as an enumeration.272#[derive(Default, Debug, Clone, Copy, AbiCoder)]273#[repr(u8)]274pub enum CollectionPermissionField {275 /// Owner of token can nest tokens under it.276 #[default]277 TokenOwner,278279 /// Admin of token collection can nest tokens under token.280 CollectionAdmin,281}282283/// Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) fields as an enumeration.284#[derive(AbiCoder, Copy, Clone, Default, Debug)]285#[repr(u8)]286pub enum TokenPermissionField {287 /// Permission to change the property and property permission. See [`up_data_structs::PropertyPermission::mutable`]288 #[default]289 Mutable,290291 /// Change permission for the collection administrator. See [`up_data_structs::PropertyPermission::token_owner`]292 TokenOwner,293294 /// Permission to change the property for the owner of the token. See [`up_data_structs::PropertyPermission::collection_admin`]295 CollectionAdmin,296}297298/// Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) as an key and value.299#[derive(Debug, Default, AbiCoder)]300pub struct PropertyPermission {301 /// TokenPermission field.302 code: TokenPermissionField,303 /// TokenPermission value.304 value: bool,305}306307impl PropertyPermission {308 /// Make vector of [`PropertyPermission`] from [`up_data_structs::PropertyPermission`].309 pub fn into_vec(pp: up_data_structs::PropertyPermission) -> Vec<Self> {310 vec![311 PropertyPermission {312 code: TokenPermissionField::Mutable,313 value: pp.mutable,314 },315 PropertyPermission {316 code: TokenPermissionField::TokenOwner,317 value: pp.token_owner,318 },319 PropertyPermission {320 code: TokenPermissionField::CollectionAdmin,321 value: pp.collection_admin,322 },323 ]324 }325326 /// Make [`up_data_structs::PropertyPermission`] from vector of [`PropertyPermission`].327 pub fn from_vec(permission: Vec<Self>) -> up_data_structs::PropertyPermission {328 let mut token_permission = up_data_structs::PropertyPermission::default();329330 for PropertyPermission { code, value } in permission {331 match code {332 TokenPermissionField::Mutable => token_permission.mutable = value,333 TokenPermissionField::TokenOwner => token_permission.token_owner = value,334 TokenPermissionField::CollectionAdmin => token_permission.collection_admin = value,335 }336 }337 token_permission338 }339}340341/// Ethereum representation of Token Property Permissions.342#[derive(Debug, Default, AbiCoder)]343pub struct TokenPropertyPermission {344 /// Token property key.345 key: evm_coder::types::String,346 /// Token property permissions.347 permissions: Vec<PropertyPermission>,348}349350impl351 From<(352 up_data_structs::PropertyKey,353 up_data_structs::PropertyPermission,354 )> for TokenPropertyPermission355{356 fn from(357 value: (358 up_data_structs::PropertyKey,359 up_data_structs::PropertyPermission,360 ),361 ) -> Self {362 let (key, permission) = value;363 let key = evm_coder::types::String::from_utf8(key.into_inner())364 .expect("Stored key must be valid");365 let permissions = PropertyPermission::into_vec(permission);366 Self { key, permissions }367 }368}369370impl TokenPropertyPermission {371 /// Convert vector of [`TokenPropertyPermission`] into vector of [`up_data_structs::PropertyKeyPermission`].372 pub fn into_property_key_permissions(373 permissions: Vec<TokenPropertyPermission>,374 ) -> evm_coder::execution::Result<Vec<up_data_structs::PropertyKeyPermission>> {375 let mut perms = Vec::new();376377 for TokenPropertyPermission { key, permissions } in permissions {378 let token_permission = PropertyPermission::from_vec(permissions);379380 perms.push(up_data_structs::PropertyKeyPermission {381 key: key.into_bytes().try_into().map_err(|_| "too long key")?,382 permission: token_permission,383 });384 }385 Ok(perms)386 }387}388389/// Nested collections.390#[derive(Debug, Default, AbiCoder)]391pub struct CollectionNesting {392 token_owner: bool,393 ids: Vec<U256>,394}395396impl CollectionNesting {397 /// Create [`CollectionNesting`].398 pub fn new(token_owner: bool, ids: Vec<U256>) -> Self {399 Self { token_owner, ids }400 }401}402403/// Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) field.404#[derive(Debug, Default, AbiCoder)]405pub struct CollectionNestingPermission {406 field: CollectionPermissionField,407 value: bool,408}409410impl CollectionNestingPermission {411 /// Create [`CollectionNestingPermission`].412 pub fn new(field: CollectionPermissionField, value: bool) -> Self {413 Self { field, value }414 }415}416417/// Ethereum representation of `AccessMode` (see [`up_data_structs::AccessMode`]).418#[derive(AbiCoder, Copy, Clone, Default, Debug)]419#[repr(u8)]420pub enum AccessMode {421 /// Access grant for owner and admins. Used as default.422 #[default]423 Normal,424 /// Like a [`Normal`](AccessMode::Normal) but also users in allow list.425 AllowList,426}427428impl From<up_data_structs::AccessMode> for AccessMode {429 fn from(value: up_data_structs::AccessMode) -> Self {430 match value {431 up_data_structs::AccessMode::Normal => AccessMode::Normal,432 up_data_structs::AccessMode::AllowList => AccessMode::AllowList,433 }434 }435}436437impl Into<up_data_structs::AccessMode> for AccessMode {438 fn into(self) -> up_data_structs::AccessMode {439 match self {440 AccessMode::Normal => up_data_structs::AccessMode::Normal,441 AccessMode::AllowList => up_data_structs::AccessMode::AllowList,442 }443 }444}pallets/nonfungible/src/erc.rsdiffbeforeafterboth--- a/pallets/nonfungible/src/erc.rs
+++ b/pallets/nonfungible/src/erc.rs
@@ -124,7 +124,7 @@
caller: caller,
token_id: U256,
key: String,
- value: bytes,
+ value: Bytes,
) -> Result<()> {
let caller = T::CrossAccountId::from_eth(caller);
let token_id: u32 = token_id.try_into().map_err(|_| "token id overflow")?;
@@ -239,7 +239,7 @@
/// @param tokenId ID of the token.
/// @param key Property key.
/// @return Property value bytes
- fn property(&self, token_id: U256, key: String) -> Result<bytes> {
+ fn property(&self, token_id: U256, key: String) -> Result<Bytes> {
let token_id: u32 = token_id.try_into().map_err(|_| "token id overflow")?;
let key = <Vec<u8>>::from(key)
.try_into()
@@ -422,7 +422,7 @@
_from: Address,
_to: Address,
_token_id: U256,
- _data: bytes,
+ _data: Bytes,
) -> Result<()> {
// TODO: Not implemetable
Err("not implemented".into())
pallets/refungible/src/erc.rsdiffbeforeafterboth--- a/pallets/refungible/src/erc.rs
+++ b/pallets/refungible/src/erc.rs
@@ -127,7 +127,7 @@
caller: caller,
token_id: U256,
key: String,
- value: bytes,
+ value: Bytes,
) -> Result<()> {
let caller = T::CrossAccountId::from_eth(caller);
let token_id: u32 = token_id.try_into().map_err(|_| "token id overflow")?;
@@ -242,7 +242,7 @@
/// @param tokenId ID of the token.
/// @param key Property key.
/// @return Property value bytes
- fn property(&self, token_id: U256, key: String) -> Result<bytes> {
+ fn property(&self, token_id: U256, key: String) -> Result<Bytes> {
let token_id: u32 = token_id.try_into().map_err(|_| "token id overflow")?;
let key = <Vec<u8>>::from(key)
.try_into()
@@ -423,7 +423,7 @@
_from: Address,
_to: Address,
_token_id: U256,
- _data: bytes,
+ _data: Bytes,
) -> Result<()> {
// TODO: Not implemetable
Err("not implemented".into())