diff --git a/ethers-contract/ethers-contract-abigen/src/contract/common.rs b/ethers-contract/ethers-contract-abigen/src/contract/common.rs index a4bfb4b7..0a7335c3 100644 --- a/ethers-contract/ethers-contract-abigen/src/contract/common.rs +++ b/ethers-contract/ethers-contract-abigen/src/contract/common.rs @@ -42,7 +42,7 @@ pub(crate) fn struct_declaration(cx: &Context) -> TokenStream { let abi_parse = if !cx.human_readable { quote! { - pub static #abi_name: #ethers_contract::Lazy<#ethers_core::abi::Abi> = #ethers_contract::Lazy::new(|| serde_json::from_str(#abi) + pub static #abi_name: #ethers_contract::Lazy<#ethers_core::abi::Abi> = #ethers_contract::Lazy::new(|| #ethers_core::utils::__serde_json::from_str(#abi) .expect("invalid abi")); } } else { diff --git a/ethers-core/ethers-derive-eip712/src/lib.rs b/ethers-core/ethers-derive-eip712/src/lib.rs index 3b3c8fd7..a64bb351 100644 --- a/ethers-core/ethers-derive-eip712/src/lib.rs +++ b/ethers-core/ethers-derive-eip712/src/lib.rs @@ -61,7 +61,6 @@ //! determine if there is a nested eip712 struct. However, this work is not yet complete. #![deny(rustdoc::broken_intra_doc_links)] -#![deny(unused_crate_dependencies)] use std::convert::TryFrom; @@ -121,7 +120,7 @@ fn impl_eip_712_macro(ast: &syn::DeriveInput) -> TokenStream { fn type_hash() -> Result<[u8; 32], Self::Error> { use std::convert::TryFrom; - let decoded = hex::decode(#type_hash)?; + let decoded = #ethers_core::utils::hex::decode(#type_hash)?; let byte_array: [u8; 32] = <[u8; 32]>::try_from(&decoded[..])?; Ok(byte_array) } @@ -129,13 +128,13 @@ fn impl_eip_712_macro(ast: &syn::DeriveInput) -> TokenStream { // Return the pre-computed domain separator from compile time; fn domain_separator(&self) -> Result<[u8; 32], Self::Error> { use std::convert::TryFrom; - let decoded = hex::decode(#domain_separator)?; + let decoded = #ethers_core::utils::hex::decode(#domain_separator)?; let byte_array: [u8; 32] = <[u8; 32]>::try_from(&decoded[..])?; Ok(byte_array) } fn domain(&self) -> Result<#ethers_core::types::transaction::eip712::EIP712Domain, Self::Error> { - let domain: #ethers_core::types::transaction::eip712::EIP712Domain = serde_json::from_str(#domain_str)?; + let domain: #ethers_core::types::transaction::eip712::EIP712Domain = # ethers_core::utils::__serde_json::from_str(#domain_str)?; Ok(domain) } diff --git a/ethers-core/src/types/transaction/eip712.rs b/ethers-core/src/types/transaction/eip712.rs index 61d7edcf..5bb7c978 100644 --- a/ethers-core/src/types/transaction/eip712.rs +++ b/ethers-core/src/types/transaction/eip712.rs @@ -9,7 +9,7 @@ use syn::{ use crate::{ abi, abi::{ParamType, Token}, - types::{Address, H160, U256}, + types::{Address, U256}, utils::keccak256, }; @@ -196,9 +196,14 @@ impl TryFrom<&syn::DeriveInput> for EIP712Domain { type Error = TokenStream; fn try_from(input: &syn::DeriveInput) -> Result { let mut domain = EIP712Domain::default(); + let mut domain_name = None; + let mut domain_version = None; + let mut chain_id = None; + let mut verifying_contract = None; + let mut found_eip712_attribute = false; - for attribute in input.attrs.iter() { + 'attribute_search: for attribute in input.attrs.iter() { if let AttrStyle::Outer = attribute.style { if let Ok(syn::Meta::List(meta)) = attribute.parse_meta() { if meta.path.is_ident("eip712") { @@ -219,7 +224,7 @@ impl TryFrom<&syn::DeriveInput> for EIP712Domain { match ident.to_string().as_ref() { "name" => match meta.lit { syn::Lit::Str(ref lit_str) => { - if domain.name != String::default() { + if domain_name.is_some() { return Err(Error::new( meta.path.span(), "domain name already specified", @@ -227,7 +232,7 @@ impl TryFrom<&syn::DeriveInput> for EIP712Domain { .to_compile_error()) } - domain.name = lit_str.value(); + domain_name = Some(lit_str.value()); } _ => { return Err(Error::new( @@ -239,7 +244,7 @@ impl TryFrom<&syn::DeriveInput> for EIP712Domain { }, "version" => match meta.lit { syn::Lit::Str(ref lit_str) => { - if domain.version != String::default() { + if domain_version.is_some() { return Err(Error::new( meta.path.span(), "domain version already specified", @@ -247,7 +252,7 @@ impl TryFrom<&syn::DeriveInput> for EIP712Domain { .to_compile_error()) } - domain.version = lit_str.value(); + domain_version = Some(lit_str.value()); } _ => { return Err(Error::new( @@ -259,7 +264,7 @@ impl TryFrom<&syn::DeriveInput> for EIP712Domain { }, "chain_id" => match meta.lit { syn::Lit::Int(ref lit_int) => { - if domain.chain_id != U256::default() { + if chain_id.is_some() { return Err(Error::new( meta.path.span(), "domain chain_id already specified", @@ -267,7 +272,7 @@ impl TryFrom<&syn::DeriveInput> for EIP712Domain { .to_compile_error()) } - domain.chain_id = U256::from( + chain_id = Some(U256::from( lit_int.base10_parse::().map_err( |_| { Error::new( @@ -277,7 +282,7 @@ impl TryFrom<&syn::DeriveInput> for EIP712Domain { .to_compile_error() }, )?, - ); + )); } _ => { return Err(Error::new( @@ -289,8 +294,7 @@ impl TryFrom<&syn::DeriveInput> for EIP712Domain { }, "verifying_contract" => match meta.lit { syn::Lit::Str(ref lit_str) => { - if domain.verifying_contract != H160::default() - { + if verifying_contract.is_some() { return Err(Error::new( meta.path.span(), "domain verifying_contract already specified", @@ -298,13 +302,13 @@ impl TryFrom<&syn::DeriveInput> for EIP712Domain { .to_compile_error()); } - domain.verifying_contract = lit_str.value().parse().map_err(|_| { + verifying_contract = Some(lit_str.value().parse().map_err(|_| { Error::new( meta.path.span(), "failed to parse verifying contract into Address", ) .to_compile_error() - })?; + })?); } _ => { return Err(Error::new( @@ -316,7 +320,7 @@ impl TryFrom<&syn::DeriveInput> for EIP712Domain { }, "salt" => match meta.lit { syn::Lit::Str(ref lit_str) => { - if domain.salt != Option::None { + if domain.salt.is_some() { return Err(Error::new( meta.path.span(), "domain salt already specified", @@ -365,36 +369,41 @@ impl TryFrom<&syn::DeriveInput> for EIP712Domain { } } - if domain.name == String::default() { - return Err(Error::new( + domain.name = domain_name.ok_or_else(|| { + Error::new( meta.path.span(), "missing required domain attribute: 'name'".to_string(), ) - .to_compile_error()) - } - if domain.version == String::default() { - return Err(Error::new( + .to_compile_error() + })?; + + domain.version = domain_version.ok_or_else(|| { + Error::new( meta.path.span(), "missing required domain attribute: 'version'".to_string(), ) - .to_compile_error()) - } - if domain.chain_id == U256::default() { - return Err(Error::new( + .to_compile_error() + })?; + + domain.chain_id = chain_id.ok_or_else(|| { + Error::new( meta.path.span(), "missing required domain attribute: 'chain_id'".to_string(), ) - .to_compile_error()) - } - if domain.verifying_contract == H160::default() { - return Err(Error::new( + .to_compile_error() + })?; + + domain.verifying_contract = verifying_contract.ok_or_else(|| { + Error::new( meta.path.span(), "missing required domain attribute: 'verifying_contract'" .to_string(), ) - .to_compile_error()) - } + .to_compile_error() + })?; } + + break 'attribute_search } } } diff --git a/ethers-core/src/utils/mod.rs b/ethers-core/src/utils/mod.rs index 1703276f..b1cf9ca2 100644 --- a/ethers-core/src/utils/mod.rs +++ b/ethers-core/src/utils/mod.rs @@ -38,6 +38,12 @@ use k256::{ecdsa::SigningKey, PublicKey as K256PublicKey}; use std::convert::{TryFrom, TryInto}; use thiserror::Error; +/// Re-export of serde-json +#[doc(hidden)] +pub mod __serde_json { + pub use serde_json::*; +} + #[derive(Error, Debug)] pub enum ConversionError { #[error("Unknown units: {0}")]