純粋P2P型SNS “Scuttlebutt”(スカットルバット)紹介

書いた人: ると @mBL9uQlxa15MF3TNRuAf790wiLVhLx0j+uUAWXKipXo=.ed25519

短いまとめ: Scuttlebutt(スカットルバット)というのは純粋P2P型のSNSで、PatchworkというElectron製のパッケージをダウンロードして起動するだけでTwitterのようなSNSに参加できます。

もう少し長いまとめ: Scuttlebuttとはゴシッププロトコルによって複製される追記専用データベースを中心としたプラットフォームであり、SNSとしても利用できます。サーバとElectronによるUIがセットになったPatchworkという実装をダウンロードして実行するだけで、Windows, macOS, Linux上でノードを立ち上げられて、Twitterのようにメッセージをやりとり(投稿やフォローやDM送受信)できます。Patchworkの他にはGitHub風のソースコード管理アプリケーション等もあります。

目次

始め方

Patchworkのインストーラをダウンロードして実行します。

起動するとプロフィールを入力するよう要求されます。

モーダルダイアログが表示され、名前と紹介文(任意)を入力するように促されます。またプロファイル画像も選べます。

項目は全て後で変更できます。名前にはアルファベット・数字・ピリオド・アンダーバー・ハイフンのみが使えます。また、最後の文字にピリオドは使えません。名前は他のユーザと被ってもかまいません(ユーザは初回起動時に生成される公開鍵によって識別されます)。

入力が終わるとメッセージを投稿できる状態になります。ただし、この時点では誰とも繋がっていないので投稿は誰にも届きません。

メッセージの入力欄等と、自分が名前を設定したというメッセージは表示されますが、それ以外はまだ表示されません。この状態では誰かをフォローするように促すシステムメッセージが表示されます。

Scuttlebuttネットワークにいる適当なノードを指定してネットワークに参加します。公式のpubリストに載っているノードから選んでもよいのですが、ここでは簡単のために筆者のノードを指定します。

まず左上の+ Join Pubというボタンを押します。

モーダルダイアログが表示され、招待コードを入力するように促されます。

そしてダイアログに次の招待コードを入力してRedeem Inviteを押します。

m.tatapa.org:8008:@mBL9uQlxa15MF3TNRuAf790wiLVhLx0j+uUAWXKipXo=.ed25519~hnAWiJk395dJSYcKsN0GdGYoCm+4gJJDMMhYFGyWbyc=

この招待コードは1,000アカウント分の使用制限がかけてあります。使えない場合はpubリストから他のpubを探してください。

なお、招待コードを使うと相手と相互フォロー状態になります。他のノードと十分フォロー関係を確立した後はフォローを外してかまいません。

初期化に成功するとpubノードからデータを取得します。初回はやや時間がかかります。

画面上部に“Indexing Database”というメッセージと共に進捗が表示されます。

初回ダウンロードが終わるとこのような状態になります。

左側に活発なチャンネル(Twitterのハッシュタグのようなもの)のリストや、おすすめユーザのリストが表示され、右側にはpubと相互フォローとなった旨のメッセージが表示されます。

MoreChannelsBrowse Allでチャンネル(Twitterのハッシュタグのようなもの)を見てみましょう。

たくさんのチャンネルがリスト表示されます。

例えば#photographyチャンネルは次のようになります。

投稿者のアイコンや名前と共に、メッセージや写真が表示されます。

あとの使い方はほとんどTwitterと同じです。メッセージの投稿ができて、Likeができて、ブロックもできます。異なる点としては、メッセージが削除できないことや、メッセージにMarkdownが使える点などがあります。また、オフライン時にも投稿できます。その場合はネットワークに繋ったときに同期されます。

仕組み

概要

Scuttlebuttはゴシッププロトコルに基づいてメッセージを交換し合います。

つまり、定期的に他のノードに接続して、「AさんやBさんの新しい投稿はありますか」と互いに問い合わせて、ローカルのデータベースに貯めていきます。

接続先は既知のpubノード(後述)のリストから順に選びます。一方、接続後に新着メッセージを問い合わせるユーザのリストはフォロー関係で3ホップ以内のユーザです。つまりフォローしているユーザと、フォローしているユーザがフォローしているユーザと、フォローしているユーザがフォローしているユーザがフォローしているユーザからなるリストです。

