蟻地獄

Twitterに書ききれない長めの文とか書くよ

マストドンのOAuth認証でログインできるWebアプリの作り方

マストドンにpixivアカウントとかでログインするほうじゃなくて、自分が作ったWebアプリにマストドンアカウントでログインする機能を付けるほう。 完成品はこちら。 concept-auction.appspot.com

OAuth2準拠のAPIなのでTwitterログインとかとほぼ同じですが、大きな違いが2つあります。

1. ユーザーにドメインを入力してもらう必要がある

Twitterの場合は https://api.twitter.com/oauth/authorize を決め打ちで叩けばよかったんですが、マストドンインスタンスは自由に立てられるので、ただボタンが押されただけだとどのインスタンスにリクエストを投げればよいか分かりません。なので、ユーザーにマストドンインスタンスドメインを入力してもらう必要があります。 というわけでこんな感じのUIになりました。 f:id:mitomemel:20170422143231j:plain

2. client_id/client_secretはインスタンスごとに必要

新規にWebアプリを作る場合、Twitterだと https://apps.twitter.com/ でアプリ情報を登録してclient_id/client_secretを発行してもらっていましたが、マストドンの場合、どのインスタンスのユーザーが来るか分からないので事前にアプリ情報を登録しておくことができません。 ではどうするのかというと、新しいドメインのユーザーがログインしてきたタイミングでアプリ情報の登録もその場でREST APIを叩いて行います。一度発行したclient_id/client_secretとドメインの組は自サイトのDB等に保存しておきます。 大まかな流れは以下の通りです。

  1. ユーザーはドメインを入力してログインボタンを押す
  2. ログインリクエストを受け取ったWebアプリサーバは、まず自サイトに保存してあるclient_id/client_secretをドメイン文字列をキーに検索する。データが見つからなかった場合は指定されたドメインの /api/v1/apps を叩いてアプリ情報を登録し、発行されたclient_id/client_secretを自サイトのDBに保存後クライアントにclient_idを返す
  3. クライアントは受け取ったclient_idをパラメータに指定してマストドンサーバの /oauth/authorize にアクセスする
  4. ログイン画面が表示されるのでメールアドレス/パスワードを入力する f:id:mitomemel:20170422143251j:plain
  5. アカウントへのアクセス要求画面が表示されるので承認を押す f:id:mitomemel:20170422143311j:plain
  6. アプリ情報登録時に設定したredirect_uriが認証コード付きで叩かれるので、Webアプリサーバからマストドンサーバの /oauth/token を叩いてアクセストークンを受け取る
  7. アクセストークンを用いて /api/v1/accounts/verify_credentials を叩いてユーザー情報を入手

ただ、マストドンサーバ側のDBデータがDocker神の荒ぶりによって消えてしまった場合が厄介で、2.で自サイトに以前に保存されたclient_idをマストドンサーバに投げたらそんなclient_id知らねえよって言われてしまうので、再度アプリ情報を登録するみたいなエラーハンドリングが必要になります。うわあめんどくさい。

ちなみに今回はGAE/Goで作ったんですが、マストドンAPIへのアクセスにはgo-mastodonを使わせていただきました*1golang最高!

*1:go-mastodonはまだパスワード認証しか対応していないので、OAuthを使用するには若干手を入れる必要があります

お一人様マストドンはメモリ512MBだと無理

ブロックチェーンはセカンドライフに似ている

あらかじめ言っておくと、これはビットコインってリンデンドルみたいなものでしょとかいう話ではありません。セカンドライフもブロックチェーンもある程度知った上での感想です。

セカンドライフというと、「戦闘が無いMMORPG」とか「広告だらけで中身スカスカ」というイメージが強いと思いますが、セカンドライフを現在の言葉で説明すると、「プレイヤーがMODを自由にアップロードできるサンドボックスタイプのMMO」というのが近いかと思います。

マインクラフトをMMO化したいというのは誰でも一度は思い付く妄想だと思いますが、それに近いものが既にセカンドライフで実現されていました。しかもプレイヤーはMODを自由にアップロードでき、それがサーバに即座に反映されて他人にも影響するというとんでもない仕様です。

こんなすごいものが突然出てきたので、当時セカンドライフを見た人は「第二のインターネットだ」と言って持て囃し、大企業も次々にセカンドライフ内に"支店"を作りました。学術的な研究も盛んに行われ、セカンドライフは世界を変えるかのように思われました。

しかし、セカンドライフは世界を変えませんでした。非常に面白い技術だし、実際に今まで成し遂げることができなかったことを実現しているのですが、所詮は「サンドボックスタイプのMMO」でしかなかったからです。第二のインターネットとなるためにはあまりにも多くのものが欠けていました。

これって最近のブロックチェーンの流行り方にそっくりじゃありませんか?ブロックチェーン界隈の皆様におかれましては、ぜひセカンドライフに学び第二のインターネットとなるよう頑張っていただきたく思います。

