diff --git a/components/clarinet-deployments/src/lib.rs b/components/clarinet-deployments/src/lib.rs index f26480af4..00c4ab1f2 100644 --- a/components/clarinet-deployments/src/lib.rs +++ b/components/clarinet-deployments/src/lib.rs @@ -352,12 +352,13 @@ pub async fn generate_default_deployment( Some(ast) => ast, None => { // Download the code - let (source, contract_location) = requirements::retrieve_contract( - &contract_id, - &cache_location, - &file_accessor, - ) - .await?; + let (source, clarity_version, contract_location) = + requirements::retrieve_contract( + &contract_id, + &cache_location, + &file_accessor, + ) + .await?; // Build the struct representing the requirement in the deployment if network.is_simnet() { @@ -394,6 +395,7 @@ pub async fn generate_default_deployment( location: contract_location, cost: deployment_fee_rate * source.len() as u64, remap_principals, + clarity_version, }; requirements_publish.insert(contract_id.clone(), data); } diff --git a/components/clarinet-deployments/src/onchain/mod.rs b/components/clarinet-deployments/src/onchain/mod.rs index c6b694b54..106ab8592 100644 --- a/components/clarinet-deployments/src/onchain/mod.rs +++ b/components/clarinet-deployments/src/onchain/mod.rs @@ -11,7 +11,7 @@ use clarity_repl::clarity::vm::types::{ PrincipalData, QualifiedContractIdentifier, StandardPrincipalData, }; use clarity_repl::clarity::vm::{ClarityName, Value}; -use clarity_repl::clarity::{ContractName, EvaluationResult}; +use clarity_repl::clarity::{ClarityVersion, ContractName, EvaluationResult}; use clarity_repl::codec::{ SinglesigHashMode, SinglesigSpendingCondition, StacksString, StacksTransactionSigner, TokenTransferMemo, TransactionAuth, TransactionContractCall, TransactionPayload, @@ -174,6 +174,7 @@ pub fn encode_stx_transfer( pub fn encode_contract_publish( contract_name: &ContractName, source: &str, + clarity_version: &ClarityVersion, account: &AccountConfig, nonce: u64, tx_fee: u64, @@ -186,7 +187,7 @@ pub fn encode_contract_publish( }; sign_transaction_payload( account, - TransactionPayload::SmartContract(payload, None), + TransactionPayload::SmartContract(payload, Some(clarity_version.clone())), nonce, tx_fee, anchor_mode, @@ -546,6 +547,7 @@ pub fn apply_on_chain_deployment( let transaction = match encode_contract_publish( &tx.contract_name, &source, + &tx.clarity_version, *account, nonce, tx.cost, @@ -621,6 +623,7 @@ pub fn apply_on_chain_deployment( let transaction = match encode_contract_publish( &tx.contract_id.name, &source, + &tx.clarity_version, *account, nonce, tx.cost, diff --git a/components/clarinet-deployments/src/requirements.rs b/components/clarinet-deployments/src/requirements.rs index 08c83db0e..b827dabc7 100644 --- a/components/clarinet-deployments/src/requirements.rs +++ b/components/clarinet-deployments/src/requirements.rs @@ -1,12 +1,12 @@ use clarinet_files::{FileAccessor, FileLocation}; -use clarity_repl::clarity::vm::types::QualifiedContractIdentifier; +use clarity_repl::clarity::{vm::types::QualifiedContractIdentifier, ClarityVersion}; use reqwest; pub async fn retrieve_contract( contract_id: &QualifiedContractIdentifier, cache_location: &FileLocation, file_accessor: &Option<&Box>, -) -> Result<(String, FileLocation), String> { +) -> Result<(String, ClarityVersion, FileLocation), String> { let contract_deployer = contract_id.issuer.to_address(); let contract_name = contract_id.name.to_string(); @@ -20,7 +20,11 @@ pub async fn retrieve_contract( }; if contract_source.is_ok() { - return Ok((contract_source.unwrap(), contract_location)); + return Ok(( + contract_source.unwrap(), + ClarityVersion::Clarity1, + contract_location, + )); } let stacks_node_addr = if contract_deployer.starts_with("SP") { @@ -36,19 +40,32 @@ pub async fn retrieve_contract( name = contract_name ); - let code = fetch_contract(request_url).await?.source; + let contract = fetch_contract(request_url).await?; let result = match file_accessor { - None => contract_location.write_content(code.as_bytes()), + None => contract_location.write_content(contract.source.as_bytes()), Some(file_accessor) => { file_accessor - .write_file(contract_location.to_string(), code.as_bytes()) + .write_file(contract_location.to_string(), contract.source.as_bytes()) .await } }; + let clarity_version = { + let version = contract.clarity_version.unwrap_or(1); + if version.eq(&1) { + ClarityVersion::Clarity1 + } else if version.eq(&2) { + ClarityVersion::Clarity2 + } else { + return Err(format!( + "unable to parse clarity_version (can either be '1' or '2'", + )); + } + }; + match result { - Ok(_) => Ok((code, contract_location)), + Ok(_) => Ok((contract.source, clarity_version, contract_location)), Err(err) => Err(err), } } @@ -58,6 +75,7 @@ pub async fn retrieve_contract( struct Contract { source: String, publish_height: u32, + clarity_version: Option, } async fn fetch_contract(request_url: String) -> Result { diff --git a/components/clarinet-deployments/src/types.rs b/components/clarinet-deployments/src/types.rs index 120b54a6e..18c449833 100644 --- a/components/clarinet-deployments/src/types.rs +++ b/components/clarinet-deployments/src/types.rs @@ -104,6 +104,8 @@ pub struct RequirementPublishSpecificationFile { pub path: Option, #[serde(skip_serializing_if = "Option::is_none")] pub url: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub clarity_version: Option, } #[derive(Debug, PartialEq, Serialize, Deserialize)] @@ -387,6 +389,7 @@ pub struct RequirementPublishSpecification { pub remap_sender: StandardPrincipalData, pub remap_principals: BTreeMap, pub source: String, + pub clarity_version: ClarityVersion, pub cost: u64, pub location: FileLocation, } @@ -453,11 +456,27 @@ impl RequirementPublishSpecification { let source = location.read_content_as_utf8()?; + let clarity_version = match specs.clarity_version { + Some(clarity_version) => { + if clarity_version.eq(&1) { + Ok(ClarityVersion::Clarity1) + } else if clarity_version.eq(&2) { + Ok(ClarityVersion::Clarity2) + } else { + Err(format!( + "unable to parse clarity_version (can either be '1' or '2'", + )) + } + } + _ => Ok(DEFAULT_CLARITY_VERSION), + }?; + Ok(RequirementPublishSpecification { contract_id, remap_sender, remap_principals, source, + clarity_version, location: location, cost: specs.cost, }) @@ -954,6 +973,10 @@ impl TransactionPlanSpecification { path: None, url: None, cost: tx.cost, + clarity_version: match tx.clarity_version { + ClarityVersion::Clarity1 => Some(1), + ClarityVersion::Clarity2 => Some(2), + }, }, ) }