fix(core, etherscan): RawAbi and Abi (#1757)
This commit is contained in:
parent
62beb6cf53
commit
d2c9db5ae9
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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"))]
|
||||
|
|
|
@ -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};
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)]
|
||||
|
|
Loading…
Reference in New Issue