ブログに戻るorder-execution

署名済み注文からオンチェーン取引まで

予測市場の注文を署名、検証、一部約定、手数料、取消、オンチェーン決済まで追い、各状態が何を証明するかを解説します。

署名済みのガラス製注文カードが、緑の確認印の付いた記録用の台座に入る。

注文への署名は、指定条件で取引する許可を与える操作です。取引が完了したことを意味しません。 APIが受理し、板で一部がマッチングしても、決済トランザクションは失敗する可能性があります。

「PolymarketとKuestの仕組み」の第五回では、つながったYESとNOの注文板を支える承認を追います。システムの各層をたどり、参加者の署名対象、マッチングサービスが適用する条件、ブロックチェーンに実際に記録される内容を区別します。

指示から始め、資産を追う

「観測所Aは、日付Cの12:00 UTCに都市Bの気温が30.0°C以上だったと公表するか」という仮定の問いを使います。YESの購入は指定された結果資産の取得ですが、BUY注文への署名は取得を許可するだけです。

標準的な二択のConditional Tokens Framework(CTF)の市場と、一般的な担保単位を使います。金額例は、小数桁が六桁で、資金と権限が十分にあり、ガスと資金調達費用はないと仮定します。手数料は明記した箇所で別に扱います。

以下では、公開署名標準、公開CTF Exchangeの例、仮定の資産移動を使います。対応ウォレット、注文タイプ、手数料など各プラットフォーム固有の情報は、その時点の公開連携ドキュメントで確認する必要があります。

三つの承認は別の役割を持つ

注文署名は特定の取引指示を承認します。API認証 はサービスに対する許可された要求元を識別します。ウォレットのバッチ署名 は、支出許可の設定など、別にまとめたウォレット呼び出しを承認します。

API認証情報は、サービスの許可された要求元を識別するもので、参加者の秘密鍵ではなく、注文署名を代替しません。Polymarketの公開ウォレット・認証ガイドが、文書化された製品例を示しています。

注文署名は取引条件を承認し、API認証情報はサービス要求を認証し、ウォレットのバッチ署名はウォレット呼び出しを承認する。それぞれ別の経路。

対象も検証も別です。ウォレットのバッチには独自のnonceと期限がありますが、それらがそのまま 取引注文の一部になるわけではありません。

EIP-712は、構造化メッセージのハッシュ化と署名を定義しています。ドメインによって指示をチェーン、アプリ名、バージョン、検証コントラクトに結び付け、別ドメイン向けの署名がそのまま有効になるのを防げます。

公開CTF Exchange V2署名コードは、アプリ固有のEIP-712ドメインの例です。ドメイン名とバージョンは署名対象の文脈の一部であり、別の取引コントラクトも同じメッセージを受け付けるという証拠ではありません。再利用の制限には、実際のコントラクトの状態と検証ルールも関わります。

数量が価格を表す

公開CTF Exchange V2の注文定義では、署名する指示にトークン、売買の側、makerとtakerの数量、アカウントの識別情報などが含まれます。署名が承認するのはその定義済みメッセージであり、あとから画面が表示する任意の価格ではありません。

ここでのmakerは資産を出すアカウントの名前で、その注文がすぐに流動性を消費する場合も同じです。板に残った注文を別の注文が消費するという、取引上の役割としてのmakerとは、フィールド名の意味が異なります。

BUYでは、makerAmountが提供する担保、takerAmountが希望する持分です。100 YESに対して60を提供する注文の指値は60 ÷ 100 = 0.60です。一方、100 YESを60で売るSELLの価格はtakerAmount ÷ makerAmountになります。

この比率を上書きする独立した署名済み価格フィールドはありません。対応する数量を作り直して再署名しなければ、表示価格を変えても承認済みの条件は変わりません。

タイムスタンプは注文の作成時刻を表していても、強制される失効期限とは限りません。連携実装では、署名フィールドとサービス向けの指示を区別し、現行の公開注文仕様でその意味を確認する必要があります。

検証によって板への登録可否が決まる

注文前に、意図する資産、指値、数量、アカウント、対応注文タイプを確認します。クライアント側の検証やAPIの受付応答は、コントラクト決済の成功を代替しません。

