diff --git a/ethers-etherscan/src/contract.rs b/ethers-etherscan/src/contract.rs index 10195ecc..7ccb5d42 100644 --- a/ethers-etherscan/src/contract.rs +++ b/ethers-etherscan/src/contract.rs @@ -133,7 +133,7 @@ impl AsRef for CodeFormat { impl Default for CodeFormat { fn default() -> Self { - CodeFormat::SingleFile + CodeFormat::StandardJsonInput } } diff --git a/ethers-solc/src/lib.rs b/ethers-solc/src/lib.rs index 3f0798e3..a65cc728 100644 --- a/ethers-solc/src/lib.rs +++ b/ethers-solc/src/lib.rs @@ -50,7 +50,7 @@ pub mod project_util; /// Represents a project workspace and handles `solc` compiling of all contracts in that workspace. #[derive(Debug)] pub struct Project { - /// The layout of the + /// The layout of the project pub paths: ProjectPathsConfig, /// Where to find solc pub solc: Solc, @@ -426,6 +426,33 @@ impl Project { pub fn flatten(&self, target: &Path) -> Result { self.paths.flatten(target) } + + /// Returns standard-json-input to compile the target contract + pub fn standard_json_input(&self, target: &Path) -> Result { + tracing::trace!("Building standard-json-input"); + let graph = Graph::resolve(&self.paths)?; + let target_index = graph.files().get(target).ok_or_else(|| { + SolcError::msg(format!("cannot resolve file at \"{:?}\"", target.display())) + })?; + let mut sources = Vec::new(); + let (path, source) = graph.node(*target_index).unpack(); + sources.push((path, source)); + sources.extend( + graph.all_imported_nodes(*target_index).map(|index| graph.node(index).unpack()), + ); + + let compiler_inputs = CompilerInput::with_sources( + sources.into_iter().map(|(s, p)| (s.clone(), p.clone())).collect(), + ); + let compiler_input = compiler_inputs + .first() + .ok_or_else(|| SolcError::msg("cannot get the compiler input"))? + .clone() + .settings(self.solc_config.settings.clone()) + .with_remappings(self.paths.remappings.clone()); + + Ok(compiler_input) + } } pub struct ProjectBuilder { diff --git a/ethers-solc/src/resolver/mod.rs b/ethers-solc/src/resolver/mod.rs index e5312cd0..02debcfb 100644 --- a/ethers-solc/src/resolver/mod.rs +++ b/ethers-solc/src/resolver/mod.rs @@ -206,6 +206,11 @@ impl Graph { self.edges.imported_nodes(from) } + /// Returns an iterator that yields all imports of a node and all their imports + pub fn all_imported_nodes(&self, from: usize) -> impl Iterator + '_ { + self.edges.all_imported_nodes(from) + } + /// Returns `true` if the given node has any outgoing edges. pub(crate) fn has_outgoing_edges(&self, index: usize) -> bool { !self.edges.edges[index].is_empty() @@ -782,6 +787,10 @@ impl Node { pub fn license(&self) -> &Option> { &self.data.license } + + pub fn unpack(&self) -> (&PathBuf, &Source) { + (&self.path, &self.source) + } } /// Helper type for formatting a node