アルゴリズムとかオーダーとか

仕事で勉強したことなどをまとめてます

Ethereumの環境構築

偉い人にスマートコントラクト勉強してっていわれたので、勉強した内容とかをまとめておこうかなと思います。
とりあえずはなにはともあれ、Ethereumの環境がないとなにもできないのでまずは環境構築から初めて行きます。

今回はEthereum環境の構築とプライベートチェーンのノードを立ててマイニングを実行するまでをゴールにします。


Ethereumには様々な言語で作られたクライアントがあるらしいのですが、今回はおすすめされたGethをインストールしてみます。
github.com

上記githubのページに丁寧にMac OSでのインストール手順が書かれていたのでその手順通りにやってみます。
僕の環境はMac OSX なので brewでインストールします。

brew tap ethereum/ethereum
brew install ethereum

brew tapってなんじゃろ?と思ったら詳しくまとめてくれてる人がいました。
https://qiita.com/saa/items/85ed5e914d424fbf9fd6qiita.com

エラーも出ずにインストールが完了したので実際に動かせるか確認してみます。

$ geth help
NAME:
   geth - the go-ethereum command line interface

   Copyright 2013-2017 The go-ethereum Authors

USAGE:
   geth [options] command [command options] [arguments...]
   
VERSION:
   1.7.2-stable-1db4ecdc
   
~~~~~

Versionは1.7.2のようですね。

続いて、以下の記事を参考にしながら早速プライベートネットワーク上でEthereumを動かしてみます。
Ethereum(geth)でプライベート・ネットワークを作る手順 | block-chain.jp
プライベート・ネットに接続する · Ethereum入門
Private network · ethereum/go-ethereum Wiki · GitHub

どうやらgenesisブロックの設定ファイルが必要みたいなのでまずはそれを用意します。
公式のREADMEに書いてあった以下の内容をコピペしてgenesis.jsonとして保存します。

{
  "config": {
        "chainId": 2017,
        "homesteadBlock": 0,
        "eip155Block": 0,
        "eip158Block": 0
    },
  "alloc"      : {},
  "coinbase"   : "0x0000000000000000000000000000000000000000",
  "difficulty" : "0x20000",
  "extraData"  : "",
  "gasLimit"   : "0x2fefd8",
  "nonce"      : "0x0000000000000042",
  "mixhash"    : "0x0000000000000000000000000000000000000000000000000000000000000000",
  "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
  "timestamp"  : "0x00"
}

genesis.jsonのchainidと開始するノードのnetworkidを一致させておかないとtransactionの送信時にエラーが起きるので注意。

んで、作ったgenesis.jsonでノード情報を初期化します。--datadirオプションを指定することでノード情報を保存するディレクトリを指定できます。この保存ディレクトリを切り替えることで1つのマシンで複数のノードを起動することもできるようです。

geth --datadir="ether-private" init genesis.json 

genesis.jsonでの初期化をしなくてもノードを起動することはできますが、その場合はminer.startでのマイニングがうまく動きませんでした。

    • minerオプションとかつければ問題ないのかな?今回はとりあえず最初に初期化することにします。

初期化が終わったので早速、以下のコマンドでノードを起動します。

$ geth --datadir="ether-private" --ipcdisable --port 50303 --rpcport 18101 --maxpeers 0 --nodiscover --networkid=2017  console 2

ここで重要なのが--networkidオプションです。Ethereumのノードはこのnetworkidとプロトコルのバージョンが同じノードに接続しに行きます。また、networkidは1~3までが予約されており、networkid=1はメインネットを指します。
なので、プライベートネットワークを構築したい場合はこのnetworkidを変更する必要があります。
また今回は他のノードとの接続は行わないので、--nodiscover --maxpeers 0を指定して他ノードと接続されないようにしています。

ノードを起動したらgethのコンソールが起動します。まずはアカウントの一覧を表示してみます。

> eth.accounts
[]

まだアカウントを1つも作ってないのでからですね。

アカウントを1つ作成します。パスフレーズは"test"としています。この初めて作成したアカウントがマイニングした際に報酬が支払われるアカウントにもなります。

> personal.newAccount("test")
"0x858a07cb1a350064075d728499a037c6d0c2b82e"

準備が整ったので早速マイニングを開始したいのですが、その前にまずはこのアカウントがetherを持っていないことを確認しておきます。

> eth.getBalance(eth.accounts[0])
0

0ですね。特に指定せずにgetBalanceを呼び出すとwei単位で表示されます。1ether=10^18weiらしい。

ではマイニングしてみます。マイニングは簡単でminer.start()するだけです。startの引数に数字を入れることで同時に実行するthread数を指定できます。今回は2threadでマイニングします。

> miner.start(2)
INFO [11-09|18:26:54] Updated mining threads                   threads=2
INFO [11-09|18:26:54] Transaction pool price threshold updated price=18000000000
INFO [11-09|18:26:54] Starting mining operation 
null
> INFO [11-09|18:26:54] Commit new mining work                   number=1 txs=0 uncles=0 elapsed=232.873µs
INFO [11-09|18:27:00] Successfully sealed new block            number=1 hash=2e7a98…783d93

無事採掘が開始されました。bitcoinだと採掘するブロック数を指定するのですが、gethではどうも停止するまで永遠と採掘を続けるみたいですね。

最後に、マイニング報酬が受け取れているか確認します。

> eth.getBalance(eth.accounts[0])
60000000000000000000
> web3.fromWei(eth.getBalance(eth.accounts[0]),"ether")
60
> 

今回の採掘で60etherを無事報酬として受け取れました。