価格刻みは、提示価格の間に認められる増分です。署名前に市場の最新の公開仕様を確認してください。クライアントの検証、サービスの応答、コントラクトのルールは、それぞれ異なることを示します。画面に最小値があるだけでは、オンチェーンの制約がある証拠にはなりません。

資金と権限は別々に確認します。BUYには使用可能な担保と、決済コントラクトへの十分な支出許可が必要です。SELLには結果トークンと転送承認が必要です。署名だけではどちらも用意されず、受付時の残高確認で、その後のアカウントの変更をすべて止められるわけでもありません。

Post-only は、すぐ流動性を消費するのではなく、板に残る注文を追加する意図の指示です。対応する組合せと拒否動作をプラットフォームの文書で確認してください。この名称だけで、すべての実装の動作は定まりません。

注文の有効期間・執行条件は、未約定数量をどう扱うかをマッチングサービスに指示します。

サービス上の注文の失効と、コントラクトに署名した期限は別の約束です。現行仕様がどこで失効を強制し、送信済みトランザクションをどう扱うか確認します。要求にフィールドがあるだけでは、コントラクトの保証にはなりません。

マッチングしても決済の成功が必要

学習用の段階として、署名済み → 受付済み・板に待機 → マッチング済み → 送信済み → 確認済みを考えます。注文は登録前に拒否されることもあり、一つの受付済み注文から、複数の部分マッチングと決済トランザクションが発生することもあります。これは責任の違いを説明するラベルで、共通のAPI列挙値の定義ではありません。

署名済み注文が受付を通り、板に残って一部がマッチングし、その後トランザクション送信と成功レシートに至る。拒否と実行取消の分岐が、受付と確認の違いを示す。

有効期間・執行条件が認める場合、部分マッチング後の残数量は次のマッチングを待ちます。決済が失敗した場合は、 再試行の前に実際の結果を照合する必要があります。

公開CTF Exchange V2コントラクトは、権限のあるマッチングと、資産移動前のコントラクト検証の例です。第4回の直接売買・新規発行・結合の例は、起こり得る資産移動と必要な資金を説明しています。

トランザクションは不可分です。必要な転送や検証がリバートすれば、そのトランザクションの状態変更は巻き戻されます。ただし、別の成功済みトランザクションまで元には戻らず、リバートした処理でもガスを消費する場合があります。

トランザクションハッシュは送信した処理を識別するもので、購入成功の証明ではありません。レシートと、選んだネットワークが求める確認状態を調べます。結果が判明するまでは、画面も不確実性を保ち、資産を受け取ったと表示すべきではありません。

運営者の画面では、注文ID、マッチング数量、トランザクション参照を別々に保持します。処理が失敗した、または結果が不明なら、再試行の前に実際の成否を照合してください。ローカルのラベルを変えても資産は移動しません。

一部約定では、提供した資産が消費される

板に残るBUYが100 YESに対し担保60を提供し、最初の約定で40 YESをちょうど0.60で受け取るとします。手数料を除くと、消費するのは担保24で、署名済みの購入余力として担保36が残ります。同じ価格なら60 YESに相当します。

100 YESを担保60で売る未約定のSELLは、その約定で40 YESを消費し、担保24を受け取ります。残りのmaker数量は 60口であって、担保36ではありません。両注文とも残り60 YESを取引できますが、オンチェーンで残りを数える資産は異なります。

BUYのmaker数量は、40 YESに24を支払うと資金60から36へ減る。SELLのmaker数量は、40を売って資金24を受け取ると100 YESから60へ減る。

同じ40口の約定でも、残数量の単位が異なります。指値と一致する価格で執行し、手数料は除きます。

公開CTF Exchange V2の計算は、最小単位の整数を使います。以下の比例計算・切り捨てモデルでは、受取数量は提供数量 × 署名済みtaker数量 ÷ 署名済みmaker数量を切り捨てた値です。正確な照合には、実際の経路の丸め方が必要です。

たとえば、3口を担保1.8で売る署名済み注文から1.000001口を売る場合、1,000,001 × 1,800,000 ÷ 3,000,000を計算し、担保の最小単位で600,000に切り捨てます。小口の約定や手数料には実装の丸め方が必要で、丸め済みの表示価格を掛けるだけでは正確に照合できません。

