go-ethereum環境構築&動作確認めも
はじめに
個人的に動作確認した際のただのメモなので正確な手順は公式や他の記事を参考にしていただければ幸いです。
動作環境用意
環境
今回は以下の環境で動作検証を行なった。
VirtualBox 6.0.2 r128162 (Qt5.6.3) Vagrant 2.2.2 Ubuntu 14.04.5 LTS, Trusty Tahr
環境構築は以下のコマンドで行う。
vagrant init ubuntu/trusty64 vagrant up
Gethのインストール(Ubuntu)
インストール方法は以下に記載されている。今回は Installing from PPA に沿ってインストールを行う。
$ sudo apt-get install software-properties-common $ sudo add-apt-repository -y ppa:ethereum/ethereum $ sudo apt-get update $ sudo apt-get install ethereum
この度の動作確認時にインストールされたのは以下のバージョンだった。
$ geth version WARN [01-19|07:13:43.244] Sanitizing cache to Go's GC limits provided=1024 updated=331 Geth Version: 1.8.21-stable Git Commit: 9dc5d1a915ac0e0bd8429d6ac41df50eec91de5f Architecture: amd64 Protocol Versions: [63 62] Network Id: 1 Go Version: go1.10.4 Operating System: linux GOPATH= GOROOT=/usr/lib/go-1.10
動作確認手順
プライベート・ネットワークに接続
Genesisファイルの作成
Genesisファイルとは,ブロックチェーンの最初(Block番号 "0")のブロックであるGenesisブロックの情報が記述されたファイルである。
プライベート・ネットでは独自のブロックチェーンをやり取りするので,独自のGenesisブロックを定義したGenesisファイルを用意して利用する。
まず,任意の場所にブロック情報やノード情報など各種データを格納するディレクトリを作成する。
$ mkdir /home/vagrant/eth_private_net
作成したディレクトリにjson形式の下記の内容のgenesisファイルを作成する。
{ "config": { "chainId": 15 }, "nonce": "0x0000000000000042", "timestamp": "0x0", "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "extraData": "", "gasLimit": "0x8000000", "difficulty": "0x4000", "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000", "coinbase": "0x3333333333333333333333333333333333333333", "alloc": {} }
Gethをプライベート・ネットで起動
genesisブロックの初期化
genesisファイルの作成ができたら以下のコマンドを実行しブロックチェーン情報をgenesisファイルの内容で初期化する。
以下のコマンドを実行すると、--datadirで指定したディレクトリ以下にgenesisブロックのブロックチェーン情報が保存される。
$ geth --datadir /home/vagrant/eth_private_net init /home/vagrant/eth_private_net/genesis.json
gethの起動
以下のコマンドを実行してGethを起動する。
$ geth --networkid "15" --nodiscover --datadir "/home/vagrant/eth_private_net" console 2>> /home/vagrant/eth_private_net/geth_err.log
各オプションについては以下のとおり。
--networkid : ネットワーク識別子(0 ~ 3は予約済み)。
--nodiscover : 自分のノードを他のノードから検出できないようにする。
--datadir : データディレクトリの指定。
console : 対話型のJavaScriptコンソールを起動する。
--maxpeers 0 : ノードに接続できるノード数。0を指定すると他のノードとは接続しなくなる。
立ち上げたプライベート・ネットのGenesisブロックの情報がgenesisファイルに記載されたものになっているのか確認する。
> eth.getBlock(0)
etherの採掘
アカウントの作成
EthereumにはEOA(Externally Owned Account)とContractの2種類のアカウントが存在する。
ここでは,EOAアカウントの新規作成手順を示す。
eth.accountsコマンドを実行すると,このノード内で作成されたEOAのリストが表示される。現時点のようなアカウントが作成されていない状態だと下記のような表示になる。
> eth.accounts [ ]
EOAの作成はpersonal.newAccount("passwd")
コマンドで行う。passwdの部分は作成するEOAのパスワードになる。
> personal.newAccount("passwd") # 1つ目のアカウント作成 "0xce9603a4a222979ba0fcde0e39feb63cf632d135" > eth.accounts ["0xce9603a4a222979ba0fcde0e39feb63cf632d135"] > personal.newAccount("passwd") # 2つ目のアカウント作成 "0x50245736a8d54edd7e0cac74810eb1224d6ead03" > eth.accounts ["0xce9603a4a222979ba0fcde0e39feb63cf632d135", "0x50245736a8d54edd7e0cac74810eb1224d6ead03"]
Etherbase
Ethereumではマイニング成功時に報酬を受け取るアカウントをEtherbaseと言い,eth.coinbase
コマンドで報酬と紐づくEOAのアドレスを表示することができる。
> eth.coinbase "0xce9603a4a222979ba0fcde0e39feb63cf632d135"
デフォルトではプライマリーのアカウント(eth.accounts[0]コマンドを実行して表示されるアドレスのEOA)がせっていされるが以下のコマンドで変更もできる。
> miner.setEtherbase(eth.accounts[1]) true > eth.coinbase "0x50245736a8d54edd7e0cac74810eb1224d6ead03"
etherの採掘
miner.start(thread_num)
コマンドで採掘が開始される。thread_num によって何本のスレッドで採掘を実行するかを指定することができる。(指定しない場合は動作環境でのCPUコア数に設定されるらしい)
> miner.start() null
停止は以下のコマンドで行うことができる。
> miner.stop() null
採掘状況はeth.blockNumber
コマンドで確認できる。また,採掘中かどうかはeth.mining
コマンドで確認できる。採掘中であればtrue,そうでなければfalseが表示される。
> eth.blockNumber 1 > eth.mining true
採掘内容はeth.getBlock(number)
コマンドで確認できる。numberに任意のブロック高を指定すると、そのブロック高のブロック情報を表示することができる。
> eth.getBlock(0) { difficulty: 16384, extraData: "0x", gasLimit: 134217728, gasUsed: 0, hash: "0x7b2e8be699df0d329cc74a99271ff7720e2875cd2c4dd0b419ec60d1fe7e0432", logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", miner: "0x3333333333333333333333333333333333333333", mixHash: "0x0000000000000000000000000000000000000000000000000000000000000000", nonce: "0x0000000000000042", number: 0, parentHash: "0x0000000000000000000000000000000000000000000000000000000000000000", receiptsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", size: 507, stateRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", timestamp: 0, totalDifficulty: 16384, transactions: [], transactionsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", uncles: [] } > eth.getBlock(1) { difficulty: 131072, extraData: "0xd883010815846765746888676f312e31302e34856c696e7578", gasLimit: 134086657, gasUsed: 0, hash: "0x391fc5bd192bc90fbaf6bf51ad0721c55f1147640783745910aae95848d86f31", logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", miner: "0x50245736a8d54edd7e0cac74810eb1224d6ead03", mixHash: "0x999150e0ac733c083225c7e9d65a928e0489d59f4379e3d7f5f51754301634f1", nonce: "0x595696ed6b06cf5e", number: 1, parentHash: "0x7b2e8be699df0d329cc74a99271ff7720e2875cd2c4dd0b419ec60d1fe7e0432", receiptsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", size: 537, stateRoot: "0xe8be75d3945c744d140ed5cf2a8a1397edc2098bdaa93d11db11dc15c1077392", timestamp: 1547736394, totalDifficulty: 147456, transactions: [], transactionsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", uncles: [] }
報酬の確認
以下のコマンド
etherの持ち高の参照はeth.getBalance(address)
コマンドで行うことができる。addressパラメータには持ち高を確認したいアカウントのアドレスを渡す。
> eth.accounts ["0xce9603a4a222979ba0fcde0e39feb63cf632d135", "0x50245736a8d54edd7e0cac74810eb1224d6ead03"] > eth.coinbase == eth.accounts[0] false > eth.coinbase == eth.accounts[1] true > eth.getBalance(eth.accounts[0]) 0 > eth.getBalance(eth.accounts[1]) 5000000000000000000
etherの送金
今回作成したアカウントのetherの持ち高を確認する。
> eth.accounts ["0xce9603a4a222979ba0fcde0e39feb63cf632d135", "0x50245736a8d54edd7e0cac74810eb1224d6ead03"] > eth.getBalance(eth.accounts[0]) 0 > eth.getBalance(eth.accounts[1]) 5000000000000000000
送金の前に送金元のロックを解除する必要がある。
> personal.unlockAccount(eth.accounts[1]) Unlock account 0x50245736a8d54edd7e0cac74810eb1224d6ead03 Passphrase: true
eth.sendTransaction
コマンドで送金を行う。fromに送金元アドレス,toに宛先アドレス,valueに送金額を指定する。
> eth.sendTransaction({from: eth.accounts[1], to: eth.accounts[0], value: web3.toWei(1, "ether")}) "0xcf632c7958bbf108d64e28b4b708b5bab457874acf5897ce13bded7fe2c84f3c"
実行結果としてトランザクションIDが返されるので確認する。
> eth.getTransaction("0xcf632c7958bbf108d64e28b4b708b5bab457874acf5897ce13bded7fe2c84f3c") { blockHash: "0x0000000000000000000000000000000000000000000000000000000000000000", blockNumber: null, from: "0x50245736a8d54edd7e0cac74810eb1224d6ead03", gas: 90000, gasPrice: 1000000000, hash: "0xcf632c7958bbf108d64e28b4b708b5bab457874acf5897ce13bded7fe2c84f3c", input: "0x", nonce: 0, r: "0x9676139862249d573bfbc9d25ea992b883e6f6df0265198e11e6a40c3a646d8b", s: "0x2332aba6a836642ab9c4d6cc6fa5935ff2529872f26c929f94b8f746c7e0673b", to: "0xce9603a4a222979ba0fcde0e39feb63cf632d135", transactionIndex: 0, v: "0x1b", value: 1000000000000000000 }
マイニングを停止していると,このトランザクションがブロックに取り込まれず,送金が完了しない。マイニングを再開してしばらく経つと,トランザクションがブロックに取り込まれ,blockNumber の値が null から取り込まれたブロックの番号に変更される。
> miner.start() > eth.getTransaction("0xcf632c7958bbf108d64e28b4b708b5bab457874acf5897ce13bded7fe2c84f3c") { blockHash: "0x25c94d690483015ed86ac96156523799ce09066e58b1a86b08448ae25a83fee8", blockNumber: 2, from: "0x50245736a8d54edd7e0cac74810eb1224d6ead03", gas: 90000, gasPrice: 1000000000, hash: "0xcf632c7958bbf108d64e28b4b708b5bab457874acf5897ce13bded7fe2c84f3c", input: "0x", nonce: 0, r: "0x9676139862249d573bfbc9d25ea992b883e6f6df0265198e11e6a40c3a646d8b", s: "0x2332aba6a836642ab9c4d6cc6fa5935ff2529872f26c929f94b8f746c7e0673b", to: "0xce9603a4a222979ba0fcde0e39feb63cf632d135", transactionIndex: 0, v: "0x1b", value: 1000000000000000000 }
トランザクションがブロックに取り込まれ送金が完了するとaccounts[0] の残高が増えていることが確認できる。
> web3.fromWei(eth.getBalance(eth.accounts[0]), "ether") 1
コンソールの終了はexitで行う。
> exit
おわりに
次はスマートコントラクトの作成と実行の手順を残そうと思う。