現在地

ブロックチェーンEthereum入門 1



目的

本コラムでは、Ethereumとブロックチェーンの入門として、プライベートなテストネットワーク環境内でGUIツールを使いながら手軽にブロックチェーンという技術を体験する方法をご紹介したいと思う。

https://www.ethereum.org/

ブロックチェーンという技術についての詳細な解説や、ブロックチェーン上での仮想通貨取引を行うようなことは範囲外だ。Ethereumを動かしながらブロックチェーンについて段階的に分かっていただければと思うが、不明な点は必要に応じて他の情報をあたってほしい。

概要

Ethereumはブロックチェーンのプロトコルの一つだ。本コラムではEthereumの動作を確かめながら、Ethereumの機能とブロックチェーンそれ自体の技術の概略をつかんでいただければと思う。

この入門では、3回シリーズを予定している。
まず、初回では、EthereumのGUIブラウザEthereum-Walletを使い、ブロックチェーン上での取引にとりあえず触れてみる。
2回目では、改めてEthereumのプライベートなテストネットワークを作成し、その監視を行う。
Ethereumの メインネットワークの現在の状況を見てほしい。
http://stats.ethdev.com/
このような状況監視環境を構築する。
3回目に、Ethereumの特徴であるコントラクトと呼ばれるプログラムされた任意の計算を実行してみる。

本コラムでは、手軽さを基準にWindowsでの動作確認手順で進める。制約は64bit版が必要なことだ。Windows 7 Professional SP1 64bitでの動作を確認している。
ただし、手順を一部だけ読み替えていただければ、LinuxおよびOS Xの環境も同様である。

なお、現在(2016年3月)のところ、Ethereumの開発は活発に行われており、まだ機能や動作が安定していない。また、本コラムをお読みいただいたタイミングでは内容が古くなっている可能性があることをご了承いただきたい。

以下、ブロックチェーン技術について初めての方に対し、若干の前提知識の説明を試みる。そうでない方は、Ethereumブロックチェーンブラウザのインストールに進んでほしい。

ブロックチェーンについて

ブロックチェーンは分散台帳管理の技術であるといわれる。もともと「ビットコイン」という仮想通貨を取引する基盤として登場した。

分散というのは、ブロックチェーンがP2Pネットワークで構成されていることからだ。P2Pネットワークには任意のコンピューターノードが参加できる。中央の権威サーバーといったものは存在せず、すべてのノードは基本的に対等だ。

台帳というのは、ブロックチェーンに記録されるデータの性質からだ。ある期間内に発生した取引データ(トランザクション)が収集され、一つのブロック内に記録される。このようなブロックを時系列の鎖状につないだデータ構造がP2Pネットワーク内で共有され、延々とブロックの鎖を成長させ続けていく。取引の履歴が延々と記録されていく性質が台帳に例えられる。
ブロックチェーンの概念図を以下に示す。

もうひとつ知っておくべきは、仮想通貨の創造過程とマイニングだ。ブロックチェーンのルールでは、取引を収集してブロックを作ることに報酬を与えている。P2Pネットワークに参加していればどのノードでも報酬を得られる可能性はあるが、ブロック生成には膨大な計算量を必要とし、それを他のノードよりも素早く行う必要がある(実際には特別なハッシュ値を計算する)。このように報酬を得るのは容易でなく、したがって報酬に希少価値が出る。この報酬が仮想通貨であり、同時にブロックチェーンのネットワークに参加する動機ともなる。

このような報酬を得るためのブロック生成過程がマイニングだ。ブロックの計算結果を探り当てることが、例えば鉱脈から希少金属を掘り出すことに似ているからだ。マイニングを行っているノードはマイナーと呼ばれる。マイナーによりブロックが次々生み出され、ブロックの鎖が成長していく。

あとは、ブロックチェーンのデータがなぜ信頼できるかなのだが、これは公開鍵暗号技術とブロック生成に必要な膨大な計算量による。まずは簡単に、ブロックチェーンに対する不正行為やデータの書き換えを行うには、暗号を破るか、ブロックチェーンのネットワークに参加しているすべてのノードを上回るような計算パワーが必要となるからと考えてほしい。

以上、ブロックチェーンの技術的特徴は、通貨のような希少な価値と信頼の形成が、例えば国家といった中央権威なしに構築できてしまうことだ。これは既存の中央権威にとっては恐ろしく破壊的なはずだ。

また、P2Pネットワークという性格上、自分のコンピューターをどこかのP2Pネットワークに参加させたり、意図せずに参加させてしまったりするのではなく、プライベートなネットワーク環境でブロックチェーンを試すというのが本コラムだ。

前置きはここまで、早速ブロックチェーンを動かしてみたいと思う。

Ethereumブロックチェーンブラウザのインストール

