0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Nostrに入門してみた

Posted at

はじめに

Nostr(Notes and Other Stuff Transmitted by Relays)は、シンプルかつ柔軟なプロトコルを基盤とした分散型のソーシャルネットワークシステムです。本記事では、Nostrの基本概念から技術的な詳細、実装例に至るまで、あらゆる側面を包括的に解説します。コードスニペットを交えながら、Nostrの仕組みを深く理解していきましょう。

Nostrとは

Nostrは、「Notes and Other Stuff Transmitted by Relays」の略で、検閲抵抗性を持つ分散型のソーシャルネットワークプロトコルです。Twitterのようなマイクロブログサービスに対する代替として設計されており、中央集権的なサーバーに依存せず、ユーザー間で直接データをやり取りすることを目指しています。

Nostrの目的

  • 検閲抵抗性: 中央管理者が存在しないため、特定のコンテンツの削除や制限が困難。
  • シンプルさ: プロトコル自体が非常にシンプルで、実装が容易。
  • 拡張性: NIP(Nostr Implementation Possibilities)を通じて機能拡張が可能。

Nostrの基本構造

Nostrは主に以下の3つのコンポーネントから構成されます。

  1. イベント(Events)
  2. クライアント
  3. リレー(Relays)

イベント(Events)

イベントはNostrプロトコルの基本単位であり、ユーザーのアクション(例:投稿、フォロー)を表現します。イベントはJSON形式で表現され、以下のプロパティを含みます。

  • id: イベントのユニークな識別子(SHA-256ハッシュ)。
  • pubkey: イベントの作成者の公開鍵。
  • created_at: UNIXタイムスタンプ。
  • kind: イベントの種類(例:1はテキストノート)。
  • content: イベントの内容。
  • tags: イベントに関連するメタデータ。
  • sig: イベントの署名。

イベントの例

{
  "id": "4376c65d2f232afbe9b882a35baa4f6fe8667c4e684749af565f981833ed6a65",
  "pubkey": "6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93",
  "created_at": 1673347337,
  "kind": 1,
  "content": "Walled gardens became prisons, and nostr is the first step towards tearing down the prison walls.",
  "tags": [
    ["e", "3da979448d9ba263864c4d6f14984c423a3838364ec255f03c7904b1ae77f206"],
    ["p", "bf2376e17ba4ec269d10fcc996a4746b451152be9031fa48e74553dde5526bce"]
  ],
  "sig": "908a15e46fb4d8675bab026fc230a0e3542bfade63da02d542fb78b2a8513fcd0092619a2c8c1221e581946e0191f2af505dfdf8657a414dbca329186f009262"
}

クライアント

クライアントは、ユーザーがNostrプロトコルとやり取りするためのソフトウェアツールです。デスクトップアプリやブラウザベースのアプリケーションが一般的です。クライアントはユーザーの公開鍵を使用してイベントを作成し、リレーと通信します。

リレー(Relays)

リレーは、Nostrイベントを受信、保存、配信するサーバーです。リレーは分散型であり、誰でもホスト可能です。クライアントは複数のリレーに接続することで、データの冗長性と耐障害性を確保します。

Nostrプロトコルの特徴

シンプルさ

Nostrのプロトコルは非常にシンプルです。イベントはJSON形式で表現され、WebSocketを通じてクライアントとリレー間でやり取りされます。プロトコル自体が少ない行数で定義されているため、実装が容易であり、言語やプラットフォームに依存しません。

耐障害性

中央集権的なサーバーに依存しないため、システム全体の耐障害性が高いです。リレーがダウンしても、他のリレーに接続することでサービスを継続できます。また、ユーザー自身がリレーを選択・変更できるため、特定のリレーの障害が全体に影響を与えにくくなっています。

検証可能性

公開鍵暗号を基盤としているため、イベントの真正性が容易に検証できます。各イベントには作成者の公開鍵と署名が含まれており、第三者がイベントの信頼性を確認できます。

NIP(Nostr Implementation Possibilities)

NIPは、Nostrプロトコルの拡張機能を提案・標準化するための仕組みです。NIPを通じて、新しい機能や改善点をコミュニティ全体で共有し、実装の互換性を保ちます。

NIPの役割

  • 標準化: 新しい機能やプロトコルの拡張を標準化し、異なるクライアントやリレー間での互換性を確保。
  • 協調開発: 開発者間でのコミュニケーションと協力を促進し、Nostrエコシステム全体の発展を支援。

主要なNIPの例

  • NIP-01: 基本プロトコルの仕様。
  • NIP-02: 公開フォロワーリストとニックネーム。
  • NIP-04: プライベートダイレクトメッセージ。
  • NIP-05: 「認証済み」アカウント。
  • NIP-09: イベントの削除(作成者による)。

Nostrの利用開始方法

鍵の理解と管理

Nostrアカウントは、公開鍵と秘密鍵のペアで管理されます。

  • 公開鍵(Public Key): ユーザーの識別子として機能し、他者に公開されます。npubで始まる形式で表示されます。
  • 秘密鍵(Private Key): ユーザーの署名に使用され、厳重に管理する必要があります。nsecで始まる形式で表示されます。

鍵の生成

鍵ペアは、Nostrクライアントが自動的に生成します。以下は、JavaScriptを使用した簡単な例です。