フィード

各ユーザは自分が投稿したメッセージのリストを持っていて、これをフィードと言います。フィードには通常の投稿の他にも、ユーザをフォローした・投稿をLikeした・ユーザーをブロックしたなどの情報もメッセージとして含まれます。

フィードは追記専用であり、メッセージの削除はできません。Likeを取り消したいときやフォローをやめたいときも「取り消した」というメッセージを追記する形になります。

ローカルのデータベースには自身のフィードのほか、ネットワークから取得した他人のフィードも保存します。各メッセージは個人の秘密鍵で署名され、さらに1つ前のメッセージのハッシュ値も含むため、他人が書き換えることはできません。

コマンドラインツール

Scuttlebuttの通信部分はScuttlebotと呼ばれ、Scuttlebotのパッケージにはコマンドラインツールが付属します。このコマンドラインツールを使うとローカルデータベースの調査やメッセージの投稿がコマンドラインから実行できます。

Scuttlebotはnpmからインストールできます。

npm install -g scuttlebot

例えば自分のID (公開鍵)を調べるには次のようにします。

sbot whoami

結果は例えば次のようになります。

{
  "id": "@mBL9uQlxa15MF3TNRuAf790wiLVhLx0j+uUAWXKipXo=.ed25519"
}

そして自分のフィードを調べるには次のようにします。ID部分は自分のIDに置き換えてください。

sbot hist --id '@mBL9uQlxa15MF3TNRuAf790wiLVhLx0j+uUAWXKipXo=.ed25519'

結果は例えば次のようになります。

{
  "key": "%sgNpsQN3fUAUkGRiEeZOVXfMxZ66eSgOCNw6RYE39jU=.sha256",
  "value": {
    "previous": null,
    "author": "@mBL9uQlxa15MF3TNRuAf790wiLVhLx0j+uUAWXKipXo=.ed25519",
    "sequence": 1,
    "timestamp": 1518854432126,
    "hash": "sha256",
    "content": {
      "type": "about",
      "about": "@mBL9uQlxa15MF3TNRuAf790wiLVhLx0j+uUAWXKipXo=.ed25519",
      "name": "cocoa_ruto"
    },
    "signature": "ijhzVGVwiY3pD5dPjNonDrMSs/PRi47X9tofJ13eFL3zfvTaPBEeNrd6RhWh92NlGBS8Ebw63AODkNU1faqyCA==.sig.ed25519"
  },
  "timestamp": 1518854432171
}

{
  "key": "%dhMsx7kWHS9YLf9SeJq5cg9KWJs3Bd9UYzgTeVzI2TU=.sha256",
  "value": {
    "previous": "%sgNpsQN3fUAUkGRiEeZOVXfMxZ66eSgOCNw6RYE39jU=.sha256",
    "author": "@mBL9uQlxa15MF3TNRuAf790wiLVhLx0j+uUAWXKipXo=.ed25519",
    "sequence": 2,
    "timestamp": 1518854780659,
    "hash": "sha256",
    "content": {
      "type": "pub",
      "address": {
        "host": "ssb.ekata.social",
        "port": 8008,
        "key": "@FJDMuATvh0a3qIcIPcstUANVIj362fWkYCG5bnkZ5nA=.ed25519"
      }
    },
    "signature": "zQ6pJa7wQSxp/GNA/RA5ELTjwSC96Md5nntEdExXwt6wvzVhz4FUJdJx9EABrpf/h3XHOIHIpbq+Q2hftBhADw==.sig.ed25519"
  },
  "timestamp": 1518854780703
}

{
  "key": "%GjD0P8fXNr5GnYVxS5UKXDF/wkYNKj6fXlAu5TSRAjU=.sha256",
  "value": {
    "previous": "%dhMsx7kWHS9YLf9SeJq5cg9KWJs3Bd9UYzgTeVzI2TU=.sha256",
    "author": "@mBL9uQlxa15MF3TNRuAf790wiLVhLx0j+uUAWXKipXo=.ed25519",
    "sequence": 3,
    "timestamp": 1518854780843,
    "hash": "sha256",
    "content": {
      "type": "contact",
      "contact": "@FJDMuATvh0a3qIcIPcstUANVIj362fWkYCG5bnkZ5nA=.ed25519",
      "following": true,
      "autofollow": true
    },
    "signature": "DEwrt1OKb2ElcFeAQedmeMGFrzpj/VRLJJcVn0cbCimzlrLfMXExpNcgwM0O18cifPdBJ6+1XEsamdKsnkaODw==.sig.ed25519"
  },
  "timestamp": 1518854780868
}

