仮想通貨 技術研究所

仮想通貨 技術研究所

実際に手を動かすことを重視した仮想通貨のHow toブログ

SolidityでDapps作ってみた | イーサリアムブロックチェーン上にコントラクトを生成して叩く【前編】

f:id:tetsuyaimagawa:20180103222759p:plain

あらすじ

ブロックチェーンでプロダクト作ってICOしたい…というお問い合わせは昨年死ぬほど頂きましたが

実際にブロックチェーン使ってアプリをがっつり開発したことがないので、

ポケモンのパクリでも作ろうかと、ファッション感覚で始めたら、結構手強かった。

(既に開発されたポケモンのパクリ↓)
Etheremon - Decentralized World of Ether Monsters


三が日が四日あれば間に合ったのに…
アプリについては【後編】で書く。


ICOしたい方々に一言

以前も書いたが、トークンセールするまでに技術的に難しい話はいらない。
tetsuyaimagawa.hatenablog.com

ビジョンだけ明示して、プロダクトはセールが成功してから考えれば良い…と思って行動した人たちが殆どだろう。
ICOしたい人は↑の過去記事の方をどうぞ。


通常の3倍単価がつくというブロックチェーンエンジニアを志す人は、続きをどうぞ。


gethの設定からマイニング開始まで

ネットに良記事は散らばってるので、SOFにダイブしないとわからなかったところを重点的に書く。
geth必須。

$ brew tap ethereum/ethereum
$ brew install ethereum

(環境はMacです)

アカウント作成

$ geth --datadir ディレクトリ名 account new

WARN [01-03|21:31:14] No etherbase set and no accounts found as default
Your new account is locked with a password. Please give a password. Do not forget this password.
Passphrase:
Repeat passphrase:
Address: {37b6ae0c0860d9e36624c51c67de29e7db556b6d}

パスワードを2回ぶっこむと、アドレスが戻ってくる。これの頭に0xをつけたものがウォレット的なアドレスになる↓。
0x37b6ae0c0860d9e36624c51c67de29e7db556b6d
パスワードはロック解除するときに使うので忘れない。

2つあると便利なのでもう一個作る。パスワードは一緒でよい。
ディレクトリはブロックのデータとかアカウント情報等が入るもの。

ここでコンソール入ったり、マイニングしたりしないのが重要。先にgenesis.jsonを作って所持金を定義する。

genesis.json作成

jsonファイルを作る↓サンプル。

{
    "config": {
        "chainId": 4580708,
        "homesteadBlock": 0,
        "eip155Block": 0,
        "eip158Block": 0
    },
    "difficulty": "200",
    "gasLimit": "2100000",
    "alloc": {
        "37b6ae0c0860d9e36624c51c67de29e7db556b6d": { "balance": "300000000000000000" },
        "e73ce4e168f59bc54cbb33e893add21fefef3e3d": { "balance": "400000000000000000" }
   }
}

chainIdはイーサのネットワークIDで、ノリで適当な値を入れる
1がモノホンのイーサで、2がイークラ…と言ったように、使われているものを避けるため、長めに入れる。
参考:go ethereum - How to select a network id or is there a list of network ids? - Ethereum Stack Exchange

difficultyは小さいほどマイニングがサクサク行くが、200にしたら速すぎてコンソールがksk状態になったので、もっと増やしてもよいだろう。
allocの中に、アカウントと初期の金額を入れる。
単位はweiなのでご注意を。1wei = 0.000000000000000001ether


f:id:tetsuyaimagawa:20180104005751p:plain


創生 -genesis- する

