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



目的

本コラムはブロックチェーンEthereum入門の最終回として2回に分けて、Ethereum上でのブログラム実行環境であるコントラクト(Contract)を紹介する。
なお、本コラムの内容はブロックチェーンEthereum入門2の内容(ネットワークの監視)と無関係に扱っていただけるが、入門1の内容は前提とさせていただきたいと思う。

入門コラムとしての性格上、コントラクトコード開発には踏み込まない(よって、本コラムをお読みいただく上でプログラミングの知識は必須でない)。サンプルコードをそのまま実行してみることで、コントラクトでどのようなことが実現できるのかを体験する。

本コラムでの実行環境はWindows 10Pro 64bit版となるが、他のWindows(要64bit)、Linux、OS Xでも同様に試していただける。

また、本コラムは以下の記事を参考にしている。

まず始めにコントラクトについて若干の説明を行う。既にご存知の方は準備の章に進んでほしい。

コントラクトについて

コントラクトはEthereum上でのプログラムモジュール的な単位にあたる。専用言語を用いてプログラミング、コンパイルし、ブロックチェーンにデプロイすることで、ブロックチェーンを基盤とした任意のロジックを実行するシステムを実現できる。

コントラクトにより、ブロックチェーンは既存のトランザクションシステム基盤の代替選択肢となり得る可能性がある。
例えば、24時間無停止の可用性を求めるようなトランザクションシステムでは、現状、一般的に冗長構成のサーバーやデータベースなどに大規模な投資を必要とする。対して、ブロックチェーンでは、P2Pネットワークにノードを参加させていくことで可用性が確保できる。ブロックチェーンのデータは改竄が困難であり、過去に発生したすべてのトランザクションデータが安全に蓄積されていく。
さらに、特定のビジネスロジックを持つシステムであっても、コントラクトのようなプログラムモジュールによりブロックチェーン上で任意のロジックが実行可能なら、既存システムと同等の機能レベルを実現できるかもしれない。(コントラクトに加え、フロントエンドとなるアプリも別途開発する必要があるだろうが)
このような点が、ブロックチェーンが既存技術に取って代わる破壊的革新技術かもしれないとして注目される理由の一つなのかもしれない。

Ethereum はEVM(Ethereum Virtual Machine)と呼ばれるプログラム実行環境を持っている。EVMが実行できるのは専用のバイトコードだ。
Ethereum ブロックチェーン上でのコントラクトの実体はこのバイトコードであるが、開発にあたっては別途プログラミング言語とバイトコードへのコンパイラを使用して行うことになる。
例えばこの関係は、JavaエコシステムでのJVMとJava,Clojure,Scala,…といった言語と同じ関係であると考えればよいかもしれない。

ただし、本コラム作成時点(2016年5月)でのプログラミング言語の選択肢は、Solidityと呼ばれる言語一択と考えてよいと思う。
Solidity言語はJavaScript類似の構文を持つ。詳細は以下を参照してほしい。

コントラクトの構成イメージを以下に示す。

コントラクトの構成イメージ

準備

本コラムでは、Ethereum Walletバージョン0.7.2を使用している。
※2016年5月現在、Ethereumは開発が勢いよく進んでおり、バージョンによって一部の既存機能の動作が不安定になってしまう場合があるようだ。最新バージョンを使用する場合は、注意が必要かもしれない。

ブロックチェーンEthereum入門1または2で使用しているEthereum Walletバージョン0.5.1でも、本コラムの例を試すうえでの機能不足はないので、そのまま使用いただける(画面レイアウトは同一、表示文言の一部で英語/日本語の違い)。従って、Ethereum Walletのインストールを飛ばしていただき、Ethereum ノード(geth)の起動に進んでいただいても構わない。
そうでない方は、Ethereum Walletのインストールからお願いしたい。

# Ethereum Wallet (Mist browser)のインストール

以下のサイトからEthereum Walletのzipファイルをダウンロードし、任意の場所に展開する。

Ethereumノードは同梱されているgeth.exeを使用する。

展開後のディレクトリイメージ

Ethereum-Wallet-win64-0-7-2
│  Ethereum-Wallet.exe
├─locales
└─resources
    └─node
        └─geth
              geth.exe

# Ethereum ノード(geth)の起動

入門1または入門2と同様のコマンドラインでgeth.exeを起動する。JSON-RPCは不要だが、マイニングは開始しておく。
起動テンプレート例は以下の通り。

geth --networkid <ネットワークID> --port <ポート番号> --maxpeers <ピアノードの数> --nodiscover --mine --minerthreads 2 console 2>> node.log

入門1または入門2での環境を継続使用してもよいし、ブロックチェーンをリセットしてもよい。
その他、起動方法については以下のあたりを参考にしてほしい。

参考:Ethereumノード(geth)のバージョンについて

本コラムでのgethバージョンは1.3.6だが、バージョン1.4.4からは、genesis.jsonの指定の仕方と、マイニング停止方法が若干変わったようなので、適宜操作を変更する。
なお、バージョンはコマンドラインで”geth version”とするなどして確認できる。

genesis.jsonの指定

gethの--genesisオプションでなく、geth initを使う。ただし、1.4.4では--genesisオプションもまだ使えるようだ。

マイニング停止

miner.stopにおいて引数なしで停止できる。以前のバージョンでも引数はオプションだったが、不要になった模様。

# アカウント作成

複数のアカウントを作っておく。以降では、4つのアカウントを使用していく。

それでは、いよいよコントラクトを扱っていきたいと思う。

