仮想通貨

[超絶番外編] IPFSで遊んでみる

目次
・IPFSで遊んでみる(ブロックチェーンにも関係あり)
・expressサーバから設定と取得
・あっという間に世界と共有

●IPFSで遊んでみる(ブロックチェーンにも関係あり)

noteでお知り合いになった daidaiさん から面白いことを教えてもらって、少し今回は遊んでみます。

その名も「IPFS」です。

上記サイトで詳細は確認いただくとして、
さくっと試してみたくなりました。

上記サイトからMac用のgo-ipfsというモジュールをダウンロードしました。

デーモンはgoで記述されているみたいですね。
(Go言語はちょっと触ったことあるけど、あまり詳しくないので、バイナリだけをダウンロードして、直接実行しましょう)

ダウンロードしたtar.gzを解凍して、中のipfs実行ファイルを実行させます。

ipfs init

初期化が終わったので、もうさっそくデーモンとして実行させちゃいましょう。

ipfs daemon

すると

Initializing daemon...
Successfully raised file descriptor limit to 2048.
Swarm listening on /ip4/127.0.0.1/tcp/4001

・・・(中略)・・・

Swarm announcing /ip4/192.168.0.5/tcp/4001
Swarm announcing /ip6/::1/tcp/4001
API server listening on /ip4/127.0.0.1/tcp/5001
Gateway (readonly) server listening on /ip4/127.0.0.1/tcp/8081
Daemon is ready

と表示され、とりあえずデーモン君起動。
(自宅のマシンではport8080に Jenkins君が動いていたので、ipfsのconfigでポートを変更して8081にしてあります)

では、さっそく ipfsで文字列を格納して、そしてそれのhash値を指定して元の文字列を取り出してみましょう。

●expressサーバから設定と取得

いつものように node.jsで書きます。
package.jsonを次にように設定しました。

{
  "name": "ipfs-example",
  "version": "0.0.1",
  "description": "ipfs-example",
  "main": "server.js",
  "scripts": {
    "start": "node -r babel-register src/server.js",
    "build": "babel src -d dist --source-maps"
  },
  "author": "o-matsuo",
  "license": "MIT",
  "repository": {
    "type": "git",
    "url": ""
  },
  "devDependencies": {
    "babel-cli": "^6.26.0",
    "babel-plugin-transform-runtime": "^6.23.0",
    "babel-preset-env": "^1.6.1",
    "babel-register": "^6.26.0"
  },
  "dependencies": {
    "express": "^4.16.3",
    "ipfs-mini": "^1.1.2"
  }
}

express本体のserver.jsは以下のように記述しました。

import express from 'express';

const IPFS = require('ipfs-mini');
//const ipfs = new IPFS({ host: 'localhost', port: 5001, protocol: 'http' });
const ipfs = new IPFS({ host: 'ipfs.infura.io', port: 5001, protocol: 'https' });

const app = express();

// ハッシュした値を一時的に格納する変数
let hash = undefined;

// getで値を設定する。(postでもよかったけど、引数を簡単に設定できるから)
app.get('/set/:name', (req, res) => {
    const name = req.params.name;
    ipfs.add(name, (err,result) => {
        hash = result;
        console.log(name + ' -> hash:[' + result + ']');
    });
    // ipfsコールバックが終わる前にresを戻しているので、直後に/getをしても値が反映されていない可能性がある。
    res.send('ok');
});

// /get で保存したハッシュ値をipfsでcatしたものをresで戻す。
app.get('/get', (req, res) => {
    if(hash == undefined) {
        res.send('hash undefined');
        return ;
    }

    ipfs.cat(hash, (err, result) => {
        console.log('hash:[' + hash + '] -> ' + result);
        // コールバックの中から応答を戻しているので、値が確実にクライアントに戻される。(少し時間がかかるが)
        res.send(result);
    });
});

// port 8000で待つ
app.listen(8000);
console.log('listen 8000');

もう「超絶簡易版」ですが、ipfsの機能を試すだけなら十分でしょう。
ipfsオブジェクトを

const ipfs = new IPFS({ host: 'localhost', port: 5001, protocol: 'http' });

で作成すればローカルで起動したデーモン君とやり取りしてくれます。

今回は、外部サーバとのやりとりを試します。

npm start

とコマンドを入力して、

listen 8000

と表示されればexpresサーバがport 8000で起動しています。

ブラウザから

と入力してみましょう。戻り値「ok」がブラウザ上で表示されれば成功です。

さらにブラウザから

と入力してみましょう。結果として先ほどセットした

「これがipfsだ」

がブラウザ上で表示されれば、hash値から設定した文字列の取り出しに成功していることになります。

●あっという間に世界と共有

http://localhost:5001/webui

で管理コンソールも起動しているようなので、ちょっと見てみましょう。

地球儀に青い爪楊枝がたくさん刺さったような画像が表示されました。

どうやらこれだけのpeerとデータを共有しているっぽいですね。

なんか、、、とても凄いことだと関心しました。

と、今回は少し脱線しましたが、未来の技術を少し垣間見た気がします。

また興味があることがあったら、ここで紹介したいと思います。
(現在、RxJSを猛烈に勉強中)


ソフトウェア・エンジニアを40年以上やってます。 「Botを作りたいけど敷居が高い」と思われている方にも「わかる」「できる」を感じてもらえるように頑張ります。 よろしくお願い致します。