こんにちは、Gincoの永田(@nagatkaz116)です。

皆さんはPoS(Proof-of-Stake)のコンセンサスアルゴリズムを持つTezosという仮想通貨をご存知でしょうか? 現在(2018年12月執筆時点)303億円ほどの時価総額を有するTezosは従来のブロックチェーンの弱点を克服する通貨として注目されています。 今回はそんなTezosについて調べてみましたのでここで紹介したいと思います。 また、Alphanetというテストネットノードの立て方も合わせて紹介したいと思います。

Tezosについて

公式のWebサイト[1]には、メタコンセンサス機能を持つコンセンサスプラットフォームであり、自己修正機能を持つ分散型台帳との説明がなされています。 なにやら、難しい言葉で書かれていますが、簡単に説明すると、プロトコルそのものの修正がハードフォークなしで可能な分散型台帳です。 開発者はスマートコントラクトを記述することによりDAppsを展開することが可能です。

現在稼働中のネットワーク

現在、Mainnet、Alphanet、Zeronetの3つのネットワークが稼働してます。

  • Mainnet
    • 本番環境のネットワークであり、実際のtezトークンを用いて取引が行われています。
    • 2018年6月30日に始動。
  • Alphanet
    • テストネットでmainnetとほぼ同じプログラムが動いています(ただし、ブロック生成間隔など定数はメインネットと異なる部分があります)。
    • faucetから取得したテスト用のトークンを用いて取引が行われています。
    • ほとんどリスタートされることはありません。
  • Zeronet
    • Tezos開発者用のテストネットであり、様々な定数やプロトコルがMiannetやAlphanetと異なります。
    • 通知なしで頻繁にリスタートされます。

Tezosをいじってみるのであれば、Alphanetを最初に試してみることをお勧めします。

Proof-of-Stakeによるコンセンサス

ベーキング

Tezosではブロック生成のことをベーキングと呼びます。 Proof-of-Stakeのコンセンサスアルゴリズムを用いており、ステークしているトークン(代表者が保有するトークンと委任されたトークンの合計)とベーカーに選ばれる確率は比例します。

エンドースメント

Tezosではブロック検証のことをエンドーシングと呼びます。 各ブロックにはENDORSERS_PER_BLOCK=32のエンドーサーがいて、ベーカーと同様に報酬をもらうことができます。 エンドーサーは最新のブロック(例えばn番目のブロックとします)の検証を行い、エンドースメントオペレーションを発行します。 このエンドースメントオペレーションはn+1番目のブロックに取り込まれますが、一度n+1のブロックが生成されると、それ以降n番目のブロックに対するエンドースメントは無効となります。 エンドースメント報酬は2/BLOCK_PRIORITY XTZと定められており、BLOCK_PRIORITY=1の時、2 XTZを報酬として手にすることができます。

委任(Delegation)

Bitsharesなどで採用されているいわゆるDPoS(Delegated PoS)とは異なりますが、Tezosにも委任の概念が存在し、Tezosトークンを保有しているけれども自分でブロック生成に参加したくない人が代表者(Delegates)にトークンをステークすることで得られる権利等を委任することができます。 代表者はいつでも変更することができますが、変更が反映されるのには一定の時間がかかります。 アクティブとパッシブという概念が存在し、アクティブな代表者はベーキング(ブロック生成)やエンドースメント(ブロック検証)に参加することが可能です。しかし、過去の一定期間内でベーキングもしくはエンドースメントに失敗するとパッシブになってしまい、しばらくベーキングにもエンドースメントにも参加することができません。

ロール

理論上は全てのトークンが誰にステークされているのかを追跡することは可能ですが、その粒度で追跡するのは大変なのでTezosではロールという概念が導入されました。 1つのロールにはTOKENS_PER_ROLL=10,000トークンが含まれ、ある代表者のステークするロール数はTOKENS_PER_ROLLでトークン数を割って切り捨てた数と定められています。 なので、ブロック生成をしたければ最低でもTOKENS_PER_ROLL=10,000トークンをステークスする必要があります。 ロールのスナップショットが取られる頻度はBLOCKS_PER_ROLL_SNAPSHOTという定数で設定されており、現在は256ブロックごとにスナップショットが取られることになっています。 現在のサイクルをnとすると、サイクルn-PRESERVRED_CYCLES-2に取られたロールスナップショットを元にベーカーやエンドーサーを選出することになっています。

