Libra是Facebook 在 6/18 發(fā)表的區(qū)塊鏈解決方案。提出 LibraCoin 加密貨幣來(lái)為金融基礎(chǔ)建設(shè)賦能。以 Facebook 與這次參與的合作伙伴,我相信在未來(lái)能讓支付、跨國(guó)跨境金融交易都能更加地便利。
Agenda
· 環(huán)境設(shè)置
· 下載與編譯 Libra
· 連上 Libra testnet
· 建立自己的 Libra account 與透過(guò)水龍頭 (Faucet) 取得 LibraCoin
· 查詢(xún) Libra account 的余額
· 發(fā)送 LibraCoin
· 查詢(xún)發(fā)送的 transaction
環(huán)境設(shè)置
目前 Libra 只支持 Linux 與MacOS 兩種環(huán)境,以下將以 Linux Ubuntu 18.04 作為示范。
Environment: Ubuntu 18.04 on AWS EC2t3.xlarge
# 更新一下 apt 與安裝 git,其他的環(huán)境 Libra 有提供他的 script 來(lái)安裝。
sudo apt update
sudo apt upgrade
sudo apt install git
下載與編譯Libra
第一步:下載最新的Libra存儲(chǔ)庫(kù)
$ git clone https://github.com/libra/libra.git && cd libra
Cloning into ‘libra’。..
remote: Enumerating objects: 133, done.
remote: Counting objects: 100% (133/133), done.
remote: Compressing objects: 100% (105/105), done.
remote: Total 1717 (delta 40), reused 55 (delta 25), pack-reused 1584
Receiving objects: 100% (1717/1717), 1.89 MiB | 1.88 MiB/s, done.
Resolving deltas: 100% (340/340), done.
第二步: 安裝 Libra Core 所需的 dependencies
$ 。/scripts/dev_setup.sh
Welcome to Libra!
This script will download and install the necessary dependencies
needed to
build Libra Core. This includes:
* Rust (and the necessary components, e.g. rust-fmt, clippy)
* CMake, protobuf, go (for building protobuf)
If you‘d prefer to install these dependencies yourself, please
exit this script
now with Ctrl-C.
Proceed with installing necessary dependencies? (y) 》
。..
。..
Installing CMake.。..。.
CMake is already installed
Installing Go.。..。.
Go is already installed
Installing Protobuf.。..。.
Protobuf is already installed
Step2-optional. 在安裝 dependencies 的過(guò)程間我有遇到 protoc 安裝失敗,原因是 18.04 的 apt 上面的 protobuf 版本是 3.0.0,而 Libra 所需的版本為 》= 3.6.0 ,所以導(dǎo)致他安裝失敗。這時(shí)我們就需要手動(dòng)安裝最新版本的 protobuf 來(lái)解決這個(gè)問(wèn)題。
sudo apt install unzip
PROTOC_ZIP=protoc-3.8.0-linux-x86_64.zip
curl -OL https://github.com/google/protobuf/releases/download/v3.8.0/$PROTOC_ZIP
sudo unzip -o $PROTOC_ZIP -d /usr/local bin/protoc
sudo unzip -o $PROTOC_ZIP -d /usr/local include/*
rm -f $PROTOC_ZIP
第三步:編譯并執(zhí)行 Libra Cli 來(lái)連上 testnet
$ 。/scripts/cli/start_cli_testnet.sh
Building and running client in debug mode.
Updating crates.io index
Updating git repository `https://github.com/pingcap/rust-rocksdb.git`
Updating git repository `https://github.com/alexcrichton/bzip2-rs.git`
Updating git repository `https://github.com/busyjay/lz4-rs.git`
Updating git repository `https://github.com/busyjay/rust-snappy.git`
Updating git repository `https://github.com/gyscos/zstd-rs.git`
Compiling proc-macro2 v0.4.30
Compiling unicode-xid v0.1.0
Compiling syn v0.15.36
。..
。..
。..
Finished dev [unoptimized + debuginfo] target(s) in 。..s
Running `target/debug/client --host ac.testnet.libra.org --port 80 -s 。/scripts/cli/trusted_peers.config.toml`
Connected to validator at: ac.testnet.libra.org:80
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》 [gas_unit_price (default=0)] [max_gas_amount (default 10000)] Suffix ’b‘ is for blocking.
Transfer coins from account to another.
help | h
Prints this help
quit | q!
Exit this client
Please, input commands:
libra%
看到 libra% 出現(xiàn)就代表我們已經(jīng)大功告成連上 testnet 了!
連接testnet
其實(shí)跟編譯 libra cli 是同一個(gè) script ,除非原始碼有更動(dòng),他就不會(huì)浪費(fèi)時(shí)間在重復(fù)編譯上了。
$ 。/scripts/cli/start_cli_testnet.sh
Building and running client in debug mode.
。..
。..
。..
。..
Finished dev [unoptimized + debuginfo] target(s) in 。..s
Running `target/debug/client --host ac.testnet.libra.org --port 80 -s 。/scripts/cli/trusted_peers.config.toml`
Connected to validator at: ac.testnet.libra.org:80
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》 [gas_unit_price (default=0)] [max_gas_amount (default 10000)] Suffix ’b‘ is for blocking.
Transfer coins from account to another.
help | h
Prints this help
quit | q!
Exit this client
Please, input commands:
libra%
建立自己的Libra account
所有跟 account 相關(guān)的功能都在 account 下面,我們可以先下 account 這個(gè)指令來(lái)看看有哪些功能可以使用吧!
libra% account
usage: account 《arg》
Use the following args for this command:
create | c
Create an account. 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_path》
Save Libra wallet mnemonic recovery seed to disk
mint | mintb | m | mb 《receiver_account_ref_id》|《receiver_account_address》 《number_of_coins》
Mint coins to the account. Suffix ’b‘ is for blocking
它主要有五大功能:
· Create: 建立一個(gè)賬號(hào),每個(gè)賬號(hào)在 local 會(huì)給一個(gè) reference ID,舉例來(lái)說(shuō),第一個(gè)被建立的賬號(hào)就是 ID=0。
libra% account create
》》 Creating/retrieving next account from wallet
Created/retrieved account #0 address
fafbbc8aeed4b019ee8d1be854aa5279b26a07d5957b3a5a04e9aaa351bea2f0
# 可以看到我建立的第一個(gè)賬號(hào),他的 reference ID #0
# 以及我的 address 就是下面那一大串 hex string
# 如果是在同一個(gè) libra cli 操作,我們都可以使用 reference ID 作為賬號(hào)的
alias。如果是要請(qǐng)別人從他的 libra cli 發(fā) transaction 給你的賬號(hào),
那就需要直接給對(duì)方你的 address 了。
· List: 印出所有被建立或者被加載的賬號(hào)。
libra% account list
User account index: 0, address:
fafbbc8aeed4b019ee8d1be854aa5279b26a07d5957b3a5a04e9aaa351bea2f0,
sequence number: 0, status: Persisted
# 列出現(xiàn)有的賬號(hào)。Sequence number 則是代表了這個(gè) account
發(fā)起過(guò)幾個(gè) transaction。
· Recover: 從一個(gè)文件還原一個(gè)錢(qián)包賬號(hào)。像是 import wallet。
· Write: 將錢(qián)包賬號(hào)儲(chǔ)存到一個(gè)檔案。像是 export wallet。
· Mint: 請(qǐng)水龍頭 (Faucet) 發(fā)錢(qián)給一個(gè)指定的賬號(hào)。
# 請(qǐng)水龍頭發(fā)錢(qián)的指令是
# account mint 《account address/ref_id》 《number_of_coin》
# 以下示范發(fā) 320 顆 Libra Token 給第一個(gè)賬號(hào)。
libra% account mint 0 320
》》 Minting coins
Mint request submitted
· Hint: 跟 transaction 相關(guān)的操作(mint/transfer)都有提供 blocking 與 non-blocking 的版本。想要使用 blocking 的版本,比如說(shuō)要等水龍頭真的發(fā)錢(qián)給你,那我們可以使用下面這種語(yǔ)法:
libra% account mintb 1 1205
》》 Minting coins
[waiting
Transaction completed, found sequence number 9357
Finished minting!
他就會(huì)直接卡住并印出 waiting 直到這個(gè) Transaction 被完成為止。
查詢(xún)Libra account的余額
語(yǔ)法是 query balance 《account address/ref_id》
libra% query balance 0
Balance is: 320
發(fā)送Libra幣
轉(zhuǎn)賬的語(yǔ)法如下:
transfer 《sender address/ref_id》 《receiver address/ref_id》
《number_of_coins》 [gas_unit_price (default=0)]
[max_gas_amount (default 10000)]
tranfer 一共有五個(gè)參數(shù):
1. Sender Account 的 address 或 reference id
2. Receiver Account 的 address 或 reference id
3. 要發(fā)送多少數(shù)量的 libra
4. 這次 transaction 的 gas 手續(xù)費(fèi),預(yù)設(shè)是 0。這個(gè)參數(shù)可以不給。
5. 這次 transaction 的最高 gas 限制,預(yù)設(shè)是 10000。這個(gè)參數(shù)可以不給。
舉例而言,如果我想從Account #0 轉(zhuǎn) 100Libra 給Account #1,我可以這樣寫(xiě) transfer 0 1 100 。
查詢(xún)發(fā)送的transaction
查詢(xún)交易的指令為:
query txn_acc_seq 《account address/ref_id》 《sequence_number》
《fetch_events=true|false》
一共有三個(gè)參數(shù):
1. Account 的 address 或 reference ID。
2. Sequence Number: 在 Libra 的設(shè)計(jì)中,sequence number 代表了該 account 發(fā)起了幾個(gè)交易,每發(fā)起一次交易且被收進(jìn) Libra blockchain 中這個(gè)數(shù)字就會(huì) +1 。這個(gè)設(shè)計(jì)是為了避免 replay 攻擊,每個(gè)發(fā)送出去的transaction 帶有當(dāng)前 account 的 sequence number ,而發(fā)送出去的 transaction 會(huì)先被放入 mempool 中等待被執(zhí)行。當(dāng) Libra blockchain 從 mempool 中拿 transaction 出來(lái)執(zhí)行的時(shí)候會(huì)去比對(duì)當(dāng)前的 account sequence number 是否跟 transaction 的 sequence number 相同。若相同才能執(zhí)行,且馬上會(huì)把 account 的 sequence number +1 ,這樣即使在 mempool 中有多個(gè)重復(fù)的 transaction 也只會(huì)有一個(gè)合法的能被執(zhí)行,其他的將會(huì)被丟棄。
3. 是否需要抓取 events。
完整的情景案例
在發(fā)送 LibraCoin 之前,我們需要有兩個(gè)賬號(hào)來(lái)進(jìn)行轉(zhuǎn)賬。以下將示范從建立兩個(gè)賬號(hào)、各自從水龍頭領(lǐng)到 LibraCoin 以及轉(zhuǎn)賬的過(guò)程吧!
# 建立第一個(gè)賬號(hào) alice
libra% account create
》》 Creating/retrieving next account from wallet
Created/retrieved account #0 address
7faff73ba54fc82503ecd6438455e8a4ab0a26dc35d399e6593bb1058338e140
# 建立第二個(gè)賬號(hào) bob
libra% account create
》》 Creating/retrieving next account from wallet
Created/retrieved account #1 address
bf2df78de21ea3727e0d48ae7142718f8c33f7eca854ac81b8866361fa2bd15d
# 幫 alice 要 320 個(gè) libra
libra% account mint 0 320
》》 Minting coins
Mint request submitted
# 查詢(xún) alice 的 balance
libra% query balance 0
Balance is: 320
# 幫 bob 要 1205 個(gè) libra
libra% account mint 1 1205
》》 Minting coins
Mint request submitted
# 查詢(xún) bob 的 balance
libra% query balance 1
Balance is: 1205
# 從 alice 轉(zhuǎn) 20 個(gè) libra 給 bob
libra% transfer 0 1 20
》》 Transferring
Transaction submitted to validator
To query for transaction status, run: query txn_acc_seq 0 0
《fetch_events=true|false》
# 查詢(xún) transaction
libra% query txn_acc_seq 0 0 true
》》 Getting committed transaction by account and sequence number
Committed transaction: SignedTransaction {
raw_txn: RawTransaction {
sender:
7faff73ba54fc82503ecd6438455e8a4ab0a26dc35d399e6593bb1058338e140,
sequence_number: 0,
payload: {,
transaction: peer_to_peer_transaction,
args: [
{ADDRESS:
bf2df78de21ea3727e0d48ae7142718f8c33f7eca854ac81b8866361fa2bd15d},
{U64: 20000000},
]
},
max_gas_amount: 10000,
gas_unit_price: 0,
expiration_time: 1560912163s,
},
public_key:
a2b9f68d1abbc887a39789a7f428df68adabfff395fff71bd0d0fe5674bdfbad,
signature: Signature( R: CompressedEdwardsY:
[74, 249, 58, 185, 235, 16, 175, 193, 158, 86, 31, 249, 215, 97,
138, 153, 65, 183, 161, 229, 162, 198, 30, 107, 246, 191, 44, 250,
12, 96, 20, 55], s: Scalar{
bytes: [170, 99, 70, 224, 9, 167, 230, 162, 110, 38, 87, 53, 164,
36, 91, 34, 116, 52, 73, 91, 169, 141, 159, 194, 40, 206, 16, 151,
5, 101, 91, 1],
} ),
}
Events:
ContractEvent { access_path: AccessPath { address:
7faff73ba54fc82503ecd6438455e8a4ab0a26dc35d399e6593bb1058338e140,
type: Resource, hash:
“217da6c6b3e19f1825cfb2676daecce3bf3de03cf26647c78df00b371b25cc97”,
suffix: “/sent_events_count/” } , index: 0, event_data: AccountEvent {
account: bf2df78de21ea3727e0d48ae7142718f8c33f7eca854ac81b8866361fa2b
d15d, amount: 20000000 } }
ContractEvent { access_path: AccessPath { address:
bf2df78de21ea3727e0d48ae7142718f8c33f7eca854ac81b8866361fa2bd15d,
type: Resource, hash: “217da6c6b3e19f1825cfb2676daecce3bf3de03cf26647
c78df00b371b25cc97”, suffix: “/received_events_count/” } ,
index: 0, event_data: AccountEvent {
account: 7faff73ba54fc82503ecd6438455e8a4ab0a26dc35d399e6593bb1058338
e140, amount: 20000000 } }
常見(jiàn)錯(cuò)誤
Libra testnet 有擋一個(gè)區(qū)間內(nèi)的爆量 request,如果你在短時(shí)間內(nèi)送一堆 transaction (mint or transfer) 有機(jī)會(huì)拿到下面這個(gè) error:
[ERROR] Error minting coins: Failed to query remote faucet server
[status=429 Too Many Requests]: “《html》《body》《h1》429 Too Many Requests
《/h1》\nYou have sent too many requests in a given amount of time.\n
《/body》《/html》\n”
這時(shí)候只要稍等一下再重新送那筆 transaction 就能解除了。
評(píng)論
查看更多