【Ethereum】Gethをプライベートネットワークで起動して操作する


1.環境

  • Ubuntu v16.04.4
  • geth v1.8.8

2.Ethereumのインストール

Ethereumでは、いくつかのEthereumのクライアントが存在していて、クライアントを使って操作をしていきます。
今回はその代表的なクライアントである「Geth」のインストールから、Ethereumをコントロールするコマンドまでをご紹介していきます。

「Geth」は「Go-Ethererum」の略称で、Go言語で実装されたCUIクライアントです。
まずはそのインストールを行っていきます。

ethereum-install
$ sudo add-apt-repository -y ppa:ethereum/ethereum
$ sudo apt-get update
$ sudo apt-get -y install ethereum

終了後、versionコマンドで下記のように表示されればインストール完了です。

geth-version
$ geth version
Geth
Version: 1.8.8-stable
Git Commit: 2688dab48c9b8ae71b8d95c7678817eaa17f2b53
Architecture: amd64
Protocol Versions: [63 62]
Network Id: 1
Go Version: go1.10
Operating System: linux
GOPATH=
GOROOT=/usr/lib/go-1.10

3.gethの起動

gethを起動するためにはgenesis.jsonというファイルが必要となりますので、こちらを作成していきます。
ブロックチェーンに積み上がる一番初めのブロックのことをジェネシスブロック(Genesis Block)と呼び、そのジェネシスブロックの情報を記載したファイルとなります。

今回はプライベートネットワークでネットワークを構築するため、ジェネシスブロックは適当な値で設定しています。
メインネットワークに接続したい場合は、すでにジェネシスブロックは存在しているため、この動作(ジェネシスブロックの採掘)は必要ありません。

make-genesis
$ mkdir private
$ cd private
$ vim genesis.json
genesis.json
{
  "config": {
    "chainId": 15
  },
  "nonce": "0x0000000000000042",
  "timestamp": "0x0",
  "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "extraData": "",
  "gasLimit": "0x8000000",
  "difficulty": "0x4000",
  "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "coinbase": "0x3333333333333333333333333333333333333333",
  "alloc": {}
}

genesis.jsonの作成が完了したら、ジェネシスブロックをコマンドから採掘してgethを起動します。

geth-start
# genesisブロックの採掘
$ geth --datadir private init private/genesis.json

# 起動コマンド
$ geth --networkid "15" --nodiscover --datadir "/home/vagrant/work/eth/private" console 2>> /home/vagrant/work/eth/geth.log

補足: gethのバックグラウンド起動について

先ほどの起動コマンドを実行すると、自動でConsoleへ入るのですが、このプロセスからexitしてしまうとgethのプロセスまで終了してしまいます。

そのため、gethを起動する際は基本的にバックグラウンドで起動していくことになるはずです。

background-start
# オプションを付けながら起動する
$ nohup geth --datadir private --mine --rpc --rpcaddr "0.0.0.0" --rpcport 8545 --rpccorsdomain "*" --rpcapi "admin,db,eth,debug,miner,net,shh,txpool,personal,web3" 2>> private/geth.log &

4.Consoleからgethを操作する

4-1.Consoleに入る

ここでは先ほどご紹介したバックグラウンドでgethを起動しているものとして、説明を進めていきます。
バックグラウンド起動後は、Consoleに入り、Ethereumを操作していきます。
※バックグラウンド起動をしなかった場合、Consoleへ勝手に入りますので、ここ(4-1)は飛ばして大丈夫です。

# consoleに入る
$ geth attach ipc:private/geth.ipc
Welcome to the Geth JavaScript console!

instance: Geth/v1.8.8-stable-2688dab4/linux-amd64/go1.10
coinbase: 0xf339d34141c8f84cb41f522e15932e61a6132404
at block: 1458 (Sun, 17 Jun 2018 12:15:01 JST)
 datadir: /home/vagrant/work/eth/private
 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

4-2.Consoleコマンドについて

Consoleに入ってから、コマンドを叩くことでgethを操作していきます。
ここではその際によく使うConsoleコマンドをご紹介します。

<アカウント情報取得系>

アカウントのアドレスを表示する

eth.accounts

# 返り値: ノードに存在する全てのEthereumアドレス
> eth.accounts
["0xf339d34141c8f84cb41f522e15932e61a6132404", "0x106cf689445729383eb5b45b6996a266ff400150", "0xe419b76396bdb3b2f0685f2126f5fb1c175d8cd1"]

# 引数: index値
# 返り値: 指定したindex番号のアカウントのアドレス
> eth.accounts[0]
"0xf339d34141c8f84cb41f522e15932e61a6132404"

新しいアカウントとアドレスを発行する

personal.newAccount("User名")

# 引数: 好きなアカウント名
# 返り値: Ethereumアドレス
> personal.newAccount("Account")
"0x345749906435fc04495715eacfc69cd72718faf1"

引数で指定したEthereumアドレスの残高を表示する

eth.getBalance("アドレス")

