通用部署合约

通用部署合约(UDC)是一个单例智能合约,它包装了 deploy 系统调用,并将其暴露给任何未实现它的合约,例如账户合约。您可以将其视为 Starknet 合约的标准化通用工厂。

由于 Starknet 没有部署交易类型,因此它提供了一种通过遵循 标准部署器接口 并发出 ContractDeployed 事件来部署智能合约的标准化方法。

有关动机和决策过程的详细信息,请参见 通用部署合约提案

UDC 合约地址

UDC 部署在 Starknet sepolia 和主网上的地址 0x02ceed65a4bd731034c01113685c831b01c15d7d432f71afb1cf1634b53a2125

接口

#[starknet::interface]
pub trait IUniversalDeployer {
    fn deploy_contract(
        class_hash: ClassHash,
        salt: felt252,
        not_from_zero: bool,
        calldata: Span<felt252>
    ) -> ContractAddress;
}

使用 UDC 部署合约

首先,声明 目标合约(如果尚未声明)。 接下来,调用 UDC 的 deploy_contract 方法。 以下是 Cairo 中的一个实现示例:

use openzeppelin_utils::interfaces::{IUniversalDeployerDispatcher, IUniversalDeployerDispatcherTrait};

const UDC_ADDRESS: felt252 = 0x04...;

fn deploy() -> ContractAddress {
    let dispatcher = IUniversalDeployerDispatcher {
        contract_address: UDC_ADDRESS.try_into().unwrap()
    };

    // Deployment parameters
    // 部署参数
    let class_hash = class_hash_const::<
       0x5c478ee27f2112411f86f207605b2e2c58cdb647bac0df27f660ef2252359c6
    >();
    let salt = 1234567879;
    let not_from_zero = true;
    let calldata = array![];

    // The UDC returns the deployed contract address
    // UDC 返回已部署的合约地址
    dispatcher.deploy_contract(class_hash, salt, not_from_zero, calldata.span())
}

部署类型

通用部署合约提供两种类型的地址来部署:依赖于来源的和独立于来源的。 顾名思义,依赖于来源的类型在地址计算中包含部署者的地址, 而独立于来源的类型则不包含。 not_from_zero 布尔参数最终决定了部署的类型。

当部署在构造函数 calldata 中使用 get_caller_address 的合约时,请记住,是 UDC 而不是帐户部署了该合约。 因此,在合约的构造函数中查询 get_caller_address 会返回 UDC 的地址,而不是帐户的地址

依赖于来源

通过使部署依赖于来源地址,用户可以保留整个地址空间,以防止其他人获得该地址的所有权。

只有来源地址的所有者才能部署到这些地址。

要实现这种类型的部署,来源必须在 deploy_contract 调用中将 not_from_zero 设置为 true。 在底层,该函数将修改后的 salt 传递给 deploy_syscall,它是来源地址与给定 salt 的哈希值。

要部署唯一的合约地址,请传递:

let deployed_addr = udc.deploy_contract(class_hash, salt, true, calldata.span());

独立于来源

独立于来源的合约部署创建独立于部署者和 UDC 实例的合约地址。 相反,只有 class hash、salt 和构造函数参数决定了地址。 这种类型的部署支持跨多个网络重新部署帐户和已知系统。 要部署可复现的部署,请将 not_from_zero 设置为 false

let deployed_addr = udc.deploy_contract(class_hash, salt, false, calldata.span());

版本变更

注意:有关初始规范,请参见 之前的通用部署器 API[之前的通用部署器 API]。

UDC 的最新迭代包括对 API 的一些显著更改,其中包括:

  • deployContract 方法被 snake_case deploy_contract 替换。

  • unique 参数在 deploy_contract 方法和 ContractDeployed 事件中都被 not_from_zero 替换。

预计算合约地址

此库提供了用 Cairo 编写的实用程序函数,用于预计算合约地址。 它们包括通用的 calculate_contract_address_from_deploy_syscall 以及 UDC 特定的 calculate_contract_address_from_udc。 查看 deployments 了解更多信息。