use crate::cli::ContractIdCommand;
use anyhow::{bail, Result};
use forc_pkg::{self as pkg, build_with_options};
use forc_tracing::println_green;
use pkg::manifest::build_profile::ExperimentalFlags;
use sway_core::{fuel_prelude::fuel_tx, BuildTarget};
use tracing::info;
pub fn contract_id(command: ContractIdCommand) -> Result<()> {
let build_options = build_opts_from_cmd(&command);
let build_plan = pkg::BuildPlan::from_build_opts(&build_options)?;
if command.salt.salt.is_some() && build_plan.member_nodes().count() > 1 {
bail!(
"A salt was specified when attempting to detect the contract id \
for a workspace with more than one member.
If you wish to find out contract id for a contract member with\
salt, run this command for the member individually.
If you wish to specify the salt for a contract dependency, \
please do so within the `[contract-dependencies]` table."
)
}
let built = build_with_options(build_options)?;
for (pinned_contract, built_contract) in built.into_members() {
let salt = command
.salt
.salt
.or_else(|| build_plan.salt(pinned_contract))
.unwrap_or_else(fuel_tx::Salt::zeroed);
let name = &pinned_contract.name;
let storage_slots = built_contract.storage_slots.clone();
let contract_id =
pkg::contract_id(built_contract.bytecode.bytes.clone(), storage_slots, &salt);
println_green(&format!(" {name}"));
info!(" Contract id: 0x{contract_id}");
}
Ok(())
}
fn build_opts_from_cmd(cmd: &ContractIdCommand) -> pkg::BuildOpts {
pkg::BuildOpts {
pkg: pkg::PkgOpts {
path: cmd.pkg.path.clone(),
offline: cmd.pkg.offline,
terse: cmd.pkg.terse,
locked: cmd.pkg.locked,
output_directory: cmd.pkg.output_directory.clone(),
json_abi_with_callpaths: cmd.pkg.json_abi_with_callpaths,
ipfs_node: cmd.pkg.ipfs_node.clone().unwrap_or_default(),
},
print: pkg::PrintOpts {
ast: cmd.print.ast,
dca_graph: cmd.print.dca_graph.clone(),
dca_graph_url_format: cmd.print.dca_graph_url_format.clone(),
finalized_asm: cmd.print.finalized_asm,
intermediate_asm: cmd.print.intermediate_asm,
ir: cmd.print.ir,
reverse_order: cmd.print.reverse_order,
},
time_phases: cmd.print.time_phases,
metrics_outfile: cmd.print.metrics_outfile.clone(),
minify: pkg::MinifyOpts {
json_abi: cmd.minify.json_abi,
json_storage_slots: cmd.minify.json_storage_slots,
},
build_profile: cmd.build_profile.build_profile.clone(),
release: cmd.build_profile.release,
error_on_warnings: cmd.build_profile.error_on_warnings,
binary_outfile: cmd.build_output.bin_file.clone(),
debug_outfile: cmd.build_output.debug_file.clone(),
build_target: BuildTarget::default(),
tests: false,
member_filter: pkg::MemberFilter::only_contracts(),
experimental: ExperimentalFlags {
new_encoding: cmd.experimental_new_encoding,
},
}
}