- 公開日:2017年10月26日
- 実施日:2017年10月26日 - 2017年11月08日
記事概要
仮想通貨の仕組みを理解するために、ethereumをインストールして色々と試してみたので、その作業記録です。
この記事を使って開発環境を構築しました。
現在利用できない箇所や足りない部分を記事で補完しています。
環境
- Ubuntu 16.04.3 LTS
- ethereum Geth/v1.7.2
ethereumのインストール
デフォルトのdockerを使う場合は、curlをインストールします。
apt-get install curl
ethereum公式のWikiに記載されている通りにethereumをインストールします。
apt-get install software-properties-common add-apt-repository -y ppa:ethereum/ethereum apt-get update apt-get install ethereum
gethコマンドでinstallが成功されたことを確認します。
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 // something
プライベート・ネットに接続
開発で使うので、プライベート・ネットで動作させます。まずは、ディレクトリを作成します。
cd /home mkdir -p test_u/eth_private_net
myGenesis.jsonを作成します。Genesisは、初期データのことです。つまり、myGenesis.jsonは初期データファイルです。
apt-get install vi cd /home/test_u/eth_private_net vi myGenesis.json { "nonce": "0x0000000000000042", "timestamp": "0x0", "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "extraData": "0x", "gasLimit": "0x8000000", "difficulty": "0x4000", "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000", "coinbase": "0x3333333333333333333333333333333333333333", "alloc": {} } // https://qiita.com/oggata/items/eea4d5e37f38785f6079
データ内容はまだ触れないでおきます。gasLimitやcoinbaseの意味は、最初はわからないと思います。
myGenesis.jsonファイルで初期化します。
geth --datadir /home/test_u/eth_private_net2 init /home/test_u/eth_private_net2/myGenesis.json
指定オプションの意味はhelpで確認しましょう。
--datadir "/root/.ethereum" Data directory for the databases and keystore init Bootstrap and initialize a new genesis block
Genesis Block = 一番初めのブロックのことです。
つまり、上記は、一番初めのブロックを初期化していることを示しています。実際に実行します。
geth --datadir /home/test_u/eth_private_net2 init /home/test_u/eth_private_net2/myGenesis.json WARN [10-25|23:04:56] No etherbase set and no accounts found as default INFO [10-25|23:04:56] Allocated cache and file handles database=/home/test_u/eth_private_net/geth/chaindata cache=16 handles=16 Fatal: Failed to write genesis block: genesis has no chain configuration
chaindataディレクトリが新しく作成されて、その中にgenesisブロックのブロックチェーン情報が保存されていることを確認します。
ls -l geth/chaindata total 12 -rw-r--r-- 1 root root 0 Oct 25 23:04 000001.log -rw-r--r-- 1 root root 16 Oct 25 23:04 CURRENT -rw-r--r-- 1 root root 0 Oct 25 23:04 LOCK -rw-r--r-- 1 root root 361 Oct 25 23:04 LOG -rw-r--r-- 1 root root 54 Oct 25 23:04 MANIFEST-000000
初期化に成功しました。
gethの起動
geth --dev --networkid "10" --datadir "/home/test_u/eth_private_net2" console 2>> /home/test_u/eth_private_net2/geth_err.log
テストネットで起動するときは、--networkid を付加します。--networkidオプションで任意の正の整数のIDを指定することで、ライブ・ネットとは異なるネットワークを立ち上げることが可能です。
また、--dev を付加して開発用途のプライベートチェーン設定で起動しましょう。--devをつけることで素早く採掘ができます。
Welcome to the Geth JavaScript console! instance: Geth/v1.7.2-stable-1db4ecdc/linux-amd64/go1.9 modules: admin:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0 >
起動に成功しました。
データの確認
まずは、対話型で動きと仕様を理解していきます。
eth.getBlock(0)で登録データを確認できます。
> eth.getBlock(0) { difficulty: 17179869184, extraData: "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa", gasLimit: 5000, gasUsed: 0, hash: "0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3", logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", miner: "0x0000000000000000000000000000000000000000", mixHash: "0x0000000000000000000000000000000000000000000000000000000000000000", nonce: "0x0000000000000042", number: 0, parentHash: "0x0000000000000000000000000000000000000000000000000000000000000000", receiptsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", size: 540, stateRoot: "0xd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544", timestamp: 0, totalDifficulty: 17179869184, transactions: [], transactionsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", uncles: [] }
eth.getBlock(0)は初期データです。
exitコマンドで退出できます。
> exit root@04a2878d5ace:/home/test_u/eth_private_net#
採掘
次は採掘してみましょう。ビットコインでいう、マイニングです。
ビットコインは平均10分ごとにブロックを生成しますが、イーサリアムは15秒です。
まず、ノードに登録されたアカウント(EOA)を表示します。
> eth.accounts []
最初は上記のように空です。
EOA(Externally Owned Account)を作成します。
personal.newAccount("passwd")コマンドを使います。
> personal.newAccount("passwd") "0xe1a9e49ee272e6ab971b5f6160d8157ff9fe412b"
passwdは、本番は実際のパスワードを入力してください。これでEOA(Externally Owned Account)を作成できます。
実行すると、作成されたEOAの20バイトのアドレスが表示されます。
頭に「0x」が付加されているので16進数のハッシュですね。
もう一つアカウントを作成します。
> personal.newAccount("passwd2") "0x0f8669608765e4df02f2a348d11954696ae5698d"
ノードに登録されたアカウント(EOA)を表示します。
> eth.accounts ["0xe1a9e49ee272e6ab971b5f6160d8157ff9fe412b", "0x0f8669608765e4df02f2a348d11954696ae5698d"]
ノードに登録されたアカウント(EOA)が表示されました。
etherbase
etherbaseとは、各ノードで採掘を行う際にその報酬を紐づけるEOAのアドレスを示します。
> eth.coinbase "0xe1a9e49ee272e6ab971b5f6160d8157ff9fe412b"
etherの採掘
作成したEOAのアドレスがetherbaseとしてセットされていれば、etherの採掘が可能です。 etherの採掘はminer.start(thread_num)コマンドで開始します。
> miner.start() null
nullが表示されていますが、採掘は実行されています。これは少しわかりにくい仕様ですね。以前はtrueが返される仕様だったのですが、なぜ変更したのでしょうか?
採掘が実行されてるかを確認するには、eth.hashrateコマンドで、現在の採掘処理のハッシュ・レートを確認します。
> eth.hashrate 2096 > eth.hashrate 66704
ハッシュ・レートがゼロよりも大きければ、採掘処理が行われていると考えます。続ければ続けるほど数値はどんどん上がっていきます。
採掘は時間がかかります。しかし、この記事ではdev環境で動かしているので、次々と採掘されます。
また、ログで確認する方法もあります。ログ出力フォルダの指定は起動時に行っておきましょう。dockerの場合は、terminalでps接続で確認できます。
docker exec -it {name} /bin/sh
採掘状況の確認
ブロックは次々と採掘されていきます。ブロックチェーンに何番目のブロックまで連なっているのか(=ブロック高)を確認するには、eth.blockNumberコマンドを用います。
> eth.blockNumber 65 > eth.blockNumber 68 > eth.blockNumber 81 > eth.blockNumber 117 > eth.blockNumber 123
必要な数のブロックを採掘したら、採掘を停止します。
> miner.stop() true
採掘したブロックの情報を確認します。
123のブロックを採掘したので、123番目のブロックを確認します。
> eth.getBlock(123) { difficulty: 139055, extraData: "0xd583010702846765746885676f312e39856c696e7578", gasLimit: 4712388, gasUsed: 0, hash: "0x8409ba210cf0a933321c9fc9b1d54dd4b39d98833fa412417ab88c6336603be0", logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", miner: "0x7a05d8030738af4ffe794d8b3d3b86ee28e11318", mixHash: "0xb090804669ad4b7922f63f4ed91c05f1dabb29ff609695bd6018de2002a01f05", nonce: "0x584cd0329f0dd51d", number: 123, parentHash: "0x07599d3aeb1dd4f9fb322326e68f89e5bc2cb6a260a82a504ee74929a2f86fab", receiptsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", size: 533, stateRoot: "0x4eab6ed2c31249285c576d0d79bf629bb811750f31e671f71ff0937a2da29aef", timestamp: 1509576985, totalDifficulty: 16739304, transactions: [], transactionsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", uncles: [] }
まだ採掘されていない124番目のブロックを確認してみます。
> eth.getBlock(124) null
報酬の確認
採掘した報酬を確認します。
> eth.getBalance(eth.accounts[0]) 369000000000000000000
eth.getBalance(address)は「wei」の単位で出力します。単位をethに変換してみましょう。
> web3.fromWei(eth.getBalance(eth.accounts[0]),"ether") 369
送金
送金の仕組みを理解します。
各アカウントの残高を確認します。
> eth.getBalance(eth.accounts[0]) 369000000000000000000 > eth.getBalance(eth.accounts[1]) 0
eth.accounts[0]からeth.accounts[1]に2ether送金してみます。
eth.sendTransactionコマンドを用います
送金の際は、採掘処理をバックグラウンドで実行しておく必要があります。また、ロックの解除も必要です。
// 採掘 miner.start() // ロック解除 パスワードが必要 personal.unlockAccount(eth.accounts[0]) // 送金の実行。 パスワードは不要 eth.sendTransaction({from: eth.accounts[0], to: eth.accounts[1], value: web3.toWei(4, "ether")}) // 確認 eth.getBalance(eth.accounts[1]) 4000000000000000000
今度は逆にaccounts[1]からaccounts[0]に送金します。
// 採掘 > miner.start() null // ロック解除 パスワードが必要 > personal.unlockAccount(eth.accounts[1]) Passphrase: true // 送金の実行。 パスワードは不要 > eth.sendTransaction({from: eth.accounts[1], to: eth.accounts[0], value: web3.toWei(2, "ether")}) "0xa0f782ee4245e886f9d79cf682006ac479857b8f43bba3d5b3df022f18cecc30" // 確認 > eth.getBalance(eth.accounts[1]) 2000000000000000000
トランザクションを調べます。sendTransaction時に発行されたハッシュを使います。
> eth.getTransaction("0xa0f782ee4245e886f9d79cf682006ac479857b8f43bba3d5b3df022f18cecc30") { blockHash: "0x2756e0ac42054df3f792b6861f16a9b19392c66b149d6a54dee56eee3ca5eeda", blockNumber: 315, from: "0xd286d2666015e7a36d5826bd49f83af4ea922f52", gas: 90000, gasPrice: 0, hash: "0xa0f782ee4245e886f9d79cf682006ac479857b8f43bba3d5b3df022f18cecc30", input: "0x", nonce: 0, r: "0xbba0222bb19a7ad54cb5fd0f9512f256285caeaa98ddb396ed1b256b0e8dab54", s: "0x2d5329ce25e69ad94709f302c972071cab2a5363bdffacdb19fdb11986ddda71", to: "0x7a05d8030738af4ffe794d8b3d3b86ee28e11318", transactionIndex: 0, v: "0xa95", value: 2000000000000000000 }
トランザクションが表示されました。gasPriceが0なので、トランザクションを生成した際に採掘者に対して支払うトランザクション手数料は無料になっていますね。
Contract
やってみたけど、情報が古くてうまくいかないので、penddingします。今はSolcが使えなくなっているので、情報を集める時は注意してください。
まとめ
実際に手を動かすと、ethereumの基本が理解できました。
とはいえ、騒がれているほどの凄さは感じなかったので、これからも少しづつブロックチェーンの学習を進めていきたいと思います。
railsやスマホのように化けて役立ってくれるかもしれないので。。。
以上。
0 件のコメント:
コメントを投稿