暗号通貨マイニングによる有料APIの提供


# 背景


私の狭い観測範囲では、最近の大きなニュースは**Coinhive利用による逮捕**と**Twitter APIの改悪**です。この2つは全く関係のない事象だと考えていましたが、並べてみると面白い共通点が見つかります。


- Coinhiveは広告に依存しない、新たな資金獲得方法
- Twitterは広告を出せないため、3rd PartyのAPI利用を厳しくしている

すなわち、Coinhiveのような仕組みをTwitter APIに乗せれば、多くの人に使ってもらうだけでお金が生まれるというシンプルなビジネスになり、改悪されないと考えられます。後述しますが、この仕組みは公開APIにまつわる多くの問題を解決します。

以下では、外部公開APIが抱える問題と、それがどう解決されるのか、また理想的な仕組みの詳細を記載します。

なお、デモサイトも作りましたので、実際に仕組みを体験することができます。
[デモサイト - Crypto API Gateway](https://mining-gateway.firebaseapp.com/) 
( [動画/コード](https://github.com/esplo/crypto-api-gateway) )
このデモでは、"Call XXXXweight API"ボタンを叩くと貯金を消費してAPIを呼び出します。貯金がない場合はしばらく掘り、貯金が溜まった時点で再度呼び出しを行います。



また、Coinhiveの可能性については、下記記事にきれいにまとまっています。併せてご覧いただくとわかりやすいかと思います。
[ブラウザで仮想通貨を採掘するサービス "Coinhive" について - nml.jp](http://nmi.jp/2017-10-10-About-coinhive)

なお、以下で言及するAPIは企業が内部で使うものではなく、Twitter APIやFacebook APIのように外部公開されており、任意の開発者が利用するものとします。


# APIが抱える問題点

APIの開発は労多くして功少ないものになりがちです。そもそも、サービスが抱える貴重なデータを第三者が簡単に使えるようにするのはビジネス面でのリスクが大きいです。

Twitterを例に取ると、広告収入に依存しているのにサードパーティクライアントでは広告がない、という状況になっています。私もずっとTwitterによる広告の出ないクライアントを使っているので、**まだ動画広告でびっくりさせられたことはありません**。これはTwitter社の意図したところでは無いと思われます。

以下に問題点をいくつか列挙してみます。ぱっと考えられるだけでもこれだけあるので、多くのサービスでAPIが公開されていないのも致し方ないと考えられます。


- 自社サイトや公式アプリから遠ざかり、収益源である**広告を見てもらえない**
- API利用者の増加が**収益に直接結びつかない**
  - それどころか、API利用者の増加により**インフラコストが増加**してゆく
- 大規模なアクセスをさばけるようなAPIを設計するのは骨が折れ、実際過労死する
- API利用を**有料にすると開発者が集まりにくく**、公開した意義が薄れる
  - 無料枠付き従量課金は提供するのが大変、使う側もクレカ登録などで大変（後述）

APIを公開するのは「サードパーティツールを充実させてサービスの魅力・価値を高めたい」という動機で、直接的な収益を狙っていないので然りなのですが。財政に余裕のある企業でないとできなさそうですね。


## 既存の有料APIとその課題点

現状、いくつかのサービスではAPI利用が有料になっています。その多くは、定められたプランを選択し、その範囲内での利用が可能になるというものです。例えば、呼び出し頻度の上限が緩和されたり、より多くの情報が取得できる、といったものです。

このような課金形態だと、重たいエンドポイントを叩きまくるユーザーとそうでないユーザーに不平等が生じたり、プランの柔軟性が無く使いにくいサービスになりがちです。

ですが、WebサービスのAPIで従量課金になっているものはあまり見たことがありません。API呼び出し自体がサービスの根幹を成すもの、例えばGCPやAWSのサービスは基本従量課金になっています。理想の姿に見えますが、クレカを登録して決済が正確に管理できることが前提なので作る側も使う側も大変です。



# 暗号通貨マイニングにより解決する問題

上記の問題を解決するにはどうすれば良いのでしょうか？


- API呼び出しに応じて収益が発生する
- 簡単に開発を開始でき、プロダクションでも利用できる

この2点を満たせば問題が解決されそうです。API呼び出しで広告が配信できれば事は簡単だったのですが、機械的に除外できてしまいますね。

ということで、**広告の代わりにマイニングさせたら良いのでは？** という本記事の趣旨がようやく出てきます。具体的には、APIの呼び出しを行うたびに一定の計算を要求し、計算が完了したら欲しがっていた結果を返してあげます。

要は「1時間勉強したら30分ゲームして良い」的な家庭環境ですね。


## 嬉しいポイント

この方式ですと、「**API呼び出しが増えればそれだけ収益になる**」「**利用者はレスポンスが悪い以外は自由に使える**」となります。「レスポンスが悪い」の程度によりますが、そういう仕組みだと納得していれば、多くの場合は気にせず使えるのではないでしょうか。

オマケとして、呼び出しに時間がかかるので単純に負荷が減る、という作用もあります。これによりインフラコストが減少したり、夜中に叩き起こされるインフラエンジニアが少し減ったりするかもしれません。


## 仕組み

もう少し具体的な仕組みを記述します。

実現する方法として考えられるのはいくつかありますが、既存のAPIサーバーに手を加えるのは手がかかります。拡張するため処理を前段に置く、すなわち**ゲートウェイ**として実装するのが理にかなっていると考えられます。

まず、自作のAPIサーバーが裏側にいます。これは公開を前提として普通に作成したAPIサーバーですが、これを直接公開することはありません。

APIサーバーへの全てのリクエストがAPIゲートウェイを通るようにします。これはCloud EndpointやAPI Gatewayと同じものだと考えるとわかりやすいでしょう。ここで本方式を実装します。

ゲートウェイはヘッダーから認証情報を取得し、DBに問い合わせて残金を確認します。もし目的のAPIを呼び出すのに必要なお金を持っていなければ、不足分の計算を要求します。残金が十分にあれば、そのまま目的のエンドポイントを呼び、結果を返してあげます。

計算の要求をどうするかですが、計算の種をクライアントに返し、計算結果を受け取るエンドポイントをゲートウェイで実装します。例えば、以下のようなエンドポイントを作成し、クライアントに叩いてもらいます。

```
GET /mining?weight=0.003
->
{
  "id": "3A28C99402E",
  "seed": "824819A8328B..."
}

POST /mining
{
  "id": "3A28C99402E",
  "answer": "..."
}
->
{
  "earn": 0.003
}
```

クライアントは、状況に応じて上記のエンドポイントを呼び出します。余計な呼び出しの回数をなるべく減らすため、少し多めの金額を掘ったり、アイドル時に掘ったりすると良さそうですね。




# 実装

ここまではただのアイデアなので、上手くいくのかを試すため実装してみました。

実際に上記の仕組みを満たす既存の実装やライブラリがあれば良かったのですが、見つからないのでCoinhiveを利用します。


## Coinhiveによる実装

Coinhiveを使う場合、いくつか実装に変更があります。下記はCoinhiveの制約で諦める必要があるものです。細かな調整が出来ないのは痛いですが、実験なので問題ないでしょう。


- 採掘量の細かな調整
- APIのみを利用した採掘（JSの実行 or リダイレクトが必要）

幸い、Coinhiveはユーザー管理機能を持っているので、下記のような**プリペイド方式**で簡単に実装ができます。

まず、クライアント側は何かしらの手段でユーザーIDを作成し（デバイスIDなど）、それを使って口座を作ります。APIアクセス時に資金が不足していればマイニングを行い、口座に貯金を貯めます。一定量溜まったところで再度APIを叩き、貯金を消費して結果を得ます。


## デモサイト

実際にデモサイトを作りました。各種サーバーはGoで書いてGAEに載せ、クライアントはJSでざっくり書いてFirebase Hostingに乗せています。
[デモサイト - Crypto API Gateway](https://mining-gateway.firebaseapp.com/) 
( [コード](https://github.com/esplo/crypto-api-gateway) )



Gatewayサーバーから400が返ってきたらマイニングをスタートし、Acceptが生まれた時に再度叩く、という非常に簡易的な実装になっています。Coinhive（XMR？）では256Hash単位でAcceptされるので、一度Acceptされれば軽い方は沢山叩けます。

Gatewayでは、極めて単純なYAMLファイルを使ってバックエンドサーバーのエンドポイントを指定し、コストを設定します（ [api.yaml](https://github.com/esplo/crypto-api-gateway/blob/master/gateway/api.yaml) ）。

```yaml
endpoints:
  - cost: 10
    path: '/'
  - cost: 250
    path: '/heavy'
```

サーバー側ではこれを読み込み、エンドポイントとして設定するだけです ([main.go](https://github.com/esplo/crypto-api-gateway/blob/master/gateway/main.go))。

デモのコードではGETしか行えず、またパラメーターやヘッダーは送れませんので、ゲートウェイとしては三流です。が、これは単に実装が手間だっただけですので、時間をかければ解決できます。

このような感じの簡単設定（YAMLを置くだけなど）で収益が生まれるなら、やる価値はありそうですね。さて、では肝心の収益はいかほどなのでしょうか。


# 収益

手持ちのPCでは、おおよそ15-20Hash/sec出ていました。携帯端末やウォームアップ時間を考えると、平均10Hash/secとして良さそうです。ここでは、許容できる増加レスポンスタイムは最大でも1秒程度とし、1回APIを叩くのに10Hash必要と設定します。

Coinhiveのサイトによると、現在の換算は下記のようになっていました。


> current payout 0.00006361 XMR per 1M hashes

現在のレートでは、`0.00006361 XMR`は`0.8JPY`ですので、**10万回APIが叩かれると0.8円増**えます。やったね！

Twitterで考えると、[2010年時点で60億/dayのAPI呼び出しがあった](https://www.slideshare.net/raffikrikorian/twitter-by-the-numbers/20-REST_API_XMLJSON_API_over)そうです（最近のデータは見つかりませんでした）。全てが外部APIかは不明ですが、仮に置き換えると6万円/dayの収益になります。**レスポンス低下の方が高くつきそう**ですね。



## 儲からないのか？

一見儲かりそうにもないように見えますが、あくまで簡単な仮定とCoinhiveで考えた結果です。

大企業であれば、独自プールの作成、サービスに最適なマイニングアルゴリズムの採用、はたまた新しいコインの作成までできます。そんなこんなで収益性が高くなれば、重要な収入源として認知されるかもしれませんね。

# その他

- プリペイド方式なので、**Crypaid（クリペイド） Gateway**という造語を思いつきました
- Cloud EndpointやAPI Gatewayに設定を用意してくれれば簡単に使えそう


# まとめ

暗号通貨マイニングによりAPI呼び出し時に対価を支払うアーキテクチャを提案し、これが有料APIの抱える問題を解決することを述べ、**Coinhiveを使ってGatewayとして実装した**例を示しました（とは言っても、ほとんどCoinhiveが元々目指していたであろう内容ですので、ゲートウェイとして実装する所くらいしか新規性が無いかもしれません）。

API公開の意義を「**直接的に収益を上げる**」とすることで、良いAPIを作る動機になります。特に大規模なAPIでは、**サードパーティの発展が直接利益に結びつく**ということで、win-winになりそうです。また、個人サービスで公開APIを作るのは極めて労力の掛かる仕事ですが、儲かるのであれば実装する人も増えるのではないでしょうか。

実際には、弱い端末が数秒計算した程度でお金になるマイニングができるのかや、相場の不安定さなど障害は多くあります。が、単純な課金以外の選択肢が増えるのはAPI利用者にとって望ましいですね。

「APIは儲かる！」「クリペイドGateway簡単！」という感じで、Webサービスや個人サイトが競ってAPIを実装し、便利に繋がった世界になって欲しいです。


## Q&A

件の事件の後ですので、気になる質問が。

Q: APIゲートウェイとして設置して、Coinhiveの件みたいに捕まらないの？
A: まず、デモサイトについては、[海外に住んでいる間は日本の多くの法律に引っかからない](http://houseikyoku.sangiin.go.jp/column/column061.htm)のでしょっぴかれることは無さそうです。初回利用時に確認ダイアログも出ますし、そもそも少しの開発者しか訪れないので心配する必要もありませんが。
また、ゲートウェイでの課金が実装されたAPIを利用した場合でも、クライアント側で最初に同意を取れば十分でしょう。多くはスマホアプリやWebアプリからの利用になるはずですので、組み込みは簡単です。


## 最後に

上記のアーキテクチャが本当に使い物になるのか、なるとしたらどれくらい時間がかかるのか、詳しい方と議論したい……。

他にも改良点や不満点あれば、コメントいただけますと幸いです。デモコードへのPRもWelcomeです！