Libra上构建第一笔交易

我的第一笔交易 本文档将指导在Libra区块链上执行第一个交易。我们提供了一个命令行接口(CLI)客户端来与区块链交互。
假设 本文档中的所有命令都假设:

  • 您正在运行Linux (Red Hat或基于debian的)或macOS系统。
  • 你的网络连接很稳定。
  • git已经安装在您的系统上。
  • Homebrew安装在macOS系统上。
  • yumor apt-get安装在Linux系统上。
提交交易的步骤 在本例中,我们将下载必要的Libra组件,并在两个用户(Alice和Bob)之间执行交易。
执行以下步骤向Libra的测试网上的验证器节点提交交易:
1、克隆和建立Libra Core。
2、构建Libra CLI客户端并连接到testnet。
3、创建Alice和Bob的帐户。
4、铸币,并加到Alice和Bob的账户上。
5、提交一个交易。
克隆和建立Libra Core 克隆Libra Core的仓库
git clone https://github.com/libra/libra.git && cd libra
切换到testnet分支
git checkout testnet
安装依赖
要安装Libra Core,切换到Libra目录并运行安装脚本安装依赖项,如下所示:
./scripts/dev_setup.sh
安装脚本执行以下操作:
  • 安装rustup -- rustup是一个用于Rust编程语言的安装程序,Libra Core就是在该语言中实现的
  • 安装rust工具链所需的版本。
  • 安装CMake -- 用于管理构建过程。
  • 安装protoc - 一个protol buffer协议编译器。
  • 安装Go -用于构建协议缓冲区。
构建Libra CLI客户端并连接到testnet 要连接到运行在Libra testnet上的验证器节点,运行客户端如下所示。
./scripts/cli/start_cli_testnet.sh
这个命令使用cargo (Rust的包管理器)构建并运行客户端,并将客户端连接到testnet上的一个验证器节点。
实际部署遇到的问题:在实际运行时,首先遇到了编译问题,提示:
error[E0658]: use of unstable library feature 'no_more_cas': no more CAS loops in user code --> common/logger/src/sample.rs:47:14

经过多种方法重试,发现把rust卸载,再重新安装就可以了,也不需要切换到nightly版本。rust安装:https://www.cntofu.com/book/192/src/ch01-01-installation.md。由于我使用虚拟机linux进行的编译,在编译到move语言一直卡死,不动,经过定位原因是虚拟机内存不够。增加虚拟机内存即可解决。1G内存不够,至少2g以上,推荐4g。
一旦客户端连接到测试网络上的节点,您将看到以下输出。要在任何时候退出客户端,请使用quit命令。
usage: Use the following commands:account | a Account operations query | q Query operations transfer | transferb | t | tb | | [gas_unit_price_in_micro_libras (default=0)] [max_gas_amount_in_micro_libras (default 400_000)] Suffix 'b' is for blocking. Transfer coins from one account to another. info | i Print cli config and client internal information dev Local Move development help | h Prints this help quit | q! Exit this clientPlease, input commands:libra%

创建Alice和Bob的账户 一旦客户端连接到testnet,就可以运行CLI命令来创建新帐户。此处将指导两个用户(称他们为Alice和Bob)创建帐户。
步骤1:检查CLI客户端是否在系统上运行
命令行提示符libra%表示libra CLI客户端正在运行。要查看account命令的帮助信息,请输入“account”,如下图所示:
libra% account usage: account Use the following args for this command:create | c Create a local account--no on-chain effect. Returns reference ID to use in other operations list | la Print all accounts that were created or loaded recover | r Recover Libra wallet from the file path write | w Save Libra wallet mnemonic recovery seed to disk mint | mintb | m | mb | [use_base_units (default=false)] Send currency of the given type from the faucet address to the given recipient address. Creates an account at the recipient address if one does not already exist. Suffix 'b' is for blocking addc | addcb | ac | acb Add specified currency to the account. Suffix 'b' is for blocking

