ヒット作

自画自賛の気持ち悪いエントリ。

ブログエントリやLTで、大体年一ぐらいでホームランを打つが、それ以外は箸にも棒にもかからない、そんなペースでこすく信頼貯金を維持している。
のが例年だったのだけど、今年はLT3発にブログエントリ1発当てている。見かけの打率は今年は上がっているのだけど、11月12月に連発していて、なんていうか北の勇者の生命の剣っぽくて命を燃やしてるだけなのがやばい。燃え尽きそう。

どれも共通してるのは、わりと引くぐらい時間をかけてることかなー 時間をかけてもハマらないことはもちろん多々ある。ブログ書くのは好きだけど文章得意ではないし練りに練る。発表はもっと苦手なので自信ありアンド練習ちゃんとした時以外はボロボロ。

過去ヒット作一覧

今見なおしても良作揃いだ。そして年一ペースと思ってたのは自分に都合良い錯覚で数年に一回っぽい。

ハッカソン素振り成果

マネーフォワードのAPIを提供したハッカソンに技術サポート兼デモサーバーのおもり兼メンター代打として参加してきた。

OAuth2といっても、使い方までいたれりつくせりのtwitter/facebook/github あたりのライブラリしか使ったことなかったので、一定時間で作れる範囲がだいぶ違うなーという感想。そりゃ世間のハッカソンも、ハッカソンという名のチーム戦・短納期デスマーチになるわ。

OAuth2API経由で触ったことないから、素振りしてみないと全部わかりませんで話にならんだろう、ってことで素振り。
ただ、ギョームに追い詰められて、当日含めてもtoken取るところまで疎通確認するのでやっとだった。

ハッカソン後日にようやく出来て、おもしろおかしい成果物animetion gifが撮れてほっとした。
game-with-transactions
おもしろおかしく書いたエントリ: Moneyforward APIで車ゲームを作る | Money Forward Engineers’ Blog

構造を知っている、入出金履歴のデータを引っ張ってくる。
日にちごとにサマリーして、ない日は0で埋める。
それを元データにして座標プロットして、phaserjsのexampleの座標データと差し替える。
たったこれだけやるのに、56 commits / 4,571 ++ / 398 —

仕様はOAuth2でわかりやすい、データ取りに行くはじめのところはsimple-oauth2のexampleからコピペ、ゲーム部分はphaserjsのexampleからコピペ、でほぼ何もしてないのに結構時間はかかるわ、$40の有償プラグイン使うわで、しんどかった。
デモサーバー自体は多分クローズドだから、サーバー立てておいてみんなに遊んでもらうわけにもいかないし。
遊べたとしてもみんなデモデータだからなー。

作り始める時には意図しなかったいいオチが勝手についてくれた幸運と、読んでくれた人は楽しんでくれたみたいなので救われる。

成果物 https://github.com/sanemat/purple-finch とpackage.json(最後)。

ライブラリは提供していないので、simple-oauth2を使い、それを使ってるライブラリを見ながらぱくる。
なぜか手元でdirenvが動かなくて、dotenv使うことにしたのがはまったとこ。
テンプレートにmarkojs使ってみたのは初めて。
https://github.com/marko-js/templating-benchmarks pugかejsか使おうと思ってたところでこれ見て使ってみることにした。
node --inspect --debug-brkってのもおもしろい。サーバー起動すると、websocketのurlが出て、それをchromeで開くと一行目で止まる。
ブレークポイントを入れて、play!
ゲームエンジンphaserjsも、なにかゲームエンジン使ってみたかったので多少は満たされた。カジュアルゲー作れるぐらいの瞬発力は欲しいもん。
github pagesに置いて動くようにしたいところだけど、implicit flowじゃないからだめなんかな。
aws lambdaやamazon api gatewayかそういうの使えばgithub pages + それで出来そうな気がしたけど、気がするところまで妄想しただけで確認していない。こういうのAmazon API Gateway の Custom Authorizer を使い、OAuth アクセストークンで API を保護する – Qiita かな。

