Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 15 additions & 11 deletions crates/dojo/utils/src/tx/deployer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,19 @@ where
Self { account, txn_config }
}

/// Get a Call for deploying a contract via the UDC.
/// Get the deterministic UDC-derived contract address along with the
/// Call required to deploy it (or `None` for the Call if the contract
/// is already deployed at that address).
///
/// The address is always returned, even on the already-deployed path,
/// so callers don't have to re-derive it themselves.
pub async fn deploy_via_udc_getcall(
&self,
class_hash: Felt,
salt: Felt,
constructor_calldata: &[Felt],
deployer_address: Felt,
) -> Result<Option<(Felt, Call)>, TransactionError<A::SignError>> {
) -> Result<(Felt, Option<Call>), TransactionError<A::SignError>> {
let udc_calldata = [
vec![class_hash, salt, deployer_address, Felt::from(constructor_calldata.len())],
constructor_calldata.to_vec(),
Expand All @@ -53,13 +58,13 @@ where
get_contract_address(salt, class_hash, constructor_calldata, deployer_address);

if is_deployed(contract_address, &self.account.provider()).await? {
return Ok(None);
return Ok((contract_address, None));
}

Ok(Some((
Ok((
contract_address,
Call { calldata: udc_calldata, selector: UDC_DEPLOY_SELECTOR, to: UDC_ADDRESS },
)))
Some(Call { calldata: udc_calldata, selector: UDC_DEPLOY_SELECTOR, to: UDC_ADDRESS }),
))
}

/// Deploys a contract via the UDC.
Expand All @@ -70,12 +75,11 @@ where
constructor_calldata: &[Felt],
deployer_address: Felt,
) -> Result<(Felt, TransactionResult), TransactionError<A::SignError>> {
let (contract_address, call) = match self
let (contract_address, call) = self
.deploy_via_udc_getcall(class_hash, salt, constructor_calldata, deployer_address)
.await?
{
Some(res) => res,
None => return Ok((Felt::ZERO, TransactionResult::Noop)),
.await?;
let Some(call) = call else {
return Ok((contract_address, TransactionResult::Noop));
};

let InvokeTransactionResult { transaction_hash } =
Expand Down
17 changes: 6 additions & 11 deletions crates/sozo/ops/src/migrate/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -917,23 +917,18 @@ where

let deployer = Deployer::new(&self.world.account, self.txn_config);

match deployer
// `deploy_via_udc_getcall` returns the UDC-derived contract
// address plus an Option<Call> — None means the contract is
// already deployed at that address and no call is needed.
let (_contract_address, call) = deployer
.deploy_via_udc_getcall(
contract.common.class_hash,
contract.salt,
&contract.encoded_constructor_data,
Felt::ZERO,
)
.await?
{
Some((_, call)) => deploy_call = Some(call),
None => {
deploy_call = {
// Already deployed, no need to deploy again.
None
}
}
}
.await?;
deploy_call = call;

is_upgradeable = contract.is_upgradeable;
}
Expand Down
Loading