Skip to content
This repository has been archived by the owner on Sep 18, 2020. It is now read-only.

Compile contracts using solcjs or solc #174

Closed
wants to merge 19 commits into from
Closed
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
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
107 changes: 98 additions & 9 deletions bridge/build.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::fs;
use std::process::Command;

fn main() {
Expand All @@ -15,14 +16,6 @@ fn main() {
let git_hash = String::from_utf8(output.stdout).unwrap();
println!("cargo:rustc-env=GIT_HASH={}", git_hash);

// make solc version used to compile contracts (`solc --version`)
// available via `env!("SOLC_VERSION")` in sources
let output = Command::new("solc").args(&["--version"]).output().unwrap();
let output_string = String::from_utf8(output.stdout).unwrap();
let solc_version = output_string.lines().last().unwrap();
println!("cargo:rustc-env=SOLC_VERSION={}", solc_version);

// compile contracts for inclusion with ethabis `use_contract!`
match Command::new("solc")
.arg("--abi")
.arg("--bin")
Expand All @@ -40,14 +33,110 @@ fn main() {
} else {
panic!("`solc` exited because it was terminated by a signal");
}
} else {
let output = Command::new("solc").args(&["--version"]).output().unwrap();
let output_string = String::from_utf8(output.stdout).unwrap();
let solc_version = output_string.lines().last().unwrap();
println!("cargo:rustc-env=SOLC_VERSION={}", solc_version);
}
}
Err(err) => {
// we could have panicked here
if let std::io::ErrorKind::NotFound = err.kind() {
panic!("`solc` executable not found in `$PATH`. `solc` is required to compile the bridge contracts. please install it: https://solidity.readthedocs.io/en/develop/installing-solidity.html");
// but let's see if solcjs is available or not
compile_using_solcjs();
} else {
panic!("an error occurred when trying to spawn `solc`: {}", err);
}
}
}
}

fn compile_using_solcjs() {
match Command::new("solcjs").arg("--version").output() {
Ok(exit_status) => {
let output_string = String::from_utf8(exit_status.stdout).unwrap();
let solc_version = output_string.lines().last().unwrap();
println!("cargo:rustc-env=SOLC_VERSION={}", solc_version);
// overwrite option is not available in solcjs
// so we better remove old compiled contracts
match fs::remove_dir_all("../compiled_contracts") {
Ok(()) => {
println!("Removed old files");
}
Err(err) => {
// do not panic if we are unable to delete files
// this may occur if files do not exist, due to this being the first run
println!("Files not removed: {}", err);
}
};
// compile contracts using `solcjs`
match Command::new("solcjs")
.arg("--abi")
.arg("--bin")
.arg("--optimize")
.arg("--output-dir")
.arg("../compiled_contracts")
.arg("../contracts/bridge.sol")
.status()
{
Ok(exit_status) => {
if !exit_status.success() {
if let Some(code) = exit_status.code() {
panic!("`solcjs` exited with error exit status code `{}`", code);
} else {
panic!("`solcjs` exited because it was terminated by a signal");
}
} else {
// make solcjs version used to compile contracts (`solcjs --version`)
// available via `env!("SOLC_VERSION")` in sources
let output = Command::new("solcjs")
.args(&["--version"])
.output()
.unwrap();
let output_string = String::from_utf8(output.stdout).unwrap();
let solc_version = output_string.lines().last().unwrap();
println!("cargo:rustc-env=SOLC_VERSION={}", solc_version);
}
}
Err(err) => {
panic!("an error occurred when trying to spawn `solcjs`: {}", err);
}
}
// contracts compiled using solcjs are named differently
// we need to rename them
let prepend = "../compiled_contracts/";
let paths = fs::read_dir("../compiled_contracts").unwrap();
for path in paths {
let _file_name: String = format!(
"{}{}",
prepend,
path.unwrap().file_name().into_string().expect(
"error: the first argument is not a file\
system path representable in UTF-8.",
)
);
let _replaced_name: String =
str::replace(&_file_name, "___contracts_bridge_sol_", "");
match fs::rename(&_file_name, &_replaced_name) {
Ok(_status) => {
println!("Renamed successfully");
}
Err(err) => {
println!("Tried looking for {}", &_file_name);
panic!("Error renaming: {}", err);
}
}
println!("Old name: {}, New name: {}", _file_name, _replaced_name);
}
}
Err(err) => {
// this shows that neither solc is available, nor solcjs
if let std::io::ErrorKind::NotFound = err.kind() {
panic!("No compiler available for solidity. Try installing `solc` or `solcjs`");
} else {
panic!("Unable to run solcjs: {}", err);
}
}
}
}