步骤2:创建Alice的帐户
注意,使用CLI创建帐户不会更新区块链,它只是创建一个本地密钥对。
要创建Alice的账户,输入以下命令:
libra% account create
成功时的示例输出:
>> Creating/retrieving next local account from wallet Created/retrieved local account #0 address cc2219df031a68115fad9aee98e051e9

0是Alice帐户的索引,十六进制字符串是Alice帐户的地址。索引只是一种引用Alice帐户的方法。account索引是一个本地CLI索引,用户可以在其他CLI命令中使用它来方便地引用他们创建的帐户。索引对于区块链是没有意义的。只有当通过minting将钱添加到Alice的账户,或者通过其他用户的转账将钱转移到Alice的账户时,Alice的账户才会在区块链上创建。注意,可以在CLI命令中使用十六进制地址。帐户索引只是一个方便的包装帐户地址。
步骤3:创建Bob的账户
要创建Bob的帐户,请重复创建帐户命令:
libra% account create
成功时示例输出:
>> Creating/retrieving next local account from wallet Created/retrieved local account #1 address 33138303ce638c8fa469435250f5f1c3

1是Bob的账户索引,十六进制字符串是Bob的账户地址。
步骤4(可选):列出帐户
要列出创建的帐户,请输入以下命令:
libra% account list
成功时示例输出:
User account index: 0, address: cc2219df031a68115fad9aee98e051e9, sequence number: 0, status: Local User account index: 1, address: 33138303ce638c8fa469435250f5f1c3, sequence number: 0, status: Local

帐户的序列号表示已从该帐户发送的交易数量。每当执行从该帐户发送的交易并存储在区块链中时,它就会增加。
把Libra币加到Alice和Bob的账户里 在testnet上铸造和添加币是通过Faucet完成的。Faucet是与testnet一起运行的服务。此服务仅存在于为testnet铸造币而不存在于mainnet。它创造的Libra没有真实的价值。假设已经创建了Alice和Bob的帐户,分别使用索引0和索引1,则可以按照下面的步骤将Libra添加到两个帐户。
步骤1:添加110 LBR到Alice的账户
要铸造Libra并添加到Alice的账户中,输入以下命令:
libra% account mint 0 110 LBR
  • 0是Alice帐户的索引。
  • 110是加到Alice的账户中的Libra的数量。
  • LBR是Libra的货币代码
【Libra上构建第一笔交易】成功执行account mint命令还将在区块链上创建Alice的帐户。
成功时示例输出:
>> Creating recipient account before minting from faucet waiting .... transaction executed! no events emitted >> Sending coins from faucet Request submitted to faucet

注意,当请求被提交时,这意味着它已经被成功添加到mempool (testnet上的一个验证器节点)。这并不一定意味着它会成功地完成。稍后我们会查询账户余额,确认造币是否成功。
注意:经过实际测试,在2020.10.08,github上提了一个新的pr,不允许mint LBR了,需要修改为Coin1。具体链接为:https://github.com/libra/libra/pull/6445。以下章节命令也是类似,需要LBR替换为Coin1。否则会报以下错误:
[ERROR] Error transferring coins from faucet: LBR not allowed to be minted or transferred. Use Coin1 instead

步骤2:添加52个LBR到Bob的账户
要铸造Libra并添加到Bob的帐户,请输入以下命令:
libra% account mint 1 52 LBR
  • 1是Bob的账户索引。
  • 52是加到鲍勃的账上的Libra的数量。
  • LBR是Libra的货币代码
  • 成功执行account mint命令还将在区块链上创建Bob的帐户。在区块链上创建Bob帐户的另一种方法是将钱从Alice的帐户转到Bob的帐户。
成功时示例输出:
>> Creating recipient account before minting from faucet waiting .... transaction executed! no events emitted >> Sending coins from faucet Request submitted to faucet

步骤3:检查余额
要查看Alice的账户余额,请输入以下命令:
libra% query balance 0
成功时示例输出:
Balance is: 110.000000LBR

要检查Bob的账户余额,输入以下命令:
libra% query balance 1
成功时示例输出:
Balance is: 52.000000LBR

