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: <command> <args>

Use the following commands:

account | a
  Account operations
query | q
  Query operations
transfer | transferb | t | tb
  <sender_account_address>|<sender_account_ref_id> <receiver_account_address>|<receiver_account_ref_id> <number_of_coins> <currency_code> [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 client


Please, input commands:

libra%

创建Alice和Bob的账户

一旦客户端连接到testnet,就可以运行CLI命令来创建新帐户。此处将指导两个用户(称他们为Alice和Bob)创建帐户。

步骤1:检查CLI客户端是否在系统上运行

命令行提示符libra%表示libra CLI客户端正在运行。要查看account命令的帮助信息,请输入“account”,如下图所示:

libra% account
usage: account <arg>

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 <file path>
  Recover Libra wallet from the file path
write | w <file name>
  Save Libra wallet mnemonic recovery seed to disk
mint | mintb | m | mb <receiver_account_ref_id>|<receiver_account_address> <number_of_coins> <currency_code> [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 <account_address> <currency_code>
  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的货币代码

成功执行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 <fetch_events=true|false>

可以使用命令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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,133评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,682评论 3 390
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,784评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,508评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,603评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,607评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,604评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,359评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,805评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,121评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,280评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,959评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,588评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,206评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,442评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,193评论 2 367
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,144评论 2 352