feat(solc): include opcodes in output (#1435)

This commit is contained in:
Matthias Seitz 2022-06-30 18:16:47 +02:00 committed by GitHub
parent 73d3d3f494
commit 9892756ee4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 35 additions and 14 deletions

View File

@ -1,4 +1,12 @@
//! A configurable artifacts handler implementation
//!
//! Configuring artifacts requires two pieces: the `ConfigurableArtifacts` handler, which contains
//! the configuration of how to construct the `ConfigurableArtifact` type based on a `Contract`. The
//! `ConfigurableArtifacts` populates a single `Artifact`, the `ConfigurableArtifact`, by default
//! with essential entries only, such as `abi`, `bytecode`,..., but may include additional values
//! based on its `ExtraOutputValues` that maps to various objects in the solc contract output, see
//! also: [`OutputSelection`](crate::artifacts::OutputSelection). In addition to that some output
//! values can also be emitted as standalone files.
use crate::{
artifacts::{
@ -34,6 +42,8 @@ pub struct ConfigurableContractArtifact {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub assembly: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub opcodes: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub method_identifiers: Option<BTreeMap<String, String>>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub generated_sources: Vec<GeneratedSource>,
@ -248,6 +258,7 @@ impl ArtifactOutput for ConfigurableArtifacts {
let mut artifact_assembly = None;
let mut artifact_storage_layout = None;
let mut generated_sources = None;
let mut opcodes = None;
let Contract {
abi,
@ -298,13 +309,17 @@ impl ArtifactOutput for ConfigurableArtifacts {
if self.additional_values.function_debug_data {
artifact_function_debug_data =
bytecode.as_ref().map(|b| b.function_debug_data.clone());
bytecode.as_mut().map(|code| std::mem::take(&mut code.function_debug_data));
}
if self.additional_values.generated_sources {
generated_sources =
bytecode.as_mut().map(|code| std::mem::take(&mut code.generated_sources));
}
if self.additional_values.opcodes {
opcodes = bytecode.as_mut().and_then(|code| code.opcodes.take())
}
artifact_bytecode = bytecode.map(Into::into);
artifact_deployed_bytecode = deployed_bytecode.map(Into::into);
artifact_method_identifiers = Some(method_identifiers);
@ -322,6 +337,7 @@ impl ArtifactOutput for ConfigurableArtifacts {
bytecode: artifact_bytecode,
deployed_bytecode: artifact_deployed_bytecode,
assembly: artifact_assembly,
opcodes,
function_debug_data: artifact_function_debug_data,
method_identifiers: artifact_method_identifiers,
gas_estimates: artifact_gas_estimates,
@ -373,6 +389,7 @@ pub struct ExtraOutputValues {
pub function_debug_data: bool,
pub generated_sources: bool,
pub source_map: bool,
pub opcodes: bool,
/// PRIVATE: This structure may grow, As such, constructing this structure should
/// _always_ be done using a public constructor or update syntax:
@ -408,6 +425,7 @@ impl ExtraOutputValues {
function_debug_data: true,
generated_sources: true,
source_map: true,
opcodes: true,
__non_exhaustive: (),
}
}
@ -444,6 +462,7 @@ impl ExtraOutputValues {
config.method_identifiers = true;
config.generated_sources = true;
config.source_map = true;
config.opcodes = true;
}
EvmOutputSelection::Assembly => {
config.assembly = true;
@ -457,6 +476,9 @@ impl ExtraOutputValues {
EvmOutputSelection::ByteCode(BytecodeOutputSelection::FunctionDebugData) => {
config.function_debug_data = true;
}
EvmOutputSelection::ByteCode(BytecodeOutputSelection::Opcodes) => {
config.opcodes = true;
}
EvmOutputSelection::ByteCode(BytecodeOutputSelection::GeneratedSources) => {
config.generated_sources = true;
}

View File

@ -1,8 +1,16 @@
//! Output artifact handling
use crate::{
artifacts::FileToContractsMap, error::Result, utils, HardhatArtifact, ProjectPathsConfig,
SolcError,
artifacts::{
contract::{CompactContract, CompactContractBytecode, Contract},
BytecodeObject, CompactBytecode, CompactContractBytecodeCow, CompactDeployedBytecode,
FileToContractsMap, SourceFile,
},
compile::output::{contracts::VersionedContracts, sources::VersionedSourceFiles},
error::Result,
sourcemap::{SourceMap, SyntaxError},
sources::VersionedSourceFile,
utils, HardhatArtifact, ProjectPathsConfig, SolcError,
};
use ethers_core::{abi::Abi, types::Bytes};
use semver::Version;
@ -13,18 +21,7 @@ use std::{
fmt, fs, io,
path::{Path, PathBuf},
};
mod configurable;
use crate::{
artifacts::{
contract::{CompactContract, CompactContractBytecode, Contract},
BytecodeObject, CompactBytecode, CompactContractBytecodeCow, CompactDeployedBytecode,
SourceFile,
},
compile::output::{contracts::VersionedContracts, sources::VersionedSourceFiles},
sourcemap::{SourceMap, SyntaxError},
sources::VersionedSourceFile,
};
pub use configurable::*;
/// Represents unique artifact metadata for identifying artifacts on output

View File

@ -139,6 +139,7 @@ fn can_compile_configured() {
metadata: true,
ir: true,
ir_optimized: true,
opcodes: true,
..Default::default()
},
..Default::default()
@ -152,6 +153,7 @@ fn can_compile_configured() {
assert!(artifact.raw_metadata.is_some());
assert!(artifact.ir.is_some());
assert!(artifact.ir_optimized.is_some());
assert!(artifact.opcodes.is_some());
}
#[test]