提交一个交易 在提交将Libra从Alice的帐户转到Bob的帐户的交易之前,将查询每个帐户的序列号。这将帮助了解执行一个交易如何更改每个帐户的序列号。
查询账户的序列号
libra% query sequence 0 >> Getting current sequence number Sequence number is: 0 libra% query sequence 1 >> Getting current sequence number Sequence number is: 0

query sequence 0中,0是Alice的帐户的索引。Alice和Bob的帐户的序列号都为0,这表示到目前为止没有执行来自Alice或Bob帐户的交易。
转账
要提交一个交易,将10 LBR从Alice的帐户转移到Bob的帐户,输入以下命令:
libra% transfer 0 1 10 LBR
  • 0是Alice帐户的索引。
  • 1是Bob的账户索引。
  • 10是从Alice的帐户转到Bob的帐户的Libra的数目。
  • LBR是Libra的货币代码
成功时示例输出:
>> Transferring Transaction submitted to validator To query for transaction status, run: query txn_acc_seq 0 0

可以使用命令query txn_acc_seq 0 0 true(按帐户和序列号处理交易)来检索关于刚刚提交的交易的信息。第一个参数是发送者帐户的本地索引,第二个参数是帐户的序列号。
刚刚将交易提交给了testnet上的一个验证器节点,它被包含在验证器的mempool中。这并不一定意味着交易已经执行。理论上,如果系统运行缓慢或超载,则需要一些时间来查看结果,并且可能必须通过查询帐户进行多次检查。要查询索引为0的帐户,可以使用命令query account_state 0
阻塞转账命令:可以使用transferb命令(如下所示),而不是transfer命令。只有在将交易提交给区块链之后,transferb才会提交交易并返回客户端提示。下面是一个例子:
libra% transferb 0 1 10 LBR
转账之后查询序列号
libra% query sequence 0 >> Getting current sequence number Sequence number is: 1 libra% query sequence 1 >> Getting current sequence number Sequence number is: 0

Alice的帐户的序号1(索引0)表示到目前为止已经从Alice的帐户发送了一个交易。Bob的帐户的序列号0(索引1)表示到目前为止还没有从Bob的帐户发送任何交易。每次从帐户发送一个交易时,序列号增加1。
转账之后检查两个账户的余额
要检查两个帐户的最终余额,请像在之前步骤中那样再次查询每个帐户的余额。如果交易(转账)成功执行,应该看到Alice的帐户中有100 LBR, Bob的帐户中有62 LBR。
libra% query balance 0 Balance is: 100.000000LBR libra% query balance 1 Balance is: 62.000000LBR

祝贺!
您已经成功地在Libra testnet上执行了您的交易,并将10 LBR从Alice的帐户转移到Bob的帐户!
附加查询命令的示例输出 通过账户和序列号查询交易
本例将使用帐户和序列号查询单个交易的详细信息。
libra% query txn_acc_seq 0 0 true >> Getting committed transaction by account and sequence number Committed transaction: TransactionView { version: 2788, transaction: UserTransaction { sender: "cc2219df031a68115fad9aee98e051e9", signature_scheme: "Scheme::Ed25519", signature: "6bbdb1410d2ff27de675a40c7d4d3a6cab149302ca3e4f789100ede739009147d066da60680d34dc1aa32dcf22d21ea679da22963e0027292c8b76f287aad70d", public_key: "babe538296960c2822f569c9ecf086e77d42c86240f6d813e7a17e0d193199ce", sequence_number: 0, chain_id: 4, max_gas_amount: 1000000, gas_unit_price: 0, gas_currency: "LBR", expiration_timestamp_secs: 1595614184, script_hash: "c8bc3dda60e9662965b3223c22e3d3e3e7b6f698cf1a6930a449eb99daa35e7c", script: PeerToPeer { receiver: "33138303ce638c8fa469435250f5f1c3", amount: 10000000, currency: "LBR", metadata: BytesView( "", ), metadata_signature: BytesView( "", ), }, }, hash: "b33f9dfb4f0cb161b3f6ce84398381dbd132978f2810d66e04003ff64e1f2dd6", events: [ EventView { key: BytesView( "0100000000000000cc2219df031a68115fad9aee98e051e9", ), sequence_number: 0, transaction_version: 2788, data: SentPayment { amount: AmountView { amount: 10000000, currency: "LBR", }, receiver: BytesView( "33138303ce638c8fa469435250f5f1c3", ), sender: BytesView( "cc2219df031a68115fad9aee98e051e9", ), metadata: BytesView( "", ), }, }, EventView { key: BytesView( "000000000000000033138303ce638c8fa469435250f5f1c3", ), sequence_number: 1, transaction_version: 2788, data: ReceivedPayment { amount: AmountView { amount: 10000000, currency: "LBR", }, sender: BytesView( "cc2219df031a68115fad9aee98e051e9", ), receiver: BytesView( "33138303ce638c8fa469435250f5f1c3", ), metadata: BytesView( "", ), }, }, ], vm_status: Executed, gas_used: 175, }

