プライベートネットでの動作確認

概要

gethで構築したプライベートネットワークを使い、作成したコントラクトが動作するか確認してみたいと思います。

設定

gethの設定

Homebrewを使いgethをインストールします

$ brew tap ethereum/ethereum
$ brew install ethereum

gethのプライベートネットを起動するにはgenesis.jsonファイルを設定する必要があります。

まずプライベートネットのデータを保管するディレクトリを作成し移動します。

$ mkdir ~/private-net && cd private-net

次にprivate-netディレクトリ内にgenesis.jsonファイルとpasswordファイルを用意します。

$ touch genesis.json
$ touch password

各ファイルの内容は以下の通りです。 genesis.json

{
  "config": {
    "chainId": 15,
    "homesteadBlock": 0,
    "eip155Block": 0,
    "eip158Block": 0,
    "byzantiumBlock": 0
  },
  "coinbase"   : "0x0000000000000000000000000000000000000000",
  "difficulty" : "0x1",
  "extraData"  : "",
  "gasLimit"   : "0x2fefd8",
  "nonce"      : "0x0000000000000042",
  "mixhash"    : "0x0000000000000000000000000000000000000000000000000000000000000000",
  "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
  "timestamp"  : "0x00",
  "alloc": {
    "945cd603a6754cb13c3d61d8fe240990f86f9f8a": { "balance": "500000000000000000000000000" },
    "66b4e7be902300f9a15d900822bbd8803be87391": { "balance": "500000000000000000000000000" },
    "104f0d848da3f760dddadc56fc4ab78305110dba": { "balance": "500000000000000000000000000" },
    "addfaa808c59581f04cdadfc0be28ebfb520e839": { "balance": "500000000000000000000000000" },
    "450a8a99bf5ad49db301f6068c619de2400de6f7": { "balance": "500000000000000000000000000" }
  }
}

password

blah
blah
blah
blah
blah

プライベートネットワークの設定

まずはプライベートネットワークの初期化を行いprivate-netディレクトリにgethディレクトリを作成します。

$ geth --datadir ~/private-net --nodiscover --maxpeers 0 init ~/private-net/genesis.json

次にgethのプライベートネットを起動します。 gethを起動するたびに下記のスクリプトを入力するのは大変なので、geth-start.shファイルを用意し、起動用のシェルスクリプトを作成します。

geth-start.sh

geth --datadir ~/private-net --networkid 15 --nodiscover --maxpeers 0 --mine --minerthreads 1 --rpc --rpcaddr  0.0.0.0 --rpccorsdomain "*" --rpcvhosts "*" --rpcapi "eth,web3,pesonal,net" --ipcpath ~/private-net/geth.ipc --ws --wsaddr  0.0.0.0  --wsapi "eth,web3,personal,net" --wsorigins "*" --unlock 0,1,2,3,4 --password ~/private-net/password --allow-insecure-unlock
$ bash geth-start.sh

プライベートネットを起動するとマイニングが始まります。現在開いてるターミナルにはマイニングの状況がリアルタイムに表示されます。別にもう一つターミナルを立ち上げgeth.ipcファイル(private-netディレクトリにあります)にアタッチしgethコンソールを起動します。

$ geth attach geth.ipc

起動

作成したコントラクト(ここではRoomFactoryというコントラクト用いますが、任意の動作確認したいコントラクトに置き換えて下さい)をtruffleを使いgethで作成したプライベートネットワークにデプロイします。

動作確認する際にABIとコントラクトアドレスが必要になるので、画面で確認出来る様にmigrationファイルを下記の様にします。

deploy_room_factory.js

const RoomFactory = artifacts.require('../contracts/RoomFactory.sol')

module.exports = deployer => {
    deployer.deploy(RoomFactory).then(instance => {
        console.log('ABI:', JSON.stringify(instance.abi))
    })
}

RoomFactoryコントラクトをデプロイします。

$ truffle migrate --rest

すると下記の様な結果が得られます。

Running migration: 1_initial_migration.js
  Deploying Migrations...
  ... 0x5fd63c3dc91f64c3ee8963cab14f020d17bb469c079603b564984574e3de4094
  Migrations: 0xf5ad7542173e8944d1ae16b4394eaa34cfda4814
Saving artifacts...
Running migration: 2_deploy_room_factory.js
  Replacing RoomFactory...
  ... 0x38d654c7e25bf331ab43de2de054bf303bf77b7abb9fe6f59e0db704eebf1828
  RoomFactory: 0xcc6cc4d996ec212a1b047b83a4f039e52783bab8
ABI: [{"constant":false,"inputs":[],"name":"unpause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"paused","outputs":[{"na
me":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonp
ayable","type":"function"},{"constant":false,"inputs":[],"name":"destroy","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"p
ause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"state
Mutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable",
"type":"function"},{"constant":false,"inputs":[{"name":"_recipient","type":"address"}],"name":"destroyAndSend","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"
anonymous":false,"inputs":[{"indexed":true,"name":"_creator","type":"address"},{"indexed":false,"name":"_room","type":"address"},{"indexed":false,"name":"_depositedValue","type":"uint256"}],"n
ame":"RoomCreated","type":"event"},{"anonymous":false,"inputs":[],"name":"Pause","type":"event"},{"anonymous":false,"inputs":[],"name":"Unpause","type":"event"},{"anonymous":false,"inputs":[{"
indexed":true,"name":"previousOwner","type":"address"}],"name":"OwnershipRenounced","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"},{"inde
xed":true,"name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"constant":false,"inputs":[],"name":"createRoom","outputs":[],"payable":true,"stateMutability":"pa
yable","type":"function"}]
Saving artifacts...

RoomFactoryに続く'0xcc6cc4d996ec212a1b047b83a4f039e52783bab8'がコントラクトアドレスになります。またABI:に続く配列のがABIになります。

動作確認

gethのプライベートネットワークにおけるコントラクトの動作確認を行います。動作確認をする際にはマイニングの作業を止める必要がありますので、先程立ち上げたgethコンソールのターミナルを開きマニングをストップさせます。

> miner.stop() 

次にコントラクトオブジェクトを定義します。 先程調べたコントラクトのABIを変数abiに定義します。

> abi = [{"constant":false,"..."type":"function"}]

同様にRoomFactoryのコントラクトアドレスをaddressに定義します。

> address = '0xcc6cc4d996ec212a1b047b83a4f039e52783bab8'

大義したabiとaddressを使いRoomFactoryコントラクトオブジェクトを定義します。

> roomFactory = eth.contract(abi).at(address)

それでは定義したコントラクトオブジェクトを使ってコントラクトの状態呼び出しと変更を行います。

ガスを消費しない状態の呼び出し(今回はpaused関数)にはcallを使用します。

> roomFactory.paused.call()
false

ガスを消費する状態の変更(今回はcreteRoom関数)にはtransactionを使用します。

> roomFactory.createRoom.sendTransaction({from: eth.accounts[0], gas: 100000, value: web3.toWei(0.1, 'ether')})
"0xa1a1239be3c65a4726842bc50b31c628326bb4197d7ff56bcc276e75797108f1"

マイニングを再度開始しトランザクションをブロックに取り込みます。

> miner.start(1)

少し時間を置いてから下記の方法でトランザクションの確認をします。

>eth.getTransaction('0xa1a1239be3c65a4726842bc50b31c628326bb4197d7ff56bcc276e75797108f1')