DC4

Gethでetherを送金する

前回作成した環境を使い、アカウント作成/マイニング/送金まで行っていきます。

gethを試すためのDocker環境を作った。 - DC4

以下コマンドでGethのインストール後、テストネットに接続します。

$ docker-compose build
$ docker-compose up

起動後暫くはDAGのダウンロードが行われます。
DAGは ethereumのPoWに必要なもので、詳しくは以下を参照して下さい。
Ethash DAG · ethereum/wiki Wiki · GitHub

コンテナに接続後、Gethにアタッチします。

docker exec -i -t gethdockersample_geth_1 /bin/bash
geth attach ipc://eth_data/geth.ipc

アカウントの作成

以下のコマンドでアドレスを発行します。
引数に入れたパスワードを忘れるとEtherが引き出せなくなるので注意して下さい。 0xから始まる値がアドレスとなります。

> personal.newAccount("hoge1")
> 0x3f10fa5b63d60f1bc89783a11c415b99fe5aac3a

送金受信用としてもう一つアカウントを作成します。

> personal.newAccount("hoge2")
> 0xf7637d91ab359f567e97e901bf4ef75142fb6e96

ここで作成されたアドレスの情報はkeystore配下に格納されています。
以下ファイルを移動する事で別のノードへアドレスを移動することができます。

root@943656414d81:/# ll eth_private_net/keystore/
total 16
drwx------ 2 root root 4096 Aug 12 15:49 ./
drwxr-xr-x 5 root root 4096 Aug 12 15:49 ../
-rw------- 1 root root  491 Aug 12 15:49 UTC--2017-08-12T06-49-18.310228365Z--3f10fa5b63d60f1bc89783a11c415b99fe5aac3a
-rw------- 1 root root  491 Aug 12 15:49 UTC--2017-08-12T06-49-22.989639328Z--f7637d91ab359f567e97e901bf4ef75142fb6e96

マイニング

以下コマンドでマイニング開始/終了が行われます。

> miner.start()
true
> miner.stop()
true

暫く待つと最初に作成されたアドレスにマイニング報酬が付与されます。

> eth.coinbase
"0x3f10fa5b63d60f1bc89783a11c415b99fe5aac3a"

> eth.getBalance(eth.coinbase)
9.575e+21

f:id:Yasun:20170812172900p:plain

送金

マイング報酬を持つアドレス 0x3f10fa5b63d60f1bc89783a11c415b99fe5aac3a から 0xf7637d91ab359f567e97e901bf4ef75142fb6e96 へEtherを送金してみます。

送信元アドレスのロックを解除します。

> personal.unlockAccount(eth.coinbase)
Unlock account 3f10fa5b63d60f1bc89783a11c415b99fe5aac3a
Passphrase:
true

10ETHを送金します。実行後にトランザクションのアドレスが発行されます。

> eth.sendTransaction({from: eth.coinbase, to: "0xf7637d91ab359f567e97e901bf4ef75142fb6e96", value: web3.toWei(10, "ether")})
"0x161da21dfe25da7920bd084c33f66863dedac0248dd92ccb84bdd11e09c33e58"

直後に受取側の残高を確認します。

> eth.getBalance('0xf7637d91ab359f567e97e901bf4ef75142fb6e96')
0

この時点ではまだ送金トランザクションがブロックに取り込まれていないため、残高が反映されていません。 マイニングを開始し、残高を確認します。

> miner.start()
> true
> eth.getBalance('0xf7637d91ab359f567e97e901bf4ef75142fb6e96')
10000000000000000000

10000000000000000000wei がアドレスに反映されています。
weiとはetherの最小単位であり、1weiは1etherの10^-18です。

10etherを受け取ったアドレスから5etherを送り返します。

> eth.sendTransaction({from: "0xf7637d91ab359f567e97e901bf4ef75142fb6e96", to: eth.coinbase , value: web3.toWei(5, "ether")})
"0x5e92caf1391a234aefa768dc8dcd32692da4412523c8c97912d3bb4227c9f4aa"

> eth.getBalance('0xf7637d91ab359f567e97e901bf4ef75142fb6e96')
4999580000000000000

5etherに加えて送金手数料として0.00042etherが余分に支払われていることがわかります。

手数料の内訳を確認するため、送金トランザクションの詳細を確認します。

> eth.getTransaction('0x5e92caf1391a234aefa768dc8dcd32692da4412523c8c97912d3bb4227c9f4aa')
{
  blockHash: "0x1e7127bdba210c3a8f75d26e5508dc9ab00a51f1534543670b7b6aedcedd7435",
  blockNumber: 1924,
  from: "0xf7637d91ab359f567e97e901bf4ef75142fb6e96",
  gas: 90000,
  gasPrice: 20000000000,
  hash: "0x5e92caf1391a234aefa768dc8dcd32692da4412523c8c97912d3bb4227c9f4aa",
  input: "0x",
  nonce: 0,
  to: "0x3f10fa5b63d60f1bc89783a11c415b99fe5aac3a",
  transactionIndex: 0,
  value: 5000000000000000000
}

上記で手数料に関係するのは gasgasPrice の値です。