注意,交易金额以microlibra显示。
查询事件
在下面的示例中,我们将在引用索引0处查询来自帐户的“已发送”事件。注意到有一个单独的事件,因为我们从这个帐户发送了一个交易。还会返回当前状态的证明,以便在查询不返回“limit”事件时执行验证以确保没有事件丢失。
libra% query event 0 sent 0 10 >> Getting events by account and event type. EventView { key: BytesView("0100000000000000cc2219df031a68115fad9aee98e051e9"), sequence_number: 0, transaction_version: 2788, data: SentPayment { amount: AmountView { amount: 10000000, currency: "LBR" }, receiver: BytesView("33138303ce638c8fa469435250f5f1c3"), sender: BytesView("cc2219df031a68115fad9aee98e051e9"), metadata: BytesView("") } } Last event state: AccountView { balances: [ AmountView { amount: 100000000, currency: "LBR", }, ], sequence_number: 1, authentication_key: BytesView( "1b72d1171fc0c2c41b06408c06e9d675cc2219df031a68115fad9aee98e051e9", ), sent_events_key: BytesView( "0100000000000000cc2219df031a68115fad9aee98e051e9", ), received_events_key: BytesView( "0000000000000000cc2219df031a68115fad9aee98e051e9", ), delegated_key_rotation_capability: false, delegated_withdrawal_capability: false, is_frozen: false, role: ParentVASP { human_name: "testnet", base_url: "https://libra.org", expiration_time: 18446744073709551615, compliance_key: BytesView( "b7a3c12dc0c8c748ab07525b701122b88bd78f600c76342d27f25e5f92444cde", ), num_children: 0, }, }

查询账户状态
在本例中,我们将查询单个帐户的状态。
libra% query account_state 0 >> Getting latest account state Latest account state is: Account: ( cc2219df031a68115fad9aee98e051e9, Some( AuthenticationKey( [ 27, 114, 209, 23, 31, 192, 194, 196, 27, 6, 64, 140, 6, 233, 214, 117, 204, 34, 25, 223, 3, 26, 104, 17, 95, 173, 154, 238, 152, 224, 81, 233, ], ), ), ) State: Some( AccountView { balances: [ AmountView { amount: 100000000, currency: "LBR", }, ], sequence_number: 1, authentication_key: BytesView( "1b72d1171fc0c2c41b06408c06e9d675cc2219df031a68115fad9aee98e051e9", ), sent_events_key: BytesView( "0100000000000000cc2219df031a68115fad9aee98e051e9", ), received_events_key: BytesView( "0000000000000000cc2219df031a68115fad9aee98e051e9", ), delegated_key_rotation_capability: false, delegated_withdrawal_capability: false, is_frozen: false, role: ParentVASP { human_name: "testnet", base_url: "https://libra.org", expiration_time: 18446744073709551615, compliance_key: BytesView( "b7a3c12dc0c8c748ab07525b701122b88bd78f600c76342d27f25e5f92444cde", ), num_children: 0, }, }, ) Blockchain Version: 8012


    推荐阅读