package.json

{
  "dependencies": {
    "dotenv": "^2.0.0",
    "express": "^4.14.0",
    "marko": "^3.12.1",
    "moment": "^2.17.0",
    "moment-timezone": "^0.5.9",
    "request": "^2.79.0",
    "request-promise-native": "^1.0.3",
    "simple-oauth2": "^1.0.1",
    "urijs": "^1.18.3"
  },
  "scripts": {
    "start": "node -r dotenv/config app.js",
    "debug": "node --inspect --debug-brk -r dotenv/config app.js",
    "lint": "eslint .",
    "lint:fix": "eslint --fix .",
    "test": "ava",
    "verify": "npm run lint && npm test"
  },
  "devDependencies": {
    "ava": "^0.17.0",
    "eslint": "^3.10.2",
    "eslint-config-airbnb": "^13.0.0",
    "eslint-plugin-import": "^2.2.0"
  }
}

ビットコインとか勉強会 2 で話してきた #暗号通貨読書会

ビットコインとか勉強会#2 – connpassで20分もらって話してきた。

前口上ここから

bitcoin関連で仕事をしているみなさん、ってびりあるさんから話がありました。
ごめんなさい一ミリもしてないです。
働いてるのはマネーフォワードという会社で、普通に家計簿のrailsアプリ書いてます。

今日は2つ話を持ってきました。資料は #暗号通貨読書会

誰向けになんの話するかって言うと、二ヶ月前の俺向けですね。
bitcoinに興味あるけど、bitcoinさわったことない。
mastering bitcoin読んでみたけど、よくわかるようなわからないような。
bitcoin読書会来てみたらAsicBoost マークルルートのコリジョンの話、より効率的にマイニングできるかもしれないの論文の話してて全然わからんぞ、みたいな。
なので、まあこういうアプローチもあるんじゃない的な。

ぼくは自分でやってみないとわからなくて、やってみて学んだので、みなさんがやってみなくても持って帰れるようにしました。

WalletのUXTO (未使用残高)をwallet実装無しで計算するツールを作ろうとした。
現在進行形で作りかけ。
結論は「既存のWalletを使え」なんだけど、そのツールを作る過程でbitcoin HD Walletのしくみを理解してきたので、まとめました。

質問は雑談形式でどんどん投げて話止めてください。

前口上ここまで

発表中反応してくれた方、質問してくれた方、質問をまるなげして答えてくれた方、懇親会で話聞いてくれた方、ちょこちょこいらっしゃったので、自分の発表が手探り感満載だった割にはよかったんじゃないかなーと自画自賛しています。

資料よく読むとろくに実装面ではまだ手が動かせていないというのがわかるので、次次回ぐらいにはちゃんと実装を持っていって、感想を話します。

Rubyのハテナってbool返すんじゃないの?

rubyのNumeric#nonzero?ってself | nilを返すんだ。ハテナってbool返すんじゃないの?
って聞かれた。
自分もこの前までそう思ってたんだけど、たしかそうじゃない便利ケースがAPIデザインケーススタディに出てきた、
ってうろ覚え知識を披露した。なにの時便利だったかは覚えてなかったので、ふわふわ。
なので調べた。

instance method Numeric#nonzero? (Ruby 2.3.0) http://docs.ruby-lang.org/ja/2.3.0/method/Numeric/i/nonzero=3f.html

Rubyではnilとfalseが偽、それ以外の値は全て真とみなされるので、このInteger#nonzero?の振る舞いは、0に対して偽、
それ以外に対して真を返すものと言えます。つまり名前に反する動作というわけではありません。
(snip)
意外な動作は学習コストを上げるので、理由がなければ避けるべき
(snip)
Enumerable#sort メソッドに与えるブロックの中の記述を簡単にするため。
APIデザインケーススタディ 田中哲

enum.sort {|a, b| c = a.x <=> b.x; c != 0 ? c : a.y <=> b.y }
が
enum.sort {|a, b| (a.x <=> b.x).nonzero? || a.y <=> b.y }

