git.delta.rocks / unique-network / refs/commits / ae3e88161256

difftreelog

feat implicit implementation of ERC165

Yaroslav Bolyukin2021-10-12parent: #39e1fa4.patch.diff
in: master

2 files changed

modifiedcrates/evm-coder-macros/src/solidity_interface.rsdiffbeforeafterboth
--- a/crates/evm-coder-macros/src/solidity_interface.rs
+++ b/crates/evm-coder-macros/src/solidity_interface.rs
@@ -672,6 +672,7 @@
 		quote! {
 			#[derive(Debug)]
 			pub enum #call_name {
+				ERC165Call(::evm_coder::ERC165Call),
 				#(
 					#calls,
 				)*
@@ -691,6 +692,7 @@
 				}
 				pub fn supports_interface(interface_id: u32) -> bool {
 					interface_id != 0xffffff && (
+						interface_id == ::evm_coder::ERC165Call::INTERFACE_ID ||
 						interface_id == Self::interface_id()
 						#(
 							|| #supports_interface
@@ -702,7 +704,7 @@
 					use core::fmt::Write;
 					let interface = SolidityInterface {
 						name: #solidity_name,
-						is: &["Dummy", #(
+						is: &["Dummy", "ERC165", #(
 							#solidity_is,
 						)* #(
 							#solidity_events_is,
@@ -712,9 +714,9 @@
 						)*),
 					};
 					if is_impl {
-						tc.collect("// Common stubs holder\ncontract Dummy {\n\tuint8 dummy;\n\tstring stub_error = \"this contract is implemented in native\";\n}\n".into());
+						tc.collect("// Common stubs holder\ncontract Dummy {\n\tuint8 dummy;\n\tstring stub_error = \"this contract is implemented in native\";\n}\ninterface ERC165 {\n\tfunction supportsInterface(bytes4 interfaceID) external view returns (bool) {\n\t\trequire(false, stub_error);\n\t\tinterfaceID;\n\t\treturn true;\n\t}\n}\n".into());
 					} else {
-						tc.collect("// Common stubs holder\ninterface Dummy {\n}\n".into());
+						tc.collect("// Common stubs holder\ninterface Dummy {\n}\ninterface ERC165 {\n\tfunction supportsInterface(bytes4 interfaceID) external view returns (bool);\n}\n".into());
 					}
 					#(
 						#solidity_generators
@@ -737,6 +739,7 @@
 				fn parse(method_id: u32, reader: &mut ::evm_coder::abi::AbiReader) -> ::evm_coder::execution::Result<Option<Self>> {
 					use ::evm_coder::abi::AbiRead;
 					match method_id {
+						::evm_coder::ERC165Call::INTERFACE_ID => return Ok(::evm_coder::ERC165Call::parse(method_id, reader)?.map(Self::ERC165Call)),
 						#(
 							#parsers,
 						)*
@@ -757,6 +760,11 @@
 						#(
 							#call_variants,
 						)*
+						InternalCall::ERC165Call(::evm_coder::ERC165Call::SupportsInterface {interface_id}) => {
+							let mut writer = ::evm_coder::abi::AbiWriter::default();
+							writer.bool(&InternalCall::supports_interface(interface_id));
+							return Ok(writer);
+						}
 						_ => {},
 					}
 					let mut writer = ::evm_coder::abi::AbiWriter::default();
