Geth で Solidity を動かす

今回は Ethereum のブロックチェーン上にスマートコントラクトを記述して動かしてみたいと思います。主にこちらを参考にしておりますが、記述内容が古くそのままだと動かない箇所がいくつかありましたので注意してください。

Geth と Solidity

ご存知の通り Ethereum のブロックチェーンはパブリックで誰でもアクセスすることができますが、直接アクセスしようとすると低レベルな処理が必要で面倒です。なので一般的にはこれらの処理を肩代わりしてくれるプログラムを使ってブロックチェーンにアクセスします。それが Geth (go-ethereum)です。またスマートコントラクトを記述するためのプログラミング言語が Solidity です。文法的には JavaScript に似ていますが、こちらは静的型付けのコンパイル言語になります。

ゴールのイメージ

まずは Geth 単体でブロックチェーンにアクセスしてみます。そのあと Solidity で書かれたコードをコンパイルしてブロックチェーン上で動かしてみます。

インストール方法

Geth と Solidity のインストールは OSX であれば Homebrew を使って簡単にできるのでググれカス的な感じで(汗

Geth 単体で使ってみる

手始めに Geth を使ってブロックチェーンにアクセスしてみようと思います。

パブリックなブロックチェーンを使うとトランザクションコストが発生してしまいますので、自分のPC 内にプライベートなブロックチェーンを用意します。プライベートなチェーンを使うとテスト用のアカウントに自由に ether を付与できるのでコストゼロでテストできます。

プライベートチェーンを作る

適当なディレクトリで

$ mkdir eth_net
$ vi genesis.json

genesis.json

{
  "config": {
    "chainId": 10,
    "homesteadBlock": 0,
    "eip155Block": 0,
    "eip158Block": 0
  },
  "alloc": {},
  "nonce": "0x0000000000000042",
  "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "difficulty": "0x00",
  "coinbase": "0x0000000000000000000000000000000000000000",
  "timestamp": "0x00",
  "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "gasLimit": "0xffffffff"
}

最後に以下のようにしてブロックチェーンを初期化しておきます。

$ geth --datadir ./eth_net init ./genesis.json

ここまででプライベートチェーンができました。

Geth コンソールの起動

Geth コンソールを立ち上げて先ほど作ったプライベートなブロックチェーンにアクセスしてみます。

$ geth --datadir ./eth_net console
(省略..)
>

(> は Geth コンソール上での作業を、$ は linux シェル上での作業の意図で使い分けていきます)

テスト用アカウントの作成

このまっさらなブロックチェーンにはまだユーザーがいませんのでテスト用のアカウントを作っておきます。

> personal.newAccount('パスフレーズ')

パスフレーズは省略可能です。

マイニング

このアカウントを使ってマイニングをしてみます。成功すれば報酬として ether が取得できるはずです。

> miner.start()
(しばらく待つ)
> miner.stop()

miner.stop() を入力する際に、ログが標準出力に出てきますが気にせずに入力してエンター押せば OK です。

アカウントの ether 残高を確認します。

> eth.getBalance(eth.accounts[0])
5000000000000000000

数字が表示されればマイニングが成功しています。単位は wei で表示されているので桁が大きいですが気にしない、気にしない。

送金してみる

このマイニングで得た either を別のアカウントに送金してみます。上の「テスト用アカウントの作成」と同じ手順で送金先のアカウントを作っておきます。

送金元のアカウントのロックを解除します。

> personal.unlockAccount(eth.accounts[0], 'パスフレーズ')

以下のようにして送金トランザクションを作成します。

> eth.sendTransaction({ from: eth.accounts[0], to: eth.accounts[1], value: 10 })

この場合 eth.accounts[0] が eth.accounts[1] に 10 wei を送金することになります。

作成したトランザクションを承認させるためにマイニングを行います。

> miner.start()
(省略...)
> miner.stop()

2つのアカウントの残高を確認します。

> eth.getBalance(eth.accounts[0])
4999999999999999990
> eth.getBalance(eth.accounts[1])
10

無事に ether が送金されました。

プログラムを書いてみる、動かしてみる

1)プログラムを書き 2)コンパイルして 3)ブロックチェーンにデプロイして 4) 実行してみます。

プログラムを書く

Solidity でサンプルプログラムを作ります。

$ vi single_num_register.sol

single_num_register.sol

pragma solidity ^0.4.11;

contract SingleNumRegister {
  uint storedData;
  function set(uint x) {
    storedData = x;
  }
  function get() constant returns (uint retVal) {
    return storedData;
  }
}

コンパイルする

Solidity のコンパイラ solc でコンパイルします。

$ echo "var out = `solc --combined-json abi,bin single_num_register.sol`" > out.js

ここでコンパイル結果を out に代入していますが、後で Geth コンソールから loadScript するために必要ですので一旦このようにしておきます。

ブロックチェーンへのデプロイ

このコードからコントラクトを作成してブロックチェーンに登録していきます。

以下のようにしてコントラクトを作成します。

> loadScript("out.js");
> var contract = web3.eth.contract(JSON.parse(out.contracts["single_num_register.sol:SingleNumRegister"].abi));
> var singleNumRegister = contract.new({ from: eth.accounts[0], data: "0x" + out.contracts["single_num_register.sol:SingleNumRegister"].bin, gas: 4700000});

マイニングを開始してこのコントラクトをブロックチェーンに登録します。

> miner.start()
(しばらく待つ)
> miner.stop()

コントラクトインスタンスの address に値が入っていればブロックチェーンへの登録が完了しています。

> singleNumRegister
{
(省略...)
address: "0x314b339a74dfc860b48e4eb5ad0dae149f51617e",
(省略...)
}

コントラクトの実行

このコントラクトを動かしてみます。

プログラムした get 関数を呼び出してみます。

> singleNumRegister.get.call()
0

0 が登録されています。

set 関数を呼び出して 7 を登録してみます。これはブロックチェーン上の値を変更することになるので ether を消費してトランザクションを生成する必要があります。

> singleNumRegister.set.sendTransaction(7, {from: eth.accounts[0], gas:1000000})

マイニングします。

> miner.start()
(しばらく待つ)
> miner.stop()

get 関数で登録された数字を取得します。

> singleNumRegister.get.call()
7

7 が表示されました。

最後に

今回は Geth を使ってプライベートなブロックチェーンを作りマイニングと送金を試しました。また Solidity で簡単なコードを書いてコンパイル、デプロイ、実行までやってみました。

Geth に関してはネットの情報が古くなっているケースが散見されたので少し注意が必要そうです。またコードを書いてからデプロイまでのプロセスが面倒くさいと感じました。コントラクト開発をするためのブラウザベースの IDE がいくつかあるようで、それを使えばこの辺りの面倒なプロセスをフォローしてくれるんじゃないかなと期待しています。

アルタ ノービス

Bitcoin、Altcoin 初心者です。このブログは独自の仮想通貨を流通させることを目論む過程を記録するドキュメンタリーブログです。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です