// 使用する暗号ライブラリのインポート
import { generatePrivateKey, getPublicKey, signEvent } from 'nostr-tools';

// 秘密鍵の生成
const privateKey = generatePrivateKey();
console.log('Private Key:', privateKey);

// 公開鍵の取得
const publicKey = getPublicKey(privateKey);
console.log('Public Key:', publicKey);

鍵の保存

秘密鍵はリセット不可であるため、安全な場所に保管することが重要です。推奨される方法は以下の通りです。

  • パスワードマネージャー: KeePassや1Passwordなど。
  • ハードウェアデバイス: Ledger Nanoなどのハードウェアウォレット。
  • ブラウザ拡張機能: Connect、nos2x、Albyなど。

クライアントの選択と設定

Nostrクライアントは多岐にわたり、各クライアントは独自の機能やインターフェースを提供します。以下は、一般的なクライアントの例です。

  • Damus: セキュリティに重点を置いたデスクトップアプリ。
  • Amber: Android向けのクライアント。
  • Specter: ブラウザベースのクライアント。

クライアントの設定例

以下は、ブラウザのJavaScriptコンソールを使用してNostrリレーに接続し、ノートを取得する例です。

// リレーへの接続
const ws = new WebSocket("wss://nostr-pub.wellorder.net");

// 接続が開いたときの処理
ws.addEventListener('open', function (event) {
    // サブスクリプションのリクエスト
    const subscription = JSON.stringify([
        "REQ",
        "my-sub",
        { "kinds": [1], "authors": ["35d26e4690cbe1"] }
    ]);
    ws.send(subscription);
});

// メッセージを受信したときの処理
ws.addEventListener('message', function (event) {
    const data = JSON.parse(event.data);
    if (data[0] === 'EVENT') {
        console.log('Note:', data[2]["content"]);
    }
});

このスクリプトは、指定した公開鍵の作者によるテキストノート(kind:1)をリレーから取得し、コンソールに表示します。

Nostrの技術的詳細

WebSocketを用いた通信

NostrはWebSocketを唯一の通信手段として採用しています。これにより、リアルタイムでの双方向通信が可能となり、クライアントとリレー間でのイベントの即時配信が実現します。

WebSocketの基本的な流れ

  1. 接続確立: クライアントがリレーに接続。
  2. サブスクリプション: クライアントが興味のあるイベントのフィルターをリレーに送信。
  3. イベントの受信: リレーがフィルターに合致するイベントをクライアントに送信。
  4. 切断: 必要に応じて接続を終了。

イベントの生成と検証

各イベントは、作成者の秘密鍵で署名されます。これにより、イベントの真正性が保証されます。

イベントの署名

イベントの署名は、以下の手順で行われます。

  1. イベントオブジェクトの作成: 必要なプロパティを設定。
  2. JSON文字列への変換: イベントオブジェクトをJSON形式に変換。
  3. ハッシュ計算: SHA-256ハッシュを計算。
  4. 署名生成: 秘密鍵を用いてハッシュに署名。

署名の検証

クライアントやリレーは、公開鍵を使用して署名の有効性を検証します。これにより、イベントが真正な作成者によって生成されたことが確認できます。

実装例

ここでは、簡単なNostrクライアントをJavaScriptで実装し、リレーに接続してデータを取得する方法を紹介します。

簡単なNostrクライアントの作成

以下のスクリプトは、ブラウザのコンソールで実行可能な簡単なNostrクライアントの例です。

// リレーへの接続
const ws = new WebSocket("wss://nostr-pub.wellorder.net");

// イベントを格納する配列
const notes = [];

// 接続が開いたときの処理
ws.addEventListener('open', function (event) {
    // サブスクリプションのリクエスト
    const subscription = JSON.stringify([
        "REQ",
        "my-sub",
        { "kinds": [1], "authors": ["35d26e4690cbe1"] }
    ]);
    ws.send(subscription);
});

// メッセージを受信したときの処理
ws.addEventListener('message', function (event) {
    const data = JSON.parse(event.data);
    if (data[0] === 'EVENT') {
        const noteContent = data[2]["content"];
        notes.push(noteContent);
        console.log('Note:', noteContent);
    }
});

リレーへの接続とデータの取得

上記のスクリプトでは、以下の手順でリレーからデータを取得しています。

  1. WebSocket接続の確立: 指定したリレーURLに接続します。
  2. サブスクリプションの送信: kind:1のイベント(テキストノート)を指定した公開鍵の作者から取得するようリレーにリクエストします。
  3. イベントの受信と表示: 受信したイベントの内容をコンソールに表示し、配列に格納します。

このように、Nostrはシンプルなプロトコル設計により、短いコードで基本的な機能を実装できます。

まとめ

Nostrは、そのシンプルさと柔軟性により、分散型ソーシャルネットワークの新たな可能性を切り開いています。公開鍵暗号を基盤とした信頼性の高いイベントシステム、拡張性を持つNIP、そして分散型リレーのアーキテクチャにより、検閲抵抗性と耐障害性を兼ね備えたプラットフォームを実現しています。

本記事では、Nostrの基本概念から技術的な詳細、実装例までを網羅的に解説しました。Nostrのエコシステムは日々進化しており、今後も多くの革新が期待されます。ぜひ、Nostrを活用し、分散型ソーシャルネットワークの未来を共に築いていきましょう。

参考資料

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?