$ geth --datadir さっきのディレクトリ --networkid 4580708 --rpc --rpcport 8545 --rpcapi "web3,eth,net,personal" --rpccorsdomain "*" --rpcaddr "localhost" --nodiscover <span style="color: #dd830c"><b>init genesis.json</b></span>
  • --datadir: データディレクトリの場所
  • --networkid: jsonのchainIdと同じもの
  • --nodiscover: ノードを探索しないようにする
  • --rpc: HTTP-RPCサーバを有効にする
  • --rpcport: ポート。デフォが8545なので、書かなくてもよい
  • --rpcapi: 受け付けるインターフェイスの種類。"admin, debug, eth, miner, net, personal, rpc, txpool, web3"が選べて、デフォは "eth,net,web3"
  • --rpccorsdomain: クロスドメインの設定をコンマ区切りで入れるものだが、"*"でよい
  • --rpcaddr: 基本localhost。デフォもそうなので書かなくてもよい

下記のような結果が出てくる。

WARN [01-03|20:43:00] No etherbase set and no accounts found as default
INFO [01-03|20:43:00] Allocated cache and file handles database=/Users/ユーザー名/ディレクトリ/geth/chaindata cache=16 handles=16
INFO [01-03|20:43:00] Writing custom genesis block
INFO [01-03|20:43:00] Successfully wrote genesis state database=chaindata hash=614a31…9df7ba
INFO [01-03|20:43:00] Allocated cache and file handles database=/Users/ユーザー名/ディレクトリ/geth/lightchaindata cache=16 handles=16
INFO [01-03|20:43:00] Writing custom genesis block
INFO [01-03|20:43:00] Successfully wrote genesis state database=lightchaindata hash=614a31…9df7ba

コンソールにログイン

$ geth --datadir さっきのディレクトリ --networkid 4580708 --rpc --rpcapi "web3,eth,net,personal" --rpccorsdomain "*" --nodiscover <span style="color: #dd830c"><b>console</b></span>

アカウントのロック解除

アカウントの確認
personal

{
listAccounts: ["0x37b6ae0c0860d9e36624c51c67de29e7db556b6d", "0xe73ce4e168f59bc54cbb33e893add21fefef3e3d"],
listWallets: [{
accounts: [{...}],
status: "Locked",
url: "keystore:///Users/ユーザー名/ディレクトリ/keystore/UTC--2018-01-03T12-31-24.935720000Z--37b6ae0c0860d9e36624c51c67de29e7db556b6d"
}, {
accounts: [{...}],
status: "Locked",
url: "keystore:///Users/ユーザー名/ディレクトリ/keystore/UTC--2018-01-03T12-31-44.033448000Z--e73ce4e168f59bc54cbb33e893add21fefef3e3d"
}],
(中略)
}

status: "Locked" になっているとコントラクト作成や送金ができない。
コンソール入らなくても見れる。

$ geth account list

(他の引数省略)

ロック解除

コンソールに入った状態で、以下実行。

> personal.unlockAccount(eth.accounts[0], "アカウント作成時に決めたパスワード", 0)

解除できるとtrueが戻ってくる。

eth.accounts[0]は一番上のアカウントなので、この例では "37b6ae0c0860d9e36624c51c67de29e7db556b6d"にあたる。
3つめの引数0は、ロック解除する時間で、何も入れないと300秒になる。0にすると解除されっぱなしになる。

ちなみに、geth実行時に解除して入る方法もある。

$ geth --unlock "0x37b6ae0c0860d9e36624c51c67de29e7db556b6d"

(他の引数省略)
0xつける。

マイニング開始

コンソールに入った状態で

> miner.start()

と入れると開始する。

INFO [01-03|21:22:39] Updated mining threads threads=0
INFO [01-03|21:22:39] Transaction pool price threshold updated price=18000000000
null
> INFO [01-03|21:22:39] Starting mining operation
INFO [01-03|21:22:39] Commit new mining work number=1 txs=0 uncles=0 elapsed=8.06ms


しばらく待つ。10分かかったりするらしい。

マイニングの報酬が入るアドレスは
eth.coinbase

で確認可。

ちなみに止めたい時は
> miner.stop()
ハッシュレート(1秒ごとの計算量)を見るには
> miner.getHashrate()
マイニングができてるかチェックするには
> eth.getBlock("latest").number

