从钱包接受燃料费

在进行本地开发时,您可以使用项目中的默认钱包发送周期并检查您的周期余额。 但是需要接收和使用这些周期的容器智能合约呢? 执行其功能并向用户提供服务? 本教程提供了一个简单的示例来说明如何将接收周期和检查周期余额的功能添加到默认模板程序中。

此示例包含以下内容:

  • wallet_balance 功能使您可以检查容器的当前循环余额。

  • wallet_receive 函数使程序能够接受发送到容器的周期。

  • greet 函数接受文本参数并在终端中显示问候语。

  • owner 函数返回消息调用者使用的principal。

开始之前

在开始本教程之前,请验证以下内容:

  • 您已按照下载并安装中的说明下载并安装了 {sdk-short-name} 包。

  • 如果您使用 Visual,您已按照链接中所述为 Motoko 安装 Visual Studio Code 插件:../../quickstart/local-quickstart.html#install-vscode[安装语言编辑器插件] Studio Code 作为您的 IDE。

  • 您已停止在本地运行的任何本地容器执行环境 计算机。

创建一个新项目

创建一个新的项目目录来测试访问控制和切换用户身份:

  1. 如果您还没有打开一个终端shell,请在您的本地计算机上打开一个终端外壳。

  2. 更改为您用于 Internet Computer 项目的文件夹(如果您正在使用一个)。

  3. 通过运行以下命令创建一个新项目:

    dfx new cycles_hello
  4. 通过运行以下命令切换到您的项目目录:

    cd cycles_hello

修改默认程序

对于本教程,您将修改模板源代码以包含用于接受周期和检查周期平衡的新函数。

修改默认程序:

  1. 在文本编辑器中打开 src/cycles_hello/main.mo 文件并删除现有内容。

  2. 将以下示例代码复制并粘贴到文件中:

    import Nat64 "mo:base/Nat64";
    import Cycles "mo:base/ExperimentalCycles";
    
    shared(msg) actor class HelloCycles (
       capacity: Nat
      ) {
    
      var balance = 0;
    
      // Return the current cycle balance
      public shared(msg) func wallet_balance() : async Nat {
        return balance;
      };
    
      // Return the cycles received up to the capacity allowed
      public func wallet_receive() : async { accepted: Nat64 } {
        let amount = Cycles.available();
        let limit : Nat = capacity - balance;
        let accepted =
          if (amount <= limit) amount
          else limit;
        let deposit = Cycles.accept(accepted);
        assert (deposit == accepted);
        balance += accepted;
        { accepted = Nat64.fromNat(accepted) };
      };
    
      // Return the greeting
      public func greet(name : Text) : async Text {
        return "Hello, " # name # "!";
      };
    
      // Return the principal of the caller/user identity
      public shared(msg) func owner() : async Principal {
        let currentOwner = msg.caller;
        return currentOwner;
      };
    
    };

    让我们来看看这个程序的几个关键元素:

    • 该程序导入了一个 Motoko 基础库——ExperimentalCycles——它提供了使用循环的基本函数。

    • 该程序使用`actor class而不是单个actor,因此它可以有多个actor实例来接受不同的循环量,直到所有实例的`容量

    • capacity 作为参数传递给actor类。

    • msg.caller 标识与调用关联的principal。

  3. 保存更改并关闭 main.mo 文件以继续。

启动本地容器执行环境

在构建 access_hello 项目之前,您需要连接到在您的开发环境中本地运行的容器执行环境,或者您需要连接到您可以访问的子网。

启动本地容器执行环境:

  1. 在本地计算机上打开一个新的终端窗口或选项卡。

  2. 如有必要,导航到项目的根目录。

  3. 通过运行以下命令在您的机器上启动本地容器执行环境:

    dfx start --clean --background

    本地容器执行环境完成启动操作后,可以继续下一步。

注册、构建和部署 dapp

连接到本地容器执行环境后,您可以在本地注册、构建和部署 dapp。

