feat: support parsing solc contract abi output in string and array form (#301)

This commit is contained in:
Matthias Seitz 2021-05-28 09:46:44 +02:00 committed by GitHub
parent 4036cfb8ef
commit 4690f8effc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 31 additions and 17 deletions

View File

@ -1,9 +1,11 @@
use crate::{abi::Abi, types::Bytes}; use std::{collections::HashMap, fmt, io::BufRead, path::PathBuf, process::Command};
use glob::glob; use glob::glob;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::{collections::HashMap, fmt, io::BufRead, path::PathBuf, process::Command};
use thiserror::Error; use thiserror::Error;
use crate::{abi::Abi, types::Bytes};
/// The name of the `solc` binary on the system /// The name of the `solc` binary on the system
const SOLC: &str = "solc"; const SOLC: &str = "solc";
@ -107,27 +109,39 @@ impl Solc {
} }
// Deserialize the output // Deserialize the output
let output: SolcOutput = serde_json::from_slice(&command.stdout)?; let mut output: serde_json::Value = serde_json::from_slice(&command.stdout)?;
let contract_values = output["contracts"].as_object_mut().ok_or_else(|| {
SolcError::SolcError("no contracts found in `solc` output".to_string())
})?;
// remove the semi-colon and the name let mut contracts = HashMap::with_capacity(contract_values.len());
let contracts = output
.contracts for (name, contract) in contract_values {
.into_iter() if let serde_json::Value::String(bin) = contract["bin"].take() {
.map(|(name, contract)| {
let name = name let name = name
.rsplit(':') .rsplit(':')
.next() .next()
.expect("could not strip fname") .expect("could not strip fname")
.to_owned(); .to_owned();
(
name, // abi could be an escaped string (solc<=0.7) or an array (solc>=0.8)
CompiledContractStr { let abi = match contract["abi"].take() {
abi: contract.abi, serde_json::Value::String(abi) => abi,
bin: contract.bin, val @ serde_json::Value::Array(_) => val.to_string(),
}, val => {
) return Err(SolcError::SolcError(format!(
}) "Expected abi in solc output, found {:?}",
.collect(); val
)))
}
};
contracts.insert(name, CompiledContractStr { abi, bin });
} else {
return Err(SolcError::SolcError(
"could not find `bin` in solc output".to_string(),
));
}
}
Ok(contracts) Ok(contracts)
} }