Skip to content
This repository has been archived by the owner on Oct 19, 2024. It is now read-only.

feat: expand solc capabilities / chore: update ethabi #445

Merged
merged 9 commits into from
Sep 13, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 5 additions & 6 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,4 @@ rand = "0.8.4"
serde = { version = "1.0.124", features = ["derive"] }
serde_json = "1.0.64"
tokio = { version = "1.5", features = ["macros", "rt-multi-thread"] }

1 change: 1 addition & 0 deletions ethers-contract/ethers-contract-derive/src/abigen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ impl Parse for Method {
Ok(Param {
name: "".into(),
kind,
internal_type: None,
})
})
.collect::<ParseResult<Vec<_>>>()?;
Expand Down
3 changes: 2 additions & 1 deletion ethers-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ keywords = ["ethereum", "web3", "celo", "ethers"]

[dependencies]
rlp = { version = "0.5.0", default-features = false }
ethabi = { version = "14.1.0", default-features = false }
# ethabi = { version = "14.1.0", default-features = false }
ethabi = { git = "https://github.com/rust-ethereum/ethabi/", branch = "master" }
arrayvec = { version = "0.7.1", default-features = false }
rlp-derive = { version = "0.1.0", default-features = false }

Expand Down
1 change: 1 addition & 0 deletions ethers-core/src/abi/human_readable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,7 @@ impl AbiParser {
Ok(Param {
name: name.to_string(),
kind: self.parse_type(type_str)?,
internal_type: None,
})
}
}
Expand Down
76 changes: 63 additions & 13 deletions ethers-core/src/utils/solc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,15 @@ pub enum SolcError {
SerdeJson(#[from] serde_json::Error),
}

#[derive(Clone, Debug)]
#[derive(Clone, Debug, Serialize, Deserialize)]
/// The result of a solc compilation
pub struct CompiledContract {
/// The contract's ABI
pub abi: Abi,
/// The contract's bytecode
pub bytecode: Bytes,
/// The contract's runtime bytecode
pub runtime_bytecode: Bytes,
}

/// Solidity Compiler Bindings
Expand Down Expand Up @@ -55,6 +57,9 @@ pub struct CompiledContract {
/// # }
/// ```
pub struct Solc {
/// The path to the Solc binary
pub solc_path: Option<PathBuf>,

/// The path where contracts will be read from
pub paths: Vec<String>,

Expand All @@ -72,17 +77,22 @@ pub struct Solc {
}

impl Solc {
/// Instantiates the Solc builder for the provided paths
/// Instantiates The Solc builder with the provided glob of Solidity files
pub fn new(path: &str) -> Self {
// Convert the glob to a vector of string paths
// TODO: This might not be the most robust way to do this
let paths = glob(path)
.expect("could not get glob")
.map(|path| path.expect("path not found").to_string_lossy().to_string())
.collect::<Vec<String>>();
Self::new_with_paths(paths)
}

/// Instantiates the Solc builder for the provided paths
pub fn new_with_paths(paths: Vec<String>) -> Self {
Self {
paths,
solc_path: None,
optimizer: Some(200), // default optimizer runs = 200
evm_version: EvmVersion::Istanbul,
allowed_paths: Vec::new(),
Expand All @@ -92,13 +102,19 @@ impl Solc {

/// Gets the ABI for the contracts
pub fn build_raw(self) -> Result<HashMap<String, CompiledContractStr>> {
let mut command = Command::new(SOLC);
let path = self.solc_path.unwrap_or_else(|| PathBuf::from(SOLC));
let mut command = Command::new(&path);
let version = Solc::version(Some(path));

command.arg("--combined-json").arg("abi,bin,bin-runtime");

command
.arg("--evm-version")
.arg(self.evm_version.to_string())
.arg("--combined-json")
.arg("abi,bin");
if (version.starts_with("0.5") && self.evm_version < EvmVersion::Istanbul)
|| !version.starts_with("0.4")
{
command
.arg("--evm-version")
.arg(self.evm_version.to_string());
}

if let Some(runs) = self.optimizer {
command
Expand Down Expand Up @@ -148,7 +164,21 @@ impl Solc {
)))
}
};
contracts.insert(name, CompiledContractStr { abi, bin });

let runtime_bin =
if let serde_json::Value::String(bin) = contract["bin-runtime"].take() {
bin
} else {
panic!("no runtime bytecode found")
};
contracts.insert(
name,
CompiledContractStr {
abi,
bin,
runtime_bin,
},
);
} else {
return Err(SolcError::SolcError(
"could not find `bin` in solc output".to_string(),
Expand All @@ -174,7 +204,19 @@ impl Solc {
let bytecode = hex::decode(contract.bin)
.expect("solc did not produce valid bytecode")
.into();
(name, CompiledContract { abi, bytecode })

// parse the runtime bytecode
let runtime_bytecode = hex::decode(contract.runtime_bin)
.expect("solc did not produce valid runtime-bytecode")
.into();
(
name,
CompiledContract {
abi,
bytecode,
runtime_bytecode,
},
)
})
.collect::<HashMap<String, CompiledContract>>();

Expand All @@ -186,8 +228,8 @@ impl Solc {
/// # Panics
///
/// If `solc` is not in the user's $PATH
pub fn version() -> String {
let command_output = Command::new(SOLC)
pub fn version(solc_path: Option<PathBuf>) -> String {
let command_output = Command::new(solc_path.unwrap_or_else(|| PathBuf::from(SOLC)))
.arg("--version")
.output()
.unwrap_or_else(|_| panic!("`{}` not in user's $PATH", SOLC));
Expand All @@ -209,6 +251,12 @@ impl Solc {
self
}

/// Sets the path to the solc binary
pub fn solc_path(mut self, path: PathBuf) -> Self {
self.solc_path = Some(std::fs::canonicalize(path).unwrap());
self
}

/// Sets the optimizer runs (default = 200). None indicates no optimization
///
/// ```rust,no_run
Expand Down Expand Up @@ -257,7 +305,7 @@ impl Solc {
}
}

#[derive(Clone, Debug)]
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub enum EvmVersion {
Homestead,
TangerineWhistle,
Expand Down Expand Up @@ -297,4 +345,6 @@ pub struct CompiledContractStr {
pub abi: String,
/// The contract's bytecode in hex
pub bin: String,
/// The contract's runtime bytecode in hex
pub runtime_bin: String,
}