diff --git a/README.md b/README.md index 82d33f39..cc52c052 100644 --- a/README.md +++ b/README.md @@ -144,6 +144,14 @@ Build the Smart Contract: # Build an existing Smart Contract pop build contract -p ./my_contract ``` +By default the contract is compiled with `debug` functionality included. + +This enables the contract to output debug messages, but increases the contract size and the amount of gas used. + +For production builds, use the --release flag: `--release`: +```sh +pop build contract -p ./my_contract --release +``` To deploy a Smart Contract you need a chain running. For testing purposes you can simply spawn a contract node: diff --git a/crates/pop-cli/src/commands/build/contract.rs b/crates/pop-cli/src/commands/build/contract.rs index 2f102050..7484d0bf 100644 --- a/crates/pop-cli/src/commands/build/contract.rs +++ b/crates/pop-cli/src/commands/build/contract.rs @@ -13,6 +13,10 @@ use pop_contracts::build_smart_contract; pub struct BuildContractCommand { #[arg(short = 'p', long, help = "Path for the contract project, [default: current directory]")] pub(crate) path: Option, + /// The default compilation includes debug functionality, increasing contract size and gas usage. + /// For production, always build in release mode to exclude debug features. + #[clap(long = "release")] + build_release: bool, } impl BuildContractCommand { @@ -21,7 +25,7 @@ impl BuildContractCommand { intro(format!("{}: Building your contract", style(" Pop CLI ").black().on_magenta()))?; set_theme(Theme); - let result_build = build_smart_contract(&self.path)?; + let result_build = build_smart_contract(&self.path, self.build_release)?; outro("Build completed successfully!")?; log::success(result_build.to_string())?; Ok(()) diff --git a/crates/pop-cli/src/commands/up/contract.rs b/crates/pop-cli/src/commands/up/contract.rs index d988dbcf..0c691a52 100644 --- a/crates/pop-cli/src/commands/up/contract.rs +++ b/crates/pop-cli/src/commands/up/contract.rs @@ -63,8 +63,8 @@ impl UpContractCommand { if !build_path.as_path().exists() { log::warning(format!("NOTE: contract has not yet been built."))?; intro(format!("{}: Building a contract", style(" Pop CLI ").black().on_magenta()))?; - // Directory exists, proceed with the rest of the code - let result = build_smart_contract(&self.path)?; + // Build the contract in release mode + let result = build_smart_contract(&self.path, true)?; log::success(result.to_string())?; } diff --git a/crates/pop-contracts/README.md b/crates/pop-contracts/README.md index 258f3aee..4469aeb6 100644 --- a/crates/pop-contracts/README.md +++ b/crates/pop-contracts/README.md @@ -18,7 +18,8 @@ Build an existing Smart Contract: use pop_contracts::build_smart_contract; let contract_path = ...; -build_smart_contract(&contract_path)?; +let build_release = true; // `true` for release mode, `false` for debug mode. +build_smart_contract(&contract_path, build_release)?; ``` Test an existing Smart Contract: diff --git a/crates/pop-contracts/src/build.rs b/crates/pop-contracts/src/build.rs index 767e239d..4caa2a5a 100644 --- a/crates/pop-contracts/src/build.rs +++ b/crates/pop-contracts/src/build.rs @@ -1,14 +1,19 @@ // SPDX-License-Identifier: GPL-3.0 -use contract_build::{execute, ExecuteArgs}; +use contract_build::{execute, BuildMode, ExecuteArgs}; use std::path::PathBuf; use crate::utils::helpers::get_manifest_path; -/// Build the smart contract located in the specified `path`. -pub fn build_smart_contract(path: &Option) -> anyhow::Result { +/// Build the smart contract located at the specified `path` in `build_release` mode. +pub fn build_smart_contract(path: &Option, build_release: bool) -> anyhow::Result { let manifest_path = get_manifest_path(path)?; + + let build_mode = match build_release { + true => BuildMode::Release, + false => BuildMode::Debug, + }; // Default values - let args = ExecuteArgs { manifest_path, ..Default::default() }; + let args = ExecuteArgs { manifest_path, build_mode, ..Default::default() }; // Execute the build and log the output of the build let result = execute(args)?; diff --git a/crates/pop-contracts/src/call.rs b/crates/pop-contracts/src/call.rs index 8f052114..a18346da 100644 --- a/crates/pop-contracts/src/call.rs +++ b/crates/pop-contracts/src/call.rs @@ -179,7 +179,7 @@ mod tests { Ok(temp_dir) } fn build_smart_contract_test_environment(temp_dir: &TempDir) -> Result<(), Error> { - build_smart_contract(&Some(temp_dir.path().join("test_contract")))?; + build_smart_contract(&Some(temp_dir.path().join("test_contract")), true)?; Ok(()) } diff --git a/crates/pop-contracts/tests/contract.rs b/crates/pop-contracts/tests/contract.rs index 05e02406..9e539c8b 100644 --- a/crates/pop-contracts/tests/contract.rs +++ b/crates/pop-contracts/tests/contract.rs @@ -16,12 +16,7 @@ fn setup_test_environment() -> std::result::Result { Ok(temp_dir) } -#[test] -fn test_contract_build() -> std::result::Result<(), Error> { - let temp_contract_dir = setup_test_environment()?; - - build_smart_contract(&Some(temp_contract_dir.path().join("test_contract")))?; - +fn verify_build_files(temp_contract_dir: TempDir) -> Result<()> { // Verify that the folder target has been created assert!(temp_contract_dir.path().join("test_contract/target").exists()); // Verify that all the artifacts has been generated @@ -37,6 +32,27 @@ fn test_contract_build() -> std::result::Result<(), Error> { .path() .join("test_contract/target/ink/test_contract.json") .exists()); + Ok(()) +} + +#[test] +fn test_contract_build() -> std::result::Result<(), Error> { + // Test building in release mode + let temp_contract_dir = setup_test_environment()?; + + let formatted_result = + build_smart_contract(&Some(temp_contract_dir.path().join("test_contract")), true)?; + assert!(formatted_result.contains("RELEASE")); + + verify_build_files(temp_contract_dir)?; + + let temp_debug_contract_dir = setup_test_environment()?; + // Test building in debug mode + let formatted_result_debug_mode = + build_smart_contract(&Some(temp_debug_contract_dir.path().join("test_contract")), false)?; + assert!(formatted_result_debug_mode.contains("DEBUG")); + + verify_build_files(temp_debug_contract_dir)?; Ok(()) } @@ -44,7 +60,7 @@ fn test_contract_build() -> std::result::Result<(), Error> { const CONTRACTS_NETWORK_URL: &str = "wss://rococo-contracts-rpc.polkadot.io"; fn build_smart_contract_test_environment(temp_dir: &TempDir) -> Result<(), Error> { - build_smart_contract(&Some(temp_dir.path().join("test_contract")))?; + build_smart_contract(&Some(temp_dir.path().join("test_contract")), true)?; Ok(()) }