すべての記事

約14分で読めます

Label 309 ゲートウェイの上に製品を構築する方法

Label 309 ゲートウェイは、存在証明(Proof of Existence)製品の背後にある公開エンジンです。Cardano への送信、ストレージ、残高、インデックス、Webhook を一手に引き受けるため、製品側はユーザー体験そのものに専念できます。

自分でブロックチェーンを運用することなく存在証明(Proof of Existence)機能を構築したいなら、ゲートウェイの上に構築します。Label 309 ゲートウェイは、存在証明製品の背後にある公開エンジンです。見積もり、アップロード、Cardano トランザクションの送信、確認、reorg の処理、レコードのインデックス、アカウント残高、ストレージの資金管理、API キー、Webhook といった重い運用作業をすべて引き受け、そのすべてをプレーンな HTTP 経由で公開します。製品側はそれらのエンドポイントを呼び出すだけで、ユーザーが実際に目にするすべて、つまりインターフェース、課金関係、業務ワークフロー、そしてブランドを自分のものにできます。

ゲートウェイのコアはオープンソースであり、CardanoWall はその上に構築されたリファレンス製品です。開発者にとって有用なのは、裏口が存在しないという点です。CardanoWall は、ご自身が使うのとまったく同じ公開エンドポイントを通じてゲートウェイに到達します。したがって、リファレンス製品で機能するパターンは、ご自身の製品でもそのまま機能します。

ゲートウェイの上に構築すべきなのは誰か

ユーザーが Web サイト上で手動で行う操作としてではなく、製品の内側に存在証明を組み込みたいのであれば、ゲートウェイの上に構築してください。

うまく適合する例には、次のようなものがあります。

  • 文書公証製品
  • コンプライアンス証拠アーカイブ
  • AI 来歴・データセットガバナンスプラットフォーム
  • 継続的インテグレーションの証明システム
  • 法的証拠ツール
  • 暗号化された開示ポータル
  • メディア真正性サービス
  • 企業内部の監査ツール
  • 出版社の証明ページ

これらすべてにおいて、ユーザーは Cardano トランザクションの構築、UTxO の資金管理、ストレージクレジット、チェーンの確認といったものについて考えたくはありません。求めているのは、永続的で検証可能な証明を生み出すワークフローです。ゲートウェイは、自社のチームが Cardano インフラの運用者になることなく、そのワークフローを実現します。

ゲートウェイは何を担い、製品は何を担うのか

この分担こそが要点なので、はっきりと述べておく価値があります。ゲートウェイはベースプレーン、つまり公開パイプラインと、その背後にあるすべての資金・チェーン・ストレージの状態を担います。

  • 見積もり、アップロード、公開
  • Cardano トランザクションの構築、送信、確認、reorg の処理、恒久的な失敗時の返金
  • ストレージへのコンテンツおよび暗号文のアップロードと、その背後にあるストレージの資金管理
  • ネットワーク上のすべての Label 309 レコードを網羅する、共有のオンチェーンレコードインデックス
  • アカウント残高と、それを動かす台帳エントリ
  • 為替価格とマージン
  • API 認証情報と Webhook の配信

これはインフラの仕事です。本番環境では、正確で、観測可能で、退屈なものでなければなりません。ゲートウェイの運用そのものが自社の本業でない限り、アプリケーション側でこれを再実装すべきではありません。もしそれが本業であるなら、自前のゲートウェイを運用するをご覧ください。

製品側はベンダープレーン、つまりベンダーらしいものすべてを担います。

  • ユーザーアカウントとセッション
  • オンボーディングと課金
  • 製品の権限
  • インターフェースとメール
  • 顧客に提示する価格設定
  • 「案件」「リリース」「データセット」「証拠パッケージ」といった業務上の概念
  • ゲートウェイのイベントから構築する読み取りモデル
  • サポートのワークフロー

