difftreelog
feat Rewrite tuple to named structures for TokenPropertyPermission. fix: AbiCoder derive macro
in: master
23 files changed
crates/evm-coder/procedural/src/abi_derive/derive_enum.rsdiffbeforeafterboth--- a/crates/evm-coder/procedural/src/abi_derive/derive_enum.rs
+++ b/crates/evm-coder/procedural/src/abi_derive/derive_enum.rs
@@ -86,6 +86,21 @@
)
}
+pub fn impl_enum_solidity_type<'a>(name: &syn::Ident) -> proc_macro2::TokenStream {
+ quote! {
+ #[cfg(feature = "stubgen")]
+ impl ::evm_coder::solidity::SolidityType for #name {
+ fn names(tc: &::evm_coder::solidity::TypeCollector) -> Vec<String> {
+ Vec::new()
+ }
+
+ fn len() -> usize {
+ 1
+ }
+ }
+ }
+}
+
pub fn impl_enum_solidity_type_name(name: &syn::Ident) -> proc_macro2::TokenStream {
quote!(
#[cfg(feature = "stubgen")]
crates/evm-coder/procedural/src/abi_derive/mod.rsdiffbeforeafterboth--- a/crates/evm-coder/procedural/src/abi_derive/mod.rs
+++ b/crates/evm-coder/procedural/src/abi_derive/mod.rs
@@ -86,6 +86,7 @@
let abi_type = impl_enum_abi_type(name, option_count);
let abi_read = impl_enum_abi_read(name);
let abi_write = impl_enum_abi_write(name);
+ let solidity_type = impl_enum_solidity_type(name);
let solidity_type_name = impl_enum_solidity_type_name(name);
let solidity_struct_collect = impl_enum_solidity_struct_collect(
name,
@@ -102,6 +103,7 @@
#abi_type
#abi_read
#abi_write
+ #solidity_type
#solidity_type_name
#solidity_struct_collect
})
crates/evm-coder/src/abi/impls.rsdiffbeforeafterboth--- a/crates/evm-coder/src/abi/impls.rs
+++ b/crates/evm-coder/src/abi/impls.rs
@@ -184,6 +184,11 @@
}
}
+macro_rules! count {
+ () => (0usize);
+ ( $x:tt $($xs:tt)* ) => (1usize + count!($($xs)*));
+}
+
macro_rules! impl_tuples {
($($ident:ident)+) => {
impl<$($ident: AbiType,)+> AbiType for ($($ident,)+)
@@ -198,7 +203,7 @@
shift_left(1)
fixed(")")
);
- const FIELDS_COUNT: usize = 0 $(+ {let _ = <$ident as AbiType>::FIELDS_COUNT; 1})+;
+ const FIELDS_COUNT: usize = count!($($ident)*);
fn is_dynamic() -> bool {
false
crates/evm-coder/src/solidity/impls.rsdiffbeforeafterboth--- a/crates/evm-coder/src/solidity/impls.rs
+++ b/crates/evm-coder/src/solidity/impls.rs
@@ -74,6 +74,16 @@
}
}
+impl<T: StructCollect + sealed::CanBePlacedInVec> StructCollect for Vec<T> {
+ fn name() -> String {
+ <T as StructCollect>::name() + "[]"
+ }
+
+ fn declaration() -> String {
+ unimplemented!("Vectors have not declarations.")
+ }
+}
+
macro_rules! count {
() => (0usize);
( $x:tt $($xs:tt)* ) => (1usize + count!($($xs)*));
@@ -131,60 +141,3 @@
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}
-
-impl StructCollect for Property {
- fn name() -> String {
- "Property".into()
- }
-
- fn declaration() -> String {
- use std::fmt::Write;
-
- let mut str = String::new();
- writeln!(str, "/// @dev Property struct").unwrap();
- writeln!(str, "struct {} {{", Self::name()).unwrap();
- writeln!(str, "\tstring key;").unwrap();
- writeln!(str, "\tbytes value;").unwrap();
- writeln!(str, "}}").unwrap();
- str
- }
-}
-
-impl SolidityTypeName for Property {
- 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>())?;
- address::solidity_default(writer, tc)?;
- write!(writer, ",")?;
- uint256::solidity_default(writer, tc)?;
- write!(writer, ")")
- }
-}
-
-impl SolidityType for Property {
- fn names(tc: &TypeCollector) -> Vec<string> {
- let mut collected = Vec::with_capacity(Self::len());
- {
- let mut out = string::new();
- string::solidity_name(&mut out, tc).expect("no fmt error");
- collected.push(out);
- }
- {
- let mut out = string::new();
- bytes::solidity_name(&mut out, tc).expect("no fmt error");
- collected.push(out);
- }
- collected
- }
-
- fn len() -> usize {
- 2
- }
-}
crates/evm-coder/src/solidity/mod.rsdiffbeforeafterboth--- a/crates/evm-coder/src/solidity/mod.rs
+++ b/crates/evm-coder/src/solidity/mod.rs
@@ -76,7 +76,8 @@
self.anonymous.borrow_mut().insert(names, id);
format!("Tuple{}", id)
}
- pub fn collect_struct<T: StructCollect>(&self) -> String {
+ pub fn collect_struct<T: StructCollect + SolidityType>(&self) -> String {
+ let _names = T::names(self);
self.collect(<T as StructCollect>::declaration());
<T as StructCollect>::name()
}
crates/evm-coder/tests/abi_derive_generation.rsdiffbeforeafterboth1mod test_struct {2 use evm_coder_procedural::AbiCoder;3 use evm_coder::types::bytes;45 #[test]6 fn empty_struct() {7 let t = trybuild::TestCases::new();8 t.compile_fail("tests/build_failed/abi_derive_struct_generation.rs");9 }1011 #[derive(AbiCoder, PartialEq, Debug)]12 struct TypeStruct1SimpleParam {13 _a: u8,14 }1516 #[derive(AbiCoder, PartialEq, Debug)]17 struct TypeStruct1DynamicParam {18 _a: String,19 }2021 #[derive(AbiCoder, PartialEq, Debug)]22 struct TypeStruct2SimpleParam {23 _a: u8,24 _b: u32,25 }2627 #[derive(AbiCoder, PartialEq, Debug)]28 struct TypeStruct2DynamicParam {29 _a: String,30 _b: bytes,31 }3233 #[derive(AbiCoder, PartialEq, Debug)]34 struct TypeStruct2MixedParam {35 _a: u8,36 _b: bytes,37 }3839 #[derive(AbiCoder, PartialEq, Debug)]40 struct TypeStruct1DerivedSimpleParam {41 _a: TypeStruct1SimpleParam,42 }4344 #[derive(AbiCoder, PartialEq, Debug)]45 struct TypeStruct2DerivedSimpleParam {46 _a: TypeStruct1SimpleParam,47 _b: TypeStruct2SimpleParam,48 }4950 #[derive(AbiCoder, PartialEq, Debug)]51 struct TypeStruct1DerivedDynamicParam {52 _a: TypeStruct1DynamicParam,53 }5455 #[derive(AbiCoder, PartialEq, Debug)]56 struct TypeStruct2DerivedDynamicParam {57 _a: TypeStruct1DynamicParam,58 _b: TypeStruct2DynamicParam,59 }6061 /// Some docs62 /// At multi63 /// line64 #[derive(AbiCoder, PartialEq, Debug)]65 struct TypeStruct3DerivedMixedParam {66 /// Docs for A67 /// multi68 /// line69 _a: TypeStruct1SimpleParam,70 /// Docs for B71 _b: TypeStruct2DynamicParam,72 /// Docs for C73 _c: TypeStruct2MixedParam,74 }7576 #[test]77 #[cfg(feature = "stubgen")]78 fn struct_collect_type_struct3_derived_mixed_param() {79 assert_eq!(80 <TypeStruct3DerivedMixedParam as ::evm_coder::solidity::StructCollect>::name(),81 "TypeStruct3DerivedMixedParam"82 );83 similar_asserts::assert_eq!(84 <TypeStruct3DerivedMixedParam as ::evm_coder::solidity::StructCollect>::declaration(),85 r#"/// @dev Some docs86/// At multi87/// line88struct TypeStruct3DerivedMixedParam {89 /// @dev Docs for A90 /// multi91 /// line92 TypeStruct1SimpleParam _a;93 /// @dev Docs for B94 TypeStruct2DynamicParam _b;95 /// @dev Docs for C96 TypeStruct2MixedParam _c;97}98"#99 );100 }101102 #[test]103 fn impl_abi_type_signature() {104 assert_eq!(105 <TypeStruct1SimpleParam as evm_coder::abi::AbiType>::SIGNATURE106 .as_str()107 .unwrap(),108 "(uint8)"109 );110 assert_eq!(111 <TypeStruct1DynamicParam as evm_coder::abi::AbiType>::SIGNATURE112 .as_str()113 .unwrap(),114 "(string)"115 );116 assert_eq!(117 <TypeStruct2SimpleParam as evm_coder::abi::AbiType>::SIGNATURE118 .as_str()119 .unwrap(),120 "(uint8,uint32)"121 );122 assert_eq!(123 <TypeStruct2DynamicParam as evm_coder::abi::AbiType>::SIGNATURE124 .as_str()125 .unwrap(),126 "(string,bytes)"127 );128 assert_eq!(129 <TypeStruct2MixedParam as evm_coder::abi::AbiType>::SIGNATURE130 .as_str()131 .unwrap(),132 "(uint8,bytes)"133 );134 assert_eq!(135 <TypeStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::SIGNATURE136 .as_str()137 .unwrap(),138 "((uint8))"139 );140 assert_eq!(141 <TypeStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::SIGNATURE142 .as_str()143 .unwrap(),144 "((uint8),(uint8,uint32))"145 );146 assert_eq!(147 <TypeStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::SIGNATURE148 .as_str()149 .unwrap(),150 "((string))"151 );152 assert_eq!(153 <TypeStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::SIGNATURE154 .as_str()155 .unwrap(),156 "((string),(string,bytes))"157 );158 assert_eq!(159 <TypeStruct3DerivedMixedParam as evm_coder::abi::AbiType>::SIGNATURE160 .as_str()161 .unwrap(),162 "((uint8),(string,bytes),(uint8,bytes))"163 );164 }165166 #[test]167 fn impl_abi_type_fields_count() {168 assert_eq!(169 <TypeStruct1SimpleParam as evm_coder::abi::AbiType>::FIELDS_COUNT,170 1171 );172 assert_eq!(173 <TypeStruct1DynamicParam as evm_coder::abi::AbiType>::FIELDS_COUNT,174 1175 );176 assert_eq!(177 <TypeStruct2SimpleParam as evm_coder::abi::AbiType>::FIELDS_COUNT,178 2179 );180 assert_eq!(181 <TypeStruct2DynamicParam as evm_coder::abi::AbiType>::FIELDS_COUNT,182 2183 );184 assert_eq!(185 <TypeStruct2MixedParam as evm_coder::abi::AbiType>::FIELDS_COUNT,186 2187 );188 assert_eq!(189 <TypeStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::FIELDS_COUNT,190 1191 );192 assert_eq!(193 <TypeStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::FIELDS_COUNT,194 2195 );196 assert_eq!(197 <TypeStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::FIELDS_COUNT,198 2199 );200 assert_eq!(201 <TypeStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::FIELDS_COUNT,202 2203 );204 assert_eq!(205 <TypeStruct3DerivedMixedParam as evm_coder::abi::AbiType>::FIELDS_COUNT,206 3207 );208 }209210 #[test]211 fn impl_abi_type_is_dynamic() {212 assert_eq!(213 <TypeStruct1SimpleParam as evm_coder::abi::AbiType>::is_dynamic(),214 false215 );216 assert_eq!(217 <TypeStruct1DynamicParam as evm_coder::abi::AbiType>::is_dynamic(),218 true219 );220 assert_eq!(221 <TypeStruct2SimpleParam as evm_coder::abi::AbiType>::is_dynamic(),222 false223 );224 assert_eq!(225 <TypeStruct2DynamicParam as evm_coder::abi::AbiType>::is_dynamic(),226 true227 );228 assert_eq!(229 <TypeStruct2MixedParam as evm_coder::abi::AbiType>::is_dynamic(),230 true231 );232 assert_eq!(233 <TypeStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::is_dynamic(),234 false235 );236 assert_eq!(237 <TypeStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::is_dynamic(),238 false239 );240 assert_eq!(241 <TypeStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::is_dynamic(),242 true243 );244 assert_eq!(245 <TypeStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::is_dynamic(),246 true247 );248 assert_eq!(249 <TypeStruct3DerivedMixedParam as evm_coder::abi::AbiType>::is_dynamic(),250 true251 );252 }253254 #[test]255 fn impl_abi_type_size() {256 const ABI_ALIGNMENT: usize = 32;257 assert_eq!(258 <TypeStruct1SimpleParam as evm_coder::abi::AbiType>::size(),259 ABI_ALIGNMENT260 );261 assert_eq!(262 <TypeStruct1DynamicParam as evm_coder::abi::AbiType>::size(),263 ABI_ALIGNMENT264 );265 assert_eq!(266 <TypeStruct2SimpleParam as evm_coder::abi::AbiType>::size(),267 ABI_ALIGNMENT * 2268 );269 assert_eq!(270 <TypeStruct2DynamicParam as evm_coder::abi::AbiType>::size(),271 ABI_ALIGNMENT * 2272 );273 assert_eq!(274 <TypeStruct2MixedParam as evm_coder::abi::AbiType>::size(),275 ABI_ALIGNMENT * 2276 );277 assert_eq!(278 <TypeStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::size(),279 ABI_ALIGNMENT280 );281 assert_eq!(282 <TypeStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::size(),283 ABI_ALIGNMENT * 3284 );285 assert_eq!(286 <TypeStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::size(),287 ABI_ALIGNMENT288 );289 assert_eq!(290 <TypeStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::size(),291 ABI_ALIGNMENT * 3292 );293 assert_eq!(294 <TypeStruct3DerivedMixedParam as evm_coder::abi::AbiType>::size(),295 ABI_ALIGNMENT * 5296 );297 }298299 #[derive(AbiCoder, PartialEq, Debug)]300 struct TupleStruct1SimpleParam(u8);301302 #[derive(AbiCoder, PartialEq, Debug)]303 struct TupleStruct1DynamicParam(String);304305 #[derive(AbiCoder, PartialEq, Debug)]306 struct TupleStruct2SimpleParam(u8, u32);307308 #[derive(AbiCoder, PartialEq, Debug)]309 struct TupleStruct2DynamicParam(String, bytes);310311 #[derive(AbiCoder, PartialEq, Debug)]312 struct TupleStruct2MixedParam(u8, bytes);313314 #[derive(AbiCoder, PartialEq, Debug)]315 struct TupleStruct1DerivedSimpleParam(TupleStruct1SimpleParam);316317 #[derive(AbiCoder, PartialEq, Debug)]318 struct TupleStruct2DerivedSimpleParam(TupleStruct1SimpleParam, TupleStruct2SimpleParam);319320 #[derive(AbiCoder, PartialEq, Debug)]321 struct TupleStruct1DerivedDynamicParam(TupleStruct1DynamicParam);322323 #[derive(AbiCoder, PartialEq, Debug)]324 struct TupleStruct2DerivedDynamicParam(TupleStruct1DynamicParam, TupleStruct2DynamicParam);325326 /// Some docs327 /// At multi328 /// line329 #[derive(AbiCoder, PartialEq, Debug)]330 struct TupleStruct3DerivedMixedParam(331 /// Docs for A332 /// multi333 /// line334 TupleStruct1SimpleParam,335 TupleStruct2DynamicParam,336 /// Docs for C337 TupleStruct2MixedParam,338 );339340 #[test]341 #[cfg(feature = "stubgen")]342 fn struct_collect_tuple_struct3_derived_mixed_param() {343 assert_eq!(344 <TupleStruct3DerivedMixedParam as ::evm_coder::solidity::StructCollect>::name(),345 "TupleStruct3DerivedMixedParam"346 );347 similar_asserts::assert_eq!(348 <TupleStruct3DerivedMixedParam as ::evm_coder::solidity::StructCollect>::declaration(),349 r#"/// @dev Some docs350/// At multi351/// line352struct TupleStruct3DerivedMixedParam {353 /// @dev Docs for A354 /// multi355 /// line356 TupleStruct1SimpleParam field0;357 TupleStruct2DynamicParam field1;358 /// @dev Docs for C359 TupleStruct2MixedParam field2;360}361"#362 );363 }364365 #[test]366 fn impl_abi_type_signature_same_for_structs() {367 assert_eq!(368 <TypeStruct1SimpleParam as evm_coder::abi::AbiType>::SIGNATURE369 .as_str()370 .unwrap(),371 <TupleStruct1SimpleParam as evm_coder::abi::AbiType>::SIGNATURE372 .as_str()373 .unwrap()374 );375 assert_eq!(376 <TypeStruct1DynamicParam as evm_coder::abi::AbiType>::SIGNATURE377 .as_str()378 .unwrap(),379 <TupleStruct1DynamicParam as evm_coder::abi::AbiType>::SIGNATURE380 .as_str()381 .unwrap()382 );383 assert_eq!(384 <TypeStruct2SimpleParam as evm_coder::abi::AbiType>::SIGNATURE385 .as_str()386 .unwrap(),387 <TupleStruct2SimpleParam as evm_coder::abi::AbiType>::SIGNATURE388 .as_str()389 .unwrap()390 );391 assert_eq!(392 <TypeStruct2DynamicParam as evm_coder::abi::AbiType>::SIGNATURE393 .as_str()394 .unwrap(),395 <TupleStruct2DynamicParam as evm_coder::abi::AbiType>::SIGNATURE396 .as_str()397 .unwrap()398 );399 assert_eq!(400 <TypeStruct2MixedParam as evm_coder::abi::AbiType>::SIGNATURE401 .as_str()402 .unwrap(),403 <TupleStruct2MixedParam as evm_coder::abi::AbiType>::SIGNATURE404 .as_str()405 .unwrap(),406 );407 assert_eq!(408 <TypeStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::SIGNATURE409 .as_str()410 .unwrap(),411 <TupleStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::SIGNATURE412 .as_str()413 .unwrap(),414 );415 assert_eq!(416 <TypeStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::SIGNATURE417 .as_str()418 .unwrap(),419 <TupleStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::SIGNATURE420 .as_str()421 .unwrap(),422 );423 assert_eq!(424 <TypeStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::SIGNATURE425 .as_str()426 .unwrap(),427 <TupleStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::SIGNATURE428 .as_str()429 .unwrap(),430 );431 assert_eq!(432 <TypeStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::SIGNATURE433 .as_str()434 .unwrap(),435 <TupleStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::SIGNATURE436 .as_str()437 .unwrap(),438 );439 assert_eq!(440 <TypeStruct3DerivedMixedParam as evm_coder::abi::AbiType>::SIGNATURE441 .as_str()442 .unwrap(),443 <TupleStruct3DerivedMixedParam as evm_coder::abi::AbiType>::SIGNATURE444 .as_str()445 .unwrap(),446 );447 }448449 #[test]450 fn impl_abi_type_is_dynamic_same_for_structs() {451 assert_eq!(452 <TypeStruct1SimpleParam as evm_coder::abi::AbiType>::is_dynamic(),453 <TupleStruct1SimpleParam as evm_coder::abi::AbiType>::is_dynamic()454 );455 assert_eq!(456 <TypeStruct1DynamicParam as evm_coder::abi::AbiType>::is_dynamic(),457 <TupleStruct1DynamicParam as evm_coder::abi::AbiType>::is_dynamic()458 );459 assert_eq!(460 <TypeStruct2SimpleParam as evm_coder::abi::AbiType>::is_dynamic(),461 <TupleStruct2SimpleParam as evm_coder::abi::AbiType>::is_dynamic()462 );463 assert_eq!(464 <TypeStruct2DynamicParam as evm_coder::abi::AbiType>::is_dynamic(),465 <TupleStruct2DynamicParam as evm_coder::abi::AbiType>::is_dynamic()466 );467 assert_eq!(468 <TypeStruct2MixedParam as evm_coder::abi::AbiType>::is_dynamic(),469 <TupleStruct2MixedParam as evm_coder::abi::AbiType>::is_dynamic()470 );471 assert_eq!(472 <TypeStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::is_dynamic(),473 <TupleStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::is_dynamic()474 );475 assert_eq!(476 <TypeStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::is_dynamic(),477 <TupleStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::is_dynamic()478 );479 assert_eq!(480 <TypeStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::is_dynamic(),481 <TupleStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::is_dynamic()482 );483 assert_eq!(484 <TypeStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::is_dynamic(),485 <TupleStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::is_dynamic()486 );487 assert_eq!(488 <TypeStruct3DerivedMixedParam as evm_coder::abi::AbiType>::is_dynamic(),489 <TupleStruct3DerivedMixedParam as evm_coder::abi::AbiType>::is_dynamic()490 );491 }492493 #[test]494 fn impl_abi_type_size_same_for_structs() {495 assert_eq!(496 <TypeStruct1SimpleParam as evm_coder::abi::AbiType>::size(),497 <TupleStruct1SimpleParam as evm_coder::abi::AbiType>::size()498 );499 assert_eq!(500 <TypeStruct1DynamicParam as evm_coder::abi::AbiType>::size(),501 <TupleStruct1DynamicParam as evm_coder::abi::AbiType>::size()502 );503 assert_eq!(504 <TypeStruct2SimpleParam as evm_coder::abi::AbiType>::size(),505 <TupleStruct2SimpleParam as evm_coder::abi::AbiType>::size()506 );507 assert_eq!(508 <TypeStruct2DynamicParam as evm_coder::abi::AbiType>::size(),509 <TupleStruct2DynamicParam as evm_coder::abi::AbiType>::size()510 );511 assert_eq!(512 <TypeStruct2MixedParam as evm_coder::abi::AbiType>::size(),513 <TupleStruct2MixedParam as evm_coder::abi::AbiType>::size()514 );515 assert_eq!(516 <TypeStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::size(),517 <TupleStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::size()518 );519 assert_eq!(520 <TypeStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::size(),521 <TupleStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::size()522 );523 assert_eq!(524 <TypeStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::size(),525 <TupleStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::size()526 );527 assert_eq!(528 <TypeStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::size(),529 <TupleStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::size()530 );531 assert_eq!(532 <TypeStruct3DerivedMixedParam as evm_coder::abi::AbiType>::size(),533 <TupleStruct3DerivedMixedParam as evm_coder::abi::AbiType>::size()534 );535 }536537 const FUNCTION_IDENTIFIER: u32 = 0xdeadbeef;538539 fn test_impl<Tuple, TupleStruct, TypeStruct>(540 tuple_data: Tuple,541 tuple_struct_data: TupleStruct,542 type_struct_data: TypeStruct,543 ) where544 TypeStruct: evm_coder::abi::AbiWrite545 + evm_coder::abi::AbiRead546 + std::cmp::PartialEq547 + std::fmt::Debug,548 TupleStruct: evm_coder::abi::AbiWrite549 + evm_coder::abi::AbiRead550 + std::cmp::PartialEq551 + std::fmt::Debug,552 Tuple: evm_coder::abi::AbiWrite553 + evm_coder::abi::AbiRead554 + std::cmp::PartialEq555 + std::fmt::Debug,556 {557 let encoded_type_struct = test_abi_write_impl(&type_struct_data);558 let encoded_tuple_struct = test_abi_write_impl(&tuple_struct_data);559 let encoded_tuple = test_abi_write_impl(&tuple_data);560561 similar_asserts::assert_eq!(encoded_tuple, encoded_type_struct);562 similar_asserts::assert_eq!(encoded_tuple, encoded_tuple_struct);563564 {565 let (_, mut decoder) = evm_coder::abi::AbiReader::new_call(&encoded_tuple).unwrap();566 let restored_struct_data = <TypeStruct>::abi_read(&mut decoder).unwrap();567 assert_eq!(restored_struct_data, type_struct_data);568 }569 {570 let (_, mut decoder) = evm_coder::abi::AbiReader::new_call(&encoded_tuple).unwrap();571 let restored_struct_data = <TupleStruct>::abi_read(&mut decoder).unwrap();572 assert_eq!(restored_struct_data, tuple_struct_data);573 }574575 {576 let (_, mut decoder) =577 evm_coder::abi::AbiReader::new_call(&encoded_type_struct).unwrap();578 let restored_tuple_data = <Tuple>::abi_read(&mut decoder).unwrap();579 assert_eq!(restored_tuple_data, tuple_data);580 }581 {582 let (_, mut decoder) =583 evm_coder::abi::AbiReader::new_call(&encoded_tuple_struct).unwrap();584 let restored_tuple_data = <Tuple>::abi_read(&mut decoder).unwrap();585 assert_eq!(restored_tuple_data, tuple_data);586 }587 }588589 fn test_abi_write_impl<A>(data: &A) -> Vec<u8>590 where591 A: evm_coder::abi::AbiWrite592 + evm_coder::abi::AbiRead593 + std::cmp::PartialEq594 + std::fmt::Debug,595 {596 let mut writer = evm_coder::abi::AbiWriter::new_call(FUNCTION_IDENTIFIER);597 data.abi_write(&mut writer);598 let encoded_tuple = writer.finish();599 encoded_tuple600 }601602 #[test]603 fn codec_struct_1_simple() {604 let _a = 0xff;605 test_impl::<(u8,), TupleStruct1SimpleParam, TypeStruct1SimpleParam>(606 (_a,),607 TupleStruct1SimpleParam(_a),608 TypeStruct1SimpleParam { _a },609 );610 }611612 #[test]613 fn codec_struct_1_dynamic() {614 let _a: String = "some string".into();615 test_impl::<(String,), TupleStruct1DynamicParam, TypeStruct1DynamicParam>(616 (_a.clone(),),617 TupleStruct1DynamicParam(_a.clone()),618 TypeStruct1DynamicParam { _a },619 );620 }621622 #[test]623 fn codec_struct_1_derived_simple() {624 let _a: u8 = 0xff;625 test_impl::<((u8,),), TupleStruct1DerivedSimpleParam, TypeStruct1DerivedSimpleParam>(626 ((_a,),),627 TupleStruct1DerivedSimpleParam(TupleStruct1SimpleParam(_a)),628 TypeStruct1DerivedSimpleParam {629 _a: TypeStruct1SimpleParam { _a },630 },631 );632 }633634 #[test]635 fn codec_struct_1_derived_dynamic() {636 let _a: String = "some string".into();637 test_impl::<((String,),), TupleStruct1DerivedDynamicParam, TypeStruct1DerivedDynamicParam>(638 ((_a.clone(),),),639 TupleStruct1DerivedDynamicParam(TupleStruct1DynamicParam(_a.clone())),640 TypeStruct1DerivedDynamicParam {641 _a: TypeStruct1DynamicParam { _a },642 },643 );644 }645646 #[test]647 fn codec_struct_2_simple() {648 let _a = 0xff;649 let _b = 0xbeefbaba;650 test_impl::<(u8, u32), TupleStruct2SimpleParam, TypeStruct2SimpleParam>(651 (_a, _b),652 TupleStruct2SimpleParam(_a, _b),653 TypeStruct2SimpleParam { _a, _b },654 );655 }656657 #[test]658 fn codec_struct_2_dynamic() {659 let _a: String = "some string".into();660 let _b: bytes = bytes(vec![0x11, 0x22, 0x33]);661 test_impl::<(String, bytes), TupleStruct2DynamicParam, TypeStruct2DynamicParam>(662 (_a.clone(), _b.clone()),663 TupleStruct2DynamicParam(_a.clone(), _b.clone()),664 TypeStruct2DynamicParam { _a, _b },665 );666 }667668 #[test]669 fn codec_struct_2_mixed() {670 let _a: u8 = 0xff;671 let _b: bytes = bytes(vec![0x11, 0x22, 0x33]);672 test_impl::<(u8, bytes), TupleStruct2MixedParam, TypeStruct2MixedParam>(673 (_a.clone(), _b.clone()),674 TupleStruct2MixedParam(_a.clone(), _b.clone()),675 TypeStruct2MixedParam { _a, _b },676 );677 }678679 #[test]680 fn codec_struct_2_derived_simple() {681 let _a = 0xff;682 let _b = 0xbeefbaba;683 test_impl::<684 ((u8,), (u8, u32)),685 TupleStruct2DerivedSimpleParam,686 TypeStruct2DerivedSimpleParam,687 >(688 ((_a,), (_a, _b)),689 TupleStruct2DerivedSimpleParam(690 TupleStruct1SimpleParam(_a),691 TupleStruct2SimpleParam(_a, _b),692 ),693 TypeStruct2DerivedSimpleParam {694 _a: TypeStruct1SimpleParam { _a },695 _b: TypeStruct2SimpleParam { _a, _b },696 },697 );698 }699700 #[test]701 fn codec_struct_2_derived_dynamic() {702 let _a = "some string".to_string();703 let _b = bytes(vec![0x11, 0x22, 0x33]);704 test_impl::<705 ((String,), (String, bytes)),706 TupleStruct2DerivedDynamicParam,707 TypeStruct2DerivedDynamicParam,708 >(709 ((_a.clone(),), (_a.clone(), _b.clone())),710 TupleStruct2DerivedDynamicParam(711 TupleStruct1DynamicParam(_a.clone()),712 TupleStruct2DynamicParam(_a.clone(), _b.clone()),713 ),714 TypeStruct2DerivedDynamicParam {715 _a: TypeStruct1DynamicParam { _a: _a.clone() },716 _b: TypeStruct2DynamicParam { _a, _b },717 },718 );719 }720721 #[test]722 fn codec_struct_3_derived_mixed() {723 let int = 0xff;724 let by = bytes(vec![0x11, 0x22, 0x33]);725 let string = "some string".to_string();726 test_impl::<727 ((u8,), (String, bytes), (u8, bytes)),728 TupleStruct3DerivedMixedParam,729 TypeStruct3DerivedMixedParam,730 >(731 ((int,), (string.clone(), by.clone()), (int, by.clone())),732 TupleStruct3DerivedMixedParam(733 TupleStruct1SimpleParam(int),734 TupleStruct2DynamicParam(string.clone(), by.clone()),735 TupleStruct2MixedParam(int, by.clone()),736 ),737 TypeStruct3DerivedMixedParam {738 _a: TypeStruct1SimpleParam { _a: int },739 _b: TypeStruct2DynamicParam {740 _a: string.clone(),741 _b: by.clone(),742 },743 _c: TypeStruct2MixedParam { _a: int, _b: by },744 },745 );746 }747748 #[derive(AbiCoder, PartialEq, Debug)]749 struct TypeStruct2SimpleStruct1Simple {750 _a: TypeStruct2SimpleParam,751 _b: TypeStruct2SimpleParam,752 _c: u8,753 }754 #[derive(AbiCoder, PartialEq, Debug)]755 struct TupleStruct2SimpleStruct1Simple(TupleStruct2SimpleParam, TupleStruct2SimpleParam, u8);756757 #[test]758 fn codec_struct_2_struct_simple_1_simple() {759 let _a = 0xff;760 let _b = 0xbeefbaba;761 test_impl::<762 ((u8, u32), (u8, u32), u8),763 TupleStruct2SimpleStruct1Simple,764 TypeStruct2SimpleStruct1Simple,765 >(766 ((_a, _b), (_a, _b), _a),767 TupleStruct2SimpleStruct1Simple(768 TupleStruct2SimpleParam(_a, _b),769 TupleStruct2SimpleParam(_a, _b),770 _a,771 ),772 TypeStruct2SimpleStruct1Simple {773 _a: TypeStruct2SimpleParam { _a, _b },774 _b: TypeStruct2SimpleParam { _a, _b },775 _c: _a,776 },777 );778 }779}780781mod test_enum {782 use evm_coder::AbiCoder;783784 /// Some docs785 /// At multi786 /// line787 #[derive(AbiCoder, Debug, PartialEq, Default, Clone, Copy)]788 #[repr(u8)]789 enum Color {790 /// Docs for Red791 /// multi792 /// line793 Red,794 Green,795 /// Docs for Blue796 #[default]797 Blue,798 }799800 #[test]801 fn empty() {}802803 #[test]804 fn bad_enums() {805 let t = trybuild::TestCases::new();806 t.compile_fail("tests/build_failed/abi_derive_enum_generation.rs");807 }808809 #[test]810 fn impl_abi_type_signature_same_for_structs() {811 assert_eq!(812 <Color as evm_coder::abi::AbiType>::SIGNATURE813 .as_str()814 .unwrap(),815 <u8 as evm_coder::abi::AbiType>::SIGNATURE.as_str().unwrap()816 );817 }818819 #[test]820 fn impl_abi_type_is_dynamic_same_for_structs() {821 assert_eq!(822 <Color as evm_coder::abi::AbiType>::is_dynamic(),823 <u8 as evm_coder::abi::AbiType>::is_dynamic()824 );825 }826827 #[test]828 fn impl_abi_type_size_same_for_structs() {829 assert_eq!(830 <Color as evm_coder::abi::AbiType>::size(),831 <u8 as evm_coder::abi::AbiType>::size()832 );833 }834835 #[test]836 fn test_coder() {837 const FUNCTION_IDENTIFIER: u32 = 0xdeadbeef;838839 let encoded_enum = {840 let mut writer = evm_coder::abi::AbiWriter::new_call(FUNCTION_IDENTIFIER);841 <Color as evm_coder::abi::AbiWrite>::abi_write(&Color::Green, &mut writer);842 writer.finish()843 };844845 let encoded_u8 = {846 let mut writer = evm_coder::abi::AbiWriter::new_call(FUNCTION_IDENTIFIER);847 <u8 as evm_coder::abi::AbiWrite>::abi_write(&(Color::Green as u8), &mut writer);848 writer.finish()849 };850851 similar_asserts::assert_eq!(encoded_enum, encoded_u8);852853 {854 let (_, mut decoder) = evm_coder::abi::AbiReader::new_call(&encoded_enum).unwrap();855 let restored_enum_data =856 <Color as evm_coder::abi::AbiRead>::abi_read(&mut decoder).unwrap();857 assert_eq!(restored_enum_data, Color::Green);858 }859 }860861 #[test]862 #[cfg(feature = "stubgen")]863 fn struct_collect_enum() {864 assert_eq!(865 <Color as ::evm_coder::solidity::StructCollect>::name(),866 "Color"867 );868 similar_asserts::assert_eq!(869 <Color as ::evm_coder::solidity::StructCollect>::declaration(),870 r#"/// @dev Some docs871/// At multi872/// line873enum Color {874 /// @dev Docs for Red875 /// multi876 /// line877 Red,878 Green,879 /// @dev Docs for Blue880 Blue881}882"#883 );884 }885}1mod test_struct {2 use evm_coder_procedural::AbiCoder;3 use evm_coder::types::bytes;45 #[test]6 fn empty_struct() {7 let t = trybuild::TestCases::new();8 t.compile_fail("tests/build_failed/abi_derive_struct_generation.rs");9 }1011 #[derive(AbiCoder, PartialEq, Debug)]12 struct TypeStruct1SimpleParam {13 _a: u8,14 }1516 #[derive(AbiCoder, PartialEq, Debug)]17 struct TypeStruct1DynamicParam {18 _a: String,19 }2021 #[derive(AbiCoder, PartialEq, Debug)]22 struct TypeStruct2SimpleParam {23 _a: u8,24 _b: u32,25 }2627 #[derive(AbiCoder, PartialEq, Debug)]28 struct TypeStruct2DynamicParam {29 _a: String,30 _b: bytes,31 }3233 #[derive(AbiCoder, PartialEq, Debug)]34 struct TypeStruct2MixedParam {35 _a: u8,36 _b: bytes,37 }3839 #[derive(AbiCoder, PartialEq, Debug)]40 struct TypeStruct1DerivedSimpleParam {41 _a: TypeStruct1SimpleParam,42 }4344 #[derive(AbiCoder, PartialEq, Debug)]45 struct TypeStruct2DerivedSimpleParam {46 _a: TypeStruct1SimpleParam,47 _b: TypeStruct2SimpleParam,48 }4950 #[derive(AbiCoder, PartialEq, Debug)]51 struct TypeStruct1DerivedDynamicParam {52 _a: TypeStruct1DynamicParam,53 }5455 #[derive(AbiCoder, PartialEq, Debug)]56 struct TypeStruct2DerivedDynamicParam {57 _a: TypeStruct1DynamicParam,58 _b: TypeStruct2DynamicParam,59 }6061 /// Some docs62 /// At multi63 /// line64 #[derive(AbiCoder, PartialEq, Debug)]65 struct TypeStruct3DerivedMixedParam {66 /// Docs for A67 /// multi68 /// line69 _a: TypeStruct1SimpleParam,70 /// Docs for B71 _b: TypeStruct2DynamicParam,72 /// Docs for C73 _c: TypeStruct2MixedParam,74 }7576 #[test]77 #[cfg(feature = "stubgen")]78 fn struct_collect_type_struct3_derived_mixed_param() {79 assert_eq!(80 <TypeStruct3DerivedMixedParam as ::evm_coder::solidity::StructCollect>::name(),81 "TypeStruct3DerivedMixedParam"82 );83 similar_asserts::assert_eq!(84 <TypeStruct3DerivedMixedParam as ::evm_coder::solidity::StructCollect>::declaration(),85 r#"/// @dev Some docs86/// At multi87/// line88struct TypeStruct3DerivedMixedParam {89 /// @dev Docs for A90 /// multi91 /// line92 TypeStruct1SimpleParam _a;93 /// @dev Docs for B94 TypeStruct2DynamicParam _b;95 /// @dev Docs for C96 TypeStruct2MixedParam _c;97}98"#99 );100 }101102 #[test]103 #[cfg(feature = "stubgen")]104 fn struct_collect_vec() {105 assert_eq!(106 <Vec<u8> as ::evm_coder::solidity::StructCollect>::name(),107 "uint8[]"108 );109 }110111 #[test]112 fn impl_abi_type_signature() {113 assert_eq!(114 <TypeStruct1SimpleParam as evm_coder::abi::AbiType>::SIGNATURE115 .as_str()116 .unwrap(),117 "(uint8)"118 );119 assert_eq!(120 <TypeStruct1DynamicParam as evm_coder::abi::AbiType>::SIGNATURE121 .as_str()122 .unwrap(),123 "(string)"124 );125 assert_eq!(126 <TypeStruct2SimpleParam as evm_coder::abi::AbiType>::SIGNATURE127 .as_str()128 .unwrap(),129 "(uint8,uint32)"130 );131 assert_eq!(132 <TypeStruct2DynamicParam as evm_coder::abi::AbiType>::SIGNATURE133 .as_str()134 .unwrap(),135 "(string,bytes)"136 );137 assert_eq!(138 <TypeStruct2MixedParam as evm_coder::abi::AbiType>::SIGNATURE139 .as_str()140 .unwrap(),141 "(uint8,bytes)"142 );143 assert_eq!(144 <TypeStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::SIGNATURE145 .as_str()146 .unwrap(),147 "((uint8))"148 );149 assert_eq!(150 <TypeStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::SIGNATURE151 .as_str()152 .unwrap(),153 "((uint8),(uint8,uint32))"154 );155 assert_eq!(156 <TypeStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::SIGNATURE157 .as_str()158 .unwrap(),159 "((string))"160 );161 assert_eq!(162 <TypeStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::SIGNATURE163 .as_str()164 .unwrap(),165 "((string),(string,bytes))"166 );167 assert_eq!(168 <TypeStruct3DerivedMixedParam as evm_coder::abi::AbiType>::SIGNATURE169 .as_str()170 .unwrap(),171 "((uint8),(string,bytes),(uint8,bytes))"172 );173 }174175 #[test]176 fn impl_abi_type_fields_count() {177 assert_eq!(178 <TypeStruct1SimpleParam as evm_coder::abi::AbiType>::FIELDS_COUNT,179 1180 );181 assert_eq!(182 <TypeStruct1DynamicParam as evm_coder::abi::AbiType>::FIELDS_COUNT,183 1184 );185 assert_eq!(186 <TypeStruct2SimpleParam as evm_coder::abi::AbiType>::FIELDS_COUNT,187 2188 );189 assert_eq!(190 <TypeStruct2DynamicParam as evm_coder::abi::AbiType>::FIELDS_COUNT,191 2192 );193 assert_eq!(194 <TypeStruct2MixedParam as evm_coder::abi::AbiType>::FIELDS_COUNT,195 2196 );197 assert_eq!(198 <TypeStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::FIELDS_COUNT,199 1200 );201 assert_eq!(202 <TypeStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::FIELDS_COUNT,203 2204 );205 assert_eq!(206 <TypeStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::FIELDS_COUNT,207 2208 );209 assert_eq!(210 <TypeStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::FIELDS_COUNT,211 2212 );213 assert_eq!(214 <TypeStruct3DerivedMixedParam as evm_coder::abi::AbiType>::FIELDS_COUNT,215 3216 );217 }218219 #[test]220 fn impl_abi_type_is_dynamic() {221 assert_eq!(222 <TypeStruct1SimpleParam as evm_coder::abi::AbiType>::is_dynamic(),223 false224 );225 assert_eq!(226 <TypeStruct1DynamicParam as evm_coder::abi::AbiType>::is_dynamic(),227 true228 );229 assert_eq!(230 <TypeStruct2SimpleParam as evm_coder::abi::AbiType>::is_dynamic(),231 false232 );233 assert_eq!(234 <TypeStruct2DynamicParam as evm_coder::abi::AbiType>::is_dynamic(),235 true236 );237 assert_eq!(238 <TypeStruct2MixedParam as evm_coder::abi::AbiType>::is_dynamic(),239 true240 );241 assert_eq!(242 <TypeStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::is_dynamic(),243 false244 );245 assert_eq!(246 <TypeStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::is_dynamic(),247 false248 );249 assert_eq!(250 <TypeStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::is_dynamic(),251 true252 );253 assert_eq!(254 <TypeStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::is_dynamic(),255 true256 );257 assert_eq!(258 <TypeStruct3DerivedMixedParam as evm_coder::abi::AbiType>::is_dynamic(),259 true260 );261 }262263 #[test]264 fn impl_abi_type_size() {265 const ABI_ALIGNMENT: usize = 32;266 assert_eq!(267 <TypeStruct1SimpleParam as evm_coder::abi::AbiType>::size(),268 ABI_ALIGNMENT269 );270 assert_eq!(271 <TypeStruct1DynamicParam as evm_coder::abi::AbiType>::size(),272 ABI_ALIGNMENT273 );274 assert_eq!(275 <TypeStruct2SimpleParam as evm_coder::abi::AbiType>::size(),276 ABI_ALIGNMENT * 2277 );278 assert_eq!(279 <TypeStruct2DynamicParam as evm_coder::abi::AbiType>::size(),280 ABI_ALIGNMENT * 2281 );282 assert_eq!(283 <TypeStruct2MixedParam as evm_coder::abi::AbiType>::size(),284 ABI_ALIGNMENT * 2285 );286 assert_eq!(287 <TypeStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::size(),288 ABI_ALIGNMENT289 );290 assert_eq!(291 <TypeStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::size(),292 ABI_ALIGNMENT * 3293 );294 assert_eq!(295 <TypeStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::size(),296 ABI_ALIGNMENT297 );298 assert_eq!(299 <TypeStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::size(),300 ABI_ALIGNMENT * 3301 );302 assert_eq!(303 <TypeStruct3DerivedMixedParam as evm_coder::abi::AbiType>::size(),304 ABI_ALIGNMENT * 5305 );306 }307308 #[derive(AbiCoder, PartialEq, Debug)]309 struct TupleStruct1SimpleParam(u8);310311 #[derive(AbiCoder, PartialEq, Debug)]312 struct TupleStruct1DynamicParam(String);313314 #[derive(AbiCoder, PartialEq, Debug)]315 struct TupleStruct2SimpleParam(u8, u32);316317 #[derive(AbiCoder, PartialEq, Debug)]318 struct TupleStruct2DynamicParam(String, bytes);319320 #[derive(AbiCoder, PartialEq, Debug)]321 struct TupleStruct2MixedParam(u8, bytes);322323 #[derive(AbiCoder, PartialEq, Debug)]324 struct TupleStruct1DerivedSimpleParam(TupleStruct1SimpleParam);325326 #[derive(AbiCoder, PartialEq, Debug)]327 struct TupleStruct2DerivedSimpleParam(TupleStruct1SimpleParam, TupleStruct2SimpleParam);328329 #[derive(AbiCoder, PartialEq, Debug)]330 struct TupleStruct1DerivedDynamicParam(TupleStruct1DynamicParam);331332 #[derive(AbiCoder, PartialEq, Debug)]333 struct TupleStruct2DerivedDynamicParam(TupleStruct1DynamicParam, TupleStruct2DynamicParam);334335 /// Some docs336 /// At multi337 /// line338 #[derive(AbiCoder, PartialEq, Debug)]339 struct TupleStruct3DerivedMixedParam(340 /// Docs for A341 /// multi342 /// line343 TupleStruct1SimpleParam,344 TupleStruct2DynamicParam,345 /// Docs for C346 TupleStruct2MixedParam,347 );348349 #[test]350 #[cfg(feature = "stubgen")]351 fn struct_collect_tuple_struct3_derived_mixed_param() {352 assert_eq!(353 <TupleStruct3DerivedMixedParam as ::evm_coder::solidity::StructCollect>::name(),354 "TupleStruct3DerivedMixedParam"355 );356 similar_asserts::assert_eq!(357 <TupleStruct3DerivedMixedParam as ::evm_coder::solidity::StructCollect>::declaration(),358 r#"/// @dev Some docs359/// At multi360/// line361struct TupleStruct3DerivedMixedParam {362 /// @dev Docs for A363 /// multi364 /// line365 TupleStruct1SimpleParam field0;366 TupleStruct2DynamicParam field1;367 /// @dev Docs for C368 TupleStruct2MixedParam field2;369}370"#371 );372 }373374 #[test]375 fn impl_abi_type_signature_same_for_structs() {376 assert_eq!(377 <TypeStruct1SimpleParam as evm_coder::abi::AbiType>::SIGNATURE378 .as_str()379 .unwrap(),380 <TupleStruct1SimpleParam as evm_coder::abi::AbiType>::SIGNATURE381 .as_str()382 .unwrap()383 );384 assert_eq!(385 <TypeStruct1DynamicParam as evm_coder::abi::AbiType>::SIGNATURE386 .as_str()387 .unwrap(),388 <TupleStruct1DynamicParam as evm_coder::abi::AbiType>::SIGNATURE389 .as_str()390 .unwrap()391 );392 assert_eq!(393 <TypeStruct2SimpleParam as evm_coder::abi::AbiType>::SIGNATURE394 .as_str()395 .unwrap(),396 <TupleStruct2SimpleParam as evm_coder::abi::AbiType>::SIGNATURE397 .as_str()398 .unwrap()399 );400 assert_eq!(401 <TypeStruct2DynamicParam as evm_coder::abi::AbiType>::SIGNATURE402 .as_str()403 .unwrap(),404 <TupleStruct2DynamicParam as evm_coder::abi::AbiType>::SIGNATURE405 .as_str()406 .unwrap()407 );408 assert_eq!(409 <TypeStruct2MixedParam as evm_coder::abi::AbiType>::SIGNATURE410 .as_str()411 .unwrap(),412 <TupleStruct2MixedParam as evm_coder::abi::AbiType>::SIGNATURE413 .as_str()414 .unwrap(),415 );416 assert_eq!(417 <TypeStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::SIGNATURE418 .as_str()419 .unwrap(),420 <TupleStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::SIGNATURE421 .as_str()422 .unwrap(),423 );424 assert_eq!(425 <TypeStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::SIGNATURE426 .as_str()427 .unwrap(),428 <TupleStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::SIGNATURE429 .as_str()430 .unwrap(),431 );432 assert_eq!(433 <TypeStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::SIGNATURE434 .as_str()435 .unwrap(),436 <TupleStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::SIGNATURE437 .as_str()438 .unwrap(),439 );440 assert_eq!(441 <TypeStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::SIGNATURE442 .as_str()443 .unwrap(),444 <TupleStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::SIGNATURE445 .as_str()446 .unwrap(),447 );448 assert_eq!(449 <TypeStruct3DerivedMixedParam as evm_coder::abi::AbiType>::SIGNATURE450 .as_str()451 .unwrap(),452 <TupleStruct3DerivedMixedParam as evm_coder::abi::AbiType>::SIGNATURE453 .as_str()454 .unwrap(),455 );456 }457458 #[test]459 fn impl_abi_type_is_dynamic_same_for_structs() {460 assert_eq!(461 <TypeStruct1SimpleParam as evm_coder::abi::AbiType>::is_dynamic(),462 <TupleStruct1SimpleParam as evm_coder::abi::AbiType>::is_dynamic()463 );464 assert_eq!(465 <TypeStruct1DynamicParam as evm_coder::abi::AbiType>::is_dynamic(),466 <TupleStruct1DynamicParam as evm_coder::abi::AbiType>::is_dynamic()467 );468 assert_eq!(469 <TypeStruct2SimpleParam as evm_coder::abi::AbiType>::is_dynamic(),470 <TupleStruct2SimpleParam as evm_coder::abi::AbiType>::is_dynamic()471 );472 assert_eq!(473 <TypeStruct2DynamicParam as evm_coder::abi::AbiType>::is_dynamic(),474 <TupleStruct2DynamicParam as evm_coder::abi::AbiType>::is_dynamic()475 );476 assert_eq!(477 <TypeStruct2MixedParam as evm_coder::abi::AbiType>::is_dynamic(),478 <TupleStruct2MixedParam as evm_coder::abi::AbiType>::is_dynamic()479 );480 assert_eq!(481 <TypeStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::is_dynamic(),482 <TupleStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::is_dynamic()483 );484 assert_eq!(485 <TypeStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::is_dynamic(),486 <TupleStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::is_dynamic()487 );488 assert_eq!(489 <TypeStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::is_dynamic(),490 <TupleStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::is_dynamic()491 );492 assert_eq!(493 <TypeStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::is_dynamic(),494 <TupleStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::is_dynamic()495 );496 assert_eq!(497 <TypeStruct3DerivedMixedParam as evm_coder::abi::AbiType>::is_dynamic(),498 <TupleStruct3DerivedMixedParam as evm_coder::abi::AbiType>::is_dynamic()499 );500 }501502 #[test]503 fn impl_abi_type_size_same_for_structs() {504 assert_eq!(505 <TypeStruct1SimpleParam as evm_coder::abi::AbiType>::size(),506 <TupleStruct1SimpleParam as evm_coder::abi::AbiType>::size()507 );508 assert_eq!(509 <TypeStruct1DynamicParam as evm_coder::abi::AbiType>::size(),510 <TupleStruct1DynamicParam as evm_coder::abi::AbiType>::size()511 );512 assert_eq!(513 <TypeStruct2SimpleParam as evm_coder::abi::AbiType>::size(),514 <TupleStruct2SimpleParam as evm_coder::abi::AbiType>::size()515 );516 assert_eq!(517 <TypeStruct2DynamicParam as evm_coder::abi::AbiType>::size(),518 <TupleStruct2DynamicParam as evm_coder::abi::AbiType>::size()519 );520 assert_eq!(521 <TypeStruct2MixedParam as evm_coder::abi::AbiType>::size(),522 <TupleStruct2MixedParam as evm_coder::abi::AbiType>::size()523 );524 assert_eq!(525 <TypeStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::size(),526 <TupleStruct1DerivedSimpleParam as evm_coder::abi::AbiType>::size()527 );528 assert_eq!(529 <TypeStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::size(),530 <TupleStruct2DerivedSimpleParam as evm_coder::abi::AbiType>::size()531 );532 assert_eq!(533 <TypeStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::size(),534 <TupleStruct1DerivedDynamicParam as evm_coder::abi::AbiType>::size()535 );536 assert_eq!(537 <TypeStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::size(),538 <TupleStruct2DerivedDynamicParam as evm_coder::abi::AbiType>::size()539 );540 assert_eq!(541 <TypeStruct3DerivedMixedParam as evm_coder::abi::AbiType>::size(),542 <TupleStruct3DerivedMixedParam as evm_coder::abi::AbiType>::size()543 );544 }545546 const FUNCTION_IDENTIFIER: u32 = 0xdeadbeef;547548 fn test_impl<Tuple, TupleStruct, TypeStruct>(549 tuple_data: Tuple,550 tuple_struct_data: TupleStruct,551 type_struct_data: TypeStruct,552 ) where553 TypeStruct: evm_coder::abi::AbiWrite554 + evm_coder::abi::AbiRead555 + std::cmp::PartialEq556 + std::fmt::Debug,557 TupleStruct: evm_coder::abi::AbiWrite558 + evm_coder::abi::AbiRead559 + std::cmp::PartialEq560 + std::fmt::Debug,561 Tuple: evm_coder::abi::AbiWrite562 + evm_coder::abi::AbiRead563 + std::cmp::PartialEq564 + std::fmt::Debug,565 {566 let encoded_type_struct = test_abi_write_impl(&type_struct_data);567 let encoded_tuple_struct = test_abi_write_impl(&tuple_struct_data);568 let encoded_tuple = test_abi_write_impl(&tuple_data);569570 similar_asserts::assert_eq!(encoded_tuple, encoded_type_struct);571 similar_asserts::assert_eq!(encoded_tuple, encoded_tuple_struct);572573 {574 let (_, mut decoder) = evm_coder::abi::AbiReader::new_call(&encoded_tuple).unwrap();575 let restored_struct_data = <TypeStruct>::abi_read(&mut decoder).unwrap();576 assert_eq!(restored_struct_data, type_struct_data);577 }578 {579 let (_, mut decoder) = evm_coder::abi::AbiReader::new_call(&encoded_tuple).unwrap();580 let restored_struct_data = <TupleStruct>::abi_read(&mut decoder).unwrap();581 assert_eq!(restored_struct_data, tuple_struct_data);582 }583584 {585 let (_, mut decoder) =586 evm_coder::abi::AbiReader::new_call(&encoded_type_struct).unwrap();587 let restored_tuple_data = <Tuple>::abi_read(&mut decoder).unwrap();588 assert_eq!(restored_tuple_data, tuple_data);589 }590 {591 let (_, mut decoder) =592 evm_coder::abi::AbiReader::new_call(&encoded_tuple_struct).unwrap();593 let restored_tuple_data = <Tuple>::abi_read(&mut decoder).unwrap();594 assert_eq!(restored_tuple_data, tuple_data);595 }596 }597598 fn test_abi_write_impl<A>(data: &A) -> Vec<u8>599 where600 A: evm_coder::abi::AbiWrite601 + evm_coder::abi::AbiRead602 + std::cmp::PartialEq603 + std::fmt::Debug,604 {605 let mut writer = evm_coder::abi::AbiWriter::new_call(FUNCTION_IDENTIFIER);606 data.abi_write(&mut writer);607 let encoded_tuple = writer.finish();608 encoded_tuple609 }610611 #[test]612 fn codec_struct_1_simple() {613 let _a = 0xff;614 test_impl::<(u8,), TupleStruct1SimpleParam, TypeStruct1SimpleParam>(615 (_a,),616 TupleStruct1SimpleParam(_a),617 TypeStruct1SimpleParam { _a },618 );619 }620621 #[test]622 fn codec_struct_1_dynamic() {623 let _a: String = "some string".into();624 test_impl::<(String,), TupleStruct1DynamicParam, TypeStruct1DynamicParam>(625 (_a.clone(),),626 TupleStruct1DynamicParam(_a.clone()),627 TypeStruct1DynamicParam { _a },628 );629 }630631 #[test]632 fn codec_struct_1_derived_simple() {633 let _a: u8 = 0xff;634 test_impl::<((u8,),), TupleStruct1DerivedSimpleParam, TypeStruct1DerivedSimpleParam>(635 ((_a,),),636 TupleStruct1DerivedSimpleParam(TupleStruct1SimpleParam(_a)),637 TypeStruct1DerivedSimpleParam {638 _a: TypeStruct1SimpleParam { _a },639 },640 );641 }642643 #[test]644 fn codec_struct_1_derived_dynamic() {645 let _a: String = "some string".into();646 test_impl::<((String,),), TupleStruct1DerivedDynamicParam, TypeStruct1DerivedDynamicParam>(647 ((_a.clone(),),),648 TupleStruct1DerivedDynamicParam(TupleStruct1DynamicParam(_a.clone())),649 TypeStruct1DerivedDynamicParam {650 _a: TypeStruct1DynamicParam { _a },651 },652 );653 }654655 #[test]656 fn codec_struct_2_simple() {657 let _a = 0xff;658 let _b = 0xbeefbaba;659 test_impl::<(u8, u32), TupleStruct2SimpleParam, TypeStruct2SimpleParam>(660 (_a, _b),661 TupleStruct2SimpleParam(_a, _b),662 TypeStruct2SimpleParam { _a, _b },663 );664 }665666 #[test]667 fn codec_struct_2_dynamic() {668 let _a: String = "some string".into();669 let _b: bytes = bytes(vec![0x11, 0x22, 0x33]);670 test_impl::<(String, bytes), TupleStruct2DynamicParam, TypeStruct2DynamicParam>(671 (_a.clone(), _b.clone()),672 TupleStruct2DynamicParam(_a.clone(), _b.clone()),673 TypeStruct2DynamicParam { _a, _b },674 );675 }676677 #[test]678 fn codec_struct_2_mixed() {679 let _a: u8 = 0xff;680 let _b: bytes = bytes(vec![0x11, 0x22, 0x33]);681 test_impl::<(u8, bytes), TupleStruct2MixedParam, TypeStruct2MixedParam>(682 (_a.clone(), _b.clone()),683 TupleStruct2MixedParam(_a.clone(), _b.clone()),684 TypeStruct2MixedParam { _a, _b },685 );686 }687688 #[test]689 fn codec_struct_2_derived_simple() {690 let _a = 0xff;691 let _b = 0xbeefbaba;692 test_impl::<693 ((u8,), (u8, u32)),694 TupleStruct2DerivedSimpleParam,695 TypeStruct2DerivedSimpleParam,696 >(697 ((_a,), (_a, _b)),698 TupleStruct2DerivedSimpleParam(699 TupleStruct1SimpleParam(_a),700 TupleStruct2SimpleParam(_a, _b),701 ),702 TypeStruct2DerivedSimpleParam {703 _a: TypeStruct1SimpleParam { _a },704 _b: TypeStruct2SimpleParam { _a, _b },705 },706 );707 }708709 #[test]710 fn codec_struct_2_derived_dynamic() {711 let _a = "some string".to_string();712 let _b = bytes(vec![0x11, 0x22, 0x33]);713 test_impl::<714 ((String,), (String, bytes)),715 TupleStruct2DerivedDynamicParam,716 TypeStruct2DerivedDynamicParam,717 >(718 ((_a.clone(),), (_a.clone(), _b.clone())),719 TupleStruct2DerivedDynamicParam(720 TupleStruct1DynamicParam(_a.clone()),721 TupleStruct2DynamicParam(_a.clone(), _b.clone()),722 ),723 TypeStruct2DerivedDynamicParam {724 _a: TypeStruct1DynamicParam { _a: _a.clone() },725 _b: TypeStruct2DynamicParam { _a, _b },726 },727 );728 }729730 #[test]731 fn codec_struct_3_derived_mixed() {732 let int = 0xff;733 let by = bytes(vec![0x11, 0x22, 0x33]);734 let string = "some string".to_string();735 test_impl::<736 ((u8,), (String, bytes), (u8, bytes)),737 TupleStruct3DerivedMixedParam,738 TypeStruct3DerivedMixedParam,739 >(740 ((int,), (string.clone(), by.clone()), (int, by.clone())),741 TupleStruct3DerivedMixedParam(742 TupleStruct1SimpleParam(int),743 TupleStruct2DynamicParam(string.clone(), by.clone()),744 TupleStruct2MixedParam(int, by.clone()),745 ),746 TypeStruct3DerivedMixedParam {747 _a: TypeStruct1SimpleParam { _a: int },748 _b: TypeStruct2DynamicParam {749 _a: string.clone(),750 _b: by.clone(),751 },752 _c: TypeStruct2MixedParam { _a: int, _b: by },753 },754 );755 }756757 #[derive(AbiCoder, PartialEq, Debug)]758 struct TypeStruct2SimpleStruct1Simple {759 _a: TypeStruct2SimpleParam,760 _b: TypeStruct2SimpleParam,761 _c: u8,762 }763 #[derive(AbiCoder, PartialEq, Debug)]764 struct TupleStruct2SimpleStruct1Simple(TupleStruct2SimpleParam, TupleStruct2SimpleParam, u8);765766 #[test]767 fn codec_struct_2_struct_simple_1_simple() {768 let _a = 0xff;769 let _b = 0xbeefbaba;770 test_impl::<771 ((u8, u32), (u8, u32), u8),772 TupleStruct2SimpleStruct1Simple,773 TypeStruct2SimpleStruct1Simple,774 >(775 ((_a, _b), (_a, _b), _a),776 TupleStruct2SimpleStruct1Simple(777 TupleStruct2SimpleParam(_a, _b),778 TupleStruct2SimpleParam(_a, _b),779 _a,780 ),781 TypeStruct2SimpleStruct1Simple {782 _a: TypeStruct2SimpleParam { _a, _b },783 _b: TypeStruct2SimpleParam { _a, _b },784 _c: _a,785 },786 );787 }788}789790mod test_enum {791 use evm_coder::AbiCoder;792793 /// Some docs794 /// At multi795 /// line796 #[derive(AbiCoder, Debug, PartialEq, Default, Clone, Copy)]797 #[repr(u8)]798 enum Color {799 /// Docs for Red800 /// multi801 /// line802 Red,803 Green,804 /// Docs for Blue805 #[default]806 Blue,807 }808809 #[test]810 fn empty() {}811812 #[test]813 fn bad_enums() {814 let t = trybuild::TestCases::new();815 t.compile_fail("tests/build_failed/abi_derive_enum_generation.rs");816 }817818 #[test]819 fn impl_abi_type_signature_same_for_structs() {820 assert_eq!(821 <Color as evm_coder::abi::AbiType>::SIGNATURE822 .as_str()823 .unwrap(),824 <u8 as evm_coder::abi::AbiType>::SIGNATURE.as_str().unwrap()825 );826 }827828 #[test]829 fn impl_abi_type_is_dynamic_same_for_structs() {830 assert_eq!(831 <Color as evm_coder::abi::AbiType>::is_dynamic(),832 <u8 as evm_coder::abi::AbiType>::is_dynamic()833 );834 }835836 #[test]837 fn impl_abi_type_size_same_for_structs() {838 assert_eq!(839 <Color as evm_coder::abi::AbiType>::size(),840 <u8 as evm_coder::abi::AbiType>::size()841 );842 }843844 #[test]845 fn test_coder() {846 const FUNCTION_IDENTIFIER: u32 = 0xdeadbeef;847848 let encoded_enum = {849 let mut writer = evm_coder::abi::AbiWriter::new_call(FUNCTION_IDENTIFIER);850 <Color as evm_coder::abi::AbiWrite>::abi_write(&Color::Green, &mut writer);851 writer.finish()852 };853854 let encoded_u8 = {855 let mut writer = evm_coder::abi::AbiWriter::new_call(FUNCTION_IDENTIFIER);856 <u8 as evm_coder::abi::AbiWrite>::abi_write(&(Color::Green as u8), &mut writer);857 writer.finish()858 };859860 similar_asserts::assert_eq!(encoded_enum, encoded_u8);861862 {863 let (_, mut decoder) = evm_coder::abi::AbiReader::new_call(&encoded_enum).unwrap();864 let restored_enum_data =865 <Color as evm_coder::abi::AbiRead>::abi_read(&mut decoder).unwrap();866 assert_eq!(restored_enum_data, Color::Green);867 }868 }869870 #[test]871 #[cfg(feature = "stubgen")]872 fn struct_collect_enum() {873 assert_eq!(874 <Color as ::evm_coder::solidity::StructCollect>::name(),875 "Color"876 );877 similar_asserts::assert_eq!(878 <Color as ::evm_coder::solidity::StructCollect>::declaration(),879 r#"/// @dev Some docs880/// At multi881/// line882enum Color {883 /// @dev Docs for Red884 /// multi885 /// line886 Red,887 Green,888 /// @dev Docs for Blue889 Blue890}891"#892 );893 }894}pallets/common/src/eth.rsdiffbeforeafterboth--- a/pallets/common/src/eth.rs
+++ b/pallets/common/src/eth.rs
@@ -16,6 +16,7 @@
//! The module contains a number of functions for converting and checking ethereum identifiers.
+use sp_std::{vec, vec::Vec};
use evm_coder::{
AbiCoder,
types::{uint256, address},
@@ -183,3 +184,102 @@
/// Permission to change the property for the owner of the token. See [`up_data_structs::PropertyPermission::collection_admin`]
CollectionAdmin,
}
+
+/// Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) as an key and value.
+#[derive(Debug, Default, AbiCoder)]
+pub struct PropertyPermission {
+ /// TokenPermission field.
+ code: EthTokenPermissions,
+ /// TokenPermission value.
+ value: bool,
+}
+
+impl PropertyPermission {
+ pub fn into_vec(pp: up_data_structs::PropertyPermission) -> Vec<Self> {
+ vec![
+ PropertyPermission {
+ code: EthTokenPermissions::Mutable,
+ value: pp.mutable,
+ },
+ PropertyPermission {
+ code: EthTokenPermissions::TokenOwner,
+ value: pp.token_owner,
+ },
+ PropertyPermission {
+ code: EthTokenPermissions::CollectionAdmin,
+ value: pp.collection_admin,
+ },
+ ]
+ }
+
+ pub fn from_vec(permission: Vec<Self>) -> up_data_structs::PropertyPermission {
+ let mut token_permission = up_data_structs::PropertyPermission::default();
+
+ for PropertyPermission { code, value } in permission {
+ match code {
+ EthTokenPermissions::Mutable => token_permission.mutable = value,
+ EthTokenPermissions::TokenOwner => token_permission.token_owner = value,
+ EthTokenPermissions::CollectionAdmin => token_permission.collection_admin = value,
+ }
+ }
+ token_permission
+ }
+}
+
+/// Ethereum representation of Token Property Permissions.
+#[derive(Debug, Default, AbiCoder)]
+pub struct TokenPropertyPermission {
+ /// Token property key.
+ key: evm_coder::types::string,
+ /// Token property permissions.
+ permissions: Vec<PropertyPermission>,
+}
+
+impl
+ From<(
+ up_data_structs::PropertyKey,
+ up_data_structs::PropertyPermission,
+ )> for TokenPropertyPermission
+{
+ fn from(
+ value: (
+ up_data_structs::PropertyKey,
+ up_data_structs::PropertyPermission,
+ ),
+ ) -> Self {
+ let (key, permission) = value;
+ let key = evm_coder::types::string::from_utf8(key.into_inner())
+ .expect("Stored key must be valid");
+ let permissions = PropertyPermission::into_vec(permission);
+ Self { key, permissions }
+ }
+}
+
+impl TokenPropertyPermission {
+ pub fn into_property_key_permissions(
+ permissions: Vec<TokenPropertyPermission>,
+ ) -> evm_coder::execution::Result<Vec<up_data_structs::PropertyKeyPermission>> {
+ let mut perms = Vec::new();
+
+ for TokenPropertyPermission { key, permissions } in permissions {
+ if permissions.len() > <EthTokenPermissions as evm_coder::abi::AbiType>::FIELDS_COUNT {
+ return Err(alloc::format!(
+ "Actual number of fields {} for {}, which exceeds the maximum value of {}",
+ permissions.len(),
+ stringify!(EthTokenPermissions),
+ <EthTokenPermissions as evm_coder::abi::AbiType>::FIELDS_COUNT
+ )
+ .as_str()
+ .into());
+ }
+
+ let token_permission = PropertyPermission::from_vec(permissions);
+
+ perms.push(up_data_structs::PropertyKeyPermission {
+ key: key.into_bytes().try_into().map_err(|_| "too long key")?,
+ permission: token_permission,
+ });
+ }
+ Ok(perms)
+ }
+}
pallets/evm-contract-helpers/src/stubs/ContractHelpers.rawdiffbeforeafterbothbinary blob — no preview
pallets/fungible/src/stubs/UniqueFungible.rawdiffbeforeafterbothbinary blob — no preview
pallets/fungible/src/stubs/UniqueFungible.soldiffbeforeafterboth--- a/pallets/fungible/src/stubs/UniqueFungible.sol
+++ b/pallets/fungible/src/stubs/UniqueFungible.sol
@@ -470,9 +470,12 @@
uint256 sub;
}
+/// @dev Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) fields as an enumeration.
enum CollectionPermissions {
- CollectionAdmin,
- TokenOwner
+ /// @dev Owner of token can nest tokens under it.
+ TokenOwner,
+ /// @dev Admin of token collection can nest tokens under token.
+ CollectionAdmin
}
/// @dev anonymous struct
@@ -516,9 +519,11 @@
uint256 field_2;
}
-/// @dev Property struct
+/// @dev Ethereum representation of collection [`PropertyKey`](up_data_structs::PropertyKey) and [`PropertyValue`](up_data_structs::PropertyValue).
struct Property {
+ /// @dev Property key.
string key;
+ /// @dev Property value.
bytes value;
}
pallets/nonfungible/src/erc.rsdiffbeforeafterboth--- a/pallets/nonfungible/src/erc.rs
+++ b/pallets/nonfungible/src/erc.rs
@@ -38,7 +38,7 @@
use pallet_common::{
CollectionHandle, CollectionPropertyPermissions, CommonCollectionOperations,
erc::{CommonEvmHandler, PrecompileResult, CollectionCall, static_property::key},
- eth::{Property as PropertyStruct, EthCrossAccount, EthTokenPermissions},
+ eth::{Property as PropertyStruct, EthCrossAccount},
};
use pallet_evm::{account::CrossAccountId, PrecompileHandle};
use pallet_evm_coder_substrate::call;
@@ -94,40 +94,12 @@
fn set_token_property_permissions(
&mut self,
caller: caller,
- permissions: Vec<(string, Vec<(EthTokenPermissions, bool)>)>,
+ permissions: Vec<pallet_common::eth::TokenPropertyPermission>,
) -> Result<()> {
let caller = T::CrossAccountId::from_eth(caller);
- let mut perms = Vec::new();
-
- for (key, pp) in permissions {
- if pp.len() > EthTokenPermissions::FIELDS_COUNT {
- return Err(alloc::format!(
- "Actual number of fields {} for {}, which exceeds the maximum value of {}",
- pp.len(),
- stringify!(EthTokenPermissions),
- EthTokenPermissions::FIELDS_COUNT
- )
- .as_str()
- .into());
- }
-
- let mut token_permission = PropertyPermission::default();
-
- for (perm, value) in pp {
- match perm {
- EthTokenPermissions::Mutable => token_permission.mutable = value,
- EthTokenPermissions::TokenOwner => token_permission.token_owner = value,
- EthTokenPermissions::CollectionAdmin => {
- token_permission.collection_admin = value
- }
- }
- }
-
- perms.push(PropertyKeyPermission {
- key: key.into_bytes().try_into().map_err(|_| "too long key")?,
- permission: token_permission,
- });
- }
+ let perms = pallet_common::eth::TokenPropertyPermission::into_property_key_permissions(
+ permissions,
+ )?;
<Pallet<T>>::set_token_property_permissions(self, &caller, perms)
.map_err(dispatch_to_evm::<T>)
@@ -136,19 +108,11 @@
/// @notice Get permissions for token properties.
fn token_property_permissions(
&self,
- ) -> Result<Vec<(string, Vec<(EthTokenPermissions, bool)>)>> {
+ ) -> Result<Vec<pallet_common::eth::TokenPropertyPermission>> {
let perms = <Pallet<T>>::token_property_permission(self.id);
Ok(perms
.into_iter()
- .map(|(key, pp)| {
- let key = string::from_utf8(key.into_inner()).expect("Stored key must be valid");
- let pp = vec![
- (EthTokenPermissions::Mutable, pp.mutable),
- (EthTokenPermissions::TokenOwner, pp.token_owner),
- (EthTokenPermissions::CollectionAdmin, pp.collection_admin),
- ];
- (key, pp)
- })
+ .map(pallet_common::eth::TokenPropertyPermission::from)
.collect())
}
pallets/nonfungible/src/stubs/UniqueNFT.rawdiffbeforeafterbothbinary blob — no preview
pallets/nonfungible/src/stubs/UniqueNFT.soldiffbeforeafterboth--- a/pallets/nonfungible/src/stubs/UniqueNFT.sol
+++ b/pallets/nonfungible/src/stubs/UniqueNFT.sol
@@ -42,7 +42,7 @@
/// @param permissions Permissions for keys.
/// @dev EVM selector for this function is: 0xbd92983a,
/// or in textual repr: setTokenPropertyPermissions((string,(uint8,bool)[])[])
- function setTokenPropertyPermissions(Tuple61[] memory permissions) public {
+ function setTokenPropertyPermissions(TokenPropertyPermission[] memory permissions) public {
require(false, stub_error);
permissions;
dummy = 0;
@@ -51,10 +51,10 @@
/// @notice Get permissions for token properties.
/// @dev EVM selector for this function is: 0xf23d7790,
/// or in textual repr: tokenPropertyPermissions()
- function tokenPropertyPermissions() public view returns (Tuple61[] memory) {
+ function tokenPropertyPermissions() public view returns (TokenPropertyPermission[] memory) {
require(false, stub_error);
dummy;
- return new Tuple61[](0);
+ return new TokenPropertyPermission[](0);
}
// /// @notice Set token property value.
@@ -127,12 +127,30 @@
}
}
-/// @dev Property struct
+/// @dev Ethereum representation of collection [`PropertyKey`](up_data_structs::PropertyKey) and [`PropertyValue`](up_data_structs::PropertyValue).
struct Property {
+ /// @dev Property key.
string key;
+ /// @dev Property value.
bytes value;
}
+/// @dev Ethereum representation of Token Property Permissions.
+struct TokenPropertyPermission {
+ /// @dev Token property key.
+ string key;
+ /// @dev Token property permissions.
+ PropertyPermission[] permissions;
+}
+
+/// @dev Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) as an key and value.
+struct PropertyPermission {
+ /// @dev TokenPermission field.
+ EthTokenPermissions code;
+ /// @dev TokenPermission value.
+ bool value;
+}
+
/// @dev Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) fields as an enumeration.
enum EthTokenPermissions {
/// @dev Permission to change the property and property permission. See [`up_data_structs::PropertyPermission::mutable`]
@@ -141,18 +159,6 @@
TokenOwner,
/// @dev Permission to change the property for the owner of the token. See [`up_data_structs::PropertyPermission::collection_admin`]
CollectionAdmin
-}
-
-/// @dev anonymous struct
-struct Tuple61 {
- string field_0;
- Tuple59[] field_1;
-}
-
-/// @dev anonymous struct
-struct Tuple59 {
- EthTokenPermissions field_0;
- bool field_1;
}
/// @title A contract that allows you to work with collections.
@@ -608,9 +614,12 @@
uint256 sub;
}
+/// @dev Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) fields as an enumeration.
enum CollectionPermissions {
- CollectionAdmin,
- TokenOwner
+ /// @dev Owner of token can nest tokens under it.
+ TokenOwner,
+ /// @dev Admin of token collection can nest tokens under token.
+ CollectionAdmin
}
/// @dev anonymous struct
pallets/refungible/src/erc.rsdiffbeforeafterboth--- a/pallets/refungible/src/erc.rs
+++ b/pallets/refungible/src/erc.rs
@@ -33,7 +33,7 @@
use pallet_common::{
CollectionHandle, CollectionPropertyPermissions, CommonCollectionOperations,
erc::{CommonEvmHandler, CollectionCall, static_property::key},
- eth::{Property as PropertyStruct, EthCrossAccount, EthTokenPermissions},
+ eth::{Property as PropertyStruct, EthCrossAccount},
Error as CommonError,
};
use pallet_evm::{account::CrossAccountId, PrecompileHandle};
@@ -97,47 +97,13 @@
fn set_token_property_permissions(
&mut self,
caller: caller,
- permissions: Vec<(string, Vec<(EthTokenPermissions, bool)>)>,
+ permissions: Vec<pallet_common::eth::TokenPropertyPermission>,
) -> Result<()> {
let caller = T::CrossAccountId::from_eth(caller);
- const PERMISSIONS_FIELDS_COUNT: usize = 3;
-
- let mut perms = Vec::new();
-
- for (key, pp) in permissions {
- if pp.len() > PERMISSIONS_FIELDS_COUNT {
- return Err(alloc::format!(
- "Actual number of fields {} for {}, which exceeds the maximum value of {}",
- pp.len(),
- stringify!(EthTokenPermissions),
- PERMISSIONS_FIELDS_COUNT
- )
- .as_str()
- .into());
- }
-
- let mut token_permission = PropertyPermission {
- mutable: false,
- collection_admin: false,
- token_owner: false,
- };
+ let perms = pallet_common::eth::TokenPropertyPermission::into_property_key_permissions(
+ permissions,
+ )?;
- for (perm, value) in pp {
- match perm {
- EthTokenPermissions::Mutable => token_permission.mutable = value,
- EthTokenPermissions::TokenOwner => token_permission.token_owner = value,
- EthTokenPermissions::CollectionAdmin => {
- token_permission.collection_admin = value
- }
- }
- }
-
- perms.push(PropertyKeyPermission {
- key: key.into_bytes().try_into().map_err(|_| "too long key")?,
- permission: token_permission,
- });
- }
-
<Pallet<T>>::set_token_property_permissions(self, &caller, perms)
.map_err(dispatch_to_evm::<T>)
}
@@ -145,19 +111,11 @@
/// @notice Get permissions for token properties.
fn token_property_permissions(
&self,
- ) -> Result<Vec<(string, Vec<(EthTokenPermissions, bool)>)>> {
+ ) -> Result<Vec<pallet_common::eth::TokenPropertyPermission>> {
let perms = <Pallet<T>>::token_property_permission(self.id);
Ok(perms
.into_iter()
- .map(|(key, pp)| {
- let key = string::from_utf8(key.into_inner()).expect("Stored key must be valid");
- let pp = vec![
- (EthTokenPermissions::Mutable, pp.mutable),
- (EthTokenPermissions::TokenOwner, pp.token_owner),
- (EthTokenPermissions::CollectionAdmin, pp.collection_admin),
- ];
- (key, pp)
- })
+ .map(pallet_common::eth::TokenPropertyPermission::from)
.collect())
}
pallets/refungible/src/stubs/UniqueRefungible.rawdiffbeforeafterbothbinary blob — no preview
pallets/refungible/src/stubs/UniqueRefungible.soldiffbeforeafterboth--- a/pallets/refungible/src/stubs/UniqueRefungible.sol
+++ b/pallets/refungible/src/stubs/UniqueRefungible.sol
@@ -42,7 +42,7 @@
/// @param permissions Permissions for keys.
/// @dev EVM selector for this function is: 0xbd92983a,
/// or in textual repr: setTokenPropertyPermissions((string,(uint8,bool)[])[])
- function setTokenPropertyPermissions(Tuple60[] memory permissions) public {
+ function setTokenPropertyPermissions(TokenPropertyPermission[] memory permissions) public {
require(false, stub_error);
permissions;
dummy = 0;
@@ -51,10 +51,10 @@
/// @notice Get permissions for token properties.
/// @dev EVM selector for this function is: 0xf23d7790,
/// or in textual repr: tokenPropertyPermissions()
- function tokenPropertyPermissions() public view returns (Tuple60[] memory) {
+ function tokenPropertyPermissions() public view returns (TokenPropertyPermission[] memory) {
require(false, stub_error);
dummy;
- return new Tuple60[](0);
+ return new TokenPropertyPermission[](0);
}
// /// @notice Set token property value.
@@ -127,12 +127,30 @@
}
}
-/// @dev Property struct
+/// @dev Ethereum representation of collection [`PropertyKey`](up_data_structs::PropertyKey) and [`PropertyValue`](up_data_structs::PropertyValue).
struct Property {
+ /// @dev Property key.
string key;
+ /// @dev Property value.
bytes value;
}
+/// @dev Ethereum representation of Token Property Permissions.
+struct TokenPropertyPermission {
+ /// @dev Token property key.
+ string key;
+ /// @dev Token property permissions.
+ PropertyPermission[] permissions;
+}
+
+/// @dev Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) as an key and value.
+struct PropertyPermission {
+ /// @dev TokenPermission field.
+ EthTokenPermissions code;
+ /// @dev TokenPermission value.
+ bool value;
+}
+
/// @dev Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) fields as an enumeration.
enum EthTokenPermissions {
/// @dev Permission to change the property and property permission. See [`up_data_structs::PropertyPermission::mutable`]
@@ -141,18 +159,6 @@
TokenOwner,
/// @dev Permission to change the property for the owner of the token. See [`up_data_structs::PropertyPermission::collection_admin`]
CollectionAdmin
-}
-
-/// @dev anonymous struct
-struct Tuple60 {
- string field_0;
- Tuple58[] field_1;
-}
-
-/// @dev anonymous struct
-struct Tuple58 {
- EthTokenPermissions field_0;
- bool field_1;
}
/// @title A contract that allows you to work with collections.
@@ -608,9 +614,12 @@
uint256 sub;
}
+/// @dev Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) fields as an enumeration.
enum CollectionPermissions {
- CollectionAdmin,
- TokenOwner
+ /// @dev Owner of token can nest tokens under it.
+ TokenOwner,
+ /// @dev Admin of token collection can nest tokens under token.
+ CollectionAdmin
}
/// @dev anonymous struct
pallets/refungible/src/stubs/UniqueRefungibleToken.rawdiffbeforeafterbothbinary blob — no preview
pallets/unique/src/eth/stubs/CollectionHelpers.rawdiffbeforeafterbothbinary blob — no preview
tests/src/eth/abi/nonFungible.jsondiffbeforeafterboth--- a/tests/src/eth/abi/nonFungible.json
+++ b/tests/src/eth/abi/nonFungible.json
@@ -752,22 +752,22 @@
"inputs": [
{
"components": [
- { "internalType": "string", "name": "field_0", "type": "string" },
+ { "internalType": "string", "name": "key", "type": "string" },
{
"components": [
{
"internalType": "enum EthTokenPermissions",
- "name": "field_0",
+ "name": "code",
"type": "uint8"
},
- { "internalType": "bool", "name": "field_1", "type": "bool" }
+ { "internalType": "bool", "name": "value", "type": "bool" }
],
- "internalType": "struct Tuple59[]",
- "name": "field_1",
+ "internalType": "struct PropertyPermission[]",
+ "name": "permissions",
"type": "tuple[]"
}
],
- "internalType": "struct Tuple61[]",
+ "internalType": "struct TokenPropertyPermission[]",
"name": "permissions",
"type": "tuple[]"
}
@@ -818,22 +818,22 @@
"outputs": [
{
"components": [
- { "internalType": "string", "name": "field_0", "type": "string" },
+ { "internalType": "string", "name": "key", "type": "string" },
{
"components": [
{
"internalType": "enum EthTokenPermissions",
- "name": "field_0",
+ "name": "code",
"type": "uint8"
},
- { "internalType": "bool", "name": "field_1", "type": "bool" }
+ { "internalType": "bool", "name": "value", "type": "bool" }
],
- "internalType": "struct Tuple59[]",
- "name": "field_1",
+ "internalType": "struct PropertyPermission[]",
+ "name": "permissions",
"type": "tuple[]"
}
],
- "internalType": "struct Tuple61[]",
+ "internalType": "struct TokenPropertyPermission[]",
"name": "",
"type": "tuple[]"
}
tests/src/eth/abi/reFungible.jsondiffbeforeafterboth--- a/tests/src/eth/abi/reFungible.json
+++ b/tests/src/eth/abi/reFungible.json
@@ -734,22 +734,22 @@
"inputs": [
{
"components": [
- { "internalType": "string", "name": "field_0", "type": "string" },
+ { "internalType": "string", "name": "key", "type": "string" },
{
"components": [
{
"internalType": "enum EthTokenPermissions",
- "name": "field_0",
+ "name": "code",
"type": "uint8"
},
- { "internalType": "bool", "name": "field_1", "type": "bool" }
+ { "internalType": "bool", "name": "value", "type": "bool" }
],
- "internalType": "struct Tuple58[]",
- "name": "field_1",
+ "internalType": "struct PropertyPermission[]",
+ "name": "permissions",
"type": "tuple[]"
}
],
- "internalType": "struct Tuple60[]",
+ "internalType": "struct TokenPropertyPermission[]",
"name": "permissions",
"type": "tuple[]"
}
@@ -809,22 +809,22 @@
"outputs": [
{
"components": [
- { "internalType": "string", "name": "field_0", "type": "string" },
+ { "internalType": "string", "name": "key", "type": "string" },
{
"components": [
{
"internalType": "enum EthTokenPermissions",
- "name": "field_0",
+ "name": "code",
"type": "uint8"
},
- { "internalType": "bool", "name": "field_1", "type": "bool" }
+ { "internalType": "bool", "name": "value", "type": "bool" }
],
- "internalType": "struct Tuple58[]",
- "name": "field_1",
+ "internalType": "struct PropertyPermission[]",
+ "name": "permissions",
"type": "tuple[]"
}
],
- "internalType": "struct Tuple60[]",
+ "internalType": "struct TokenPropertyPermission[]",
"name": "",
"type": "tuple[]"
}
tests/src/eth/api/UniqueFungible.soldiffbeforeafterboth--- a/tests/src/eth/api/UniqueFungible.sol
+++ b/tests/src/eth/api/UniqueFungible.sol
@@ -316,9 +316,12 @@
bool field_1;
}
+/// @dev Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) fields as an enumeration.
enum CollectionPermissions {
- CollectionAdmin,
- TokenOwner
+ /// @dev Owner of token can nest tokens under it.
+ TokenOwner,
+ /// @dev Admin of token collection can nest tokens under token.
+ CollectionAdmin
}
/// @dev anonymous struct
@@ -356,9 +359,11 @@
uint256 field_2;
}
-/// @dev Property struct
+/// @dev Ethereum representation of collection [`PropertyKey`](up_data_structs::PropertyKey) and [`PropertyValue`](up_data_structs::PropertyValue).
struct Property {
+ /// @dev Property key.
string key;
+ /// @dev Property value.
bytes value;
}
tests/src/eth/api/UniqueNFT.soldiffbeforeafterboth--- a/tests/src/eth/api/UniqueNFT.sol
+++ b/tests/src/eth/api/UniqueNFT.sol
@@ -30,12 +30,12 @@
/// @param permissions Permissions for keys.
/// @dev EVM selector for this function is: 0xbd92983a,
/// or in textual repr: setTokenPropertyPermissions((string,(uint8,bool)[])[])
- function setTokenPropertyPermissions(Tuple53[] memory permissions) external;
+ function setTokenPropertyPermissions(TokenPropertyPermission[] memory permissions) external;
/// @notice Get permissions for token properties.
/// @dev EVM selector for this function is: 0xf23d7790,
/// or in textual repr: tokenPropertyPermissions()
- function tokenPropertyPermissions() external view returns (Tuple53[] memory);
+ function tokenPropertyPermissions() external view returns (TokenPropertyPermission[] memory);
// /// @notice Set token property value.
// /// @dev Throws error if `msg.sender` has no permission to edit the property.
@@ -80,12 +80,30 @@
function property(uint256 tokenId, string memory key) external view returns (bytes memory);
}
-/// @dev Property struct
+/// @dev Ethereum representation of collection [`PropertyKey`](up_data_structs::PropertyKey) and [`PropertyValue`](up_data_structs::PropertyValue).
struct Property {
+ /// @dev Property key.
string key;
+ /// @dev Property value.
bytes value;
}
+/// @dev Ethereum representation of Token Property Permissions.
+struct TokenPropertyPermission {
+ /// @dev Token property key.
+ string key;
+ /// @dev Token property permissions.
+ PropertyPermission[] permissions;
+}
+
+/// @dev Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) as an key and value.
+struct PropertyPermission {
+ /// @dev TokenPermission field.
+ EthTokenPermissions code;
+ /// @dev TokenPermission value.
+ bool value;
+}
+
/// @dev Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) fields as an enumeration.
enum EthTokenPermissions {
/// @dev Permission to change the property and property permission. See [`up_data_structs::PropertyPermission::mutable`]
@@ -96,18 +114,6 @@
CollectionAdmin
}
-/// @dev anonymous struct
-struct Tuple53 {
- string field_0;
- Tuple51[] field_1;
-}
-
-/// @dev anonymous struct
-struct Tuple51 {
- EthTokenPermissions field_0;
- bool field_1;
-}
-
/// @title A contract that allows you to work with collections.
/// @dev the ERC-165 identifier for this interface is 0x81172a75
interface Collection is Dummy, ERC165 {
@@ -412,9 +418,12 @@
bool field_1;
}
+/// @dev Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) fields as an enumeration.
enum CollectionPermissions {
- CollectionAdmin,
- TokenOwner
+ /// @dev Owner of token can nest tokens under it.
+ TokenOwner,
+ /// @dev Admin of token collection can nest tokens under token.
+ CollectionAdmin
}
/// @dev anonymous struct
tests/src/eth/api/UniqueRefungible.soldiffbeforeafterboth--- a/tests/src/eth/api/UniqueRefungible.sol
+++ b/tests/src/eth/api/UniqueRefungible.sol
@@ -30,12 +30,12 @@
/// @param permissions Permissions for keys.
/// @dev EVM selector for this function is: 0xbd92983a,
/// or in textual repr: setTokenPropertyPermissions((string,(uint8,bool)[])[])
- function setTokenPropertyPermissions(Tuple52[] memory permissions) external;
+ function setTokenPropertyPermissions(TokenPropertyPermission[] memory permissions) external;
/// @notice Get permissions for token properties.
/// @dev EVM selector for this function is: 0xf23d7790,
/// or in textual repr: tokenPropertyPermissions()
- function tokenPropertyPermissions() external view returns (Tuple52[] memory);
+ function tokenPropertyPermissions() external view returns (TokenPropertyPermission[] memory);
// /// @notice Set token property value.
// /// @dev Throws error if `msg.sender` has no permission to edit the property.
@@ -80,12 +80,30 @@
function property(uint256 tokenId, string memory key) external view returns (bytes memory);
}
-/// @dev Property struct
+/// @dev Ethereum representation of collection [`PropertyKey`](up_data_structs::PropertyKey) and [`PropertyValue`](up_data_structs::PropertyValue).
struct Property {
+ /// @dev Property key.
string key;
+ /// @dev Property value.
bytes value;
}
+/// @dev Ethereum representation of Token Property Permissions.
+struct TokenPropertyPermission {
+ /// @dev Token property key.
+ string key;
+ /// @dev Token property permissions.
+ PropertyPermission[] permissions;
+}
+
+/// @dev Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) as an key and value.
+struct PropertyPermission {
+ /// @dev TokenPermission field.
+ EthTokenPermissions code;
+ /// @dev TokenPermission value.
+ bool value;
+}
+
/// @dev Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) fields as an enumeration.
enum EthTokenPermissions {
/// @dev Permission to change the property and property permission. See [`up_data_structs::PropertyPermission::mutable`]
@@ -96,18 +114,6 @@
CollectionAdmin
}
-/// @dev anonymous struct
-struct Tuple52 {
- string field_0;
- Tuple50[] field_1;
-}
-
-/// @dev anonymous struct
-struct Tuple50 {
- EthTokenPermissions field_0;
- bool field_1;
-}
-
/// @title A contract that allows you to work with collections.
/// @dev the ERC-165 identifier for this interface is 0x81172a75
interface Collection is Dummy, ERC165 {
@@ -412,9 +418,12 @@
bool field_1;
}
+/// @dev Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) fields as an enumeration.
enum CollectionPermissions {
- CollectionAdmin,
- TokenOwner
+ /// @dev Owner of token can nest tokens under it.
+ TokenOwner,
+ /// @dev Admin of token collection can nest tokens under token.
+ CollectionAdmin
}
/// @dev anonymous struct