ちなみに散々アバターがバタ臭いと言われたセカンドライフですが、最近は日本人受けする容姿もデフォルトで選べるようです。これを機にプレイしてみてはいかがでしょうか?

join.secondlife.com

以上、セカンドライフステマでした:)

3大メガバンクがブロックチェーンではない何かの実証実験をしている

みずほフィナンシャルグループ三井住友銀行三菱UFJフィナンシャル・グループという三大メガバンクが参加したブロックチェーン実証実験の報告書が公開されました。

www2.deloitte.com

システム構成としては、トランザクションを承認するコアノードは信頼できる中立的な機関が担い、各銀行は承認機能を持たないノードでトランザクションの生成およびデータの参照のみを行う、というものです。

実験内容は、銀行間で振込を行うというもので、既存の決済システムとの連携・データ秘匿性など現状問題視されている部分は全てオミットでスループットとデータ完全性を見るだけ、という非常にシンプルな構成となっています。

先日の日本取引所グループが出した報告書と比べるとどうしても物足りなさを感じてしまいますが、一点非常に気になる記述を見つけました。

 p.11 

c. ハードウェア購入費

従来技術では冗長化構成やバックアップセンタ設置により高稼働率を実現しているが、ブロックチェーン技術ではその特性上、これらの措置を施さずに高稼働率を期待できる。また、1 つのシステムで集中的に処理を行う従来技術に対して、複数システムで分散的に処理を行うブロックチェーン技術では、ハードウェアの低スペック化が期待できる。

高可用性は良いとして、ブロックチェーンで負荷分散???

ブロックチェーンというのは、同じデータのコピーを全ノードが持ち、全ノードがそれぞれ検証する、という富豪的な仕組みによってロバスト性を上げるものだと思っていました。負荷分散はブロックチェーンが苦手なものの筆頭のはずで、集中的に処理を行う従来技術よりもハードウェア面で低コストが期待できるというのは考えにくいです。彼らはブロックチェーンではない別の何かを検証していた可能性があります。

ただ私もブロックチェーンについては素人なので、解釈を間違えているのかもしれません。この部分の記述について、どう解釈すれば良いのかわかる方がいましたらぜひコメントを頂きたいです。

Google App Engine と Cloud Datastore だけでオークションサイトを作った

こんばんは!サーバレスしてますか!

Google App Engine (GAE)がなんか最近イケてるとかイケてないとかいう話を聞いて、とりあえず何か小さなサービスを作って試してみようと思ったのですが、どうせ作るなら毒にも薬にもならない掲示板とかじゃなくて罠を踏み倒しそうな感じのが良いと思い、オークションサイトを作ってみました。

concept-auction.appspot.com

データべースはRDBを一切使用せず、Cloud Datastoreのみで構築しています。え、Cloud DatastoreってKey-Valueストアじゃないの?と思うかもしれませんが、実は色々なクエリが使えたりトランザクションが使えたりするので、仮想通貨の受け渡しなんかもわりと真っ当に実装することができます。

ただし、RDBのように扱えるかというとやはりそうではなく、様々な制約があるので、Cloud Datastoreに特化したテーブル設計が必要となります。特にData Consistencyのドキュメントは10回くらい読んだほうが良いです。

Data Consistency  |  Google Cloud Platform

制約はいろいろありますが3行でまとめると、

という感じです。なのでテーブル設計の段階から、トランザクションが必要なデータはルートエンティティにしないようにしたり、1つのエンティティグループへの更新が集中しないような親子関係にするといった工夫が必要になります。1秒1トランザクションという制約はかなり厄介で、今回作ったオークションサイトでも入札の整合性をどうやって保つかで苦労しました。

とは言え勝手にスケールアウトしてくれるというのはとても魅力的で、今回作ったオークションサイトも、アクセスが無ければ維持費$0、何かの間違いでYahoo砲を食らっても無限にスケールする(※ただし予算がスケールするとは言っていない)というのは非常に楽です。

まあそんなこんなで、本当にちゃんとスケールするのか試してみたいのでみんなツイッターで拡散してね!

concept-auction.appspot.com

日本取引所グループがブロックチェーンをぼろくそに言ってる

日本取引所グループ(東証大証の総元締め)がブロックチェーンの実証実験をやるっていうのが以前話題になっていましたが、その結果がついに出ました。ありがたいことになんとレポートを全文無料で読むことができます。
http://www.jpx.co.jp/corporate/research-study/working-paper/tvdivq0000008q5y-att/JPX_working_paper_No15.pdf

そんなに長くないのでぜひ原文を読んでほしいのですが、要点をまとめると以下のような感じです。

実証実験内容

  • コンソーシアム型ブロックチェーン。ノードを持つのは市場管理者・金融機関・株式発行体(要は上場企業)の三者
  • 市場管理者と金融機関が認証処理を行う権限を持つ。株式発行体はデータの参照のみ可能で、書き込みはブロックチェーン外で市場管理者に依頼する。投資家は金融機関に受託して取引を行う
  • 金融機関は自社の顧客以外の取引内容は参照不可。株式発行体は自社の株式の所有者と保有残高以外は参照不可。市場管理者は全ての情報が参照可能
  • コンセンサスアルゴリズムはProof of Workではスループット性能が不足することが予想されたので、3分の2以上の合意を認証の条件とするPractical Byzantine Fault Toleranceを採用
  • スマートコントラクトでロジックを実装