と記述できる。

具体的には自分でハテナつきメソッドを書くとき、気を使うときは、
わざわざtrue/false を返すように、最後絶対bool返すぞ!って foo ? true : falseって書くことはある。
どこかで何かを読んで、しかも最近、必ずしもそうしなくて良くて、
truthy/falsy 返すだけで名前に反するわけではない、と何かで読んだ。
そのなにかがAPIデザインケーススタディだった。

別のものを返すことで使いやすいケースだったりそういう使い方しかないケースでは、bool以外が返ることがある。
だったはずだから、ドキュメントにあるはず。

documentみていく。
ObjectやEnumerableにはbool返すのしか生えてなかった。

Numeric#nonzero? -> self | nil
Encoding.compatible?(obj1, obj2) -> Encoding | nil
Kernel.#autoload?(const_name) -> String | nil

だんだん見ていくとだいたいboolなんだけど、いくつかboolじゃないものもあった。
上記は全部ではなく、ぱっと見て出てきたもの。

ほぼだいたいboolだがそうでもないのもいるから、truthy/falsyで判別すればびっくりしなそう。

bitcoin readonly wallet

bitcoinでreadonlyなwalletを使いたい。
リードオンリーじゃなくてもいいけど、レジ端末的なところには秘密鍵なし。
可能なら、取引ごとに異なるビットコインアドレスを生成して表示。
まあ無理でも、ウォレット単位の残高を見たい。見せたい。

結論として、公開鍵あれば読めることはわかった。ただその公開鍵公開していいかはまだよくわかってない。

規格

mastering bitcoinのHDウォレット周り読んだり、ググったりしたがいまいちピンとこない。
また、readonly address というのが、規格もあり実装しているクライアントもある。
しかし、addressをreadonlyにできても、アドレスは使い捨てるほうが良いわけで、だいぶナンダカナー感がある。

xpubで始まる master public key を持ち運べば良さそうに見える。
ただ、copay2.6.0でmaster public keyをimportする口がなさそう?。
なお、electrum 2.6.4にcopay2.6.0からwalletのmaster public keyをimportすることができた。よっしゃよっしゃ。

copayの実装

パスワード制限

いまいちなほうから。

copayは送金時にパスワードを必須にすることができる。
なので、レジ端末側に秘密鍵を入れ、送金するときにパスワードを要求することで、一応守れる。
あとMnemonic code吐き出しも設定から潰せるので、何かの時にだいぶ危ない以外は、目的が多少達成できる。
walletのexportも潰さないとダメな気がするけど、潰せるのかな。

export wallet, Do not include private key (独自実装?)

export wallet時にadvanced optionが設定できる。
秘密鍵含むことなしにexportできて、それにパスフレーズをつける。独自実装かな?

このファイルを別のcopayでimportできる(試したのはdesktop -> android)。
送金しようとすると、readonly側のウォレット的には送信のproposalを出し、秘密鍵持ってる側のウォレットに、approveの画面が出てくるところ。
このproposal機能はじめ独自実装かなと思ってたけど、独自実装じゃないっぽい。
master public key でimportしたreadonly walletのelectrumから送ってみたら、unsignedのtransactionが飛ぶ。
copay側でそれを拾って自分がsign出来そうだったらなんか出すんだ。かしこい。
そしてrejectしたらなかったことになる。かしこい。

master public key

ElectrumはWallet -> Master Public Keysから。
copayは歯車 -> Advanced -> Wallet Information -> Extended Public Keysから。
xpubではじまるやつ。

前述だけど、copayで出したpublic keyをelectrumでimportできた。ほかは試してない。

このmaster public keyがどの強度のやつなのかはよくわからない。

どの強度is何

まんまmastering bitcoinからの抜粋

強化子公開鍵導出(hardened child key derivation)
もし拡張公開鍵の利便性を使い、しかもchain codeの漏洩リスクを回避したいのであれば、
通常の親(親公開鍵)ではなく強化された親(親秘密鍵)からから拡張公開鍵を導出すべきです。
ベストプラクティスとしては、マスターキーの1階層目の子供を常にhardened derivationを通して
導出されるようにしておくことが良いでしょう。