Ethereumはブロックチェーン技術のプロトコルの一つだ。特徴としては、仮想通貨の取引に加え、プログラム可能な任意の計算を実行できることだ。
この初回では、Ethereum上の仮想通貨etherの取引を実行してみる。

まずは、以下のサイトからEthereum-Walletをダウンロードする。Walletという名前だが、Ethereumブロックチェーンの簡易ブラウザとして使える。
https://github.com/ethereum/mist/releases
ページを下にスクロールし、Downloadsからバイナリをダウンロードできる。
(以降では、本コラム作成時点の最新バージョンWallet 0.5.1 (Beta 9)のEthereum-Wallet-win64-0-5-1.zipを使用している)

zipファイルを任意の場所に展開する。展開されたディレクトリ配下は次のような構成になる。

Ethereum-Wallet-win64-0-5-1
│ Ethereum-Wallet.exe
├─locales
└─resources
    └─node
        ├─eth
        │      eth.exe
        └─geth
               geth.exe

ブラウザ本体はEthereum-Wallet.exeだ。

EthereumのP2Pノードの実行プログラムはgeth.exeで、Go言語のEthereum実装だ。もう一つの実行ファイルeth.exeも同様にEthereumノードの実行プログラムだが、C++の実装である。
つまり、Ethereum自体はプロトコルであり、Ethereumの実装は様々あるわけだ。

今回はこちらのgethを使用するが、Ethereumノードとしてだけの役割とするコンピューターには別途インストールすることになると思う。gethを別途インストールする場合、以下を参照してほしい。

https://github.com/ethereum/go-ethereum/wiki/Building-Ethereum#installation-instructions

ここで、いきなりEthereum-Wallet.exe起動してもよいのだが、ちょっと注意が必要だ。
今回使用するEthereum-Walletでは、メインのP2Pネットワークへの接続を行おうとするため、プライベートテストネットワーク内で動かしたいという趣旨に反してしまう。
そこで、手動によりEthereumノードを起動する。

Ethereumノードの起動

Ethereumノードをプライベートテストネットワーク内で起動する。

https://github.com/ethereum/mist#using-mist-with-a-privatenet

期待しないP2P通信を防止し、プライベートなテストネットワーク内だけで通信するにはnetworkidとport(P2Pノード間通信ポート)を独自に選ぶ。
networkidはできるだけユニークな数値とし、portはデフォルトの30303以外としておくのが安心と思う。

また、genesis.jsonというファイルを以下の内容で作成し、geth.exeと同じ場所に置いてほしい。
(ひとまずテスト効率化のためと考えていただき、詳細は次回)

genesis.json

{
    "nonce": "0x00006d6f7264656e",
    "difficulty": "0x200",
    "mixhash": "0x00000000000000000000000000000000000000647572616c65787365646c6578",
    "coinbase": "0x0000000000000000000000000000000000000000",
    "timestamp": "0x00",
    "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
    "extraData": "0x",
    "gasLimit": "0x2FEFD8",
    "alloc": {
    }
}

コマンドプロンプトを開き、ノードを起動する。
以下の起動テンプレートに、独自に決めたnetworkidとportを埋め込んでほしい。

geth --networkid <ネットワークID> --port <ポート番号> --maxpeers 0 --nodiscover --genesis genesis.json console 2>> node.log

例えば次のように起動する(確認時点ではnetworkidに符号なし32bit値を使用できた。例では起動時点のエポック秒を使っている)

geth --networkid 1457239471 --port 50303 --maxpeers 0 --nodiscover --genesis genesis.json console 2>> node.log

gethコンソールが立ち上がる。なお、コンソールを閉じるにはCtrl+Dキーを押すか、exitを入力する。

datadir とcoinbaseの表示が見える。

datadirは、ブロックチェーンのデータが格納されるディレクトリだ。
起動テンプレート通りなら以下のようなはずだ。

C:\Users\<ユーザー名>\ AppData\Roaming\Ethereum
├─chaindata
└─dapp

coinbaseは、今起動したEthereumノードでマイニングを行う特別なアカウントだ。まだアカウントが存在しないのでnullになっている。ここではcoinbaseという特別なアカウントがあることを覚えておく。
そもそも、何らかの取引を行うにはアカウントが必要だ。アカウントはこの後すぐ作成する。

Ethereum-Walletの起動

ここでEthereum-Walletを起動する。
実行ファイルは、Ethereum-Walletを展開したディレクトリ直下にある。

Ethereum-Wallet-win64-0-5-1
└─Ethereum-Wallet.exe

スプラッシュ画面でSKIP PEER SERCHが出たら、それをクリックする。