サイクル

BLOCKS_PER_CYCLE=4,096ブロックのまとまりをサイクルと呼びます。ブロック生成の間隔は最低でもTIME_BETWEEN_BLOCKS=1分と設定されているので、1サイクルは最低でも2日20時間16分かかる計算になります。

デポジット(Security Deposit)

代表者がベーキングやエンドースメントを行うにはシステムの安全性を担保するためのデポジットを預ける必要があります。 ベーキングには1ブロックあたり512 XTZ、エンドースメントには64 XTZかかります。 ベーキングやエンドースメントをする際には自動的にトークンがデポジット用アカウントに移され、PRESERVED_CYCLES=5サイクルの間凍結されますが、その後自動的に代表者のアカウントに戻されます。 デポジットの凍結期間を考慮すると、代表者が保有するトークンの目安を計算することができます。

  • BLOCK_SECURIY_DEPOSIT=512
  • ENDORSEMENT_SECURITY_DEPOSIT=64
  • ENDORSERS_PER_BLOCK=32
  • PRESERVED_CYCLES=5
  • BLOCKS_PER_CYCLE=4096
  • TOTAL_TOKEN_AMOUNT=763e6

とすると、

((512 + 64 * 32) *(5 + 1) * 4096) / 763e6 = 8.25%

と計算することができます。

適合性

Tezosではブロックチェーンの質を測るための指標として適合性(Fitness)が導入されています。 これは、ビットコインでいうところのブロックチェーンの長さに相当する概念ですが、Tezosではブロックチェーンの長さにエンドースメントの数を加えたものを指します。 例えば、n番目のブロックの適合性をfとした場合、n+1番目のブロックにnに関するエンドースメントオペレーションがe個含まれているとすると、n+1番目のブロックの適合性はf+1+eとなります。

インフレーション

ベーキングとエンドーシングにより報酬として新規のトークンが発行されるので、毎年トークンの総量が増えていくことになります。 これを仮想通貨の業界ではインフレーションと呼びます。 インフレーションというと真っ先にみなさんが思い浮かべるのはプライスインフレーション、つまりは物価レベルの上昇だと思いますが、このインフレーションの語源はマネタリーサプライの上昇を意味するマネタリーインフレーションなのです。 仮想通貨のインフレーションという呼び方に違和感を感じる人は結構多いと思いますが、実はインフレーションという単語の語源に近い用法なんですね。 Tezosでは以下のようにインフレ率を計算することができます。

  • ENDORSERS_PER_BLOCK=32
  • ENDORSEMENT_REWARD=2
  • BLOCK_REWARD=16
  • TIME_BETWEEN_BLOCKS=1 分
  • TOTAL_TOKEN_AMOUNT=763e6

とすると、

(32 * 2 + 16) * (365 * 24 * 60) / 1 / 763e6 = 5.51%

つまり、自分がステークするトークンの5.51%が年間で手に入る報酬の目安ということになります。

結局ベーカーになるには何が必要か?

長々とTezosについてお話してきましたが、おそらくみなさんが一番知りたいのはこれでしょう。簡単にまとめると以下の二つが必要です。

  • ステークしているトークンが10,000以上であること
  • ブロック生成やエンドースメントのデポジットに必要な額のトークンを保有していること

まず一つ目についてですが、先述の通りロールというトークンのまとまりがベーカーに選出される権利として機能するので、最低でも1ロール分のトークンは保有する必要があります。 二つ目についてですが、第三者からトークンを委任してもらうのであれば、代表者が保有するトークン以上の額をステークすることになります。 しかし、デポジットを預ける必要があるので、ステーク量の8.25%を代表者が保有する必要があります。

Tezosのテストネットを立てる