unsigned

unsignedで送れてしまうから、うっかりするとうっかりしそう。

web api

web apiで取れるのかな。少なくともココにはなかった。
https://blockchain.info/api/blockchain_api

やりたかった定点観測

なんか作ったら or 既存のものでreadonlyのwallet定点観測できないかなーと思ってた。
親公開鍵を預ける/預かることがどのくらいリスクなのかまだよく理解してないから、まだあれ。

公開鍵を使って、ビットコインアドレスが生成できる。
また、トランザクションから自分のウォレットに属するかがわかってしまう。
秘密鍵/公開鍵という響きだけから感じる公開鍵は公開していいもの、という印象よりだいぶうかつに公開するとまずそうな気がする。

APIデザインケーススタディ読んだ

ようやく積んでた本を読んだ。読んだというか、途中まで読んでてきつくなったのでパラパラ眺めてどうにか一周終わらせた、ってかんじ。話の内容は多分面白くて書いてある中身もきっと面白いんだけど、対象に今の自分があまり興味がなかったから仕方ない。

APIデザインケーススタディ ――Rubyの実例から学ぶ。問題に即したデザインと普遍の考え方 | Gihyo Digital Publishing … 技術評論社の電子書籍

第1章─I/O, 第2章─ソケット, 第3章─プロセス, 第4章─時刻, 第5章─数,文字列 とあって、要は自分が一番好きなプレゼンの使いやすいライブラリ API デザイン. 日本Rubyカンファレンス2006 コレと近い内容なんだけど、I/O, ソケット、プロセス、時刻まであんまり興味がないので、その、あれ。

URI.encode_www_form出てきてやっと興味あるとこキタ! と思ったらそれが最後でしょんぼり。

なので、あとは思い出したことを並べる。

使いやすいライブラリAPIデザインから、自分は強烈な印象を受けていて、過去の自分の名作 https://github.com/sanemat/slip/blob/b49f8a609741c29054cacf0fe84a2a6d377bba53/slip.rb#L14 に色濃く出ている。

脱線すると、httpライブラリの好みの変遷としては、何使ってたか覚えていない -> 感銘を受けて open-uriに -> httparty で楽して楽しく -> REST厨なのでrest-client -> faraday でインターフェースを統一するんだ -> net-http やっぱり標準ライブラリだね、あとeasy, simpleだとsimpleよりのがいい イマココ

コレも好き。matz を説得する方法. RubyKaigi2008

さがしてまわっちゃったけどここにあった。Publications of Tanaka Akira

MASTERING BITCOIN二周目と商店

mastering bitcoin一周目が途中でさっぱりわからなくなったのでMastering Bitcoin一周目とbitcoin買うまで | 實松アウトプット、社内商店のとなりにbitcoinでしか買えない商店を開いて、実験してみた。

50-100円ぐらい単位で消費したい社内商店だとtransaction feesにまけちゃうなーとか、なかなかたのしい。一般的なモバイルクライアント?だとそこまでtransaction feesけちれない。

二周目はコレがこうなって、とblockchain.info みながら、なるほど、なるほどと読めた。秘密鍵なしにビットコインアドレスの残高は取れるけど、秘密鍵なしにウォレットの残高取れないと、決済とか資産管理とかつらいんじゃないかなーと思うけどどうなんだろう。

bitcoinで少額を送る

From electrum 2.6.4 (desktop)
8000bits送ろうとしたら、fee 40bitsでは送れなくて、50bitsかかった。

From Mycelium (android)
2000bits送ろうとしたら、41.46bitsかかった。

From Copay (android)
2000bits送ろうとしたら36bitsかかった。

一度8000bits受け取って、それを原資に2000bitsおくると、お釣りの計算できるまで5964bitsあるわけではなく、
0bitsになるんだ。なるほど…