# 引数: Ethereumアドレス
# 返り値: 指定アドレスの残高(Wei単位で表示)
> eth.getBalance("0xf339d34141c8f84cb41f522e15932e61a6132404")
1.1395e+22

<ブロック・トランザクション情報取得系>

現在のブロック数を表示する

eth.blockNumber

# 返り値: 現在のブロック数
> eth.blockNumber
154

指定したBlock番号のBlock情報を表示する

eth.getBlock("Block番号")

# 引数: Block番号
# 返り値: 指定したBlock番号のBlock情報
> eth.getBlock(2382)
{
  difficulty: 396051,
  extraData: "0xd683010808846765746886676f312e3130856c696e7578",
  gasLimit: 13095390,
  gasUsed: 21000,
  hash: "0x935a8c4771417814e728f0623876dcc08d5cada52e706003be3e8d63cd4fa4f5",
  logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  miner: "0xf339d34141c8f84cb41f522e15932e61a6132404",
  mixHash: "0x926aae5dc8d3a7bcd340b9b2b98be24d6f691ca3d848ae590e118f8b618f9f64",
  nonce: "0x39fca5458e5dd50f",
  number: 2382,
  parentHash: "0x9e50acf21c8337ae745b71d872997a1b474e2c670010dfb3b2865b0bf2183954",
  receiptsRoot: "0x8227202bce5e79b7f4b0a76c03d53a39ea08b6fd238912b90fdf3a7f63572d22",
  sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
  size: 644,
  stateRoot: "0xe5df2b4b15e578a6f312f830ebe5e078f1b007ef10c274d4bf4ffd605542239c",
  timestamp: 1529209512,
  totalDifficulty: 578276739,
  transactions: ["0xa5e7146a89e634808f6ded9ac2bc6127935863a5eff3e12c6d9c74376b3dab2b"],
  transactionsRoot: "0x5ff30b4021d60bf6dc899232c11cd15f623861b29596d88970d2d52c0a99b4a6",
  uncles: []
}

指定したTransactionIDを持つ、Transaction情報を取得する

eth.getTransaction("TransactionID")

# 引数: TransactionID
# 返り値: Transaction情報
> eth.getTransaction("0xa5e7146a89e634808f6ded9ac2bc6127935863a5eff3e12c6d9c74376b3dab2b")
{
  blockHash: "0x935a8c4771417814e728f0623876dcc08d5cada52e706003be3e8d63cd4fa4f5",
  blockNumber: 2382,
  from: "0xf339d34141c8f84cb41f522e15932e61a6132404",
  gas: 90000,
  gasPrice: 18000000000,
  hash: "0xa5e7146a89e634808f6ded9ac2bc6127935863a5eff3e12c6d9c74376b3dab2b",
  input: "0x",
  nonce: 0,
  r: "0xe6ce234fb5d2ac1dacb11c2f39f025720b801f8512ca561b1554feab9f90668b",
  s: "0x4611c4f29ecd4beb5c11fe216a0cc2bcfd06cccac9596bd675591bc8e5f688db",
  to: "0x345749906435fc04495715eacfc69cd72718faf1",
  transactionIndex: 0,
  v: "0x1b",
  value: 3000
}

<マイニング系>

マイニングを開始する

miner.start()

> miner.start()
null

マイニングを停止する

miner.stop()

> miner.stop()
true

マイニングが現在、動いているかどうかを表示する。

eth.mining

# 返り値: boolean(マイニングをしているかどうか)
> eth.mining
true

<送金系>

送金を行うためにアカウントをアンロックする

personal.unlockAccount("Ethereumアドレス")

# 引数: Ethereumアドレス(自分のノードでないとアンロックは不可)
## Passphrase: Ethereumアドレスを発行する際(Personal.newAccount())に入力したアカウント名
# 返り値: boolean(アンロックに成功したかどうか)
> personal.unlockAccount("0xf339d34141c8f84cb41f522e15932e61a6132404")
Unlock account 0xf339d34141c8f84cb41f522e15932e61a6132404
Passphrase:
true

Ethereumを送金する

eth.sendTransaction({from: "送金元Ethereumアドレス", to: "送金先Ethereumアドレス", value: "送金額(Wei)"})
※送金元アカウントはアンロック必須。

# 引数: 
## from: 送金元Ethereumアドレス
## to: 送金先Ethereumアドレス
## value: 送金額(Wei単位)
# 返り値: TransactionID
> eth.sendTransaction({from: "0xf339d34141c8f84cb41f522e15932e61a6132404", to: "0x345749906435fc04495715eacfc69cd72718faf1", value: "3000"})
"0xa5e7146a89e634808f6ded9ac2bc6127935863a5eff3e12c6d9c74376b3dab2b"

5.インストールまとめ

大して手間でもないですが、シェルにまとめましたので、インストールする際はこちらをコピペORシェルで実行していただければと思います。
※rootユーザーで叩いてください!

eth-install.sh
#!/bin/sh

sudo add-apt-repository -y ppa:ethereum/ethereum
sudo apt-get update
sudo apt-get -y install ethereum

6.参考文献