Facebook謹製のLibra、テストネットでトランザクション生成までやってみた

2019年6月18日に公開されたばかりのFacabook謹製のブロックチェーンを利用したLibra。日本でも話題になっているので、テストネットでトランザクションの生成までやってみました。実際に動かしてみると色々なことが分かってきました。
#前提
- Libraのテストネットは、MacOSとLinuxで動きます。
- 今回はDockerでコンテナを立ち上げて試しました。

FLOCがブロックチェーンのスクールを運営していることもあり、再現性を高めるためにDockerを利用しました。（今回に関してはなくても全然大丈夫です。）

なお、筆者の環境は以下の通りです。

- Macbook Pro 2018 13-inch
- macOS Mojave 10.14.5
- Docker 18.09.2

#そもそもLibraって？
LibraはFacabookが作ったブロックチェーンで、イーサリアムのような汎用性とテザーをはじめとするステーブルコインの価値の安定性を持ちます。

既存のブロックチェーンが持つスケーラビリティ問題や価値の不安定さといった課題を解決すべく開発されています。

また、独自言語としてMoveも開発されており、スマートコントラクト開発に利用できるようになっています。

ホワイトペーパーも公開されているのでぜひこちらも合わせて御覧ください。より技術的に専門性の高いテクニカルペーパーも用意されています。
[＞＞＞Libraホワイトペーパー](https://libra.org/en-US/white-paper/?noredirect=en-US)
[＞＞＞Libraテクニカルペーパー](https://developers.libra.org/docs/assets/papers/the-libra-blockchain.pdf)

#Docker周りの準備
Dockerが入っていない場合は、インストールしておく必要があります。

何はともあれ、Dockerfileを用意します。

```Dockerfile:Dockerfile
FROM ubuntu:19.04
RUN apt-get update && apt-get -y upgrade && \
    apt-get install -y git curl sudo cmake golang protobuf-compiler vim
RUN git clone https://github.com/libra/libra.git
WORKDIR /libra
```

ここはお好みですが、起動するときに色々と入力するのが面倒くさいという方は以下のようにdocker-compose.ymlを作成しましょう。

```docker-compose.yml:docker-compose.yml
version: '3'
services:
 libra-test:
   image: libra
   build: .
   container_name: 'libra-test'
   tty: true
```


Dockerfileやdocker-compose.ymlは自分の使いやすいディレクトリに保存しておきましょう。そのディレクトリにターミナルで移動して、`docker-compose up -d`を実行します。

うまくコンテナが立ち上がったら、`docker exec -it libra-test /bin/bash`を打ち込んでコンテナに乗り込みます。

#実行環境の構築
コンテナに乗り込んで最初にすることは、`./scripts/dev_setup.sh`を実行することです。実行するとウェルカムLibraへ！と歓迎されたあとに、必要なパッケージをインストールしてもいいかを確認されるので`y`を入力してあとは流れに任せます。
<img width="627" alt="スクリーンショット 2019-07-05 12.55.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454589/e186c89e-99a3-a633-69ae-7bc6898a9cb2.png">
すべての依存パッケージをインストールするとCargoに関する処理を行います。CargoはRustのパッケージ管理＆ビルドツールですね。具体的には、`source /root/.cargo/env`と`cargo build`を順番に実行します。ここからは少し時間がかかるのでコーヒーでも飲みながら待ちましょう。

すべて実行できれば、`./scripts/cli/start_cli_testnet.sh`を実行します。これは、テストネットをスタートさせるためのコマンドです。

ここまで問題なくできれば、ようやくトランザクションの生成ができるようになります。
#テストネットでトランザクション生成
いよいよ本題、トランザクションの生成へと移りましょう！
##コマンドの確認
Libraのテストネットのコマンドはいくつか用意されています。

| コマンド     　　　　  | 意味                                    |
|:-----------------|:-----------------|
| account          |アカウント作成などアカウントにまつわる処理を行う|
| query            |色々なデータを取得する際に利用する|
| transfer         |送金処理を行う|
| submit           |ファイルからトランザクションの生データをロードしたり、ネットワークへ送ったりする処理を行う|
| help             |困ったときはhelpを叩くとヒントをくれる|
| quit             |修了するときの処理|

他にも、それぞれのコマンドにより細かいコマンドが用意されています。とはいえ、テストネットなのでそれほど機能も多くはないです。

##アカウントの作成
トランザクションの生成にあたり、アカウントを作成しなくてはいけません。`account create`で簡単に生成できます。今回は送金を試すため、2つ作成しましょう。インデックスが0と1のものの両方が作成できます。

```
libra% account create
>> Creating/retrieving next account from wallet
Created/retrieved account #0 address cdbe0a60fe35e48db3eb0f893107bec69dc8b40c4333b9c31a2532560fed79bc

libra% account create
>> Creating/retrieving next account from wallet
Created/retrieved account #1 address 0c3842afb40568954e77bb8f30d4f0f8790165cd3018b9a8c9b593491e50572e
```

`account list`で作成したアカウントの一覧を確認できます。

```
libra% account list
User account index: 0, address: cdbe0a60fe35e48db3eb0f893107bec69dc8b40c4333b9c31a2532560fed79bc, sequence number: 0, status: Local
User account index: 1, address: 0c3842afb40568954e77bb8f30d4f0f8790165cd3018b9a8c9b593491e50572e, sequence number: 0, status: Local
```

##アカウントへの入金
作成した2つのアカウントにそれぞれ100Libraと50Libraを入金しましょう。特定のインデックスのアカウントに入金する時は以下のように実行します。

`account mint {金額}`

今回であれば、`account mint 0 100`と`account mint 1 50`を実行します。

```
libra% account mint 0 100
>> Minting coins
Mint request submitted

libra% account mint 1 50
>> Minting coins
Mint request submitted
```


`quary balance {インデックス}`で残高が確認できるので、`quary balance 0`と`quary balance 1`をそれぞれ実行してみましょう。

```
libra% query balance 0
Balance is: 100.000000

libra% query balance 1
Balance is: 50.000000
```

##送金してみる
次にいよいよ送金です！送金はtransferコマンドを利用して以下のように記述します。

`transfer {送金元のインデックス} {送金先のインデックス} {金額}`

今回はAさんからBさんに20Libraを送金するとすると、以下のように実行します。

`transfer 0 1 20`

実行すると「Transaction submitted to validator」と表記されているので、Libraのホワイトペーパーにある通り、承認者によって承認するタイプのコンセンサスアルゴリズムを使っていることがここからも分かります。

```
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>
```

うまくいったか確認するため、`quary balance 0`と`quary balance 1`を実行してみましょう。

```
libra% query balance 0
Balance is: 80.000000

libra% query balance 1
Balance is: 70.000000
```

うまく行っているみたいですね！

##トランザクションデータの確認
トランザクションデータのより詳細を見るためには、以下のコマンドを実行します。

`query txn_acc_seq 0 0 true`

```
libra% query txn_acc_seq 0 0 true
>> Getting committed transaction by account and sequence number
Committed transaction: SignedTransaction { 
 raw_txn: RawTransaction { 
	sender: cdbe0a60fe35e48db3eb0f893107bec69dc8b40c4333b9c31a2532560fed79bc, 
	sequence_number: 0, 
	payload: {, 
		transaction: peer_to_peer_transaction, 
		args: [ 
			{ADDRESS: 0c3842afb40568954e77bb8f30d4f0f8790165cd3018b9a8c9b593491e50572e},
			{U64: 20000000}, 
		]
	}, 
	max_gas_amount: 10000, 
	gas_unit_price: 0, 
	expiration_time: 1562298424s, 
}, 
 public_key: 947127600327e626cc0dd2b52724387b15bf2508384d8dfc4d08ba3bd6aba39f, 
 signature: Signature( R: CompressedEdwardsY: [174, 224, 169, 0, 160, 42, 169, 128, 122, 211, 110, 36, 135, 2, 100, 132, 32, 50, 24, 138, 22, 252, 79, 6, 43, 42, 179, 128, 48, 240, 81, 114], s: Scalar{
	bytes: [24, 225, 182, 137, 147, 170, 79, 219, 198, 3, 213, 26, 116, 93, 211, 246, 20, 80, 152, 151, 77, 253, 204, 184, 61, 254, 46, 101, 192, 79, 15, 9],
} ), 
 }
Events: 
ContractEvent { access_path: AccessPath { address: cdbe0a60fe35e48db3eb0f893107bec69dc8b40c4333b9c31a2532560fed79bc, type: Resource, hash: "217da6c6b3e19f1825cfb2676daecce3bf3de03cf26647c78df00b371b25cc97", suffix: "/sent_events_count/" } , index: 0, event_data: AccountEvent { account: 0c3842afb40568954e77bb8f30d4f0f8790165cd3018b9a8c9b593491e50572e, amount: 20000000 } }
ContractEvent { access_path: AccessPath { address: 0c3842afb40568954e77bb8f30d4f0f8790165cd3018b9a8c9b593491e50572e, type: Resource, hash: "217da6c6b3e19f1825cfb2676daecce3bf3de03cf26647c78df00b371b25cc97", suffix: "/received_events_count/" } , index: 0, event_data: AccountEvent { account: cdbe0a60fe35e48db3eb0f893107bec69dc8b40c4333b9c31a2532560fed79bc, amount: 20000000 } }
```

SenderとADDREESSの部分にそれぞれ送金元アドレスである`cdbe0a60fe35e48db3eb0f893107bec69dc8b40c4333b9c31a2532560fed79bc`と送金先アドレスである`0c3842afb40568954e77bb8f30d4f0f8790165cd3018b9a8c9b593491e50572e`が入っていることが分かります。また、gasという単語がraw_txnの部分に見えますが、イーサリアムと同じくスマートコントラクトを実行するための仕掛けを感じさせます。

また、最後のEvents: と書かれた部分もスマートコントラクトのデザインになっています。上部が`suffix: "/sent_events_count/"`、下部が`suffix: "/received_events_count/"`となっており、それぞれ送金と受け取りのイベントとして処理されています。

#わかったこと
- ビットコインとイーサリアム、ステーブルコインをちゃんと研究して作っていることがひしひしと伝わる。

- トランザクションの承認が承認者によるものなので承認そのものは速いだろうが、発表によると今後パブリックチェーンに移行するらしい。どんな段階を踏むのかプロセスをもっと知りたい。

- 言語としてRustを使っており、Moveはこれに似ている独自言語。Rustは学習難易度が高い言語で有名ですが、、早めに手を出しておこうか、、

- 何より、短期間でこれだけのものをデザインして、実装まで持ってきたFacebookの技術力に脱帽です。。