Copay androidはよくあることだけどnexus 5xでカメラが逆になる。
phonegap のplugin?のバージョン上げる必要がありそうだ。

bitcoinとmoneyforward

moneyforwardでbitcoinはアグリゲーションできる。できるのだけど、1ビットコインアドレスあたり1金融機関扱いになってしまうので、実用性があんまりない。せめて1walletが1金融機関扱いじゃないとなあ。もっというと、1walletはビットコインという金融機関下の、普通預金とか定期預金とかそのカテゴリーでほしい。

現状こんなかんじになってしまう。

Screenshot from 2016-08-14 16-48-46

bitflyerだと1金融機関にまとめられる気はするが、取引所においておくってのナンセンスなのでなし。

Mastering Bitcoin一周目とbitcoin買うまで

Mastering Bitcoinの日本語版がCC by SAで読めるTranslations of Mastering Bitcoin | Mastering Bitcoinので、読んだ。

一周目、途中でさっぱりわからなくなったが最後までたどり着いた。

翻訳にむむむってところがあれば、ここから直しに行くと良さそう。多分typo直せた気がする。
Mastering Bitcoin | Overview

あとは自分でいじってみたり、alt coinやalt chain作ってみたりしないとわからんな、ということでbitcoinを買った。

1JvMhFUq7BDF1RFxXednUHSVbdvQ4j3RW7 Screenshot from 2016-08-14 00-17-37 送ってみたい人受け取ってみたい人は連絡ください。

ビットコインの保管(ウォレット比較) | Bitcoin日本語情報サイト こういうところ読んだりしつつ、まあたいていこういうのの日本語情報って周回遅れになってること多いので、コレも話半分に見ていく。

ubuntu desktop環境なので、いろいろ困るかと思いきや、Electrum (Pythonベース、GUIも)とCopay(Javascriptベース、nwjs)とで、Electrumはaptで、Copayはファイル伸長するだけで動いた。先にElectrumで環境整えたので、Electrumでやってるが、制限などなければChrome extensionなどあるCopayもよさそう。

スマホ側はandroidなのでMyceliumいれた。iosにはbreadwallet入れたが、breadwalletはまだ試してない。

クライアント側の準備ができたので、早速ビットコインを買う。ビットコインは購入所と交換所がある、などの基礎的なところからふむふむ読んでいく。bitflyer.jp にアカウント作って、銀行口座登録して承認され、住信SBIネット銀行から7000円入金。ビットコインが0.01BTC単位で買えるので、1BTC 61000円ぐらいだったので 0.11BTC購入。取引所に滞空させておく意味はないので、bitflyerの自分のアドレスから、デスクトップの自分のアドレスに送金してbitflyerの出番は終わり。transaction feeはbitflyerが今のところ負担してくれる。日本円端数がbitflyerに残り続けてしまうけど、まあしゃーない。

最小単位は現在のところ1 satoshi。100 satoshis = 1 bits (あるいは1 μBTC)。1000 μBTC = 1 mBTC、1000 mBTC = 1 BTC。
546 satoshis 以下はdustとして送金できない。
1BTC 60000円ぐらいなので、1 mBTC 60円、 1μBTC 0.06円 ぐらい。

よく、手数料安いよ、最高!の文脈でbitcoin出てくることある。ただ、それは相場として情報転送量あたりに値段をつけて、それを処理してもらうので、supereconomyモードでもコレぐらいだよ、ってcopayは表示してる。 165bits/kiB。なので、安い安いとはいっても、少ない額を送金するほど手数料の割合は増す。実際Electrumでは、少なすぎるfeeは弾かれてしまった。800bitsにfee8bitsとかそのくらい。Electrumは圧縮転送サポートしてないからデータでかくなりがち、っての数年前のフォーラムで出てきたけどいまどうかはよくわからない。8000bitsにfee40bitsは送れた。ずっと承認されなかったらどうなるんだろ?とおもうが承認されたので良かった。少額決済はやっぱりまとめないとダメなのかなあ。むー。