少しややこしいのですが gas とはトランザクション処理時の最大の 手数料値 です。
実際に発生する料金ではなく、最大で発生する可能性のある料金です。
この値は実行されるトランザクションの内容によって変動し、estimageGasメソッドを用いて見積もる事が可能です。

gasPriceとは 1 gasが何weiかを表す値です。
この値は常に変動しており、gasPriceメソッド等を用いて確認することができます。
Ethereum Average GasPrice Chart

上記の場合は、90000(gas) * 20000000000wei(gasPrice) となり、 最大で0.0018etherの手数料が発生する可能性がある、ということになります。

今回はここまで。

最近試しているRails+Reactの構成

最近試しているRails+Reactの構成について。

Rails + React

Rails上でReactを使用する方法は大きく分けて3パターンに分けることができると考えています。

www.openmindedinnovations.com

  1. react-rails 等のGemを用いてRails内で使用する。
  2. frontendディレクトリ等を作成し、一部JS実装部分をRailsから切り離して yarn/npm/webpack 等で管理する。
  3. APIサーバとクライントで完全に分離する。

フロントエンドの実装ボリュームによってどの構成を選択するかが変わってくると思います。

今回の要望

新規Railsプロジェクトを作成する際の要望は以下でした。

  • フロントエンド専任はいない。
  • SPAにしない。
  • なるべくレールに乗りたい。
  • 複雑な箇所、非同期処理の部分はReactを使いたい。
  • Reduxを使うほどの複雑さでもない。でもFlux的な事はしたい。
  • 適宜jQueryも使いたい。
  • ES6を使いたい。
  • JSライブラリの管理はGemでしたくない。

試している構成

検討した結果、現在はパターン2 の構成で試しています。

Railsプロジェクト内にfrontendディレクトリを作成し、npm/webpack/babel でフロントエンドの開発を行い、その成果物をreact-railsでDOMにマウントしています。

frontend/
├── package.json
├── src
│   ├── components
│   │   ├── hoge-container
│   │   │   └── index.js
│   │   └── huga-container
│   │       └── index.js
│   └── entry.js
└── webpack.config.js

react-railsを使用してDOMにマウントするため、各コンポーネントをグローバルから参照できるようにしておきます。

frontend/src/components/hoge-container/index.js

import MicroContainer from 'react-micro-container';
import React, { Component } from 'react';

export default class HogeContainer extends MicroContainer {
  constructor(props) {
    super(props);
  }
.....
}

frontend/src/entry.js

import HogeContainer from './components/hoge-container';
window.HogeContainer = HogeContainer;

webpackので依存関係を解決したjsファイルを/app/assets/javascripts/配下に配置します。

app/assets/javascripts/
├── application.js
├── cable.js
├── channels
└── entry.bundle.js

View内で react-railsのヘルパーメソッド react_component を使用してマウントします。

....
<%= react_component('HogeContainer') %>
....

Flux的なこと。

react-micro-containerを利用しています。

GitHub - hokaccha/react-micro-container: Micro framework for React

所感

RailsとReactの恩恵をどちらも受けれるので、フロント実装が多くないプロジェクトならやっていけるのではないかなと感じています。

部分的にReactを導入できるので今回のようにフロントエンジニア不在の環境下でも現実的な気がしています。

Rails5 + ES6 + React + react-router + axios + CSS Modules でTodoアプリを作った。

前回 Angular2で作成したTODOアプリのReact バージョンを作成しました。

作ったもの

f:id:Yasun:20170225194059p:plain

todo-rails-xxx-js

構成

todo-rails-xxx-js/front/react-ver at master · yassun/todo-rails-xxx-js · GitHub

React

Angular同様に公式のチュートリアルがとても充実していました。

Tutorial: Intro To React - React

ライフサイクルについてはコチラの記事がとても参考になりました。

React component ライフサイクル図 - Qiita

react-router

React.jsのシンプルなルーティングライブラリです。

こちらも公式チュートリアルがあります。 GitHub - reactjs/react-router-tutorial

axios

APIとの通信時にAngularの場合はhttpモジュールが用意されているのですが、 Reactの場合は自分でライブラリを選択する必要があります。

調べた結果、候補として superagentaxios が挙がりました。

GitHub - mzabriskie/axios: Promise based HTTP client for the browser and node.js

GitHub - visionmedia/superagent: Ajax with less suck - (and node.js HTTP client to match)

今回はAngularのhttpモジュールに似ているという理由で axiosにしました。

CSS Modules

CSSモジュール ― 明るい未来へようこそ | プログラミング | POSTD

Reactと組み合わせることでCSSコンポーネント単位で管理することができます。

今までBEM記法等の命名ルールで行っていたことをwebpack(style-loader, css-loader)で自動的に行ってくれます。

今回のようにデザインテンプレートを使用している場合でも、 グローバルで使うために宣言されたクラスとローカルだけで使いたいクラスがコンポーネントを見た際に解かる利点がありました。

その他

css/jsのbundleにwebpack、ES6のコンパイルにBabelを使用しました。

まとめ

今回の構成は何かを作る際に第一候補として考えたいと思ってます。

その際にはRails 5.1 でもJSに関する変更点が多く入っているので、この当たりも合わせて試していきたいです。 weblog.rubyonrails.org

次回はVue.js と Flowtypeを試す予定です。