Ethereum-Walletが立ち上がる。
WALLETS、SEND、CONTRACTSの3つの画面がある。慣れないうち画面内で迷ったら、ともかくWALLETSをクリックすれば、起動時の最初の画面に戻ることができる。

まずはアカウントを作成する。
ADD ACCOUNTをクリックし、パスワードを2回入力する。このパスワードは絶対に忘れてはならない。

ETHERBASEアカウントができる。このアカウントが、先ほどコンソールで見たcoinbaseとなる。デフォルトでは、最初に作成されたアカウントはcoinbaseアカウントになる。
アカウントは20バイトのアドレス値により識別される。
画面例では0xcdcbc2dfdd8f6d63cf94ff7fa3ad508a4258912dだ。

実際にはアカウントの種類はもう一つあり、コントラクト(contract)と呼ばれる(契約アカウントと日本語訳しているドキュメントもある)。CONTRACTS画面で操作できる。
コントラクトはプログラムされた計算オブジェクトだ。コントラクトで任意の計算を実行できることがEthereumの特徴であり、3回目の記事で紹介する予定だ。

なお、Ethereumで扱う仮想通貨の通貨単位はether、最小単位はweiで1etherは10の18乗weiとなっている。通貨記号はΞ (ギリシャ文字のクサイ、クシー)である。
http://forum.ethereum.org/discussion/1007/the-symbol-for-ether-is
例えば、通貨単位の円と銭、通貨記号¥の関係を思い浮かべるとよいかもしれない。

etherが0.00の状態ではアカウント作成を除いて何もできないので、マイニングを開始する。マイニングの報酬はcoinbaseのアカウントが受け取ることになる。いまは単一ノードなので、このcoinbaseアカウントがetherを独り占めだ。

マイニング開始

コンソールでminer.start(2)と入力する。
なお、ここで指定した数字2はマイニング処理スレッド数であり、もしもマイニングが数十分以内に始まらなければ、より大きな値で試してほしい。CPUコア数と同じ値程度までは指定しても大丈夫だと思うが、CPU時間を使い切ってしまうかもしれないので注意。

開始されればtrueが返る。
なお、マイニングの停止にはminer.stop(2)とする。数字はstartで指定した値と同じにする。

実際にマイニングが開始されるまで数十分程度かかる。その間に少しだけEthereum詳細を見てみる。

外部アカウント:EOA (externally owned accounts)

先ほどコンソールで見たdatadirを開く。以下のようになっているはずだ。

C:\USERS\<ユーザー名>\APPDATA\ROAMING\ETHEREUM
│  nodekey
├─chaindata
├─dapp
└─keystore
        UTC--2016-02-21T05-35-11.825672000Z--566b1ed95097b5d6b362e7294e93d0b068d5f580

keystore下にファイルができている。これが先ほど作成したアカウントの実体で、中身は暗号化された秘密鍵だ。正式名称は、外部アカウント:EOA (externally owned accounts) である。
なお、ファイル名は作成日時とアカウントの識別アドレス(20バイトの値)になる。

ブロックチェーンでは公開鍵暗号技術が使用され、鍵による署名によって当該アカウントが持つ仮想通貨(Ethereumではether)へのアクセスが制限される。
アクセスには、このファイルが示すアカウントのアドレスと秘密鍵が使われるのだ。ファイルが失われたり、パスワードを忘れてしまい秘密鍵が使えなくなったりすると、当該アカウントのetherにアクセスする手段はなくなる。パスワードを忘れてはいけない理由はこれだ。また、万一、アカウントのアドレスと秘密鍵が漏れた場合、一切の防備はなくなるのでetherは簡単に盗まれてしまう。

以上から、本格的にEthereumを使うなら、このファイルとパスワードの扱いは要注意だ。ファイルのバックアップ対策も必要だろう。なお、このファイルは他のノードに移動したり、Ethereumノード破損による復元時に再配置したりすることが可能だ。ディレクトリ構成はどのノードでも同じなので、keystoreにファイルを配置すればよい。

ログファイルの確認

gethのログは、起動時のコマンドラインで標準エラー出力のリダイレクトによりファイル出力できる。
(先ほどの起動テンプレートを再掲すると、”2>> node.log”としていた)

geth --networkid <ネットワークID> --port <ポート番号> --maxpeers 0 --nodiscover --genesis genesis.json console 2>> node.log

この起動テンプレート通りなら、geth.exeと同じディレクトリにnode.logファイルが作られたはずだ。

C:\ETHEREUM-WALLET-WIN64-0-4-0
│  Ethereum-Wallet.exe
├─locales
└─resources
    └─node
        ├─eth
        └─geth
                geth.exe
                node.log

ログファイル開くと「Generating DAG: ?%」という行がある。

