fix(core, etherscan): RawAbi and Abi (#1757)

This commit is contained in:
DaniPopes 2022-09-29 20:15:04 +02:00 committed by GitHub
parent 62beb6cf53
commit d2c9db5ae9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 47 additions and 53 deletions

View File

@ -7,12 +7,9 @@ pub(crate) mod structs;
mod types;
use super::{util, Abigen};
use crate::{
contract::{methods::MethodAlias, structs::InternalStructs},
rawabi::JsonAbi,
};
use crate::contract::{methods::MethodAlias, structs::InternalStructs};
use ethers_core::{
abi::{Abi, AbiParser, ErrorExt, EventExt},
abi::{Abi, AbiParser, ErrorExt, EventExt, JsonAbi},
macros::{ethers_contract_crate, ethers_core_crate, ethers_providers_crate},
types::Bytes,
};

View File

@ -1,13 +1,12 @@
//! Methods for expanding structs
use crate::{
contract::{types, Context},
rawabi::{Component, RawAbi},
util,
};
use ethers_core::{
abi::{
struct_def::{FieldDeclaration, FieldType, StructFieldType, StructType},
HumanReadableParser, ParamType, SolStruct,
Component, HumanReadableParser, ParamType, RawAbi, SolStruct,
},
macros::ethers_contract_crate,
};

View File

@ -16,9 +16,6 @@ pub mod contract;
pub use contract::structs::InternalStructs;
use contract::Context;
pub mod rawabi;
pub use rawabi::RawAbi;
mod rustfmt;
mod source;
mod util;

View File

@ -49,7 +49,7 @@ pub mod builders {
#[cfg(any(test, feature = "abigen"))]
#[cfg_attr(docsrs, doc(cfg(feature = "abigen")))]
pub use ethers_contract_abigen::{
Abigen, ContractFilter, ExcludeContracts, InternalStructs, MultiAbigen, RawAbi, SelectContracts,
Abigen, ContractFilter, ExcludeContracts, InternalStructs, MultiAbigen, SelectContracts,
};
#[cfg(any(test, feature = "abigen"))]

View File

@ -22,6 +22,10 @@ mod human_readable;
pub use human_readable::{
lexer::HumanReadableParser, parse as parse_abi, parse_str as parse_abi_str, AbiParser,
};
mod raw;
pub use raw::{AbiObject, Component, Item, JsonAbi, RawAbi};
mod sealed {
use ethabi::{Event, Function};

View File

@ -2,7 +2,7 @@
//! raw content of the ABI.
#![allow(missing_docs)]
use ethers_core::types::Bytes;
use crate::types::Bytes;
use serde::{
de::{MapAccess, SeqAccess, Visitor},
Deserialize, Deserializer, Serialize,
@ -109,7 +109,7 @@ pub struct Component {
/// Represents contract ABI input variants
#[derive(Deserialize)]
#[serde(untagged)]
pub(crate) enum JsonAbi {
pub enum JsonAbi {
/// json object input as `{"abi": [..], "bin": "..."}`
Object(AbiObject),
/// json array input as `[]`
@ -125,7 +125,7 @@ where
}
/// Contract ABI and optional bytecode as JSON object
pub(crate) struct AbiObject {
pub struct AbiObject {
pub abi: RawAbi,
pub bytecode: Option<Bytes>,
}
@ -158,7 +158,7 @@ impl<'de> Visitor<'de> for AbiObjectVisitor {
where
D: Deserializer<'de>,
{
Ok(DeserializeBytes(ethers_core::types::deserialize_bytes(deserializer)?.into()))
Ok(DeserializeBytes(crate::types::deserialize_bytes(deserializer)?.into()))
}
}
@ -204,7 +204,7 @@ impl<'de> Deserialize<'de> for AbiObject {
#[cfg(test)]
mod tests {
use super::*;
use ethers_core::abi::Abi;
use crate::abi::Abi;
fn assert_has_bytecode(s: &str) {
match serde_json::from_str::<JsonAbi>(s).unwrap() {
@ -219,14 +219,16 @@ mod tests {
#[test]
fn can_parse_raw_abi() {
const VERIFIER_ABI: &str = include_str!("../../tests/solidity-contracts/verifier_abi.json");
const VERIFIER_ABI: &str =
include_str!("../../../ethers-contract/tests/solidity-contracts/verifier_abi.json");
let _ = serde_json::from_str::<RawAbi>(VERIFIER_ABI).unwrap();
}
#[test]
fn can_parse_hardhat_raw_abi() {
const VERIFIER_ABI: &str =
include_str!("../../tests/solidity-contracts/verifier_abi_hardhat.json");
const VERIFIER_ABI: &str = include_str!(
"../../../ethers-contract/tests/solidity-contracts/verifier_abi_hardhat.json"
);
let _ = serde_json::from_str::<RawAbi>(VERIFIER_ABI).unwrap();
}
@ -261,7 +263,9 @@ mod tests {
let s = format!(r#"{{"abi": {}, "bytecode" : {{ "object": "{}" }} }}"#, abi_str, code);
assert_has_bytecode(&s);
let hh_artifact = include_str!("../../tests/solidity-contracts/verifier_abi_hardhat.json");
let hh_artifact = include_str!(
"../../../ethers-contract/tests/solidity-contracts/verifier_abi_hardhat.json"
);
match serde_json::from_str::<JsonAbi>(hh_artifact).unwrap() {
JsonAbi::Object(abi) => {
assert!(abi.bytecode.is_none());
@ -274,7 +278,8 @@ mod tests {
#[test]
fn can_parse_greeter_bytecode() {
let artifact = include_str!("../../tests/solidity-contracts/greeter.json");
let artifact =
include_str!("../../../ethers-contract/tests/solidity-contracts/greeter.json");
assert_has_bytecode(artifact);
}

View File

@ -1,12 +1,10 @@
use crate::{
source_tree::{SourceTree, SourceTreeEntry},
utils::{
deserialize_address_opt, deserialize_stringified_abi, deserialize_stringified_source_code,
},
utils::{deserialize_address_opt, deserialize_stringified_source_code},
Client, EtherscanError, Response, Result,
};
use ethers_core::{
abi::{Abi, Address},
abi::{Abi, Address, RawAbi},
types::{serde_helpers::deserialize_stringified_u64, Bytes},
};
use semver::Version;
@ -113,8 +111,8 @@ pub struct Metadata {
pub source_code: SourceCodeMetadata,
/// The ABI of the contract.
#[serde(rename = "ABI", deserialize_with = "deserialize_stringified_abi")]
pub abi: Abi,
#[serde(rename = "ABI")]
pub abi: String,
/// The name of the contract.
pub contract_name: String,
@ -179,6 +177,16 @@ impl Metadata {
self.source_code.sources()
}
/// Parses the Abi String as an [RawAbi] struct.
pub fn raw_abi(&self) -> Result<RawAbi> {
Ok(serde_json::from_str(&self.abi)?)
}
/// Parses the Abi String as an [Abi] struct.
pub fn abi(&self) -> Result<Abi> {
Ok(serde_json::from_str(&self.abi)?)
}
/// Parses the compiler version.
pub fn compiler_version(&self) -> Result<Version> {
let v = &self.compiler_version;
@ -274,8 +282,13 @@ impl IntoIterator for ContractMetadata {
impl ContractMetadata {
/// Returns the ABI of all contracts.
pub fn abis(&self) -> Vec<&Abi> {
self.items.iter().map(|c| &c.abi).collect()
pub fn abis(&self) -> Result<Vec<Abi>> {
self.items.iter().map(|c| c.abi()).collect()
}
/// Returns the raw ABI of all contracts.
pub fn raw_abis(&self) -> Result<Vec<RawAbi>> {
self.items.iter().map(|c| c.raw_abi()).collect()
}
/// Returns the combined source code of all contracts.
@ -460,7 +473,7 @@ mod tests {
let item = &meta.items[0];
assert!(matches!(item.source_code, SourceCodeMetadata::SourceCode(_)));
assert_eq!(item.source_code.sources().len(), 1);
assert_eq!(item.abi, serde_json::from_str(DAO_ABI).unwrap());
assert_eq!(item.abi().unwrap(), serde_json::from_str(DAO_ABI).unwrap());
})
.await
}
@ -497,7 +510,7 @@ mod tests {
let item = &meta.items[0];
assert!(matches!(item.source_code, SourceCodeMetadata::SourceCode(_)));
assert_eq!(item.source_code.sources().len(), 1);
assert_eq!(item.abi, serde_json::from_str(DAO_ABI).unwrap());
assert_eq!(item.abi().unwrap(), serde_json::from_str(DAO_ABI).unwrap());
})
.await
}

View File

@ -1,5 +1,5 @@
use crate::{contract::SourceCodeMetadata, EtherscanError, Result};
use ethers_core::{abi::Abi, types::Address};
use ethers_core::types::Address;
use semver::Version;
use serde::{Deserialize, Deserializer};
@ -53,14 +53,6 @@ pub fn deserialize_stringified_source_code<'de, D: Deserializer<'de>>(
}
}
/// Deserializes as JSON: "\[...\]"
pub fn deserialize_stringified_abi<'de, D: Deserializer<'de>>(
deserializer: D,
) -> std::result::Result<Abi, D::Error> {
let s = String::deserialize(deserializer)?;
serde_json::from_str(&s).map_err(serde::de::Error::custom)
}
#[cfg(test)]
mod tests {
use super::*;
@ -115,19 +107,6 @@ mod tests {
assert_eq!(de.address, Some(expected));
}
#[test]
fn can_deserialize_stringified_abi() {
#[derive(Deserialize)]
struct Test {
#[serde(deserialize_with = "deserialize_stringified_abi")]
abi: Abi,
}
let json = r#"{"abi": "[]"}"#;
let de: Test = serde_json::from_str(json).unwrap();
assert_eq!(de.abi, Abi::default());
}
#[test]
fn can_deserialize_stringified_source_code() {
#[derive(Deserialize)]