ここからは実際にTezosのテストネットノードを立ててみましょう。 Alphanetというテストネットでノードを立てる方法を説明します。 Dockerを使ってノードを立てる方法とソースコードからビルドする方法がありますので、両方説明したいと思います。

Dockerを使ってノードを立てる

こちらはDockerを使って簡単にノードを立てる方法です。最初はこちらの方法がおすすめです。

事前準備

公式Webサイトを参照してDockerとDocker Composeをインストールしてください。

STEP1

まずは公式リポジトリからalphanet.shというスクリプトファイルをダウンロードして、実行可能ファイルにします。 基本的にはこのスクリプトにコマンドオプションを渡して操作を行います。

wget https://gitlab.com/tezos/tezos/raw/master/scripts/alphanet.sh
chmod +x alphanet.sh

STEP2

次に、以下のコマンドを実行することでコンテナを起動します。

sudo ./alphanet.sh start

以下の4つのコンテナが起動するはずです。

  • node
  • baker
  • endorser
  • accuser

nodeコンテナが起動すると、自動的にブートストラップ(データの同期)が始まります。以下のコマンドでブートストラップの進捗状況を確認することができます。

sudo ./alphanet.sh client bootstrapped

ブートストラップが終了するまで気長に待ちましょう。最終的にbootstrappedという文字列が表示されたらブートストラップ完了です。 ちなみに、ノードに対してtezos-clientというプログラムから操作をするのですが、本来その際に用いるRPCアドレスはノードを立てる時に指定します。 また、ノードを立てる際には、アイデンティティを生成する必要があります。 実は、コンテナを起動した時に自動的にRPCアドレスとアイデンティティの設定は済んでおり、自分で設定する必要はありません。

ソースコードからビルドする方法

自分でソースコードからビルドしてノードを立てる方法を紹介します。 Dockerを使った方法よりもやや難易度は高いですが、様々な設定ができて便利です。

STEP1

まずは、以下のコマンドで依存パッケージをインストールします。

sudo apt install -y rsync git m4 build-essential patch unzip bubblewrap wget

ここで、人によっては自分のディストリビューションでbubblewrapパッケージが存在しないかもしれませんが、結論をいうと無くても大丈夫です。

STEP2

TezosはOCamlで書かれているので、OCamlをインストールする必要があります。 OCamlにはOPAMというパッケージマネージャが存在し、OPAMをインストールすることでOCamlは自動的にインストールされます。

wget https://github.com/ocaml/opam/releases/download/2.0.1/opam-2.0.1-x86_64-linux
sudo cp opam-2.0.1-x86_64-linux /usr/local/bin/opam
sudo chmod a+x /usr/local/bin/opam

STEP3

Tezosのレポジトリをローカルにクローンし、alphanetブランチに切り替えます。

git clone https://gitlab.com/tezos/tezos.git
cd tezos
git checkout alphanet

STEP4

OPAMを初期化します。

opam init --bare

ここで、STEP1でbubblewrapのインストールをスキップした人は–disable-sandboxオプションを付けるのを忘れないでください。

opam init --bare --disable-sandbox

STEP5

OPAMでTezosの依存パッケージをインストールします。

make build-deps

STEP6

コンパイルします。

eval $(opam env)
make

STEP7

ノードを起動する前に準備が必要です。 アイデンティティという各ノードを識別さるためのIDを生成します。 これは、tzscanのPeerコラムにあるidから始まる文字列のことです。

tezos identity

identity

以下のコマンドでアイデンティティの生成をします。

./tezos-node identity generate

STEP8

各種設定を行います。 まずはconfig.jsonというファイルを作成します。

./tezos-node config init

config.jsonに設定を加えていきます。 筆者は次のような設定を行いました。

./tezos-node config update --rpc-addr=127.0.0.1
./tezos-node config update --peer=<IPAddr:Port>

Dockerを使った方法でも説明しましたが、ノードを操作するにはtezos-clientがノードにアクセスできる必要があります。 また、ブートストラップの際にToo few connectionsという警告がでる場合は、参照するノードを指定してあげると良いです。 tzscanでIPアドレスは確認できます。

