今回の記事では、Swarmの概要について説明します。
SwarmとはEthereumのブロックチェーン上に組み込まれている分散ファイルストレージの仕組みです。
SwarmもIPFSと非常によく似ており、P2Pネットワーク、停止時間ゼロ、DDOS耐性、フォールトトラント耐性、インセンティブシステム(※Swarm個有)など、多様な機能を提供しています。
[ゴール]
Swarmの大まかな仕組みを理解します。
[ターゲット]
分散ファイル、ブロックチェーンを使ったストレージに興味がある方。
[前提知識]
P2Pネットワーク、ブロックチェーンの基礎的知識が必要となります。
Swarmのロードマップ
まずは、本執筆時点(2018/05)で公開されているSwarmのロードマップについて簡単に記述します。
現在のSwarmは実証実験中ということで、POC(プルーフ・オブ・コンセプト)という単位でロードマップが敷かれています。
現時点でPOCは1、2、3、4と定義されており、POC1、2までは完了している状況です。
POC1、2(実装済み)
実装内容は下記のGithubで公開されています。
Q2 achievements · ethersphere/swarm Wiki · GitHub
POC3(実装予定)
- ネットワークレイヤーをリプレイスするために、分散ハッシュテーブルKademliaを採用
- プライベートなコンテンツもアップロードできるようにするための暗号化
- マニフェストをサポートする
- SWAP自体、SWAP Contractのchequebook(仮想小切手) のリプレイス
- light modeを実装
- Binary Merkle Tree(BMT) Hashをchunkのために実装
- Filesystem in Userspace (FUSE) を使って、Swarmファイルシステムの実装
- Peer間のメッセージングを行うPSSの実装
- POC4(実装予定)
- Inmemory database POTのサポート
- 動画コンテンツなどのマルチキャストストリーミングの実装
- ネットワークの監視、ログの集約
- コンテンツを保持しているPeerに対して、保持している事実証明するためにゼロ知識証明により実装する
- ストレージインセンティブのための、SWEAR、SWINDLE実装
Swarm関連プロジェクトの紹介
この章では、実際にSwarmに関連しているプロジェクト(ライブラリ)を何件か紹介していきたいと思います。
pss
pssプロジェクトは別名bzz whisperedとも呼ばれています。分散ハッシュテーブルのbzzサブプロトコル、Kademliaを使い、swarmネットワーク間でインセンティブ提供のメッセージングを行うサービスです
kademilaを使用することで、インセンティブPeer間でP2Pの効率的なメッセージングを行います。すでに実装されているbzzサブプロトコルをリファクタリングしたり、匿名性を高めるための拡張するプロジェクトです。
SWATCH
リアルタイムオーディオ、ビデオストリーミングなどのライブ配信をSwarm上のP2Pネットワークで利用するためのプロトコルです。実際に、Livepeerというサービスで開発、実装がおこなわれております。
ネットワークレイヤー部分では、Ethereumのdevp2pライブリを利用してライブ配信を行ったり、録画したコンテンツをチャンクに分割して、SwarmのPeer上にチャンクを保存します。
中央集権的なライブ配信テクノロジーであるWebRTCのシグナリングサーバーを、このSWATCHを利用して非中央集権的なサービスに置きかける試みもされています。
SWATCH on Swarm · livepeer/wiki Wiki · GitHub
SWAP
SWAPおよび、次項で紹介するSWEAR、SWINDLEは、Swarmのインセンティブシステムにおけるライブラリ、またはContractにあたります。
SWAPはSwarm Accounting Protocolの略です。
SWAPはSwarmのインセンティブシステムにおいて、PeerとPeer間のP2P情報伝達、ネットワークインセンティブの管理、インセンティブの支払いを担当しています。
当然、分割化されたコンテンツ(Chunk)を、分散ハッシュテーブルのロジックにより指定のPeerにデリバリーするのもSWAPの役割になります。
インセンティブは、chequebook Contractという仮想小切手のような仕組みを使いSwarmに貢献したPeerに支払いを行います。
SWAPは多岐にわたる役割を担当するため重要なライブラリです。
Swap · ethersphere/swarm Wiki · GitHub
SWEAR
SWEARはSecure Ways of Ensuring ARchival または SWarm Enforcement And Registrationの省略語になります。
SWEARはSwarmインセンティブシステムにおいて、参加したいPeerに対してChunkの納品保証、品質保証を担保させる役割(契約)を担っています。
参加したいPeerはインセンティブをもらいうけるかわりに、SWEAR Contractに対してまずは保証金を納める必要があります。
それにより、SwarmはPeerが途中でPeerを落として切断したり、コンテンツ(Chunk)を紛失したりすることを防ぎます。
そうすることで、PeerにChunkを長期にわたり安全に保管してもらうことを目標にしています。
SWINDLE
SWINDLEはSecured With INsurance Deposit Litigation and Escrowの省略語になります。
Swarmインセンティブシステムにおいては、SWEAR contractで結ばれた契約が履行されるかどうか、監視する役割を持ちます。
Peerがコンテンツを損失した場合や、SWEARとの契約内容に違反していた場合に、ペナルティとして保証金を没収します。
Peerはインセンティブを受け取るために、SWINDLEに対して領収書を自分の公開鍵で証明し、提出を行います。
SWINDLEはその領収書が正当なものであるか、整合性チェックを行います。ここで正当性を認められるまでは、Peerはインセンティブ報酬を受け取ることができません。
Peerの違反が判明した場合には、罰則としてSwarmネットワークからPeerとして活動できないように、停止を行うなどの措置をとります。
罰則を受けたPeerも、再度Swarmに参加することは可能ですが、その際は新しく、Identity(身分証明)を提出し、保証金も入れ直さなければなりません。
そうすることで、Peerによる不正、過失が発生することを防ぎます。
Swarmインセンティブネットワークの処理の流れと、SWAP、SWEAR、SWINDLEの関係性
SWAP、SWEAR、SWINDLEに関しては、それぞれが密接に相互依存しているため関係性を図で表現してみます。
Swarmインセンティブネットワークの処理の流れは以下のようになっています。
1.SWEARに対して、PeerとのSwarmインセンティブネットワークの契約を依頼します
2.SWAPに対して、Peerから預かった保証金の管理を依頼します。
3.SWEARに対して、Peerとの契約を宣言します。
4.SWINDLEに対して、Peerが契約を履行するかどうかジャッジを依頼します。
5.SWAPに対して、支払いの正当性を連絡します。
6.SWINDLEに対して、領収書の正当性の確認を依頼します。
アーキテクチャの説明
この章では、chunkの登録、検索について簡単な説明をしていきたいと思います。
(※利用している画像はLondon Ethereum Meetupの動画から抜粋させていただきました。 画像に出てくるnodeという名称はPeerと同義です )
chunkの登録
コンテンツownerがなにがしらかのコンテンツをPeerにアップロードしますと、コンテンツは4Kbyteに分割されたchunkになります。chunk毎に算出されたハッシュが与えられます。
chunkのハッシュをこの図ではchunk addressと表現しています。このchunk addressに近いPeerをclosest nodeと呼んでいます。
コンテンツownerからアップロードされたchunkは、Peer間をキャッシュしながら、最終的にclosest Peerに転送されます。
chunkの検索
1.コンテンツにアクセスしたい人をここではretrieverと表現しています。コンテンツはchunk単位に分割された複数のchunk addressの集合体ですので、chunk addressをキーにchunkを見つけていきます。
2.chunkに一番近い、closest nodeを見つける必要があります。その際のPeerの探索に、分散ハッシュテーブルである、Kademliaが利用されます。
3.retrieverからのリクエストは、Peer間を次々に転送され、closest nodeまでたどりつきます。この図には載っていませんが、closest nodeはリクエストを受けとると、chunkをレスポンスとして返します。
chunkの登録、検索時のフローにおいて、PeerとPeerの間ではSwarmインセンティブシステムよる契約が結ばれ、前回の記事で説明した、SWAER、SWINDLEの監視により、パケットの信頼性を高めています。
Swarmのインストール設定方法 + 簡単な利用方法
ダウンロードとインストール
Swarmの実装はgethのrepositoryに含まれていますので、gethがインストールされていればそのまま使えることがあります。
しかし、gethをバイナリでインストールしている場合は、別途インストールが必要になります。
以下にSwarmをソースからインストールする方法を記述しておきます。
(ソースからインストール)
$ go get github.com/ethereum/go-ethereum
$ cd $GOPATH/src/github.com/ethereum/go-ethereum
$ go install -v ./cmd/swarm
初期化
Swarmネットワークに参加するには、bzzkeyと呼ばれる、識別子を設定する必要があります。bzzkeyはEthereumのアカウントになりますので、新規にアカウントを作成します。
作成が完了しますと、レスポンスとしてアカウントのアドレスが返されます。
下記のようにアドレスが表示されれば、正常にアカウントが作成できています。
(初期化)
$ geth account new
Address: {2f1cd699b0bf461dcfbf0098ad8f5587b038f0f1}
次に、このアカウントのアドレスをBZZKEYという環境変数の値にセットしておきます。
$ BZZKEY=2f1cd699b0bf461dcfbf0098ad8f5587b038f0f1
gethとswarmの起動
続いてswarmコマンドでdaemonを起動します。
geth daemonを起動していないとPeer間の同期ができないので、先にgethを起動します。
gethで–datadirでデータディレクトリを指定した場合は、swarmコマンドでも同じく–datadirオプションをつけて起動してください。
(gethとswarm daemonの起動)
$ geth
$ swarm --bzzaccount 2f1cd699b0bf461dcfbf0098ad8f5587b038f0f1
コンテンツのアップロード
Swarmにコンテンツをアップロードするにはupコマンドを使用します。
アップロードするコンテンツの例として、IPFS編と同じくローカルPCに以下のようなディレクトリ構造を用意します。
$ tree demo/
demo/
├── index.html
└── top/
└── main.html
demoというディレクトリ配下を再帰的にアップロードするには、upコマンドに–recursiveオプションをつけます。コンテンツ単体であれば、upコマンドだけでアップロードできます。レスポンスにはハッシュ化されたディレクトリ、ファイルの値が返ります。
(コンテンツのアップロード)
$ swarm --recursive up demo/
bf916c384436d05ccc4a11263b10b24fc4df1325494f15dcba11526d2c5e976e
アップロードできたか確認するため、demo/index.htmlにブラウザからアクセスしてみます。
ブラウザからのアクセスにはローカルで起動したSwarm daemon経由でのアクセスと、Swarm Gateway経由でのアクセスが可能です。Gateway経由の場合は、キャッシュ化されるために、時間がかかるかもしれません。
(ローカルdaemon経由でのアクセス)
http://localhost:8500/bzz:/bf916c384436d05ccc4a11263b10b24fc4df1325494f15dcba11526d2c5e976e/index.html
(gateway経由でのアクセス)
https://swarm-gateways.net/bzz:/bf916c384436d05ccc4a11263b10b24fc4df1325494f15dcba11526d2c5e976e/index.html
(※httpsでのアクセス)
demo/top/main.htmlにアクセスするには、ハッシュの後にディレクトリのパスを指定してアクセスが可能です。
https://swarm-gateways.net/bzz:/bf916c384436d05ccc4a11263b10b24fc4df1325494f15dcba11526d2c5e976e/top/main.html
Webサーバーで設定可能なディレクトリインデックスに似た–defaultpathというオプションもあります。このオプションを指定して、コンテンツをアップロードすることで、下のように省略することが可能です。
$ swarm --defaultpath demo/index.html --recursive up demo/
082469ad711de36c0ef9affc46404c14a8590a82511fc526046706b2a5853631
https://swarm-gateways.net/bzz:/082469ad711de36c0ef9affc46404c14a8590a82511fc526046706b2a5853631/index.html
↓
(--defaultpath 有り)
https://swarm-gateways.net/bzz:/082469ad711de36c0ef9affc46404c14a8590a82511fc526046706b2a5853631/
bzz-schemeの種類
bzz:/で始まるbzz-schemeは他にも種類があり、schemeを変更することにより、異なるアウトプットを得ることができます。
ディレクトリ階層を表示する(bzz-list:/)
demo以下の階層構造をブラウザ上で出力することが可能になります。
Manifestファイルを取得する(bzz-raw:/)
アクセスしているURLのManifestをJSONファイルとしてダウンロードし、内容を確認することができます。
{
"entries": [
{
"hash": "8d526bd836f43eb73349ab4369f886a46a77408cc8c9d022c5794c3e078733e9",
"path": "index.html",
"contentType": "text/html; charset=utf-8",
"mode": 420,
"size": 20,
"mod_time": "2018-05-21T11:39:07+09:00"
},
{
"hash": "951bfc156012c7d8213732dca97e2219c22ff3060cc4b88d90162d8a179e5b5d",
"path": "top/",
"contentType": "application/bzz-manifest+json",
"mod_time": "0001-01-01T00:00:00Z"
},
{
"hash": "8d526bd836f43eb73349ab4369f886a46a77408cc8c9d022c5794c3e078733e9",
"contentType": "text/html; charset=utf-8",
"mode": 420,
"size": 20,
"mod_time": "2018-05-21T11:39:07+09:00"
}
]
}
まとめ、総括
これまでのシリーズでは、IPFSとSwarmを例に分散ストレージシステムの解説を行なって来ました。
この両者ですが、プロトコル、仕様レベルで厳密に比較しますと差異があるものの、全体像を俯瞰してみると似ていると感じられた方も多いのではないでしょうか。
実際に互いのコミュニティにおいて、統合案、コラボレーションの案もでていたりします。下記に何件か案をピックアップしてみました。
- SwarmにIPFSプラグインを実装し、Swarmインセンティブシステムを使いIPFSを動かす案
- IPFSにSwarmと同じようなインセンティブシステムを導入して、同じ開発チームで開発をおこなっていく案
- Ethereumのネットワークレイヤーである、devp2pの上に、IPFSを乗せて、現状のIPFSの機能をそのまま利用する案
このような話題が出るということはIPFS、Swarmの分散ファイルストレージとして将来への期待が高い証左と言えるのではないかと思います。。
IPFS、Swarmはともにstableという状況ではないため、仕様変更が今後も頻繁に発生することでしょう。
このような状況下では、分散ファイルストレージを使用する必要がでてきた場合にどちらを導入しようか迷うこともあるかと思います。
いろいろ調査してきた中での所感ですが、現時点では導入実績が多いIPFSを選択するのが無難ではないかと思います。
Swarmインセンティブシステムを利用したPeerの安定供給などの発展性は、Swarmの方があると思います。POCアップデートが終了するのが2018年末〜2019年Q1ぐらいですので、2019年はSwarmの年になっていると個人的には嬉しい限りです。