が0より大きくなっているか確認する。
eth.getBlock(ブロック番号) でブロックの詳細が見れる

> eth.getBlock(0)

{
difficulty: 200,
extraData: "0x",
gasLimit: 2100000,
gasUsed: 0,
hash: "0x074882667b15c6b8840b2bda8e3b031c6a096d00846e24c3fe94d704fb283c5a",
logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
miner: "0x0000000000000000000000000000000000000000",
mixHash: "0x0000000000000000000000000000000000000000000000000000000000000000",
nonce: "0x0000000000000000",
number: 0,
parentHash: "0x0000000000000000000000000000000000000000000000000000000000000000",
receiptsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
sha3Uncles: "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
size: 505,
stateRoot: "0x44eb684aaa2eb1a15eca07a322f3bd0f7785dedb65fb445f76441a1d6273f7fe",
timestamp: 0,
totalDifficulty: 200,
transactions: ,
transactionsRoot: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
uncles:

}

コンソールに入らないでマイニングする場合は
$ geth --fast --cache=1024

fastとcacheは早くなるおまじない的なもの
(他の引数省略)

ヘッダーしか落とさない場合は

$ geth --syncmode "light"

(他の引数省略)

Browser-Solidityを入れる

gethを起動した状態で行う。

https://github.com/ethereum/browser-solidity/archive/gh-pages.zip

↑解凍してindex.htmlを開くと
f:id:tetsuyaimagawa:20180104120820p:plain
こんな画面が出てくるので、EnvironmentでWeb3 Providerを選択する。

f:id:tetsuyaimagawa:20180104120817p:plain
--rpcaddrと
--rpcportに対応するものを入れる。デフォはlocalhost:8545。

f:id:tetsuyaimagawa:20180104120814p:plain
アカウント一覧と、最初に配分した金額が出てくる。

コントラクトを書く

↑画像のUntitled.sol みたいなサンプルを入れておく。
Solidityの文法とかはアプリの話をまとめるときに書くので本記事では割愛。

画像のソースは↓。

pragma solidity ^0.4.0;
contract getset {
    int i;
    function get() returns(int){
        return i;
    }
    function set (int x){
        i = x;
    }
}

f:id:tetsuyaimagawa:20180104121611p:plain

Createボタンを押すと、pendingになる。
マイニングしないと処理されないので、マイニング止めてる場合は、再びminer.start()

> INFO [01-04|11:59:33] Submitted contract creation fullhash=0x7a23d47774aa2b4336ee5da53df8a7c8d0e1fdf94698ef286ff88fc4c7168231 contract=0x682c87969b92b292514c5dfa0ef18308384e33c3
INFO [01-04|11:59:47] Successfully sealed new block number=300 hash=a60ea7…d672af
INFO [01-04|11:59:47] 🔨 mined potential block number=300 hash=a60ea7…d672af<<

f:id:tetsuyaimagawa:20180104132123p:plain

こんな感じでコントラクトが生成される。

Gas limit exceeded 問題

Gas limit が exceededとか言われたら
remixのgas limitを

> eth.getBlock('latest').gasLimit

と同じ値にする。

コントラクト実行

f:id:tetsuyaimagawa:20180104135418p:plain

  1. get
  2. 1をset
  3. get

の操作をしてみる。
↓コンソールにトランザクションが送信されたことが表示される。

INFO [01-04|13:21:50] Submitted transaction fullhash=0xe9e8fb76ab3bb58e0bd1508423842175e26ca9b78b933e19befa88eefb4c9d85 recipient=0x64f110cd4b63d9c105590f42bc1af59d637500cd
INFO [01-04|13:21:55] Submitted transaction fullhash=0x4cddf01f98d2c07b10d9ccebadb1cb28a2f02ea22d3d337a1888fe41869171a1 recipient=0x64f110cd4b63d9c105590f42bc1af59d637500cd
INFO [01-04|13:21:58] Submitted transaction fullhash=0x59432b0fac16510c1ff5ecd4602b23c76082c69cb4875b3d5862abe49f24a474 recipient=0x64f110cd4b63d9c105590f42bc1af59d637500cd