STEP9

ノードの起動を行います。

./.tezos-node run

STEP10

ベーカーデーモンを起動します。 ベーカーデーモンはmempoolからトランザクションを集め、ベーキングを行います。 後ほど説明しますが、ベーカーのアカウントになれるのはtz1から始まるimplicit accountのみです。 それぞれのアカウントにはアライアスが設定でき、基本的にはこのアライアスを用いてアカウントに対する操作を行います。

./tezos-baker-alpha run with local node ~/.tezos-node <account alias>

STEP11

エンドーサーデーモンを起動します。 エンドーサーデーモンはブロックの検証を行い、エンドースメントオペレーションを発行します。 特定のアカウントに対してエンドースメントを行うことも可能ですし、アカウントを省略すれば全てのアカウントに対してエンドースメントを行うことができます。

./tezos-endorser-alpha run

STEP12

アキューザーデーモンを起動します。 アキューザーは同レベルで二つのブロックに対してサインをしているベーカーや同じベーキングスロットに対して二つ以上のエンドースメントオペレーションを発行しようとしているエンドーサーを見つけ出し、糾弾する役割があります。 糾弾されると、そのベーカーもしくはエンドーサーはデポジットを失います。

./tezos-accuser-alpha run

以上で、ソースコードからビルドする場合の手順は終了です。

Tezosを使ってみる

さて、ノードを立て終わったので実際に使ってみましょう。 ここではtezos-clientの使い方を説明したいと思います。 Dockerを使っている場合のコマンドも合わせて掲載しているので参考にしていただければと思います。

鍵を生成する

鍵の生成は次のコマンドで行います。

./tezos-client gen keys <account alias>

# Dockerを使っている場合は以下のコマンド
./alphanet.sh client gen keys <account alias>

faucetからトークンを取得する

faucetからtz1から始まる名前のjsonファイルを取得します。 以下のコマンドでアクティベートします。

./tezos-client activate account <account alias> with "tz1__xxx__.json"

# Dockerを使っている場合は以下のコマンド
./alphanet.sh client activate account <account alias> with "container:tz1__xxx__.json"

残高を確認する

次のコマンドでアカウント残高を確認することができます。

./tezos-client get balance for <account alias>

# Dockerを使っている場合は以下のコマンド
./alphanet.sh client get balance for <account alias>

送金する

次のコマンドで送金します。

./tezos-client transfer <amount> from <from account> to <to account> --fee <fee>

# Dockerを使っている場合は以下のコマンド
./alphanet.sh client transfer <amount> from <from account> to <to account> --fee <fee>

トークンを委任する

アカウントにはimplicit accountとoriginated accountの2種類存在します。 mplicit accountを用いてトークンを委任することはできないため、委任用のoriginated accountを作成する必要があります。

./tezos-client originate account <account_del> for <account alias> \
                                  transferring <amount> from <account alias> \
                                  --delegate <delegate account>

# Dockerを使っている場合は以下のコマンド
./alphanet.sh client originate account <account_del> for <account alias> \
                                  transferring <amount> from <account alias> \
                                  --delegate <delegate account>

ここで、<delegate account>は代表者のアカウントであり、implicit account(tz1から始まる)です。

ベーカーとして登録する

あるimplicit accountがベーカーになるためには、次のコマンドで登録が必要です。

./tezos-client register key <account alias> as delegate

# Dockerを使っている場合は以下のコマンド
./alphanet.sh client register key <account alias> as delegate

ベーカーとして登録されると、tzscanで現在ステークしているロール数や自分に委任している人の一覧等を確認することができます。

baker_account

an example of baker account

まとめ

今回はTezosについて用語ごとに解説していきました。 また、Alphanetというテストネットのノードを実際に立てるやり方も説明しました。 Tezosのブロック生成がどのように行われ、報酬を得るにはどうすれば良いか、イメージを掴んで頂ければと思います。

Tip us!

エンジニアチームのブログを書くモチベーションが上がります 💪

address

0xd6d478dCe4585a394834690158cf83581223C08f

参考文献