結果

  • 証券市場の取引(注文のマッチング)は集中処理のほうが効率が良く、注文の変更・取り消しも頻繁に発生するのでブロックチェーンには不向き。決済、証券保有者管理、配当などのポストトレード分野では有用かも
  • いちいちスナップショット保管したりしなくても過去の任意の時点の状態を確認できるのは便利。株主に対する権利付与の基準日時を過去の任意の時点に指定したりできる
  • 各ノードのシステム時刻の差、外部データを取得する処理、乱数を用いた処理などの非決定的要因でノード間の差異が生じて認証に失敗する場合がある。これらの処理は証券取引には必須なので大問題。そういう処理を特定のノードだけにやらせるという手もあるが、そのノードが単一障害点となるので本末転倒
  • 先進国の上場株式市場で求められる処理性能は秒間数千〜数万件くらいだが、負荷テストの結果は秒間数十〜百件程度だった。ブロックチェーン実装の開発元のデモで示されてる数値はあてにならない
  • ネックはスマートコントラクトを1件ずつ直列実行しているところ。ブロックチェーンは各ノードが1台構成なのが前提なので複数サーバでの並列処理ができない
  • 秘匿性要件は満たせたが、それはHyperlegderの機能であって他のブロックチェーン実装は未対応のものがほとんど
  • 可用性、データ復旧の容易さは良さげ。ただし前述の単一障害点の問題が無ければの話
  • 単純なITインフラの置き換えによるコスト削減効果は限定的で、どっちかというと過去データの断面取得が可能なことによるビジネスプロセスの改善や、業界横断的にノードを持つことでディザスタリカバリの費用を削減できることに期待
  • ブロックチェーン上のファイナリティはPractical Byzantine Fault Toleranceを採用したことで解決
  • ブロックチェーン外のファイナリティが問題。現行の法律では証券保管振替機構口座振替をもってファイナリティを得ており、ブロックチェーン上の記録を真正とするには法整備が必要
  • 現状日本円はブロックチェーン上に記録されていないので、資金決済のファイナリティについては一工夫必要。そもそも中央銀行がデジタル通貨を発行すれば全部解決するがせやかて工藤

以上のように、実際作ってみたら問題がぼろぼろ出てきました、という内容となっています。なので結論としては過大評価でしたね、となると思いきや、「V. まとめ」のセクションを見てみると・・・

DLTを金融市場インフラに活用した場合、いくつかの課題があるものの、新たなビジネスの創出、業務オペレーションの効率化、コストの削減等に寄与し、金融ビジネスの構造を大きく変革する可能性の高い技術であることが分かった。

ええぇぇぇ〜!「いくつかの課題」どころか、わりと根本的な欠点をさっきまでガンガン挙げてましたやん!可能性の大安売りや!

ここだけ別の人が書いたんですかね……
過去データの断面取得が可能なことをやたら持ち上げてますが、これ別にブロックチェーンの発明じゃなくただの追記型のデータ構造だってだけですし、可用性については現実的には単一障害点ができてしまうって自分で言うてましたやん。

という感じなので、ぜひまとめのセクションだけでなく中身も読んでみることをおすすめします。数式とか出てこないし意外とさくっと読めますよ。

socket.io とは何だったのか

「Socket.IO は必要か?」または「WebSocket は通るのか?」問題について 2016 年版
socket.io が提供してくれているものは何か - from scratch

実はこの辺りの話って、公式サイトのFAQに書いてあるんですよね。・・・と思って久しぶりに公式サイト見てみたら、おっしゃれーにリニューアルされてて以前のFAQが無くなっていました。

というわけでv0.9の頃のサイトをInternet Archiveから引っ張り出してきました。
Socket.IO: the cross-browser WebSocket for realtime apps.

Why not just call it `WebSocket` if the actual WebSocket is not present and mimick its API?

抄訳: ヘイボブ!これってただのWebSocketの代わりじゃないの?

Socket.IO does more than WebSocket, even if WebSocket is selected as the transport and the user is browsing your website with an ultra modern browser. Certain features like heartbeats, timeouts and disconnection support are vital to realtime applications but are not provided by the WebSocket API out of the box.

This is akin to jQuery's decision of creating a feature-rich and simple $.ajax API as opposed to normalizing XMLHttpRequest.

抄訳: 何を言ってるんだいアリス!たとえWebSocketで通信できる環境でも、Socket.IOはWebSocketよりすごいんだ!ハートビートやタイムアウトや再接続なんかはリアルタイムアプリケーションには必須だけど、WebSocketは提供していないだろう?jQueryがただのXMLHttpRequestの代わりじゃないのと同じさ!