modifiedcrates/evm-coder/src/lib.rsdiffbeforeafterboth
before · crates/evm-coder/src/lib.rs
1#![cfg_attr(not(feature = "std"), no_std)]2#[cfg(not(feature = "std"))]3extern crate alloc;45use abi::{AbiReader, AbiWriter};6pub use evm_coder_macros::{event_topic, fn_selector, solidity_interface, solidity, ToLog};7pub mod abi;8pub mod events;9pub use events::ToLog;10pub mod execution;11pub mod solidity;1213/// Solidity type definitions14pub mod types {15	#![allow(non_camel_case_types)]1617	#[cfg(not(feature = "std"))]18	use alloc::{vec::Vec};19	use primitive_types::{U256, H160, H256};2021	pub type address = H160;2223	pub type uint8 = u8;24	pub type uint16 = u16;25	pub type uint32 = u32;26	pub type uint64 = u64;27	pub type uint128 = u128;28	pub type uint256 = U256;2930	pub type bytes4 = u32;3132	pub type topic = H256;3334	#[cfg(not(feature = "std"))]35	pub type string = ::alloc::string::String;36	#[cfg(feature = "std")]37	pub type string = ::std::string::String;38	pub type bytes = Vec<u8>;3940	pub type void = ();4142	//#region Special types43	/// Makes function payable44	pub type value = U256;45	/// Makes function caller-sensitive46	pub type caller = address;47	//#endregion4849	pub struct Msg<C> {50		pub call: C,51		pub caller: H160,52		pub value: U256,53	}54}5556pub trait Call: Sized {57	fn parse(selector: u32, input: &mut AbiReader) -> execution::Result<Option<Self>>;58}5960pub trait Callable<C: Call> {61	fn call(&mut self, call: types::Msg<C>) -> execution::Result<AbiWriter>;62}6364#[macro_export]65macro_rules! generate_stubgen {66	($name:ident, $decl:ident, $is_impl:literal) => {67		#[test]68		#[ignore]69		fn $name() {70			use evm_coder::solidity::TypeCollector;71			let mut out = TypeCollector::new();72			$decl::generate_solidity_interface(&mut out, $is_impl);73			println!("=== SNIP START ===");74			println!("// SPDX-License-Identifier: OTHER");75			println!("// This code is automatically generated");76			println!();77			println!("pragma solidity >=0.8.0 <0.9.0;");78			println!();79			for b in out.finish() {80				println!("{}", b);81			}82			println!("=== SNIP END ===");83		}84	};85}8687#[cfg(test)]88mod tests {89	use super::*;9091	#[test]92	fn function_selector_generation() {93		assert_eq!(fn_selector!(transfer(address, uint256)), 0xa9059cbb);94	}9596	#[test]97	fn event_topic_generation() {98		assert_eq!(99			hex::encode(&event_topic!(Transfer(address, address, uint256))[..]),100			"ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",101		);102	}103}
after · crates/evm-coder/src/lib.rs
1#![cfg_attr(not(feature = "std"), no_std)]2#[cfg(not(feature = "std"))]3extern crate alloc;45use abi::{AbiRead, AbiReader, AbiWriter};6pub use evm_coder_macros::{event_topic, fn_selector, solidity_interface, solidity, ToLog};7pub mod abi;8pub mod events;9pub use events::ToLog;10pub mod execution;11pub mod solidity;1213/// Solidity type definitions14pub mod types {15	#![allow(non_camel_case_types)]1617	#[cfg(not(feature = "std"))]18	use alloc::{vec::Vec};19	use primitive_types::{U256, H160, H256};2021	pub type address = H160;2223	pub type uint8 = u8;24	pub type uint16 = u16;25	pub type uint32 = u32;26	pub type uint64 = u64;27	pub type uint128 = u128;28	pub type uint256 = U256;2930	pub type bytes4 = u32;3132	pub type topic = H256;3334	#[cfg(not(feature = "std"))]35	pub type string = ::alloc::string::String;36	#[cfg(feature = "std")]37	pub type string = ::std::string::String;38	pub type bytes = Vec<u8>;3940	pub type void = ();4142	//#region Special types43	/// Makes function payable44	pub type value = U256;45	/// Makes function caller-sensitive46	pub type caller = address;47	//#endregion4849	pub struct Msg<C> {50		pub call: C,51		pub caller: H160,52		pub value: U256,53	}54}5556pub trait Call: Sized {57	fn parse(selector: u32, input: &mut AbiReader) -> execution::Result<Option<Self>>;58}5960pub trait Callable<C: Call> {61	fn call(&mut self, call: types::Msg<C>) -> execution::Result<AbiWriter>;62}6364/// Implementation is implicitly provided for all interfaces65///66/// Note: no Callable implementation is provided67#[derive(Debug)]68pub enum ERC165Call {69	SupportsInterface { interface_id: types::bytes4 },70}7172impl ERC165Call {73	pub const INTERFACE_ID: types::bytes4 = 0x01ffc9a7;74}7576impl Call for ERC165Call {77	fn parse(selector: u32, input: &mut AbiReader) -> execution::Result<Option<Self>> {78		if selector != Self::INTERFACE_ID {79			return Ok(None);80		}81		Ok(Some(Self::SupportsInterface {82			interface_id: input.abi_read()?,83		}))84	}85}8687#[macro_export]88macro_rules! generate_stubgen {89	($name:ident, $decl:ident, $is_impl:literal) => {90		#[test]91		#[ignore]92		fn $name() {93			use evm_coder::solidity::TypeCollector;94			let mut out = TypeCollector::new();95			$decl::generate_solidity_interface(&mut out, $is_impl);96			println!("=== SNIP START ===");97			println!("// SPDX-License-Identifier: OTHER");98			println!("// This code is automatically generated");99			println!();100			println!("pragma solidity >=0.8.0 <0.9.0;");101			println!();102			for b in out.finish() {103				println!("{}", b);104			}105			println!("=== SNIP END ===");106		}107	};108}109110#[cfg(test)]111mod tests {112	use super::*;113114	#[test]115	fn function_selector_generation() {116		assert_eq!(fn_selector!(transfer(address, uint256)), 0xa9059cbb);117	}118119	#[test]120	fn event_topic_generation() {121		assert_eq!(122			hex::encode(&event_topic!(Transfer(address, address, uint256))[..]),123			"ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",124		);125	}126}