手数料は別の台帳で整理する

100 YESを担保60で直接買い、各参加者に仮定の手数料0.60がかかるとします。買い手には担保60.60が必要で、売り手の受取は59.40です。残る1.20が合計手数料なので、買い手の全支出を説明できます。

買い手の担保支払60.60は、代金60と手数料0.60。売り手は自分の手数料0.60を引いた59.40を受け取り、手数料受取先には合計1.20が計上される。

仮定の手数料であり、現在の料金ではありません。買い手の支出60.60 = 売り手の受取59.40 + 合計手数料1.20。既存の100 YESは買い手へ移ります。

この具体例では、BUYの手数料を買い手の必要資金に加え、SELLの手数料を売却代金から差し引きます。実際の料金、受取先、丸め方は、選んだプラットフォームと経路で確認してください。この例は料金表ではありません。

取消が及ぶ範囲を理解する

未約定注文を取り除く要求は、まだ執行していない残数量に関するものです。完了した約定を元には戻しません。取消の確認と、進行中の決済トランザクションは別の記録として扱い、資金を再利用する前に両方を確認します。

すでに決済が送信されていた場合、その後の板の取消で停止を約束することはできません。特に元の注文が一部約定しているときは、資産をまだ使えると考える前に、トランザクションの結果を確認してください。

マッチングの決済をチェーンへ送信した後の板の取消は残りの注文を取り除くが、送信済み処理は成功する可能性がある。取引システムのユーザー停止とウォレットの緊急操作には、それぞれ別の待機時間がある。

残りの取消と、先にマッチングした取引の決済は両方起こり得ます。遅延のある保護機能のどちらも、 成功済みトランザクションを元には戻しません。

アカウント全体への制限は、一つの注文の取消とは異なります。復旧機能には、それぞれ異なる対象範囲、待機時間、権限があります。すべての操作が即時停止になると考えず、実際のアカウントの公開コントラクトと製品ドキュメントを確認してください。

Deposit Walletには、緊急出金や承認取消の前に、別の停止と緊急待機時間があります。そのコードでは、ウォレットの停止だけでバッチ実行や署名検証が無効になるわけではなく、取引を即座に止める機能ではありません。

バージョン名だけでは連携方法は決まらない

Polymarketの従来のCTF注文は、taker、expiration、nonce、feeRateBpsに署名していました。別系統のCTF Exchange V2注文では、これらを取り除いてtimestamp、metadata、builderを追加しています。価格は引き続き数量の比率です。

V2のリポジトリはfillOrder/fillOrdersも削除し、matchOrdersによるオペレーターのマッチングを残しています。このCTF Exchange V2は、polymarket-v2-externalのProtocol V2のポジション構造とは異なります。Kuestに、どちらかのリポジトリの更新が自動的に反映されるわけでもありません。

コントラクトの構造体に失効フィールドがなくても、製品に期限付き注文がないとは限りません。Polymarketの現在のライフサイクルドキュメントは製品上のGTDを説明し、ポジションのガイドはCTFとProtocol V2の台帳を区別しています。連携を作る前に、実際の市場の経路を確認してください。

Kuest運営者が明示すべきこと

Kuestの公開運営者ガイドは、運営者のアプリと共通サービスを区別しています。参加者には、対応するアカウント操作、合計手数料の見積もり、受付・マッチング・確認という異なる状態を示します。これらは観察可能な製品要件であり、内部実装の詳細ではありません。

Kuestの公開手数料ドキュメントは、運営者の取引手数料への参加と、設定可能なアフィリエイト配分を説明しています。手数料の配分は、取引元本への追加請求とは異なります。参加者の支払額を説明する際は、現在の公開設定と決済記録を使ってください。

独自ブランドの運営者にとっては、正しいbuilderの識別情報を保ち、実際の合計料金を表示し、その配分を決済記録と照合するという具体的な連携判断になります。コードや独自の画面だけで、受付、手数料を受け取る権利、収入が保証されるわけではありません。

参加者に理解できる執行方針を用意して、Kuestで独自の予測市場を立ち上げましょう。対象者の法域、正確な市場ルールと結果確定経路、必要な取引数量、対応するウォレット操作、手数料情報、受付・マッチング・確認を区別した状態表示を整理します。