美文网首页
本地运行Move程序

本地运行Move程序

作者: yangzming | 来源:发表于2020-11-17 09:25 被阅读0次

    本地运行Move程序

    • 注意:目前只能在本地网络上运行自定义Move模块和脚本,不能在Libra测试网上运行。

    本教程将指导在本地区块链上发布Move模块并执行Move交易脚本。要执行现有Move交易脚本本身不支持的操作,可以创建和发布Move模块,并编写脚本来使用这些模块。Libra CLI客户端提供dev命令来编译、发布和执行本地的Move程序。要查看子命令列表,在CLI上输入dev

    要创建、编译和发布Move模块到本地区块链上的帐户,请遵循以下编译和发布Move模块中的说明。要编译和执行Move交易脚本,请遵循以下编译和执行交易脚本中的说明。

    编译和发布Move模块

    启动一个本地验证器节点网络

    首先运行一个本地验证器网络。参考启动一个本地网络文档。

    创建一个账户

    每个Move模块和资源类型由一个特定的帐户地址托管。例如,Libra模块由地址为0x1的帐户托管。要在其他模块或交易脚本中导入Libra模块,Move代码将指定use 0x1::Libra

    在发布Move模块之前,首先需要创建一个帐户来托管它:

    libra% account create
    >> Creating/retrieving next local account from wallet
    Created/retrieved local account #0 address 717da70a461fef6307990847590ad7af
    

    在上面的输出中,0是您刚刚创建的帐户的索引,十六进制字符串是该帐户的地址。索引只是在本地引用该帐户的一种方便方式,它也被称为ref_id。有关帐号创建的更多信息,请参考我的第一次交易

    create命令生成一个本地密匙对。要在本地区块链上创建帐户,需要将货币注入该帐户,如下所示:

    libra% account mintb 0 76 Coin1
    >> Creating recipient account before minting from faucet
    waiting ....
    transaction executed!
    no events emitted
    >> Sending coins from faucet
    waiting ....
    transaction executed!
    Finished sending coins from faucet!
    

    要检查在本地区块链上是否成功创建了帐户,请查询帐户余额。

    libra% query balance 0
    Balance is: 76.000000Coin1
    

    创建Move模块

    让我们从一个名为SimpleFee的简单模块开始。这个模块实现每个帐户的处理费用,可以添加到支付交易中。帐户可以指定链上Move资源的费用金额,应该为每种货币类型收费。帐户所有者可以设置费用金额,任何人都可以检索费用并将其添加到支付中。下面提供了这个模块的Move代码。将第一行中的地址更改为刚刚创建的帐户的地址,然后将其保存在名为SimpleFee.move的文件中。(确保账户地址保持“0x”前缀。)

    address 0x717da70a461fef6307990847590ad7af {
    
    module SimpleFee {
      // A simple fixed-price per-account processing fee that can be added
      // to payment transactions. There is a different fee for each CoinType.
      resource struct Fee<CoinType> {
        fee: u64
      }
    
      // Set the fee amount.
      public fun set_fee<CoinType>(account: &signer, fee: u64) {
        move_to(account, Fee<CoinType> { fee })
      }
    
      // Get the fee for an account.
      public fun get_fee<CoinType>(account: address): u64 acquires Fee {
        if (exists<Fee<CoinType>>(account))
          borrow_global<Fee<CoinType>>(account).fee
        else
          0
      }
    }
    }
    

    编译Move模块

    为了编译SimpleFee.move,使用dev编译命令。

    libra% dev compile 0 <path to SimpleFee.move> <path to language/stdlib/modules>
    
    • 0 - 索引/ref_id的帐户,该模块将发布在这个账户下。
    • 源文件名后面列出的参数指定依赖项,由于该模块依赖于Move标准库,因此需要指定到该目录的路径。

    Move代码以.Move文件的形式输入编译器,编译器输出相应的字节码文件。当准备好将此模块发布到区块链上的帐户中时,请使用该字节码文件,而不是.move文件。

    成功编译模块后,将在输出中看到以下消息,它包含编译SimpleFee.move生成的字节码文件的路径。

    Successfully compiled a program at:
      /tmp/741fdedbc67720028e60cf637b835a6c/modules/0_SimpleFee.mv
    

    发布已编译的模块

    要在本地区块链上发布模块字节码,运行dev publish命令,并使用编译后的模块字节码文件的路径,如下所示:

    libra% dev publish 0 /var/folders/tq/8gxrrmhx16376zxd5r4h9hhn_x1zq3/T/b8639bd9fe2403874bbfde5643486bde/modules/0_SimpleFee.mv
    
    waiting .....
    transaction executed!
    no events emitted.
    Successfully published module
    

    在成功执行dev publish命令后,SimpleFee的字节码将在发送者的帐户下发布。要使用SimpleFee中声明的过程和类型,其他交易脚本和模块可以通过use <sender_address>::SimpleFee导入它。

    <sender_address>下发布的后续模块不能被命名为SimpleFee。每个帐户最多只能持有一个具有给定名称的模块。试图在<sender_address>下发布第二个名为SimpleFee的模块将导致交易失败。

    编译和执行交易脚本

    创建交易脚本

    要使用SimpleFee模块,首先创建一个交易脚本来设置费用金额。在下面的脚本中编辑SimpleFee帐户地址以匹配创建的帐户,然后将其保存为set_lbr_fee.move:

    script {
    use 0x1::Coin1::Coin1;
    use 0x717da70a461fef6307990847590ad7af::SimpleFee;
    
    fun set_lbr_fee(account: &signer, fee: u64) {
      SimpleFee::set_fee<Coin1>(account, fee)
    }
    }
    

    CLI客户端目前还没有将货币代码转换为自定义脚本的货币类型,所以这个示例脚本硬编码为使用LBR硬币。)

    你还需要一个自定义脚本来发送带有附加费用的支付,所以用同样的方法,在下面的脚本中编辑帐户地址,并将其保存为pay_lbr_with_fee.move:

    script {
    use 0x1::LibraAccount;
    use 0x1::Coin1::Coin1;
    use 0x717da70a461fef6307990847590ad7af::SimpleFee;
    
    fun pay_lbr_with_fee(payer: &signer, payee: address, amount: u64) {
      let payer_withdrawal_cap = LibraAccount::extract_withdraw_capability(payer);
      let total = amount + SimpleFee::get_fee<Coin1>(payee);
      LibraAccount::pay_from<Coin1>(&payer_withdrawal_cap, payee, total, x"", x"");
      LibraAccount::restore_withdraw_capability(payer_withdrawal_cap);
    }
    }
    

    编译交易脚本

    为了编译交易脚本,使用dev compile命令。

    libra% dev compile 0 <path to set_lbr_fee.move> <path to SimpleFee.move> <path to language/stdlib/modules>
    

    set_lbr_fee.move是Move源文件,在成功编译set_lbr_fee.move之后。Move编译器将输出相应的字节码文件。当执行这个脚本时,将使用这个字节码文件(不是.move文件)。当脚本成功编译后,会在输出中看到字节码文件的路径:

    Successfully compiled a program at:
      /tmp/897541d70c8578528ed6d7ae98e044d0/scripts/set_lbr_fee.mv
    

    pay_lbr_with_fee.move重复编译步骤:

    libra% dev compile 0 <path to pay_lbr_with_fee.move> <path to SimpleFee.move> <path to language/stdlib/modules>
    >> Compiling program
    Successfully compiled a program at:
      /var/folders/tq/8gxrrmhx16376zxd5r4h9hhn_x1zq3/T/5fa11d0acf5d53e8d257ab31534b2017/scripts/pay_lbr_with_fee.mv
    

    执行交易脚本

    要执行自定义脚本,请对上面编译交易脚本的字节码输出使用dev execute命令。首先,使用set_lbr_fee脚本来指定费用金额:

    • 注意:传递给dev execute命令的确切参数集将取决于特定脚本所期望的参数。
    libra% dev execute 0 /var/folders/tq/8gxrrmhx16376zxd5r4h9hhn_x1zq3/T/5fa11d0acf5d53e8d257ab31534b2017/scripts/set_lbr_fee.mv 10000
    waiting .....
    transaction executed!
    no events emitted
    Successfully finished execution
    
    • 0 - 发件人帐户的索引/ref_id。对于本例,编译和发布模块的帐户是相同的。
    • /var/folders/tq/8gxrrmhx16376zxd5r4h9hhn_x1zq3/T/5fa11d0acf5d53e8d257ab31534b2017/scripts/set_lbr_fee.mv - 已编译脚本的路径。
    • 10000 - 费用金额,以微Libra为单位(0.01Libra)。

    接下来,我们可以设置另一个帐户,并使用pay_lbr_with_fee脚本发送附加费用的支付:

    libra% account create
    >> Creating/retrieving next local account from wallet
    Created/retrieved local account #1 address aed273e4e7b36276e1442656cc16eb31
    libra% account mintb 1 10 LBR
    >> Creating recipient account before minting from faucet
    waiting ....
    transaction executed!
    no events emitted
    >> Sending coins from faucet
    waiting ....
    transaction executed!
    Finished sending coins from faucet!
    libra% dev execute 1 /var/folders/tq/8gxrrmhx16376zxd5r4h9hhn_x1zq3/T/5fa11d0acf5d53e8d257ab31534b2017/scripts/pay_lbr_with_fee.mv 0x717da70a461fef6307990847590ad7af 1000000
    waiting ....
    transaction executed!
    Successfully finished execution
    
    • 1 - 发送者帐户的Index/ref_id,这是新创建的帐户,将发送支付。
    • /var/folders/tq/8gxrrmhx16376zxd5r4h9hhn_x1zq3/T/5fa11d0acf5d53e8d257ab31534b2017/scripts/pay_lbr_with_fee.mv - 已编译脚本的路径
    • 0x717da70a461fef6307990847590ad7af - 收款人帐户地址(帐户索引0)。
    • 1000000 -支付金额,以微Libra为单位(0.01Libra)。

    这项交易的结果可通过查询帐户余额来观察:

    libra% query balance 0
    Balance is: 77.010000Coin1
    libra% query balance 1
    Balance is: 8.990000Coin1
    

    正如预期的那样,1.0个Coin1付款增加了0.01Coin1费用,因此1.01Coin1付款从账户1转到账户0。

    故障排除

    编译Move程序

    如果客户端无法找到你的Move源文件,你会看到这样的错误:

    libra% dev compile 0 ~/my-tscripts/set_lbr_fee.move
    >> Compiling program
    Error: No such file or directory '~/my-tscripts/set_lbr_fee.move'
    compilation failed
    

    这可能是因为客户端当前没有执行波浪线扩展,所以需要列出到主目录的路径。

    如果看到以下错误,请参考dev compile命令的用法,指定所有必需的参数并再次尝试编译。

    Invalid number of arguments for compilation
    

    发布已编译的模块

    如果你编译一个模块使用一个帐户(例如,dev compile 0…),并试图将它发布到另一个帐户(例如,dev publish 1…),你会看到以下错误:

    libra% dev publish 1 /var/folders/tq/8gxrrmhx16376zxd5r4h9hhn_x1zq3/T/b8639bd9fe2403874bbfde5643486bde/modules/0_SimpleFee.mv
    
    transaction failed to execute; status: VerificationError!
    

    编译后的模块包含要发布模块的帐户地址,Move虚拟机(VM)只允许交易发送方在发送方自己的帐户地址下发布模块。如果不是这样,其他用户就可以在您的帐户下发布模块!若要修复此错误,请使用所需的发送方地址重新编译模块。

    如果你没有提供正确的路径到你的编译模块,你会看到这个错误:

    libra% dev publish 0 incorrect-path-to-compiled-module
    No such file or directory (os error 2)
    

    如果索引1的帐户不存在,尝试将模块发布到1将导致以下错误:

    Unable to find account by account reference id: 1, to see all existing accounts, run: 'account list'
    

    在相同发件人帐户地址下重新发布/更新现有模块不会对区块链产生任何影响。这是一个失败的交易,但是它从发送方帐户中扣除gas并将发送方帐户的序列号增加1。可以在不同的发送方帐户地址发布相同的模块,前提是模块是使用该帐户地址编译的。

    执行交易脚本

    如果发件人帐户索引无效,您将看到以下错误:

    libra% dev execute 2 /var/folders/tq/8gxrrmhx16376zxd5r4h9hhn_x1zq3/T/5fa11d0acf5d53e8d257ab31534b2017/scripts/set_lbr_fee.mv 10000
    Unable to find account by account reference id: 2, to see all existing accounts, run: 'account list'
    

    下面的错误表明,交易脚本的参数要么丢失,要么一个或多个参数类型错误。

    libra% dev execute 0 /var/folders/tq/8gxrrmhx16376zxd5r4h9hhn_x1zq3/T/5fa11d0acf5d53e8d257ab31534b2017/scripts/set_lbr_fee.mv
    transaction failed to execute; status: VerificationError!
    

    相关文章

      网友评论

          本文标题:本地运行Move程序

          本文链接:https://www.haomeiwen.com/subject/tbztiktx.html