Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
8
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

Rubyを使って、Ethereumへ接続し、Smart Contractを実行する

Ethereumのライブラリとして有名なのはおそらくweb3.jsでしょう。

しかし、Rubyist(のはしくれ)としては、Ethereumを使ったアプリもRubyで開発したいな〜

そう、思ってました。

そこで、EthereumのRuby実装のライブラリであるethereum.rbを使って、Ethereumに接続し、スマートコントラクトを実行するところまで試してみました。
(その後、その勢いで、具体的なアプリケーションまで作ってみました)

1.事前準備

1. gethのインストール
今回はローカル環境でブロックチェーンを動かすので、gethをインストールする。
手順は以下を参照↓
https://github.com/ethereum/go-ethereum/wiki/Installation-Instructions-for-Mac

2. プライベートネットでgethを起動
genesisファイルを作成して、プライベートネットでgethを起動する。

genesisファイルは以下の通り。

{
  "nonce": "0x0000000000000042",
  "timestamp": "0x0",
  "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "extraData": "0x0",
  "gasLimit": "0xffffffff",
  "difficulty": "0x4000",
  "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "coinbase": "0x0000000000000000000000000000000000000000",
  "alloc": {}
  }

gethの起動コマンドは以下の通り。
今回はHTTP-RPCサーバーを有効にして起動する。

geth --networkid 10 --nodiscover --maxpeers 0 --datadir /Users/user1/eth/data_testnet
 --mine --minerthreads 1 --rpc --rpcaddr "0.0.0.0" --rpcport 8545 --rpccorsdomain "*" --rpcapi "admin, db, eth,
 debug, miner, net, shh, txpool, personal, web3" 2>> /Users/user1/eth/data_testnet/geth.log

その後、gethコンソール上でアカウントを作成して、マイニングを開始します。マイニングが開始されれば、hashrateが0より大きくなっているはずです。

geth attach rpc:http://localhost:8545
> personal.newAccount("pass0")
> personal.unlockAccount(eth.accounts[0], 'pass0', 1000000)
true
> miner.start(1)
> eth.hashrate
140956

2.Smart Contractの準備

今回は毎度おなじみのコントラクトを使って、試してみます。

pragma solidity ^0.4.15;

contract HelloWorld {
    string public greeting;

    function HelloWorld(string _greeting) {
        greeting = _greeting;
    }

    function setGreeting(string _greeting) {
        greeting = _greeting;
    }

    function say() constant returns (string) {
        return greeting;
    }
}

3. Smart Contractの実行

1. ethereum.rbのインストール

gem install ethereum.rb

2. コントラクトをデプロイする
今回はirbを使って、進めます。

> require 'ethereum'
=> true

geth.ipcとコントラクトのパスを定義します。

> ETHEREUM_ADDRESS = "/Users/user1/eth/data_testnet/geth.ipc"
=> "/Users/user1/eth/data_testnet/geth.ipc"
> CONTRACT_PATH="/Users/user1/eth/HelloWorld.sol"
=> "/Users/user1/eth/HelloWorld.sol"

IPC Clientを作成して、gethに接続して、コントラクトをデプロイします。

> client = Ethereum::IpcClient.new(ETHEREUM_ADDRESS)
=> #<Ethereum::IpcClient:0x007fb7c79fa458 @id=0, @log=true, @batch=nil, @formatter=#<Ethereum::Formatter:0x007fb7c79fa3b8>, @gas_price=22000000000, @gas_limit=4000000, @logger=#<Logger:0x007fb7c79fa368 @progname=nil, @level=0, @default_formatter=#<Logger::Formatter:0x007fb7c79fa2f0 @datetime_format=nil>, @formatter=nil, @logdev=#<Logger::LogDevice:0x007fb7c79fa2a0 @shift_size=1048576, @shift_age=0, @filename="/tmp/ethereum_ruby_http.log", @dev=#<File:/tmp/ethereum_ruby_http.log>, @mon_owner=nil, @mon_count=0, @mon_mutex=#<Thread::Mutex:0x007fb7c79fa228>>>, @ipcpath="/Users/user1/eth/data_testnet/geth.ipc"

いよいよ、コントラクトをデプロイします。
createメソッドはオブジェクト指向で言うところのインスタンスの生成のようなものです。
contractというインスタンスを生成し、deploy_and_waitメソッドでデプロイします。

> contract = Ethereum::Contract.create(file: CONTRACT_PATH, client: client)
=> #<HelloWorld:0x007fb7c71dedc8>
> address = contract.deploy_and_wait("Hello, World!")
=> "0x3f2033e41c80647bf3bdeb9b08128bec5972ff46" 

このcontractを使って、デプロイしたコントラクトのメソッドを実行します。
まず、sayメソッドを呼び出してみます。

> contract.call.say()
=> "Hello, World!"

コンストラクタで指定した"Hello, World!"が返ってきました!

次にsetGreetingメソッドを実行してみます。

> contract.transact_and_wait.set_greeting("Hello, Ruby Ethereum!")
=> #<Ethereum::Transaction:0x007fb7c7b706e8 @mined=true, @connection=#<Ethereum::IpcClient:0x007fb7c79fa458 @id=0, @log=true, @batch=nil, @formatter=#<Ethereum::Formatter:0x007fb7c79fa3b8>, @gas_price=22000000000, @gas_limit=4000000, @logger=#<Logger:0x007fb7c79fa368 @progname=nil, @level=0, @default_formatter=#<Logger::Formatter:0x007fb7c79fa2f0 @datetime_format=nil>, @formatter=nil, @logdev=#<Logger::LogDevice:0x007fb7c79fa2a0 @shift_size=1048576, @shift_age=0, @filename="/tmp/ethereum_ruby_http.log", @dev=#<File:/tmp/ethereum_ruby_http.log>, @mon_owner=nil, @mon_count=0, @mon_mutex=#<Thread::Mutex:0x007fb7c79fa228>>>, @ipcpath="/Users/user1/eth/data_testnet/geth.ipc", @default_account="0x394083a0212f7781a31d774df1f3e0b9610e8eef">, @id="0x57546d8bb1c593bab10eb71ab4babcae337db4d71b76eed1f8425499efe2e5af", @input="0xa41368620000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001548656c6c6f2c205275627920457468657265756d210000000000000000000000", @input_parameters=["Hello, Ruby Ethereum!"]

sayメソッドをもう一度呼び出すと、

> contract.call.say()
=> "Hello, Ruby Ethereum!"

変数の値が更新されていることが分かります。

4. まとめ

以上の手順で、ethereum.rbを使って、ブロックチェーンに接続し、コントラクトを実行できることが確認できました。Webアプリの世界ではまだまだ、Ruby(on Rails)での開発も盛んなので、RubyによるEthereumのアプリ開発も候補に入れてみてはいかがでしょうか?

ちなみに、その後、トークンを発行し、それをトレードに出すというデモ用のアプリをRuby on Railsで作ってみました。まだまだ、課題も多いですが、ご参考までにどうぞ。
https://github.com/shiki-tak/token-trader-app

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
8
Help us understand the problem. What are the problem?