ウォレットアドレスは決済システムではありません。それは単なる「送り先」であり、それ以上の何物でもありません。その文字列を知っている人なら誰でも、いつでも、何をでも送ることができます。信頼関係のある二者間の単発の取引なら、それで十分かもしれません。しかし、SaaS製品、マーケットプレイス、あるいはオンラインショップを運営している場合、チェックアウトページに静的なアドレスを貼り付けることは、運用の混乱を招くことになります。正体不明のトランザクションを実際の顧客と照合し、誰が何を支払ったのかを推測し、誰かが間違ったネットワークで間違ったトークンを送ってきたときにその混乱を片付けることに、日々を費やすことになるでしょう。
スケーラブルなものを作るには、「寄付箱」のような考え方をやめ、構造化された決済システムとして考え始める必要があります。
なぜウォレットアドレスではスケールしないのか
問題はコンテキスト(文脈)、あるいはその欠如にあります。顧客があなたのウォレットアドレスをコピーし、取引所やセルフカストディ・ウォレットから暗号資産を送金したとき、ブロックチェーンに記録されるのは「何が動いたか」だけです。つまり、金額、タイムスタンプ、そして2つの公開アドレスです。請求書番号は記録されません。顧客IDも含まれません。その送金がサブスクリプションの更新なのか、日割り計算によるアップグレードなのか、あるいは全く新しい購入なのかも分かりません。
毎月500人の顧客にステーブルコインで請求を行っているSaaS企業を考えてみましょう。もしすべての顧客が同じ静的なアドレスにUSDTを送金した場合、経理チームはスプレッドシートの悪夢に直面します。一つの送金が別の送金と全く同じに見えるからです。午前2時に届いた20ドルが、顧客Aのプラン更新なのか、それとも顧客Bのサイクル途中でのアップグレードなのかを判断することはできません。ブロックチェーンが見ているのは「数字」です。ビジネスが必要としているのは「ストーリー」なのです。
マーケットプレイスでは、取引の両側でこの問題に直面します。買い手が資金を預け入れたことを確認し、売り手が商品を発送する間それを保持し、配送確認後にのみ資金を解放する必要があります。生の(単なる)アドレスでは、買い手の入金と、ランダムな入金やベンダー自身の資金をプログラム的に区別する方法がありません。Eコマースも同様に混乱しています。トランザクションを特定の注文に紐付けなければ、フルフィルメント(注文履行)をトリガーすることはできません。誰かが手動でチェーンをスキャンし、送金を見つけ、データベースを更新しなければなりません。これを一日に10回行えば、照合ミスが発生します。1,000回行えば、損失につながります。
この転換はシンプルですが、極めて重要です。「アドレスに資金が届いたか」を問うのをやめましょう。「特定の支払いリクエストが正しい状態に達したか」を問い始めるのです。
支払いリクエストを中心に構築する
信頼できる暗号資産決済フローは、支払いリクエストを中央オブジェクトとして扱います。ウォレットアドレスは、そのリクエストに奉仕するために存在する一時的なコンテナとなります。リクエストには、ブロックチェーンの送金を認識可能なビジネスイベントへと変えるメタデータが含まれます。
チェックアウトの選択肢を提示する前に、支払いを識別可能にするデータポイントを定義してください:
- 購入またはサブスクリプションID:なぜ資金が移動しているのかを正確に把握するため。
- 期待される金額:小数点以下まで指定。
- 正確なアセットとネットワークの種類:Ethereum上のUSDT送金は、TronやPolygon上の送金とは互換性がないため。
- 顧客または内部アカウントへの参照。
- 有効期限:3月の未払い見積もりが、誤って6月の注文を完了させないようにするため。
顧客が「支払う」をクリックすると、システムはこれらのフィールドを含むリクエストを生成します。顧客はその特定の「リクエスト」に対して支払うのであり、単なる「アドレス」に対して支払うのではありません。オンチェーンのトランザクションには、オフチェーンのアイデンティティが付与されます。あなたのシステムは、ブロックエクスプローラーに問い合わせる前に、その支払いが何のためのものかを把握できるのです。
ステータスを正確にモデル化する
ブロックチェーン上の資金移動には段階があります。内部システムには、それらの段階に対応する用語体系が必要です。そうでなければ、エンジニアリング、サポート、運用の各チーム間で意思疎通が図れなくなってしまいます。
モデルはフラットで説明的なものに保ってください。技術的な知識のないサポート担当者がステータスを読み、顧客に何を伝えるべきかを理解できるようにします。
- Created: リクエストは存在しますが、ブロックチェーン上にはまだ何も表示されていません。顧客がトランザクションをブロードキャストしていません。
- Detected: モニタリングによって、mempoolまたは最近のブロック内で関連するトランザクションが検知されましたが、ファイナリティ(確定性)が不足しています。製品は発送しないでください。
- Confirming: トランザクションはオンチェーンにあり、承認(コンファメーション)が蓄積されています。チェーンによって進行速度は異なります。Bitcoinでは6ブロックが必要な場合があり、Ethereumではリスク許容度に応じて12ブロック以上が必要になる場合があります。システムはネットワーク自体の挙動に従う必要があります。
- Completed: 支払いが、期待される金額、アセット、ネットワーク、およびコンテキストと一致しています。定義されたすべてのルールが満たされました。これで、注文の履行、サブスクリプションの有効化、またはエスクローの解除が可能になります。
- Expired: 顧客が支払い期限を過ぎました。明示的に再有効化しない限り、このリクエストで将来の支払いを受け付けてはいけません。
- Mismatch: 顧客は資金を送金しましたが、何らかの問題があります。金額が不足している、ネットワークが異なる、あるいはアセットが一致していません。これはサポートに回してください。フルフィルメントシステムに推測させてはいけません。
このパイプラインにより、混沌としたチェーンデータのストリームを、会社全体が論理的に理解できるプロセスへと変換します。
ポーリングをやめ、リスニングを開始する。
インフラ予算を最も早く使い果たす方法の一つは、バックエンドがプロバイダーに対して、数秒おきに「入金は完了したか」と問い合わせることです。これは双方のリソースを浪費し、不要なレイテンシを生じさせます。
より優れたアーキテクチャは、ステータス通知モデルを採用することです。決済プロバイダーまたはノードインフラストラクチャは、ステータスが変化した瞬間にシステムへイベントをプッシュすべきです。トランザクションが検知されたときにウェブフックを受け取り、承認中(confirming)のときにもう一つ、完了または失敗したときに最後の一つを受け取ります。
これにより、不要なCPUサイクルを消費することなく、システムのレスポンスを維持できます。