マイニング中であれば、トランザクションがそのまま処理される↓。
f:id:tetsuyaimagawa:20180104135532p:plain



この後の動き

↑のgetやsetをjsから処理できるようにすれば、Dappsは完成である。
【後半】に続く…

Kaggle はじめてみた | メルカリのビッグデータでデータサイエンス

f:id:tetsuyaimagawa:20180102222030j:plain

これまでのあらすじ

昨年は「どの仮想通貨が上がるんですか!?」
に霞んでいたが、

聞かれてうざい質問トップに名を連ねる
「データサイエンティストになるにはどうすればいいんですか?」

を皆さんは覚えているだろうか。

そう、私はデータサイエンティストと呼ばれる人を捕まえては、同じ質問を繰り返していた。
彼らの答えは決まって「かぐる…とか…やればいいんじゃないかな…(ボソ」

だった。かぐるって何。

今回のあらすじ

2018年だから Kaggleデビューする。
Kaggleは言うまでもなく、企業が"お題"を出し、データサイエンティストがそれを解くプラットフォームだ。
解くと懸賞金が貰える。

簡単に言うと、リーマン予想説いたら千円あげる…みたいな話である。

難しく言うと、ルフィ捕まえたら5億ベリーあげる…みたいな話である。

さっそく覗いてみる

f:id:tetsuyaimagawa:20180102223445p:plain





コンペティションのページに飛んでみる。




f:id:tetsuyaimagawa:20180102223547p:plain





おや、日本最後の希望と謳われたユニコーン・メルカリがいるではないか。


日本円にして、懸賞金1,000万ベリー。
一生 一年遊んで暮らせる金だ。

1,300チームが鎬を削っているらしい。金額結構高めだな…


データを落とす

お題は「中古品の販売価格予想」だそうで
学習データと、テストデータが用意されているので、オーソドックスにTensorflowとかにぶっこんでコネコネすればよさそうである。(分析する気ゼロ)


↓がテストデータで、学習データはこれに価格を加えたもの。
f:id:tetsuyaimagawa:20180102224740p:plain



商品名とカテゴリから価格を予想するのか…



テキストマイニング…アウトオブ専門外だ。



Coach bag とか、bagの適正価格出して、Coachだからマシマシとかするのか?…気が遠くなる。



というか、カテゴリの平均値の方が、下手なコネクリアルゴリズムより、強いのではないか… Simple is best 論。


データ分析

1カテゴリあたりのアイテム数数えてみる。
f:id:tetsuyaimagawa:20180102225624p:plain

…十分ありそうじゃないですか。意識高い系だから下は見ない…。



…カテゴリ平均を取ろう…(白目


JupyterLab

データサイエンスしてる感が出て安心する、安定のJupyterで作業する。
(導入方法などはこちら↓)

tetsuyaimagawa.hatenablog.com



〜5時間後〜



f:id:tetsuyaimagawa:20180102230323p:plain
f:id:tetsuyaimagawa:20180102230331p:plain



はい、平均をもって、カテゴリの適正価格とした結果がでました。



なんのAI感もない、Pandasのお勉強です。



提出フォーマットが↓なので、揃えました。
f:id:tetsuyaimagawa:20180102230523p:plain



提出

よし・・・1,000万円はすぐそこだ。


機械学習とかしてた方々、モノの価値はカテゴリで決まるんですよ。



”提出” ボタンを押す。




・・・




ん?




f:id:tetsuyaimagawa:20180102230924p:plain








ふおお導出過程も出さなければならないやんこれ…




こんなもの出したら最期、二度とAIの会社やってます…とか言えなくなるやんけ…



まとめ

大事なのは結果ではない、過程なのだ…
大事なのは回帰係数なのだ…



次回「この世の全ての事象は、線形である…」に続く。