...

メッセージの種類についてはドキュメントのMessage Typesを参照してください。また、他のサブコマンドについても同じドキュメントを参照してください。

pubノード

pubノードとは、他のノードから接続できると確認されたノードのことです。通常では、ノードが招待コードを発行してそれを他のノードが使った時点でpubノードとして扱われるようになります。

具体的には招待コードを使った側がpubというtypeを持つメッセージを公開して、pubノードのホスト名(またはIPアドレス)とポート番号などの情報を公開します。このpubメッセージを見た他のノードは自分の接続先候補リストにこのノードを追加します。

pubノードと一般のノードでは動作の違いはありません。

用語

Scuttlebutt周辺には、ScuttlebuttやScuttlebotやPatchworkなど様々な用語があってわかりづらいのでまとめます。

Scuttlebutt

Scuttlebuttという言葉はあいまいな言葉で、次のような複数の意味で使われています。

豆知識: 英語では“scuttlebutt”というのは「噂話」という意味で、“butt”は樽、“scuttle”というのは船などを沈める際に穴を開けることを言います。昔、船の上では穴を開けた樽に真水を入れて水飲み場に置いておいたらしく、今でも一般に船の上の水飲み場のことを“scuttlebutt”と言うことがあります。そして水飲み場で休憩中に噂のやりとりがされたことから噂話のことを“scuttlebutt”と言うようになったらしいです。

Secure Scuttlebutt

Secure Scuttlebuttも次のような複数の意味で使われています。

SSB

SSBは略語であり、次の2つの意味で使われます。

Scuttlebot

Scuttlebotとは、Secure ScuttlebuttデータベースをP2Pネットワークで複製するサーバです。ライブラリとして利用できるほか、コマンドラインのインターフェースを通じても利用できます。 略してsbotとも呼ばれます。

Patchwork

Patchworkとは、Scuttlebuttを使ってSNSを構築するクライアントアプリの1つです。P2Pでデータをやりとりするサーバと、ElectronによるUIが1つになっています。

SNS以外の応用

SNS以外の応用としては、Gitレポジトリを共有するgit-ssbおよびgit-ssbに対してGitHub風のウェブインターフェースを提供するgit-ssb-webや、DNSを実現するdnssbなどがあります。

疑問と答え

秘密鍵/公開鍵ペアやデータベースはどこにあるの?

~/.ssb/にあります。

ポートを開ける必要はある?

通常は必要ありません。pubノードになる場合は8008を開ける必要があります。

ポートを変える方法は?

Patchworkの場合、現状ではソースを直接書き換える必要があります。

sbot server (GUI無しのサーバ)の場合は.ssb/configに設定を書けば変更できます。詳細はマニュアルのConfigure Scuttlebotを参照してください。

全くの他人の(危険な)データを中継することはある?

はい。

通常のメッセージに関しては、フォロー関係で3ホップ以内のユーザのフィードを取得して保存します。他のノードから要求されれば自分が保存しているメッセージを提供します。一方、添付ファイル(blob)に関してはさらに広く、他のノードから要求されたときに自分が持っていないければ他のノードに再帰的に問い合わせて、見付かればデータをローカルに保存しつつ元のノードに転送します。デフォルトでは再帰の深さは3です(オリジナルの問い合わせを-1としてカウンタを再帰ごとに減らしていき、-3の問い合わせに答えられない場合は再帰しません)。

ホームには何が表示される?

フォロー関係で2ホップ以内のユーザのメッセージが表示されます。フォローしているユーザのメッセージと、フォローしているユーザがフォローしているユーザのメッセージが表示されます。

大規模なスパムへの対策は?

今のところありません。ユーザのブロック機能やdown vote機能はあります。

なりすましへの対策は?

今のところ公認マーク等はありません。他人と全く同じ名前を名乗ることができます。プロトコルレベルではユーザに対してup voteする機能とdown voteする機能はあります。誰かが信頼できるアカウントリストを作って、それをクライアントで表示する機能などが望まれます。