use acvm::{FieldElement, acir::circuit::Program};
use noirc_abi::{Abi, AbiType, AbiValue};
use serde::{Deserialize, Serialize};
use std::collections::{BTreeMap, HashMap};
use fm::FileId;
use crate::{
debug::{DebugFile, DebugInfo, ProgramDebugInfo},
program::CompiledProgram,
ssa::SsaReport,
};
use super::{deserialize_hash, serialize_hash};
#[derive(Clone, Serialize, Deserialize, Debug)]
pub struct ContractOutputsArtifact {
pub structs: HashMap<String, Vec<AbiType>>,
pub globals: HashMap<String, Vec<AbiValue>>,
}
impl From<CompiledContractOutputs> for ContractOutputsArtifact {
fn from(outputs: CompiledContractOutputs) -> Self {
ContractOutputsArtifact { structs: outputs.structs, globals: outputs.globals }
}
}
#[derive(Clone, Serialize, Deserialize, Debug)]
pub struct ContractArtifact {
pub noir_version: String,
pub name: String,
pub functions: Vec<ContractFunctionArtifact>,
pub outputs: ContractOutputsArtifact,
pub file_map: BTreeMap<FileId, DebugFile>,
}
impl From<CompiledContract> for ContractArtifact {
fn from(contract: CompiledContract) -> Self {
ContractArtifact {
noir_version: contract.noir_version,
name: contract.name,
functions: contract.functions.into_iter().map(ContractFunctionArtifact::from).collect(),
outputs: contract.outputs.into(),
file_map: contract.file_map,
}
}
}
impl ContractArtifact {
pub fn function_as_compiled_program(&self, function_name: &str) -> Option<CompiledProgram> {
self.functions.iter().find(|f| f.name == function_name).map(|f| {
f.clone().into_compiled_program(self.noir_version.clone(), self.file_map.clone())
})
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ContractFunctionArtifact {
pub name: String,
#[serde(default)] #[serde(serialize_with = "serialize_hash", deserialize_with = "deserialize_hash")]
pub hash: u64,
pub is_unconstrained: bool,
pub custom_attributes: Vec<String>,
pub abi: Abi,
#[serde(
serialize_with = "Program::serialize_program_base64",
deserialize_with = "Program::deserialize_program_base64"
)]
pub bytecode: Program<FieldElement>,
#[serde(
serialize_with = "ProgramDebugInfo::serialize_compressed_base64_json",
deserialize_with = "ProgramDebugInfo::deserialize_compressed_base64_json"
)]
pub debug_symbols: ProgramDebugInfo,
}
impl ContractFunctionArtifact {
pub fn into_compiled_program(
self,
noir_version: String,
file_map: BTreeMap<FileId, DebugFile>,
) -> CompiledProgram {
CompiledProgram {
noir_version,
hash: self.hash,
program: self.bytecode,
abi: self.abi,
debug: self.debug_symbols.debug_infos,
file_map,
warnings: Vec::new(),
}
}
}
impl From<ContractFunction> for ContractFunctionArtifact {
fn from(func: ContractFunction) -> Self {
ContractFunctionArtifact {
name: func.name,
hash: func.hash,
is_unconstrained: func.is_unconstrained,
custom_attributes: func.custom_attributes,
abi: func.abi,
bytecode: func.bytecode,
debug_symbols: ProgramDebugInfo { debug_infos: func.debug },
}
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct CompiledContractOutputs {
pub structs: HashMap<String, Vec<AbiType>>,
pub globals: HashMap<String, Vec<AbiValue>>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct CompiledContract {
pub noir_version: String,
pub name: String,
pub functions: Vec<ContractFunction>,
pub outputs: CompiledContractOutputs,
pub file_map: BTreeMap<FileId, DebugFile>,
pub warnings: Vec<SsaReport>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ContractFunction {
pub name: String,
pub hash: u64,
pub is_unconstrained: bool,
pub custom_attributes: Vec<String>,
pub abi: Abi,
#[serde(
serialize_with = "Program::serialize_program_base64",
deserialize_with = "Program::deserialize_program_base64"
)]
pub bytecode: Program<FieldElement>,
pub debug: Vec<DebugInfo>,
}