ゲートウェイは、ある証明が訴訟、モデル学習の実行、四半期のコンプライアンスパッケージ、あるいは雑誌の号のどれに属するのかを知る必要はありません。必要なのは、正しい Label 309 レコードを公開し、その周辺にある運用状態を維持することだけです。この分離によって両方のシステムをより整然と保てます。製品はチェーンや資金の状態に触れることなく作り直したりリブランドしたりでき、ゲートウェイは製品の存在を知らないまま更新できます。

ユーザーに代わってデータプレーンを呼び出すにはどうするか

データプレーン (/api/v1/*) は、アカウント向けの API です。操作がユーザーまたはアカウントに代わって行われる場合は、いつでもこれを使います。

  • 公開の見積もり
  • コンテンツまたは暗号文のアップロード
  • レコードの公開
  • 残高またはアカウント台帳の読み取り
  • 公開レコードの一覧取得、取得、検証
  • アカウント単位の Webhook の登録

ラッパー製品では、バックエンドがユーザーのゲートウェイアカウント向けに短命のアカウントトークンを発行し、クライアントは必要なスコープだけを持ってデータプレーンを呼び出します。スコープが権限の境界です。公開画面には poe:create が、残高ウィジェットには account:read が必要であり、公開レコードのエンドポイントには認証情報がまったく要りません。匿名の呼び出し元に応答するからこそ、このインデックスは顧客ごとのビューではなく公共財になっているのです。

トークンは設計上、短命です(デフォルトでは 1 時間)。セッションごとに 1 つ発行し、期限切れになったら再発行してください。そうすれば、漏洩したトークンはインシデントではなく 1 時間限りの問題で済みます。そして、オペレーター認証情報をブラウザーへ送ることは決してしないでください。これこそ、次のセクションが守ろうとしている唯一のルールです。

オペレーターとしてコントロールプレーンを呼び出すにはどうするか

コントロールプレーン (/control/v1/*) は、信頼されたバックエンドとオペレーターだけのためのものです。次の用途に使います。

  • ゲートウェイアカウントの作成と、その有効化・無効化
  • 課金システムが入金を回収した後の台帳調整の適用
  • アカウントごとのマージンの設定
  • アカウントトークンと API キーの発行
  • オペレーターの Webhook ファイアホースの登録
  • ウォレットとストレージ資金源の登録・管理
  • 監査および運用状態の読み取り

このプレーンはバックエンドの背後に置かれます。オペレーター認証情報は、支出権限を持つ本番のシークレットとして扱ってください。実際にその権限を持っているからです。日々の管理は短命のオペレータートークン(デフォルトでは 24 時間)が担い、ウォレットやストレージ資金源を登録するごく一部の操作のためには、シークレットストアに保管された単一のルートシークレットを取っておきます。

コントロールプレーンは、自社の課金システムとゲートウェイのプリペイド残高をつなぎ続ける仕組みです。自社のシステムで決済が成功すると、バックエンドがゲートウェイアカウントに対して、冪等な台帳調整を 1 つ適用します。これがクレジットの仕組みのすべてであり、なぜまさにこの形で作られているのかは、続く 2 つのセクションで説明します。

なぜゲートウェイのテーブルを直接クエリすべきでないのか

スキーマは契約ではないからです。契約となるのは HTTP API と Webhook です。

ゲートウェイエンジンは、自身の Postgres スキーマ (cw_corecw_api) を所有します。両方のシステムが同じ Postgres インスタンスを共有している場合でも、製品側はそれらを読み書きすべきではありません。スキーマの共存はサポートされたデプロイ形態ですが、境界はデータベースではなくスキーマです。それらのエンジンスキーマは内部的なものであり、予告なく変わり得る一方で、HTTP のプレーンとファイアホースは安定しています。この境界を越えて手を伸ばすと、通常のゲートウェイ更新が、気づかぬうちに製品を壊してしまいかねません。

API が公開していないデータが必要なら、それはスキーマをまたいで結合してよいという許可ではなく、提起すべき API のギャップとして扱ってください。

ゲートウェイのイベントから自前の画面を構築するにはどうするか

どの製品にも、自前のビューが必要です。送信済みレコード、顧客履歴、残高、公開の失敗、案件のタイムライン、証拠パッケージ、監査ダッシュボードなどです。これらを、すべての行をポーリングしたり、ゲートウェイの内部に結合したりして作ってはいけません。

代わりに、Webhook を登録し、イベントを自前のテーブルへ射影します。ゲートウェイはオペレーターのファイアホース、つまりインスタンス上のすべてのライフサイクルイベントに加え、より狭いワークフロー向けにアカウント単位の Webhook サブスクリプションを公開しています。「送信済み」ビューが代表的な例です。公開ステータスのイベントを取り込み、自前のテーブルへ射影し、そこから描画します。

配信は at-least-once(最低 1 回)なので、射影は冪等にしてください。実用的な読み取りモデルは、次のものをキーにできます。

  • イベント ID または配信 ID(再配信が何もしない操作になるように)
  • ゲートウェイのレコード ID
  • 最終的なトランザクションハッシュ
  • 自前のユーザー ID
  • 自前の業務オブジェクト ID
  • ステータスとタイムスタンプ

そうすればインターフェースは自前のテーブルから描画でき、その間ゲートウェイは支出、公開のライフサイクル、チェーンの事実についての権威であり続けます。各配信には署名が付いています。イベントを信頼する前に、署名を検証し、タイムスタンプの許容ウィンドウを適用してください。

課金とゲートウェイの間で資金はどう流れるべきか

モデルはシンプルに保ってください。ゲートウェイの残高が支出可能な残高であり、自社の課金システムはそこへ資金を届ける一手段にすぎません。

自社の課金経路は、カード、請求書、暗号資産による支払い、手動の企業向けクレジット、あるいは付与金を回収するかもしれません。ゲートウェイはそのいずれも知る必要がありません。きれいなパターンは次のとおりです。

  1. 自社の課金システムが決済を確定する。
  2. バックエンドが、決済の ID をキーとして、冪等な台帳調整を 1 つゲートウェイアカウントに適用する。
  3. ゲートウェイの残高が増える。
  4. 以後の公開・アップロード操作がその残高から引き落とす。
  5. 公開が恒久的に失敗した場合、ゲートウェイ自身がその引き落としを取り消す。

ここから 2 つの帰結が導かれます。第一に、冪等性が重要なのは、課金パイプラインが at-least-once で配信するからです。調整の参照として決済自身の ID を渡せば、1 件の決済が 5 回配信されても残高は 1 回だけ増えます。第二に、ゲートウェイの台帳を自前のテーブルにミラーして、そのミラーを支出判断の真実として扱ってはいけません。どうしても必要なら描画のためにキャッシュしても構いませんが、判断が実際に資金を動かすときは必ずゲートウェイを読んでください。ゲートウェイは自身で返金を発行するため、公開の失敗に対してベンダー側の返金パスを作るべきでもありません。それは二重返金になってしまいます。

各種の鍵はどこに置くべきか

ゲートウェイがユーザーの Identity Seed(アイデンティティの種)を必要とすることは決してありません。コンテンツのハッシュ化、封印付きペイロードの暗号化、レコードへの署名は、クライアントまたは SDK がローカルで行えます。ゲートウェイは、確定したレコードのバイト列を公開し、Cardano トランザクションを送信するだけです。(その境界がなぜ端から端まで重要なのかは、鍵がデバイスから出ない理由をご覧ください。)

完全な統合には、いくつかの異なる鍵のクラスがあり、避けるべき間違いは、それらを 1 つの「API シークレット」へ平坦化してしまうことです。それぞれ被害範囲がまったく異なります。

  • ユーザーの Identity Seed と受信者の秘密鍵。ユーザーの暗号上のアイデンティティであり、エッジに属します。
  • そのアイデンティティから導出される、レコード署名用の鍵。
  • アカウント API キーと短命のアカウントトークン。それを必要とする製品またはクライアントのコンテキストに属します。
  • オペレータートークンとルートシークレット。信頼されたバックエンドにのみ属します。
  • ゲートウェイ自身の Cardano およびストレージの署名鍵と、Webhook の署名シークレット。ゲートウェイのキーリングに属します。

各クラスを、それを保持できる最小の場所に対応づければ、ひとつの漏洩は封じ込められたままになります。

ホスト型ではなく自前でゲートウェイをホストすべきなのはいつか

運用上の独立性が利便性より重要なときに、自前でホストしてください。

ホスト型ゲートウェイは、ほとんどの統合にとって最もシンプルな道です。標準的な API サーフェス越しに、用意されたサービスを通じて公開でき、チェーンやストレージの運用を自分で行うことは一切ありません。自前でホストする場合は、そのシンプルさと引き換えに制御を得ます。自前の Cardano ウォレットへの資金供給、自前のストレージへの資金供給、自前のオペレーターポリシー、自前の稼働率とネットワーク依存、自前のマージン、自前のコンプライアンス境界、そして公開を第三者に依存しないこと、です。

しかし制御は責任でもあります。自前でホストするということは、ADA とストレージクレジットへの資金供給、キーリングの保護、Postgres の運用、チェーンプロバイダーの監視、バックアップの処理、認証情報のローテーション、Webhook の管理、そしてインシデントへの対応を、自分で行うということです。ベンダー依存はなくなりますが、運用作業はなくなりません。自前のゲートウェイを運用するでは、それが実際に何を伴うのかを順を追って説明します。

ユーザーは証明の中に何を見るべきか

ほとんどのユーザーは、まず製品の概念を目にするべきです。彼らが気にかけるのは「証拠を公開する」「このファイルを封印する」「このデータセットのスナップショットを証明する」「このリリースをチェーン上に記録する」といったことです。製品を使うためにメタデータ仕様を読まされるべきではありません。

とはいえ、どの証明ビューも、その主張を独立して確認可能にする事実を提示すべきです。

  • トランザクションハッシュ
  • ブロック時刻と確認状況
  • ハッシュアルゴリズムとダイジェスト
  • レコードが署名されている場合は、署名者の公開鍵
  • 存在する場合は、ストレージ URI
  • 関連する場合は、封印された受信者の状況
  • レコードが多数のファイルをバッチ処理している場合は、Merkle ルートとリーフ証明
  • 検証の判定そのもの

これが、その下にある暗号上の主張を隠すことなく、製品を快適に使い続けられるようにする方法です。

製品を 1 つのゲートウェイに固定しないようにするにはどうするか

ゲートウェイは公開を助けるものであり、決して証明そのものになってはいけません。

チェーン上のレコードは Label 309 メタデータであり、検証は次の 3 つの入力だけから機能するよう設計されています。トランザクションメタデータ、(任意で)コンテンツのバイト列、そして公開された Cardano エクスプローラーです。封印付きレコードを復号する場合にのみ、受信者の鍵が加わります。その信頼経路に発行者のサーバーは存在しません。仮に明日ご自身のゲートウェイが消えても、有効なレコードは独立したツールでなお検証できるはずです。あわせて覚えておく価値があるのは、そうした証明が何を主張し、何を主張しないかです。それは、まさにそのバイト列が公的に検証可能な時刻までに存在したことを示すのであって、それらに関する何らかの主張が真である、あるいはそれらが所有されている、認可されているといったことを示すものではありません

その約束を中心に製品を構築してください。

  • トランザクションハッシュを永続的に保存する
  • ユーザーが検証レポートをエクスポートし、証拠パッケージをダウンロードできるようにする
  • Merkle のリーフリストとその証明を保持する
  • インターフェースの外でレコードを検証する方法を文書化する
  • バックエンドだけが解釈できる非公開フィールドを避ける

これが「データベースに行がある」と「誰でも確認できる証明を生み出した」との違いです。

関連資料

gatewayapidevelopers