BlockChainを使ったアプリケーションを試してみる


この記事は「Opt Technologies Advent Calendar 2017」6日目です。

## はじめに

こんにちは。仮想通貨の波に完全に乗り遅れております。
BitCoinに関しては、以前調べた時に「店頭での少額の支払いに向かないだろう」と思ってたのですが、業者側がリスクを取ることでリアルタイムの決済プラットフォームとして浸透しているようですね。

本記事では、先日社内の開発合宿ハッカソンで取り組んだ「BlockChainの可能性を探る」について簡単にまとめようと思います。

## 何を調べたか

当社が主に広告代理店業をしていることもあり、非中央集権のキュレーションプラットフォームを作ろうとしている [userfeeds](https://userfeeds.io/)の仕組みに目をつけました。

例えばTechCrunchでこのような記事が上がっています。

→「[Userfeeds aims to stop fake news by linking the blockchain to social content](https://techcrunch.com/2017/05/03/userfeeds-aims-to-stop-fake-news-by-linking-the-blockchain-to-social-content/)」

あいにくホワイトペーパーは2017/12時点でまだ無いようなのですが、ブログ記事やスライドなどドキュメントがいくつかあったのでそれを元に仕組みを考察してみました。

（※断片的な知識を組み合わせているため、事実と正しくないものが含まれるとは思います。「どういう応用例が考えつきそうか、の一例として見て頂ければ」）

## 問題意識

そもそもなぜ非中央集権のキュレーションプラットフォームを作るかですが、近年の情報化社会においてユーザーが知りたいのは、「ある分野（医療やBlockChainなど）においての有識者とされる人がオススメする情報」だとします。

しかし、GoogleではSEO次第でまとめサイトなどが上位に食い込んでしまうし、Facebookも素人の友達の声に影響されてしまう、（日本でも某お店評価サイトが裏でランキングをいじっているのではないか疑惑とか）など、プラットフォーマーによる不透明な情報源・不透明なアルゴリズムで情報がキュレーションされています。

そこで、

- その分野の詳しい人がちゃんと評価され、報酬を得られる仕組みを作ろう
- ランキングに使うための情報を全てBlockChainに記録しておいて、誰でも使えるようにしよう

ということで考え出されたようです。

## 仕組み

> https://www.slideshare.net/userfeeds/building-google-for-the-economic-web-using-the-ethereum-blockchain

こちらのスライドや、

> https://userfeeds-platform.readthedocs-hosted.com/en/latest/ref/claims.html

こちらのデータモデルを見ると、

ブロックチェーンに貯める情報としては、

- あるユーザーが、その分野に詳しい人を支援する（back）
- あるユーザーが、その分野の良い記事を推薦する（endorse / キュレーション）

で、それらの情報をプラットフォーマーそれぞれが集計してわかりやすく表示、というのが出来るということのようです。

また、これらの活動を行った際にtokenが発生して、これを広告主などが買うことで（広告枠的な枠に）記事を掲載出来てキュレーターが儲かる、という仕組みになっています。
上記のスライドの図ですが、このようにサイクルが回ると書かれています。（eyeballsは注目度とかpv数のことでしょう）

![Screenshot 2017-12-06 01:28:19.png](https://qiita-image-store.s3.amazonaws.com/0/7185/93c9102c-f9ee-6991-5633-2c64b83bd5bb.png)

（コミュニティを荒らそうとしたり、tokenの価値を毀損しようとしたりといったことについても考えて設計されているのですが、ここで細かく述べるには前提知識が多く必要だったり、不確実な情報が含まれるためここでは触れません。）

## 実装してみる

参照実装ということで試してみます。
ここではEthereum上にスマートコントラクトを形成して、それをブラウザから操作・取得する例を取り上げます。

### Ethereum環境の構築

publicなところで動作確認をするとgassとしてコストが掛かってしまうし、一時的に止めたりも出来ないので、ローカルにクラスタを構築します。

公式の手順でやると色々動かなかったので、こちらの本にかかれていることにほぼ準拠して用意しました。日本語情報としてオススメです。 https://www.amazon.co.jp/dp/4798151343
ただ本の内容をなぞるだけになってしまうのと、面倒なのでここでは詳細は書きません。

### スマートコントラクトの作成

```curationContract.sol

contract CurationContract is owned {
    string[] public urls;
    address[] public contributors;

    function curate(string bookmark){
        urls.push(bookmark);
        contributors.push(msg.sender);
    }
}
```

すごくシンプルにこんな感じです。（キュレーションした際にtokenが発行されるようにする部分は今回は省略）
curate APIを呼ぶと、キュレーションしたユーザーと、どのリンクを推薦したかの情報が記録されていきます。

これをEthereum Walletで見てみるとこんな感じ。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/7185/aaa543f4-5534-78d4-83f6-9d1ebca95ffa.png)

ContributorsのところなどはpublicなAPIのため、Walletから値が見れています。

また、画面からABI(Application Binary Interface)を取得することが出来て、呼び出し側ではこのInterfaceを使うことでcurate APIを呼ぶことが出来ます。

### ブラウザからcurate APIを呼ぶ

ここでは [metamask](https://metamask.io/) を使います。
metamaskのextentionが入っている状態で、以下の様な記述をすると呼び出せます。

```js:call_api.js
function myFunction() {

  var abi = /* ここにABIを貼り付ける*/

  var contract = web3.eth.contract(abi).at(/* ここにスマートコントラクトのアドレスを指定する */);

//APIを呼ぶ。返り値はcallbackで来る
contract.curate("http://example.com", function(err, res){console.log(err);})
}
```

このような記述をすることで、画面からこのメソッドを呼ぶと拡張のmetamaskが立ち上がり、スマートコントラクトの実行をすることが出来ます。

<img width="265" alt="スクリーンショット 2017-12-06 2.14.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/7185/0aa123d5-69de-0bff-bc08-096d6c5c3c17.png">


### キュレーション結果を確認する

userfeedsでは、キュレーションの集計をするのは、画面を提供する各社で競争しましょうというスタンスのようです。 [Ranking API](https://userfeeds-platform.readthedocs-hosted.com/en/latest/ref/algorithms.html#links)を見るとサンプル実装がある。

支援者の多いキュレーターの評価を上げるなど色々チューニングの余地はあるのですが、とりあえず表示しようと思うとこんな感じです。

```js:get_urls.js
var abi = /* ここにABIを貼り付ける*/

var contract = web3.eth.contract(abi).at(/* ここにスマートコントラクトのアドレスを指定する */);

contract.urls(0,(function(err, url){
  if(!result) return;
  console.log(url)
}));
```

このように取得出来ます。

## まとめ

あくまで概要とサンプル実装のみなので簡単なものですが、ブロックチェーンを使ったプログラミングをご紹介しました。userfeedsについては、ホワイトペーパーが出たら追っかけてみたいと思います。