了解 Universal Deployer 合约并通过 Argent X 部署您的合约

使用通用部署合约在 Starknet 上部署合约

使用通用部署合约在 Starknet 上部署合约

StarkNet 对于开发人员来说是一个相对较新的网络,它可能会带来挑战。幸运的是,有很多很棒的文档、教程和愿意帮助构建的开发人员。尽管如此,各种能力的开发者还是会时不时地遇到问题。其中之一是最近对合同部署到 StarkNet 的方式所做的更改导致开发人员遇到以下错误: 

客户端失败,代码 500:{“代码”:“StarknetErrorCode.DEPRECATED_TRANSACTION”,“消息”:“不再支持部署事务。”

如果你遇到这些错误,你可能会交叉检查你的构造函数输入和你能想到的所有其他调试过程,但都无济于事……

那么出了什么问题呢? 

随着最近 StarkNet 更新到 0.10.3,DEPLOY 事务被弃用并且不再有效。 

当 StarkNet 推出时,StarkWare 补贴网络使用,允许开发人员免费将合约部署到网络,以鼓励更多的开发人员活动。这意味着您永远不必像 Argent X 那样从您的StarkNet 钱包中支付部署费用。

但这会导致一些问题。 

如果 StarkWare 补贴网络使用,那么网络 Sequencer 就没有动力。定序器是执行 Cairo OS 程序、证明结果并更新 StarkNet 状态的 StarkNet 节点。它们对于 StarkNet 的安全至关重要。 

对于以太坊等第 1 层区块链,支付交易费用以激励验证者,但有争议的是,在弃用 DEPLOY 命令之前,部署到 StarkNet 网络一直是免费的。如果没有费用,这将意味着以下两种情况之一:(1) 网络是中心化的,或者 (2) Sequencer 像一个亏损的慈善机构一样运作。 

这两个选项都没有比例。 

因此,为了防止最近在网络上频繁发生的 DDOS(分布式拒绝服务),也为了向完全去中心化的目标迈出一步,必须完全弃用免费部署。 

此更改的结果意味着以前部署合同的方法已被弃用,并被deploy 系统调用取代,它允许导入任何合同并与通用部署合同 (UDC) 一起使用。

WTF 是通用部署合同 (UDC)?

Openzeppelin 团队提出了 Universal Deployer Contract 来创建一种方法,通过该方法将部署功能转移到外部的、专门的部署者合约,该合约可以被任何其他账户合约安全可靠地调用。

为了使账户实现简单,功能尽可能少,我们决定一个账户可以调用来部署合约的外部合约将是一个更好的设计选择。

 还建议将该外部合同设为通用,以确保每个人都能使用它,并使用 deploy_from_zero=TRUE 进行部署,以保证在所有 StarkNet 网络实例中具有相同的确定性地址,从而促进工具和互操作性。

通过我们最近的更新,您可以轻松地从您的 Argent X 钱包声明和部署交易,在本教程中,我们将在演示明确使用 UDC 的困难路线之前引导您完成整个过程。

使用 Argent X 声明和部署合约

在我们开始使用 Argent X 在 StarkNet 上声明和部署合约之前,我们假设您熟悉编写和编译基本的 Cairo 合约。如果这对你来说是新的,并且你想了解更多关于 StarkNet 上的合约,我们推荐这个教程

以下是我们将要部署的基本合约:

%lang 星网
从 starkware.cairo.common.math 导入 assert_nn
从 starkware.cairo.common.cairo_builtins 导入 HashBuiltin

@storage_var
func balance() -> (res: felt) {
}

@构造函数
func constructor{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(input: felt) {
    balance.write(输入);
    返回 ();
}

@外部的
func increase_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(
    数量:毛毡
) {
    with_attr error_message(“金额必须为正数。得到:{amount}。”){
        assert_nn(金额);
    }

    让 (res) = balance.read();
    balance.write(res + amount);
    返回 ();
}

@看法
func get_balance{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}() -> (res: felt) {
    让 (res) = balance.read();
    返回(资源,);
}

1.打开你的Argent X,点击右上角的设置图标

Argent X 中的突出显示设置

2.向下滚动,选择“开发者设置”

在 Argent X 中突出显示开发人员设置

3.选择“智能合约开发”

选择

4.要部署合约,我们需要先通过声明合约来获取classhash。要声明合约,请选择“声明智能合约”

在 Argent X 中声明智能合约

5. 选择“Click to upload contract JSON”上传你编译basic.cairo合约得到的JSON ABI

在 Argent X 中上传 JSON

6. 您现在需要选择将部署合约的网络和用于部署的帐户,然后按Declare。您将需要签署交易,您将被重定向到包含合同类哈希的页面

在 Argent X 中声明的合同

7. 复制输出的类哈希,然后选择“Go to deployment” 

8. 同样,您需要选择将部署合约的网络和用于部署的帐户。完成后,构造函数输入字段将自动弹出。填写构造函数参数并选择一个随机盐(在我们的例子中为 5)。您也可以使用一个唯一的地址,最后按“ Deploy ”按钮来部署合约

使用 Argent X 部署智能合约

唯一地址是一个可选字段,可帮助确定您是否要为部署者生成一个不能被占用(地址接管)的唯一地址。

9. 签署交易,您将被重定向到包含您部署的合约地址的页面 

您的智能合约已部署!

使用 Universal Deployer Contract 部署合约

我们刚刚完成了在 StarkNet 上部署和声明合约的最简单和最简单的方法。但这不是唯一的选择。您可以部署和声明与 UDC 的合同,正如我们现在将要解释的那样。 

就像我们之前所做的那样,确保从上面编译basic.cairo合约以跟随本教程。对于本教程,我们将使用 Protostar,但无论您使用何种开发框架,步骤都是相同的。 

我们将遵循 4 个简单的步骤:

  1. 编译我们的合约以获取 JSON ABI
  2. 声明我们的合约以获取合约的classhash
  3. 调用UDC的deployContract函数,传入需要的参数
  4. 在发出的事件中检查你的合约地址

但感谢 Protostar,步骤数已简化为 3,其中步骤 3 和 4 在调用部署命令时执行(我们将对此进行更深入的研究)。

1. 编写合约

使用 Protostar 编译合约就像运行命令“ protostar build ”一样简单,但请确保将路径添加到protostar.toml配置文件中的basic.cairo文件。

darlingtonnnam@Darlingtons-MacBook-Air 测试 % protostar build
建筑工程合同                                                                                                                                                                 
合约“基本”的类哈希:0x745f2d517414cc07d74fb162fca62492f11eb589189ab74c12c7a535ebac2ec
12:00:26 [信息] 执行时间:2.16 秒

2. 声明你的合同

接下来,我们需要声明我们的合约以获得合约类哈希。要在 Protostar 中执行此操作,请运行以下命令:

protostar declare ./build/basic.json --network testnet --account-address 0x046c5877EE8d297107Bd8E507Fb97b8cAB4ECD6C83892AD92EA40100412b4976 --max-fee auto

在执行上述命令之前,您应该在文件或终端中设置与指定帐户地址关联的私钥。要在终端中设置您的私钥,请运行以下命令:

export PROTOSTAR_ACCOUNT_PRIVATE_KEY=[你的私钥在这里]

您应该像这样在屏幕上输出类哈希:

darlingtonnnam@Darlingtons-MacBook-Air 测试 % protostar declare ./build/basic.json --network testnet --account-address 0x046c5877EE8d297107Bd8E507Fb97b8cAB4ECD6C83892AD92EA40100412b4976 --max-fee auto
声明交易已发送。                                                                                                                                                                
类哈希:0x0745f2d517414cc07d74fb162fca62492f11eb589189ab74c12c7a535ebac2ec
StarkScan https://testnet.starkscan.co/class/0x0745f2d517414cc07d74fb162fca62492f11eb589189ab74c12c7a535ebac2ec
航海者 https://goerli.voyager.online/class/0x0745f2d517414cc07d74fb162fca62492f11eb589189ab74c12c7a535ebac2ec

交易哈希:0x00c15ec8c5305c2b581df344ae121b1d9c998afdf68f4171c811375ae34b724e
StarkScan https://testnet.starkscan.co/tx/0x00c15ec8c5305c2b581df344ae121b1d9c998afdf68f4171c811375ae34b724e
航海者 https://goerli.voyager.online/tx/0x00c15ec8c5305c2b581df344ae121b1d9c998afdf68f4171c811375ae34b724e
12:06:54 [INFO] 执行时间:5.13 秒

3. 部署你的合约

最后,我们将把我们的合约部署到 StarkNet。我们可以通过运行 Protostar 命令来简单地做到这一点:

protostar deploy [classhash] –network testnet –account-address 0x046c5877EE8d297107Bd8E507Fb97b8cAB4ECD6C83892AD92EA40100412b4976 –max-fee auto –inputs 10

我们应该在屏幕上输出我们的合同地址。

调用交易被发送到通用部署者合约。                                                                                                                              
合约地址:0x038a40eb43f1d830211512dbd3f6a83c2065b1b91e1056ce9603d12d7d775f85
StarkScan https://testnet.starkscan.co/contract/0x038a40eb43f1d830211512dbd3f6a83c2065b1b91e1056ce9603d12d7d775f85
航海者 https://goerli.voyager.online/contract/0x038a40eb43f1d830211512dbd3f6a83c2065b1b91e1056ce9603d12d7d775f85

交易哈希:483740916302696625162989563270470904410869738490209728461194936287947680474
StarkScan https://testnet.starkscan.co/tx/0x0111c9a3d225eee4b0657eca027b053931826a27689811511d7cee2dec086ada
航海者 https://goerli.voyager.online/tx/0x0111c9a3d225eee4b0657eca027b053931826a27689811511d7cee2dec086ada
12:09:23 [信息] 执行时间:3.20 秒

像那样,我们刚刚按照非常简单的步骤将我们的合约部署到 StarkNet。我们从来没有直接与 UDC 交互,因为这个过程是由 Protostar 抽象出来的。

只是为了好玩,让我们直接与 UDC 进行交互。

调用 deployContract 函数 

声明我们的合同后,我们将调用deployContract函数,但我们需要首先检查其接口以了解它需要哪些参数。

@外部的
func deployContract{...}(
    classHash:感觉,
    盐:感觉,
    独特:感觉,
    calldata_len:感觉,
    通话数据:感觉*
) -> (地址: 毛毡) {...}

如您所见,它需要我们传入我们已经从声明中获得的合约的 classHash、一个随机盐、一个唯一字段(0 表示 false,1 表示 true)、calldata_len(构造函数参数的数量)和一个 calldata数组(构造函数参数)。

这是我们的调用命令的样子:

protostar invoke --contract-address 0x041a78e741e5af2fec34b695679bc6891742439f7afb8484ecd7766661ad02bf --function "deployContract" --network testnet --account-address 0x046c5877EE8d297107Bd8E507Fb97b8cAB4ECD6C83892AD92EA40100412b4976 --max-fee auto --inputs [classhash] 13 0 1 1

有关 Protostar 调用的更多信息,请查看此处的文档。

如果我们的调用命令通过,我们应该得到输出的交易哈希,我们将进一步检查我们的合约地址。

PS:如果您遇到输入验证错误,那是因为在撰写本文时最新的 Protostar 版本 v0.9.0 及以下版本在通过 CLI 进行数组解析时存在一些问题。这应该在下一次更新中修复。

4. 检查合约地址发出的事件

调用deployContract命令,输出我们刚刚执行的交易的交易哈希。查看 UDC 代码,我们可以看到交易发出了一个包含新创建的合约地址的事件:

@事件
func ContractDeployed(
    地址:毛毡,
    部署者:感觉,
    独特:感觉,
    classHash:感觉,
    calldata_len:感觉,
    通话数据:感觉*,
    盐:感觉
) {
}

因此,我们可以检查交易哈希中发出的事件,以获取已部署合约的合约地址,如下所示:

检查交易哈希中发出的事件

结论

通过我们的教程,您应该对为什么需要执行 DEPLOY 命令、通用部署合同 (UDC) 如何出现以及如何有效地使用 Argent X 进行无压力部署有深入的了解。

如果您对此有任何疑问,请联系我@0xdarlington,我很乐意帮助您使用 Argent X 在 StarkNet 上进行构建。 

如需更多开发人员资源,请关注我们的社交网站:

推特—— @argentHq

工程 Twitter — @argentDeveloper

领英——  @argentHq

Youtube—— @argentHQ

英文原文链接:https://www.argent.xyz/blog/understanding-the-universal-deployer-contract/

所有文章项目交互项目介绍

Primex:2022 年回顾

2023-1-1 14:06:20

所有文章项目介绍

Aleo 宣布与 Forte 建立合作伙伴关系

2023-1-3 22:33:00

搜索