トークンコントラクトを試す

トークンはEthereum上で仮想通貨etherと同様な取り扱いができる独自の電子資産であり、コントラクトとしてプログラミングされたシステムである。アカウントによる所有、およびアカウント間での転送ができる。
トークンは既定の標準APIを持つコントラクトであり、API仕様が以下で議論されている。

例えば、トークンを利用して小売店のポイントカードシステムのようなものを構築できると思う。

本コラムでは、トークンのコントラクトから、トークンを株主総会での議決投票権のような投票単位として利用する投票システムのコントラクトへと進んでいく。

トークンコントラクトのデプロイ

トークンのコントラクトコードのコンパイルおよびデプロイ(配置)を行う。
コントラクトコード自体は開発せずにサンプルコードを利用する。コンパイルはEthereum Walletが行ってくれる。

まずは、コントラクトを選択して表示される下記の画面にて、新しいコントラクトを配置 をクリックする。

配置 コントラクト 画面で、デプロイのトランザクション実行パラメーターを指定していく。
トランザクションの考え方はether送金のそれと同じだ。ただし、デプロイトランザクションにはTOアドレスがなくFROMアドレスしか指定しない。
etherを持っていないアカウントではトランザクションが実行できないので、FROMアドレスにはetherを保持しているアカウントを指定する。ここでは、Main Accountを使用する。
AMOUNTは空のままとしておく。

SOLIDITY コントラクトソースコード には、コントラクトのSolidityコードを入力する。
以下のリンク先のソースコードを全選択してコピーし、SOLIDITY コントラクトソースコード の枠内に貼り付ける。

バイトコードにコンパイルされるまでしばらく待つ。
コンパイル完了後、デプロイ対象とするコントラクトを選択する。
コントラクトはデプロイ単位ごとにブロックチェーン上で唯一の実体として扱われることになる。例えば、オブジェクト指向言語との対比ではコントラクトのソースコードはクラスであり、デプロイはインスタンス化すること、もしくは、関数型言語との対比ではデプロイされたコントラクトはクロージャーのようなものと思えばよいと思う。

配置するコントラクトを選択 でMyTokenを選択する。
コントラクトのコンストラクタパラメーターが設定できるようになる。MyTokenのコンストラクタパラメーターを指定していく。(画面では「顧客パラメーター」という変な日本語になっている)
下表のようにMyPointという名前のトークンで、その全量は100.00ptという設定で進めていく。

コンストラクタパラメーター

項目備考
supply10000トークンの全供給量、ここでは100.00ptになる。
nameMyPointトークンの名前
symbolptトークンの単位
decimals2小数点以下の桁数

なお、このサンプルではデプロイ後にトークンの設定変更はできない。設定変更したいときは再デプロイする必要がある。
コンストラクタパラメーターの入力後、配置ボタンをクリックする。

次の画面にて、SEND TRANSACTIONをクリックする。

デプロイ後(デプロイトランザクションがブロックに記録された後)、コントラクト画面でトークンコントラクトの情報が確認できる。

上側の方(名前が若干変だが)をクリックすると、以下のような画面となる。

アドレスをコピー をクリックすると、コントラクトを識別するアドレス値がクリップボードにコピーできる。この値はアカウントのアドレスと同じ20バイトの値である。

※ Ethereumのアドレス値について

アドレス値により識別されるオブジェクトはいずれも「Ethereumアカウント」であり、以下の2種類に分かれる。

  • EOA(externally owned accounts):本コラムではアカウント(Account)と表記
  • コントラクトアカウント(contract accounts):本コラムではコントラクト(Contract)と表記

インターフェイスを表示 をクリックすると、コントラクトのインターフェイス定義が確認できる。
自分で開発したコントラクトを他の人にも使用させたり、反対に他人のコントラクトを使用したりする場合、アドレス値とインターフェイス定義が必要になる。
詳細は下記を参照。

なお、このようなポップアップ画面の表示は、半透明の部分をクリックすると表示が消えて元画面に戻る。

下側の方をクリックすると、トークンの諸情報が確認できる。

トークンの送金

トークンの初期状態では、デプロイトランザクションを実行した(Fromアドレスに指定した)アカウントがトークンの全量を保持する。上記の操作通りであればMain Accountが100.00ptを保持することになる。
トークンの保持量は、以下のように各アカウントの画面で確認できる。

588

トークンは、トークンコントラクトをデプロイしたアカウントを供給源とする、ローカル通貨的な位置づけと考えられる。トークンはetherと同様に他のアカウントに送金することが可能であり、送金の仕方もether送金と同じ考え方である。

Main AccountからAccount1へトークンを送金する。
Account1の画面で、アドレスをコピー をクリックし、アカウントのアドレスをクリップボードにコピーする。

なお、以降を進めるにあたって各アカウントとコントラクトのアドレスをテキストエディタにコピーしておくと、毎回の画面遷移が不要になり便利と思う。

送信画面を開く。
FROMアドレスでMain Accountを選択すると、このアカウントが所有しているトークン名が選択できる。ここでMyPointを選択する。

TOに先ほどコピーしたAccount1のアドレスを貼り付け(Ctrl+P)する。
AMOUNTに送金トークン額を入力し、送金トランザクションを実行する。

送金トランザクションがブロックに記録されれば、以下のようにAccount1がトークンを保持するようになったはずだ。

今回は、トークンの送金までを説明した。第4回では、トークンを利用した投票システムのコントラクトについて見ていきたい。



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