偉い人にスマートコントラクト勉強してっていわれたので、勉強した内容とかをまとめておこうかなと思います。
とりあえずはなにはともあれ、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を無事報酬として受け取れました。