Skip to content
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
24 changes: 12 additions & 12 deletions Cargo.lock

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

Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,26 @@
//! The Solidity contract build.
//!

pub mod object;

use std::collections::BTreeSet;
use std::io::Write;
use std::path::Path;
use std::path::PathBuf;

use self::object::Object;

///
/// The Solidity contract build.
///
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct Contract {
/// The contract name.
pub name: era_compiler_common::ContractName,
/// The deploy bytecode identifier.
pub deploy_identifier: String,
/// The deploy bytecode.
pub deploy_build: Vec<u8>,
/// The runtime bytecode identifier.
pub runtime_identifier: String,
/// The runtime bytecode.
pub runtime_build: Vec<u8>,
/// The deploy code object.
pub deploy_object: Object,
/// The runtime code object.
pub runtime_object: Object,
/// The metadata hash.
pub metadata_hash: Option<era_compiler_common::Hash>,
/// The metadata JSON.
Expand All @@ -38,21 +38,17 @@ impl Contract {
///
pub fn new(
name: era_compiler_common::ContractName,
deploy_identifier: String,
deploy_build: Vec<u8>,
runtime_identifier: String,
runtime_build: Vec<u8>,
deploy_object: Object,
runtime_object: Object,
metadata_hash: Option<era_compiler_common::Hash>,
metadata_json: serde_json::Value,
missing_libraries: BTreeSet<String>,
object_format: era_compiler_common::ObjectFormat,
) -> Self {
Self {
name,
deploy_identifier,
deploy_build,
runtime_identifier,
runtime_build,
deploy_object,
runtime_object,
metadata_hash,
metadata_json,
missing_libraries,
Expand Down Expand Up @@ -81,8 +77,8 @@ impl Contract {
writeln!(
std::io::stdout(),
"Binary:\n{}{}",
hex::encode(self.deploy_build),
hex::encode(self.runtime_build),
hex::encode(self.deploy_object.bytecode),
hex::encode(self.runtime_object.bytecode),
)?;
}

Expand Down Expand Up @@ -166,8 +162,8 @@ impl Contract {
"Refusing to overwrite an existing file {output_path:?} (use --overwrite to force)."
);
} else {
let mut bytecode_hexadecimal = hex::encode(self.deploy_build.as_slice());
bytecode_hexadecimal.push_str(hex::encode(self.runtime_build.as_slice()).as_str());
let mut bytecode_hexadecimal = hex::encode(self.deploy_object.bytecode);
bytecode_hexadecimal.push_str(hex::encode(self.runtime_object.bytecode).as_str());
std::fs::write(output_path.as_path(), bytecode_hexadecimal.as_bytes())
.map_err(|error| anyhow::anyhow!("File {output_path:?} writing: {error}"))?;
}
Expand All @@ -183,14 +179,11 @@ impl Contract {
self,
standard_json_contract: &mut era_solc::StandardJsonOutputContract,
) -> anyhow::Result<()> {
let deploy_bytecode = hex::encode(self.deploy_build.as_slice());
let runtime_bytecode = hex::encode(self.runtime_build.as_slice());

standard_json_contract.metadata = self.metadata_json;
standard_json_contract
.evm
.get_or_insert_with(era_solc::StandardJsonOutputContractEVM::default)
.modify_evm(deploy_bytecode, runtime_bytecode);
.modify_evm(hex::encode(self.deploy_object.bytecode));
standard_json_contract
.missing_libraries
.extend(self.missing_libraries);
Expand All @@ -210,8 +203,8 @@ impl Contract {
*metadata = self.metadata_json.to_string();
}

combined_json_contract.bin = Some(hex::encode(self.deploy_build));
combined_json_contract.bin_runtime = Some(hex::encode(self.runtime_build));
combined_json_contract.bin = Some(hex::encode(self.deploy_object.bytecode));
combined_json_contract.bin_runtime = Some(hex::encode(self.runtime_object.bytecode));

combined_json_contract
.missing_libraries
Expand Down
77 changes: 77 additions & 0 deletions era-compiler-solidity/src/build_evm/contract/object.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
//!
//! Bytecode object.
//!

///
/// Bytecode object.
///
/// Can be either deploy and runtime code.
///
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct Object {
/// Object identifier.
pub identifier: String,
/// Contract full name.
pub contract_name: era_compiler_common::ContractName,
/// Bytecode.
pub bytecode: Vec<u8>,
/// Codegen.
pub codegen: Option<era_solc::StandardJsonInputCodegen>,
/// Code segment.
pub code_segment: era_compiler_common::CodeSegment,
/// Dependencies.
pub dependencies: era_yul::Dependencies,
/// Whether the object is already assembled.
pub is_assembled: bool,
/// The binary object format.
pub object_format: era_compiler_common::ObjectFormat,
}

impl Object {
///
/// A shortcut constructor.
///
pub fn new(
identifier: String,
contract_name: era_compiler_common::ContractName,
bytecode: Vec<u8>,
codegen: Option<era_solc::StandardJsonInputCodegen>,
code_segment: era_compiler_common::CodeSegment,
dependencies: era_yul::Dependencies,
) -> Self {
Self {
identifier,
contract_name,
bytecode,
codegen,
code_segment,
dependencies,
is_assembled: false,
object_format: era_compiler_common::ObjectFormat::ELF,
}
}

///
/// Whether the object requires assebmling with its dependencies.
///
pub fn requires_assembling(&self) -> bool {
!self.is_assembled && !self.dependencies.inner.is_empty()
}

///
/// Checks whether the object name matches a dot-separated dependency name.
///
/// This function is only useful for Yul codegen where object names like `A_25.A_25_deployed` are found.
/// For EVM assembly codegen, it performs a simple comparison.
///
pub fn matches_dependency(&self, dependency: &str) -> bool {
let dependency = match self.codegen {
Some(era_solc::StandardJsonInputCodegen::EVMLA) | None => dependency,
Some(era_solc::StandardJsonInputCodegen::Yul) => {
dependency.split('.').last().expect("Always exists")
}
};

self.identifier.as_str() == dependency
}
}
29 changes: 29 additions & 0 deletions era-compiler-solidity/src/build_evm/contract/runtime_build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//!
//! Runtime code.
//!

///
/// The runtime code LLVM module build.
///
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct RuntimeBuild {
/// Object identifier.
pub identifier: String,
/// Bytecode.
pub bytecode: Vec<u8>,
/// Dependencies.
pub dependencies: era_yul::Dependencies,
}

impl RuntimeBuild {
///
/// A shortcut constructor.
///
pub fn new(identifier: String, bytecode: Vec<u8>, dependencies: era_yul::Dependencies) -> Self {
Self {
identifier,
bytecode,
dependencies,
}
}
}
Loading
Loading