DAGという1GBの巨大なファイルを作成しているログで、これが100%になるまでしばらくかかる。これは、ブロックチェーンのハッシュ計算のために使用されるデータファイルだ。マイニング開始までの待ち時間(数十分程度)の理由の一つは、このファイルの作成時間だ。
ファイルが作成される場所は以下になる。
例えば以下では、full-R23-0000000000000000がDAGファイルだ。

C:\USERS\<ユーザー名>\APPDATA\ETHASH
    full-R23-0000000000000000

アカウント間でether送金取引を行う

マイニングが始まると、ブロック数が増えていくに伴いMain Accountが保持するetherも増えていく。
なお、バージョン0.5.1ではWalletにて作成したアカウント表示がちらついてしまう現象が出るが、この場合、一度ウィンドウを閉じて再起動すると直る。

基本的な操作であるアカウント間でのether送金取引(トランザクション)を実行してみる。
WALLETSとSENDの2画面を使っていく。(以下の画面例ではWALLETSにいる) Main Account作成と同様に、送金先となるアカウントを2件追加してほしい。

まず、Main AccountからAccount 2への送金を行う。
WALLETS画面でAccount2をクリックする。

以下のようにAccount2についての情報が表示される。Copy Addressを押したあと、WALLETS画面に戻る。

SENDをクリックする。
etherの送信元と送信先のアカウントアドレスを入力する。FROMはリストからMain Accountを選択、TOは先ほどコピーしたアドレスを貼り付け(Ctrl+P)する。
AMOUNTに送金額を入力する。(画面例では100etherとしている)

最初なので、詳細を気にせず進む。画面を下にスクロールしてSENDボタンを押す。
次に、トランザクション実行確認画面が出るので、確認として送信元であるMain Accountパスワードを入力後、SEND TRANSACTIONボタンを押す。

トランザクションが実行されるには、マイニングにより新しいブロックが作られて、そのブロック内にトランザクションが記録されなければならない。
新しいブロックが作られれば、アカウント間でetherが転送されたはずだ。

トランザクション手数料

今度はAccount2からAccount3への送金トランザクションを行う。
上記と同様の手順で、Account3のアドレスをコピーしたあと、SENDをクリックする。
(なお、アカウントのアドレスはテキストエディタなどに貼り付けておくと便利。アカウント画面を開く手間を省略できる)
etherの送信元と送信先のアカウントアドレスを入力する。FROMはリストからAccount2を選択、TOは先ほどコピーしたアドレスを貼り付け(Ctrl+P)する。
AMOUNTに送金額を入力する。(画面例では30etherとしている)

今回は若干詳細を見ながら進めていく。
トランザクション実行には、実際には手数料としてetherの支払いが必要だ。よって、etherを保持していないアカウントでは、そのアカウントが送信元となる取引はできない。

下にスクロールしていくと表示される値が、手数料をいくらにするかだ。

ここではデフォルトのまま進めていく。手数料として0.00042etherは払ってもよいとしている。
SENDボタンを押す。
次のトランザクション実行確認画面で表示されているのが、手数料の見積もり(Estimated fee consumption)と最大手数料(Provided maximum fee)だ。最大手数料を超えるetherを取られることはないので、トランザクション送信元アカウントが、手数料で破産してしまうことはない。

なお、より正確には手数料の単位はgasだ。
トランザクション実行に対して何gasまで使うつもりか(Provided maximum fee)を指定し、Gas priceという比率でetherへの換算が行われる。

ここまで確認したら、Account2のパスワードを入力してSEND TRANSACTIONボタンを押す。

送金結果を確認すると、手数料が引かれている。
以下の画面内容では、手数料として見積もり通りの0.00042etherが引かれた。
なお、手数料はマイニングを実行したアカウントの取り分となる。今回はMain Accountのetherに加算されている(マイニングしていると分かりづらいが)。

トランザクションの詳細確認

送金トランザクションが本当にブロックに記録されているか確認してみる。
WALLETS画面で最下部までスクロールすると、ここまで実行したトランザクションのリストが現れる。

たった今実行したAccount2からAccount3への送金トランザクショが見えるはずだ。クリックすると詳細画面が出る。
画面例では、当該トランザクションはブロック211に登録され、36ブロックの承認を経た(このトランザクションを含むブロック以降に36ブロックが作られた)ことなどが確認できる。
表示を消すには欄外の部分(半透明の部分)をクリックする。

なお、トランザクションは、アカウントの画面からも同様に確認できる。こちらは、当該アカウントが絡んでいるトランザクションのリストだ。

最後に

今回はEthereumを起動し、基本取引であるetherの送金までを行った。Ethereumの基本的な操作と、分散台帳管理と呼ばれるブロックチェーン技術のイメージをつかむ手助けとなっていれば幸いだ。
次回は、改めてEthereumのテストネットワークを作成し、その監視を行う。