difftreelog
feat(evm-coder) implementation generator
in: master
8 files changed
crates/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
@@ -73,6 +73,20 @@
}
}
}
+
+ fn expand_generator(&self) -> proc_macro2::TokenStream {
+ let pascal_call_name = &self.pascal_call_name;
+ quote! {
+ #pascal_call_name::generate_solidity_interface(out_set, is_impl);
+ }
+ }
+
+ fn expand_event_generator(&self) -> proc_macro2::TokenStream {
+ let name = &self.name;
+ quote! {
+ #name::generate_solidity_interface(out_set, is_impl);
+ }
+ }
}
#[derive(Default)]
@@ -109,12 +123,15 @@
struct MethodArg {
name: Ident,
+ camel_name: String,
ty: Ident,
}
impl MethodArg {
fn try_from(value: &PatType) -> syn::Result<Self> {
+ let name = parse_ident_from_pat(&value.pat)?.clone();
Ok(Self {
- name: parse_ident_from_pat(&value.pat)?.clone(),
+ camel_name: cases::camelcase::to_camel_case(&name.to_string()),
+ name,
ty: parse_ident_from_type(&value.ty, false)?.clone(),
})
}
@@ -168,10 +185,10 @@
}
fn expand_solidity_argument(&self) -> proc_macro2::TokenStream {
- let name = &self.name.to_string();
+ let camel_name = &self.camel_name.to_string();
let ty = &self.ty;
quote! {
- <NamedArgument<#ty>>::new(#name)
+ <NamedArgument<#ty>>::new(#camel_name)
}
}
}
@@ -397,7 +414,11 @@
};
let result = &self.result;
- let args = self.args.iter().map(MethodArg::expand_solidity_argument);
+ let args = self
+ .args
+ .iter()
+ .filter(|a| !a.is_special())
+ .map(MethodArg::expand_solidity_argument);
quote! {
SolidityFunction {
@@ -475,6 +496,24 @@
let call_variants_this = self.methods.iter().map(Method::expand_variant_call);
let solidity_functions = self.methods.iter().map(Method::expand_solidity_function);
+ // TODO: Inline inline_is
+ let solidity_is = self
+ .info
+ .is
+ .0
+ .iter()
+ .chain(self.info.inline_is.0.iter())
+ .map(|is| is.name.to_string());
+ let solidity_events_is = self.info.events.0.iter().map(|is| is.name.to_string());
+ let solidity_generators = self
+ .info
+ .is
+ .0
+ .iter()
+ .chain(self.info.inline_is.0.iter())
+ .map(Is::expand_generator);
+ let solidity_event_generators = self.info.events.0.iter().map(Is::expand_event_generator);
+
// let methods = self.methods.iter().map(Method::solidity_def);
quote! {
@@ -505,18 +544,40 @@
)*
)
}
- pub fn generate_solidity_interface() -> string {
+ pub fn generate_solidity_interface(out_set: &mut sp_std::collections::btree_set::BTreeSet<string>, is_impl: bool) {
use evm_coder::solidity::*;
use core::fmt::Write;
let interface = SolidityInterface {
name: #solidity_name,
+ is: &["Dummy", #(
+ #solidity_is,
+ )* #(
+ #solidity_events_is,
+ )* ],
functions: (#(
#solidity_functions,
)*),
};
+ if is_impl {
+ out_set.insert("// Common stubs holder\ncontract Dummy {\n\tuint8 dummy;\n\tstring stub_error = \"this contract is implemented in native\";\n}\n".into());
+ } else {
+ out_set.insert("// Common stubs holder\ninterface Dummy {\n}\n".into());
+ }
+ #(
+ #solidity_generators
+ )*
+ #(
+ #solidity_event_generators
+ )*
+
let mut out = string::new();
- let _ = interface.format(&mut out);
- out
+ // In solidity interface usage (is) should be preceeded by interface definition
+ // This comment helps to sort it in a set
+ if #solidity_name.starts_with("Inline") {
+ out.push_str("// Inline\n");
+ }
+ let _ = interface.format(is_impl, &mut out);
+ out_set.insert(out);
}
}
impl ::evm_coder::Call for #call_name {
crates/evm-coder-macros/src/to_log.rsdiffbeforeafterboth--- a/crates/evm-coder-macros/src/to_log.rs
+++ b/crates/evm-coder-macros/src/to_log.rs
@@ -1,3 +1,4 @@
+use inflector::cases;
use syn::{Data, DeriveInput, Field, Fields, Ident, Variant, spanned::Spanned};
use std::fmt::Write;
use quote::quote;
@@ -6,6 +7,7 @@
struct EventField {
name: Ident,
+ camel_name: String,
ty: Ident,
indexed: bool,
}
@@ -24,10 +26,18 @@
}
Ok(Self {
name: name.to_owned(),
+ camel_name: cases::camelcase::to_camel_case(&name.to_string()),
ty: ty.to_owned(),
indexed,
})
}
+ fn expand_solidity_argument(&self) -> proc_macro2::TokenStream {
+ let camel_name = &self.camel_name;
+ let ty = &self.ty;
+ quote! {
+ <NamedArgument<#ty>>::new(#camel_name)
+ }
+ }
}
struct Event {
@@ -116,6 +126,21 @@
)*];
}
}
+
+ fn expand_solidity_function(&self) -> proc_macro2::TokenStream {
+ let name = self.name.to_string();
+ let args = self.fields.iter().map(EventField::expand_solidity_argument);
+ quote! {
+ SolidityEvent {
+ name: #name,
+ args: (
+ #(
+ #args,
+ )*
+ ),
+ }
+ }
+ }
}
pub struct Events {
@@ -144,12 +169,30 @@
let consts = self.events.iter().map(Event::expand_consts);
let serializers = self.events.iter().map(Event::expand_serializers);
+ let solidity_name = self.name.to_string();
+ let solidity_functions = self.events.iter().map(Event::expand_solidity_function);
quote! {
impl #name {
#(
#consts
)*
+
+ pub fn generate_solidity_interface(out_set: &mut sp_std::collections::btree_set::BTreeSet<string>, is_impl: bool) {
+ use evm_coder::solidity::*;
+ use core::fmt::Write;
+ let interface = SolidityInterface {
+ name: #solidity_name,
+ is: &[],
+ functions: (#(
+ #solidity_functions,
+ )*),
+ };
+ let mut out = string::new();
+ out.push_str("// Inline\n");
+ let _ = interface.format(is_impl, &mut out);
+ out_set.insert(out);
+ }
}
#[automatically_derived]
crates/evm-coder/src/solidity.rsdiffbeforeafterboth667pub trait SolidityTypeName: 'static {7pub trait SolidityTypeName: 'static {8 fn solidity_name(writer: &mut impl fmt::Write) -> fmt::Result;8 fn solidity_name(writer: &mut impl fmt::Write) -> fmt::Result;9 fn solidity_default(writer: &mut impl fmt::Write) -> fmt::Result;9 fn is_void() -> bool {10 fn is_void() -> bool {10 false11 false11 }12 }12}13}131414macro_rules! solidity_type_name {15macro_rules! solidity_type_name {15 ($($ty:ident => $name:expr),* $(,)?) => {16 ($($ty:ident => $name:literal = $default:literal),* $(,)?) => {16 $(17 $(17 impl SolidityTypeName for $ty {18 impl SolidityTypeName for $ty {18 fn solidity_name(writer: &mut impl core::fmt::Write) -> core::fmt::Result {19 fn solidity_name(writer: &mut impl core::fmt::Write) -> core::fmt::Result {19 write!(writer, $name)20 write!(writer, $name)20 }21 }22 fn solidity_default(writer: &mut impl core::fmt::Write) -> core::fmt::Result {23 write!(writer, $default)24 }21 }25 }22 )*26 )*23 };27 };24}28}252926solidity_type_name! {30solidity_type_name! {27 uint8 => "uint8",31 uint8 => "uint8" = "0",28 uint32 => "uint32",32 uint32 => "uint32" = "0",29 uint128 => "uint128",33 uint128 => "uint128" = "0",30 uint256 => "uint256",34 uint256 => "uint256" = "0",31 address => "address",35 address => "address" = "0x0000000000000000000000000000000000000000",32 string => "memory string",36 string => "string memory" = "\"\"",33 bytes => "memory bytes",37 bytes => "bytes memory" = "hex\"\"",34 bool => "bool",38 bool => "bool" = "false",35}39}36impl SolidityTypeName for void {40impl SolidityTypeName for void {37 fn solidity_name(_writer: &mut impl fmt::Write) -> fmt::Result {41 fn solidity_name(_writer: &mut impl fmt::Write) -> fmt::Result {38 Ok(())42 Ok(())39 }43 }44 fn solidity_default(_writer: &mut impl fmt::Write) -> fmt::Result {45 Ok(())46 }40 fn is_void() -> bool {47 fn is_void() -> bool {41 true48 true42 }49 }43}50}445145pub trait SolidityArguments {52pub trait SolidityArguments {46 fn solidity_name(&self, writer: &mut impl fmt::Write) -> fmt::Result;53 fn solidity_name(&self, writer: &mut impl fmt::Write) -> fmt::Result;54 fn solidity_get(&self, writer: &mut impl fmt::Write) -> fmt::Result;55 fn solidity_default(&self, writer: &mut impl fmt::Write) -> fmt::Result;47 fn is_empty(&self) -> bool {56 fn is_empty(&self) -> bool {48 self.len() == 057 self.len() == 049 }58 }61 Ok(())70 Ok(())62 }71 }63 }72 }73 fn solidity_get(&self, _writer: &mut impl fmt::Write) -> fmt::Result {74 Ok(())75 }76 fn solidity_default(&self, writer: &mut impl fmt::Write) -> fmt::Result {77 T::solidity_default(writer)78 }64 fn len(&self) -> usize {79 fn len(&self) -> usize {65 if T::is_void() {80 if T::is_void() {66 081 087 Ok(())102 Ok(())88 }103 }89 }104 }105 fn solidity_get(&self, writer: &mut impl fmt::Write) -> fmt::Result {106 writeln!(writer, "\t\t{};", self.0)107 }108 fn solidity_default(&self, writer: &mut impl fmt::Write) -> fmt::Result {109 T::solidity_default(writer)110 }90 fn len(&self) -> usize {111 fn len(&self) -> usize {91 if T::is_void() {112 if T::is_void() {92 0113 0100 fn solidity_name(&self, _writer: &mut impl fmt::Write) -> fmt::Result {121 fn solidity_name(&self, _writer: &mut impl fmt::Write) -> fmt::Result {101 Ok(())122 Ok(())102 }123 }124 fn solidity_get(&self, _writer: &mut impl fmt::Write) -> fmt::Result {125 Ok(())126 }127 fn solidity_default(&self, _writer: &mut impl fmt::Write) -> fmt::Result {128 Ok(())129 }103 fn len(&self) -> usize {130 fn len(&self) -> usize {104 0131 0105 }132 }122 )* );149 )* );123 Ok(())150 Ok(())124 }151 }152 fn solidity_get(&self, writer: &mut impl fmt::Write) -> fmt::Result {153 for_tuples!( #(154 Tuple.solidity_get(writer)?;155 )* );156 Ok(())157 }158 fn solidity_default(&self, writer: &mut impl fmt::Write) -> fmt::Result {159 if self.is_empty() {160 Ok(())161 } else if self.len() == 1 {162 for_tuples!( #(163 Tuple.solidity_default(writer)?;164 )* );165 Ok(())166 } else {167 write!(writer, "(")?;168 let mut first = true;169 for_tuples!( #(170 if !Tuple.is_empty() {171 if !first {172 write!(writer, ", ")?;173 }174 first = false;175 Tuple.solidity_name(writer)?;176 }177 )* );178 write!(writer, ")")?;179 Ok(())180 }181 }125 fn len(&self) -> usize {182 fn len(&self) -> usize {126 for_tuples!( #( Tuple.len() )+* )183 for_tuples!( #( Tuple.len() )+* )127 }184 }128}185}129186130pub trait SolidityFunctions {187pub trait SolidityFunctions {131 fn solidity_name(&self, writer: &mut impl fmt::Write) -> fmt::Result;188 fn solidity_name(&self, is_impl: bool, writer: &mut impl fmt::Write) -> fmt::Result;132}189}133190134pub enum SolidityMutability {191pub enum SolidityMutability {143 pub mutability: SolidityMutability,200 pub mutability: SolidityMutability,144}201}145impl<A: SolidityArguments, R: SolidityArguments> SolidityFunctions for SolidityFunction<A, R> {202impl<A: SolidityArguments, R: SolidityArguments> SolidityFunctions for SolidityFunction<A, R> {146 fn solidity_name(&self, writer: &mut impl fmt::Write) -> fmt::Result {203 fn solidity_name(&self, is_impl: bool, writer: &mut impl fmt::Write) -> fmt::Result {147 write!(writer, "function {}(", self.name)?;204 write!(writer, "\tfunction {}(", self.name)?;148 self.args.solidity_name(writer)?;205 self.args.solidity_name(writer)?;149 write!(writer, ") external")?;206 write!(writer, ")")?;207 if is_impl {208 write!(writer, " public")?;209 } else {210 write!(writer, " external")?;211 }150 match &self.mutability {212 match &self.mutability {151 SolidityMutability::Pure => write!(writer, " pure")?,213 SolidityMutability::Pure => write!(writer, " pure")?,152 SolidityMutability::View => write!(writer, " view")?,214 SolidityMutability::View => write!(writer, " view")?,157 self.result.solidity_name(writer)?;219 self.result.solidity_name(writer)?;158 write!(writer, ")")?;220 write!(writer, ")")?;159 }221 }222 if is_impl {223 writeln!(writer, " {{")?;224 writeln!(writer, "\t\trequire(false, stub_error);")?;225 self.args.solidity_get(writer)?;226 match &self.mutability {227 SolidityMutability::Pure => {}228 SolidityMutability::View => writeln!(writer, "\t\tdummy;")?,229 SolidityMutability::Mutable => writeln!(writer, "\t\tdummy = 0;")?,230 }231 if !self.result.is_empty() {232 write!(writer, "\t\treturn ")?;233 self.result.solidity_default(writer)?;234 writeln!(writer, ";")?;235 }236 writeln!(writer, "\t}}")?;237 } else {160 writeln!(writer, ";")238 writeln!(writer, ";")?;239 }240 Ok(())161 }241 }162}242}163243164#[impl_for_tuples(0, 12)]244#[impl_for_tuples(0, 12)]165impl SolidityFunctions for Tuple {245impl SolidityFunctions for Tuple {166 for_tuples!( where #( Tuple: SolidityFunctions ),* );246 for_tuples!( where #( Tuple: SolidityFunctions ),* );167247168 fn solidity_name(&self, writer: &mut impl fmt::Write) -> fmt::Result {248 fn solidity_name(&self, is_impl: bool, writer: &mut impl fmt::Write) -> fmt::Result {169 let mut first = false;249 let mut first = false;170 for_tuples!( #(250 for_tuples!( #(171 Tuple.solidity_name(writer)?;251 Tuple.solidity_name(is_impl, writer)?;172 )* );252 )* );173 Ok(())253 Ok(())174 }254 }175}255}176256177pub struct SolidityInterface<F: SolidityFunctions> {257pub struct SolidityInterface<F: SolidityFunctions> {178 pub name: &'static str,258 pub name: &'static str,259 pub is: &'static [&'static str],179 pub functions: F,260 pub functions: F,180}261}181262182impl<F: SolidityFunctions> SolidityInterface<F> {263impl<F: SolidityFunctions> SolidityInterface<F> {183 pub fn format(&self, out: &mut impl fmt::Write) -> fmt::Result {264 pub fn format(&self, is_impl: bool, out: &mut impl fmt::Write) -> fmt::Result {265 if is_impl {266 write!(out, "contract ")?;267 } else {268 write!(out, "interface ")?;269 }184 writeln!(out, "interface {} {{", self.name)?;270 write!(out, "{}", self.name)?;271 if !self.is.is_empty() {272 write!(out, " is")?;273 for (i, n) in self.is.iter().enumerate() {274 if i != 0 {275 write!(out, ",")?;276 }277 write!(out, " {}", n)?;278 }279 }280 writeln!(out, " {{")?;185 self.functions.solidity_name(out)?;281 self.functions.solidity_name(is_impl, out)?;186 writeln!(out, "}}")?;282 writeln!(out, "}}")?;187 Ok(())283 Ok(())188 }284 }189}285}286287pub struct SolidityEvent<A> {288 pub name: &'static str,289 pub args: A,290}291292impl<A: SolidityArguments> SolidityFunctions for SolidityEvent<A> {293 fn solidity_name(&self, _is_impl: bool, writer: &mut impl fmt::Write) -> fmt::Result {294 write!(writer, "\tevent {}(", self.name)?;295 self.args.solidity_name(writer)?;296 writeln!(writer, ");")297 }298}190299pallets/nft/src/eth/erc.rsdiffbeforeafterboth--- a/pallets/nft/src/eth/erc.rs
+++ b/pallets/nft/src/eth/erc.rs
@@ -395,3 +395,32 @@
#[solidity_interface(name = "UniqueFungible", is(ERC165, ERC20))]
impl<T: Config> CollectionHandle<T> {}
+
+macro_rules! generate_code {
+ ($name:ident, $decl:ident, $is_impl:literal) => {
+ #[test]
+ #[ignore]
+ fn $name() {
+ use sp_std::collections::btree_set::BTreeSet;
+ let mut out = BTreeSet::new();
+ $decl::generate_solidity_interface(&mut out, $is_impl);
+ println!("=== SNIP START ===");
+ println!("// SPDX-License-Identifier: OTHER");
+ println!("// This code is automatically generated with `cargo test --package pallet-nft -- eth::erc::{} --exact --nocapture --ignored`", stringify!(name));
+ println!();
+ println!("pragma solidity >=0.8.0 <0.9.0;");
+ println!();
+ for b in out {
+ println!("{}", b);
+ }
+ println!("=== SNIP END ===");
+ }
+ };
+}
+
+// Not a tests, but code generators
+generate_code!(nft_impl, UniqueNFTCall, true);
+generate_code!(nft_iface, UniqueNFTCall, false);
+
+generate_code!(fungible_impl, UniqueFungibleCall, true);
+generate_code!(fungible_iface, UniqueFungibleCall, false);
pallets/nft/src/eth/stubs/ERC20.bindiffbeforeafterbothbinary blob — no preview
pallets/nft/src/eth/stubs/ERC20.soldiffbeforeafterboth--- a/pallets/nft/src/eth/stubs/ERC20.sol
+++ b/pallets/nft/src/eth/stubs/ERC20.sol
@@ -1,69 +1,94 @@
// SPDX-License-Identifier: OTHER
+// This code is automatically generated with `cargo test --package pallet-nft -- eth::erc::name --exact --nocapture --ignored`
pragma solidity >=0.8.0 <0.9.0;
-contract ERC20 {
- uint8 _dummy = 0;
- string stub_error = "this contract does not exists, code for collections is implemented at pallet side";
+// Common stubs holder
+contract Dummy {
+ uint8 dummy;
+ string stub_error = "this contract is implemented in native";
+}
- // 0x18160ddd
- function totalSupply() external view returns (uint256) {
+// Inline
+contract ERC20Events {
+ event Transfer(address from, address to, uint256 value);
+ event Approval(address owner, address spender, uint256 value);
+}
+
+// Inline
+contract InlineNameSymbol is Dummy {
+ function name() public view returns (string memory) {
require(false, stub_error);
- _dummy;
- return 0;
+ dummy;
+ return "";
}
+ function symbol() public view returns (string memory) {
+ require(false, stub_error);
+ dummy;
+ return "";
+ }
+}
- // 0x70a08231
- function balanceOf(address account) external view returns (uint256) {
+// Inline
+contract InlineTotalSupply is Dummy {
+ function totalSupply() public view returns (uint256) {
require(false, stub_error);
- account;
- _dummy;
+ dummy;
return 0;
}
+}
- // 0xa9059cbb
- function transfer(address recipient, uint256 amount) external returns (bool) {
+contract ERC165 is Dummy {
+ function supportsInterface(uint32 interfaceId) public view returns (bool) {
require(false, stub_error);
- recipient;
- amount;
- _dummy = 0;
+ interfaceId;
+ dummy;
return false;
}
+}
- // 0xdd62ed3e
- function allowance(address owner, address spender) external view returns (uint256) {
+contract ERC20 is Dummy, InlineNameSymbol, InlineTotalSupply, ERC20Events {
+ function decimals() public view returns (uint8) {
require(false, stub_error);
+ dummy;
+ return 0;
+ }
+ function balanceOf(address owner) public view returns (uint256) {
+ require(false, stub_error);
owner;
- spender;
- return _dummy;
+ dummy;
+ return 0;
+ }
+ function transfer(address to, uint256 amount) public returns (bool) {
+ require(false, stub_error);
+ to;
+ amount;
+ dummy = 0;
+ return false;
}
-
- // 0x095ea7b3
- function approve(address spender, uint256 amount) external returns (bool) {
+ function transferFrom(address from, address to, uint256 amount) public returns (bool) {
require(false, stub_error);
- spender;
+ from;
+ to;
amount;
- _dummy = 0;
+ dummy = 0;
return false;
}
-
- // 0x23b872dd
- function transferFrom(address sender, address recipient, uint256 amount) external returns (bool) {
+ function approve(address spender, uint256 amount) public returns (bool) {
require(false, stub_error);
- sender;
- recipient;
+ spender;
amount;
- _dummy = 0;
+ dummy = 0;
return false;
}
+ function allowance(address owner, address spender) public view returns (uint256) {
+ require(false, stub_error);
+ owner;
+ spender;
+ dummy;
+ return 0;
+ }
+}
- // While ERC165 is not required by spec of ERC20, better implement it
- // 0x01ffc9a7
- function supportsInterface(bytes4 interfaceID) public pure returns (bool) {
- return
- // ERC20
- interfaceID == 0x36372b07 ||
- // ERC165
- interfaceID == 0x01ffc9a7;
- }
+contract UniqueFungible is Dummy, ERC165, ERC20 {
}
\ No newline at end of file
pallets/nft/src/eth/stubs/ERC721.bindiffbeforeafterbothbinary blob — no preview
pallets/nft/src/eth/stubs/ERC721.soldiffbeforeafterboth--- a/pallets/nft/src/eth/stubs/ERC721.sol
+++ b/pallets/nft/src/eth/stubs/ERC721.sol
@@ -1,163 +1,194 @@
// SPDX-License-Identifier: OTHER
+// This code is automatically generated with `cargo test --package pallet-nft -- eth::erc::name --exact --nocapture --ignored`
pragma solidity >=0.8.0 <0.9.0;
-contract ERC721 {
- uint8 _dummy = 0;
- address _dummy_addr = 0x0000000000000000000000000000000000000000;
- string _dummy_string = "";
- string stub_error =
- "this contract does not exists, code for collections is implemented at pallet side";
+// Common stubs holder
+contract Dummy {
+ uint8 dummy;
+ string stub_error = "this contract is implemented in native";
+}
- event Transfer(
- address indexed from,
- address indexed to,
- uint256 indexed tokenId
- );
+// Inline
+contract ERC721Events {
+ event Transfer(address from, address to, uint256 tokenId);
+ event Approval(address owner, address approved, uint256 tokenId);
+ event ApprovalForAll(address owner, address operator, bool approved);
+}
- event Approval(
- address indexed owner,
- address indexed approved,
- uint256 indexed tokenId
- );
+// Inline
+contract ERC721MintableEvents {
+ event MintingFinished();
+}
- event ApprovalForAll(
- address indexed owner,
- address indexed operator,
- bool approved
- );
+// Inline
+contract InlineNameSymbol is Dummy {
+ function name() public view returns (string memory) {
+ require(false, stub_error);
+ dummy;
+ return "";
+ }
+ function symbol() public view returns (string memory) {
+ require(false, stub_error);
+ dummy;
+ return "";
+ }
+}
- // 0x18160ddd
- function totalSupply() external view returns (uint256) {
- require(false, stub_error);
- return 0;
- }
+// Inline
+contract InlineTotalSupply is Dummy {
+ function totalSupply() public view returns (uint256) {
+ require(false, stub_error);
+ dummy;
+ return 0;
+ }
+}
- function name() external view returns (string memory res_name) {
- require(false, stub_error);
- res_name = _dummy_string;
- }
+contract ERC165 is Dummy {
+ function supportsInterface(uint32 interfaceId) public view returns (bool) {
+ require(false, stub_error);
+ interfaceId;
+ dummy;
+ return false;
+ }
+}
- function symbol() external view returns (string memory res_symbol) {
- require(false, stub_error);
- res_symbol = _dummy_string;
- }
+contract ERC721 is Dummy, ERC165, ERC721Events {
+ function balanceOf(address owner) public view returns (uint256) {
+ require(false, stub_error);
+ owner;
+ dummy;
+ return 0;
+ }
+ function ownerOf(uint256 tokenId) public view returns (address) {
+ require(false, stub_error);
+ tokenId;
+ dummy;
+ return 0x0000000000000000000000000000000000000000;
+ }
+ function safeTransferFromWithData(address from, address to, uint256 tokenId, bytes memory data) public {
+ require(false, stub_error);
+ from;
+ to;
+ tokenId;
+ data;
+ dummy = 0;
+ }
+ function safeTransferFrom(address from, address to, uint256 tokenId) public {
+ require(false, stub_error);
+ from;
+ to;
+ tokenId;
+ dummy = 0;
+ }
+ function transferFrom(address from, address to, uint256 tokenId) public {
+ require(false, stub_error);
+ from;
+ to;
+ tokenId;
+ dummy = 0;
+ }
+ function approve(address approved, uint256 tokenId) public {
+ require(false, stub_error);
+ approved;
+ tokenId;
+ dummy = 0;
+ }
+ function setApprovalForAll(address operator, bool approved) public {
+ require(false, stub_error);
+ operator;
+ approved;
+ dummy = 0;
+ }
+ function getApproved(uint256 tokenId) public view returns (address) {
+ require(false, stub_error);
+ tokenId;
+ dummy;
+ return 0x0000000000000000000000000000000000000000;
+ }
+ function isApprovedForAll(address owner, address operator) public view returns (address) {
+ require(false, stub_error);
+ owner;
+ operator;
+ dummy;
+ return 0x0000000000000000000000000000000000000000;
+ }
+}
- function tokenURI(uint256 tokenId) external view returns (string memory) {
- require(false, stub_error);
- tokenId;
- return _dummy_string;
- }
+contract ERC721Burnable is Dummy {
+ function burn(uint256 tokenId) public {
+ require(false, stub_error);
+ tokenId;
+ dummy = 0;
+ }
+}
- function tokenByIndex(uint256 index) external view returns (uint256) {
- require(false, stub_error);
- index;
+contract ERC721Enumerable is Dummy, InlineTotalSupply {
+ function tokenByIndex(uint256 index) public view returns (uint256) {
+ require(false, stub_error);
+ index;
+ dummy;
return 0;
- }
-
- function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256) {
- require(false, stub_error);
+ }
+ function tokenOfOwnerByIndex(address owner, uint256 index) public view returns (uint256) {
+ require(false, stub_error);
owner;
index;
+ dummy;
return 0;
- }
+ }
+}
- // 0x70a08231
- function balanceOf(address owner) external view returns (uint256) {
- require(false, stub_error);
- owner;
- return 0;
- }
+contract ERC721Metadata is Dummy, InlineNameSymbol {
+ function tokenUri(uint256 tokenId) public view returns (string memory) {
+ require(false, stub_error);
+ tokenId;
+ dummy;
+ return "";
+ }
+}
- // 0x6352211e
- function ownerOf(uint256 tokenId) external view returns (address) {
- require(false, stub_error);
- tokenId;
- return _dummy_addr;
- }
+contract ERC721Mintable is Dummy, ERC721MintableEvents {
+ function mintingFinished() public view returns (bool) {
+ require(false, stub_error);
+ dummy;
+ return false;
+ }
+ function mint(address to, uint256 tokenId) public returns (bool) {
+ require(false, stub_error);
+ to;
+ tokenId;
+ dummy = 0;
+ return false;
+ }
+ function mintWithTokenURI(address to, uint256 tokenId, string memory tokenUri) public returns (bool) {
+ require(false, stub_error);
+ to;
+ tokenId;
+ tokenUri;
+ dummy = 0;
+ return false;
+ }
+ function finishMinting() public returns (bool) {
+ require(false, stub_error);
+ dummy = 0;
+ return false;
+ }
+}
- // 0xb88d4fde
- function safeTransferFrom(
- address from,
- address to,
- uint256 tokenId,
- bytes calldata data
- ) external payable {
- require(false, stub_error);
- from;
- to;
- tokenId;
- data;
- }
-
- // 0x42842e0e
- function safeTransferFrom(
- address from,
- address to,
- uint256 tokenId
- ) external payable {
- require(false, stub_error);
- from;
- to;
- tokenId;
- }
-
- // 0x23b872dd
- function transferFrom(
- address from,
- address to,
- uint256 tokenId
- ) external payable {
- require(false, stub_error);
- from;
- to;
- tokenId;
- }
+contract ERC721UniqueExtensions is Dummy {
+ function transfer(address to, uint256 tokenId) public {
+ require(false, stub_error);
+ to;
+ tokenId;
+ dummy = 0;
+ }
+ function nextTokenId() public view returns (uint256) {
+ require(false, stub_error);
+ dummy;
+ return 0;
+ }
+}
- // 0x095ea7b3
- function approve(address approved, uint256 tokenId) external payable {
- require(false, stub_error);
- approved;
- tokenId;
- }
-
- // 0xa22cb465
- function setApprovalForAll(address operator, bool approved) external {
- require(false, stub_error);
- operator;
- approved;
- _dummy = 0;
- }
-
- // 0x081812fc
- function getApproved(uint256 tokenId) external view returns (address) {
- require(false, stub_error);
- tokenId;
- return _dummy_addr;
- }
-
- // 0xe985e9c5
- function isApprovedForAll(address owner, address operator)
- external
- view
- returns (bool)
- {
- require(false, stub_error);
- owner;
- operator;
- return false;
- }
-
- // 0x01ffc9a7
- function supportsInterface(bytes4 interfaceID) public pure returns (bool) {
- return
- // ERC721
- interfaceID == 0x80ac58cd ||
- // ERC721Metadata
- interfaceID == 0x5b5e139f ||
- // ERC721Enumerable
- interfaceID == 0x780e9d63 ||
- // ERC165
- interfaceID == 0x01ffc9a7;
- }
-}
+contract UniqueNFT is Dummy, ERC165, ERC721, ERC721Metadata, ERC721Enumerable, ERC721UniqueExtensions, ERC721Mintable, ERC721Burnable {
+}
\ No newline at end of file