Bitcoinのブロックチェーンは取引記録を台帳に記録していくプラットフォームなのに対し、Ethereumは独自のブロックチェーンネットワークで分散アプリケーションを実行するプラットフォームを提供している。
今回は、そんなEthereumの動作環境を作ってみた。
セットアップ
Ethereumの実装は公式では今のところ↓の3つの言語で用意されている。
- Goによる実装
https://github.com/ethereum/go-ethereum - C++による実装
https://github.com/ethereum/webthree-umbrella - Pythonによる実装
https://github.com/ethereum/pyethapp
インストール
今回はGoの実装をUbuntu上にインストールする。 パッケージをインストールするだけなので、基本的にはethereumのPPAリポジトリ追加してapt-getでインストールするだけ。
$ sudo apt-get install software-properties-common $ sudo add-apt-repository -y ppa:ethereum/ethereum $ sudo add-apt-repository -y ppa:ethereum/ethereum-dev $ sudo apt-get update $ sudo apt-get install ethereum
コマンド
インストールされると↓のコマンドが利用可能になる。
- geth
EthereumのCLI - bootnode
Ethereum Discovery Protocol用のbootstrapノードを起動する - ethtest
JSONファイルに記述されたテストを実行する。 - evm
EVM(Ethereum Virtual Machine)*1のコードを実行する。 - disasm
EVMのバイトコードをpretty printしてくれる。 - rlpdump
RLP(Recursive Length Prefix)*2なデータをpretty printしてくれる。
アカウントの作成
Ethereumのアカウントには2種類ある。
- Externally Owned Accounts (EOAs)
一般的に認識されているアカウントで外部からユーザが作成してコントロールするタイプのもの。
ehterの残高を持ち、トランザクションを送信でき、秘密鍵によって制御されコードとの関連は無い。 - Contract Accounts
Ethereumにはcontractと呼ばれるコード(機能)とデータ(状態)の集合が、ブロックチェーン上の特定のアドレスに存在しており、このcontractと関連付けられるアカウント。
etherの残高を持ち、コードとの関連があり、他のcontractsからのトランザクションもしくはメッセージの受信をトリガーにコードを実行する。
console上では↓でアカウントが作れる。
> personal.newAccount("パスワード") "0x4d3477c4b74c1d30f803984d363b4603c230a309"
※ consoleで使えるコマンドの一覧は↓で確認できる。
JavaScript Console · ethereum/go-ethereum Wiki · GitHub
Test Network
BitcoinのtestnetのようにEthereumにもMordenと呼ばれるテスト用のネットワークがある。
また、Morden testnetのetherを取得には↓の2通りの方法がある。
- 自分でマイニングする
- Ethereum wei faucetでもらう。
testneは--testnetオプションを付加すれば起動できる。
$ geth --testnet
ローカルにprivate testnetをセットアップする
Morden testnetでも↑のようにetherを入手する必要があるが、private testnetを利用すれば事前にetherを生成するか自前でマイニングが簡単に行える。(Bitcoinでいうregtestモードみたいなもの)
private chainを作成するにあたって必要なのが↓
Custom Genesis File
Bitcoinと同様にgenesisブロックがブロックチェーンの開始となる。このgenesisブロックを↓のようにJSON形式でファイルに定義して、
{ "nonce": "0x0000000000000042", "timestamp": "0x0", "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "extraData": "0x0", "gasLimit": "0x8000000", "difficulty": "0x400", "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000", "coinbase": "0x3333333333333333333333333333333333333333", "alloc": { } }
gethコマンドでノードをスタートする際に、--genesisオプションでこのファイルを指定する。
同じgenesisブロックを持ってない限り、他のノードとブロックチェーンのバージョンが異なるため、他のブロックチェーンからはこのノードに接続できないので、すきなだけprivate testnetが作れるみたい。
Custom Data Directory
private chainのデータを保存する場所を--datadirオプションで指定する。
Custom NetworkID
--networkidオプションでネットワークIDを指定。(通常のtestnetは2)
Disable Node Discovery
自分のノードを他のノードから見つけれれないよう--nodiscoverオプションを付加する。(このオプションを付けても手動で追加することはできる) ※ Custom Genesis Fileを使っても万が一同じ内容だった場合、network idも一緒なら繋がってしまうため。
↑を意識してgethコマンドでノードを起動すればprivate chainが起動できる。
$ geth --identity "MyNodeName" --genesis /path/to/CustomGenesis.json --rpc --rpcport "8080" --rpccorsdomain "*" --datadir "C:\chains\TestChain1" --port "30303" --nodiscover --rpcapi "db,eth,net,web3" --networkid 1999 console
※ ↑実行すると以下のような警告が表示される。特に起動に問題は無いが将来的にinitに置き換わって使われなくなるっぽい。
# --genesis is deprecated. Switch to use 'geth init /path/to/file' #
↑のCustom Genesis Fileにdifficultyが“0x400”と指定されているが、これはすぐにetherのマイニングが可能なレベルの値になっている。もしくはマイニングするより前にetherを入手したい場合は以下の手順でできる。
- private chainを起動した後にアカウントを作成する
- 作成したアカウントのアドレスをコピーする
- Custom Genesis Fileの"alloc"の項目を以下のように追記する
"alloc": { "2でコピーしたアドレスを記述": { "balance": "20000000000000000000" } }
ノードを再起動しetherの残高を確認すると
> eth.getBalance(eth.accounts[0]) 20000000000000000000
etherが増えてるのが分かる。