要在本地部署 dapp:

  1. 如果需要,请检查您是否仍在项目的根目录中。

  2. 通过运行以下命令注册、构建和部署您的 dapp:

    dfx deploy --argument '(360000000000)'

    此示例将容器的“容量”设置为 360,000,000,000 次循环。 然后,dfx deploy 命令输出会显示有关它执行的操作的信息,包括与为此本地项目创建的钱包容器相关联的身份和钱包容器标识符。

    例如:

    Deploying all canisters.
    Creating canisters...
    Creating canister "cycles_hello"...
    Creating the canister using the wallet canister...
    Creating a wallet canister on the local network.
    The wallet canister on the "local" network for user "default" is "rwlgt-iiaaa-aaaaa-aaaaa-cai"
    "cycles_hello" canister created with canister id: "rrkah-fqaaa-aaaaa-aaaaq-cai"
    Creating canister "cycles_hello_assets"...
    Creating the canister using the wallet canister...
    "cycles_hello_assets" canister created with canister id: "ryjl3-tyaaa-aaaaa-aaaba-cai"
    Building canisters...
    Building frontend...
    Installing canisters...
    Installing code for canister cycles_hello, with canister_id rrkah-fqaaa-aaaaa-aaaaq-cai
    Installing code for canister cycles_hello_assets, with canister_id ryjl3-tyaaa-aaaaa-aaaba-cai
    Authorizing our identity (default) to the asset canister...
    Uploading assets to asset canister...
    Deployed canisters.

测试 dapp

在本地容器执行环境中部署 dapp 后,您可以使用 dfx canister call 命令试验钱包功能并测试您的程序。

测试 dapp:

  1. 通过运行以下命令检查“default”用户身份的principal:

    dfx canister call cycles_hello owner

    该命令针对当前身份显示类似于以下内容的输出:

    (principal "g3jww-sbmtm-gxsag-4mecu-72yc4-kef5v-euixq-og2kd-sav2v-p2sb3-pae")

    如果您没有更改用于运行 dfx deploy 命令的身份,则应该通过运行 dfx identity get-principal 命令获得相同的principal。 这很重要,因为您必须是钱包容器的所有者才能执行某些任务,例如发送燃料费或授予其他 保管人 身份发送周期的权限。

  2. 通过运行以下命令检查初始钱包燃料费余额:

    dfx canister call cycles_hello wallet_balance

    您尚未向容器发送任何周期,因此该命令显示以下余额:

    (0)
  3. 通过运行类似于以下的命令,使用容器的principal将一些周期从您的默认钱包容器发送到 cycles_hello 容器:

    dfx canister call rwlgt-iiaaa-aaaaa-aaaaa-cai wallet_send '(record { canister = principal "rrkah-fqaaa-aaaaa-aaaaq-cai"; amount = (256000000000:nat64); } )'
  4. 调用 wallet_balance 函数以查看 cycles_hello 容器是否具有您转移的周期数,如果您指定的数量低于允许的容量,或者您在运行 dfx deploy 命令时指定的 容量

    dfx canister call cycles_hello wallet_balance

    该命令显示类似于以下内容的输出:

    (256_000_000_000)
  5. 调用 wallet_balance 函数,通过运行类似于以下的命令来查看默认钱包中的周期数:

    dfx canister call rwlgt-iiaaa-aaaaa-aaaaa-cai wallet_balance

    该命令使用 Candid 格式返回您指定为记录的钱包容器标识符的余额。 例如,该命令可能会显示一条带有“amount”字段(由哈希“3_573_748_184”表示)和余额为 97,738,624,621,042 个燃料费的记录,如下所示:

    (record { 3_573_748_184 = 97_738_624_621_042 })

    对于这个简单的教程,燃料费仅从默认钱包容器中的余额消耗,而不是从 cycles_hello 容器中消耗。

  6. 通过运行类似于以下的命令调用 greet 函数:

    dfx canister call cycles_hello greet '("from DFINITY")'
  7. 重新调用 wallet_balance 函数以查看从您的默认钱包中扣除的燃料费数:

    dfx canister call rwlgt-iiaaa-aaaaa-aaaaa-cai wallet_balance

    For example, you might a result similar to this:

    (record { 3_573_748_184 = 97_638_622_179_500 })

停止本地容器执行环境

完成对程序的试验后,您可以停止本地容器执行环境,使其不会继续在后台运行。

要停止本地容器执行环境:

  1. 在显示操作的终端中,按 Control-C 中断该过程。

  2. 通过运行以下命令停止本地容器执行环境:

    dfx stop