2015-05-06にOpen Asset Protocolに新しく追加されていた仕様「Open Assets Extensions to Payment Requests」をざっと訳してみる。
この機能は、通常のBitcoinに代わってOpen Assets Protocolを使ってBIP-70とBIT-21で定義されている支払いを行うための仕様。
(BIP-70は売り手と顧客のBitcoinを使った決済プロセス中の中間者攻撃を防ぐために定義されたプロトコルで、BIP-21はBitcoinの支払いで使われるURI Schemeについて定義した仕様)
動機
Open Assetsの支払いを受け取る売り手は、顧客と支払いの詳細について便利で安全な方法を用意する必要がある。顧客には、Bitcoinの支払いとOpen Assetsの支払い両方(もしくは指定したどちらか1つの方法)をサポートする標準的なメカニズムが必要になる。
標準的なBitcoinの支払いでは、Bitcoinという1つのアセットのみしかサポートできないが、Open Assets Protocolでは多くの異なるアセットが利用できるので可能性が広がる。そのためリスクなくアセットを別のものや色付けされていないBitcoinと交換できる方法は興味深いもので、この仕様では、単一のトランザクションでこれを実現する方法を説明する。
Open Assets Payment Request
売り手がOpen Assetsの単位で支払いを受けとれるようにするには、BIP-70に次の拡張が必要になる。
- Payment Requestには、Open Assetsに互換性の無いウォレットからの取引を防ぐために、payment_details_version(値は0x4f41)というデータを含める必要がある。
(0x4f41というのは、Open Assetのトランザクション内のMarker outputに含められるOpen Assets Transactionであることを示すタグと同じ値) - Output メッセージのscript部を"optional bytes asset_id = 4001;"とし、160-bitのAsset IDを含める形で拡張する。
- Output メッセージのamount部を"optional uint64 asset_amount = 4002;"とアセットの量を含める形で拡張する。
量に関しては、オプションフィールドのoutput.amountもあるが、これは(将来利用されるため)利用できない。支払いを行う送信者は、充分なsatoshiを含める必要がある。このへんはトランザクションに充分な採掘料を加えるのに似ている。
output.amountを指定した場合は、output.asset_idとoutput.asset_amountは指定してはいけない。これは出力が純粋なbitcoinの出力であることを意味している。
4001と4002というタグを使うのは、将来の支払いのリクエストの拡張との競合を避けるためで、将来、Open Assetsとの互換性をもたせることも考えられてる。
Open Assets Atomic Swap
bitcoinとassetsの交換を有効にするのに、repeated Inputを利用する。入力には売り手が支払いと引き換えに顧客に提供するものを定義する。
message PaymentDetails { optional string network = 1 [default = "main"]; repeated Output outputs = 2; (...) repeated Input inputs = 8; } message Input { required bytes txhash = 1; required uint32 index = 2; }
txhash | インプットに使われるトランザクションの32byteのハッシュのバイナリ |
index | txhashが参照するトランザクション内の出力のインデックス |
inputを参照すると、クライアントは提案されているアセットと量を決定することができる。売り手は必要なトランザクションの変更を決めるため、Outputフィールドを使う必要がある。クライアントは、assetと純粋なBitcoinに関してネット転送される値を計算する際、入力と出力両方のアカウントを取得する必要がある。
クライアントは指定された全ての入力を含み、それぞれの入力に対して空の署名スクリプトを使用する。
クライアントは独自の入力と出力のいずれかの前にトランザクション内の指定された入力と出力を含める必要がある。
入力が指定されている場合は、まだ完全に署名されていないのでネットワークに中継してはいけないが、Paymentメッセージ内にPaymentDetails.payment_urlをラップして直接売り手に送信する必要がある。また入力のPayment Requestは、必ず有効なpayment URLを含んでいる必要があり、そうでない場合はリジェクトする必要がある。
MIME types for Open Assets Payment Requests
売り手と顧客がどのPayment Request typeがサポートされているか確認できるようにするため、BIP-71とBIP-73に対して以下の拡張を提案する。
Open Assets Payment Requestsではmedia typeとして"application/oa-paymentrequest"を使用しバイナリとして符号化する。
HTTPヘッダ"Accept:"は、ウォレットで利用可能なMIMEタイプリストアップするのに使われる。ウォレットが通常のBitcoinの支払いとOpen Assetsの支払い両方をサポートする場合、両方のMIMEタイプ(application/bitcoin-paymentrequestとapplication/oa-paymentrequest)がリストアップされる。Open Assetsの支払いのみサポートしてる場合は、Open AssetsのMIMEタイプしか使われない。売り手が要求されたタイプのいずれかでもサポートできない場合は、HTTPエラーコード406(Not Acceptable)を返す。
Payment URI
アドレスへの直接支払いを可能にするため、Bitcoin URI(BIP-21,BIP-72)への拡張を提案する。
- bitcoin:スキーマに加えて、openassets:スキーマを追加する。これは売り手がクライアントがOpen Assets互換のソフトウェアを使ってOpen Assetsの支払いをしようとしていることを確認するために必要となる。
- 標準のBitcoinアドレスのエンコーディングに代わって、Open Assets Addressのエンコーディングを利用できるようにする。Open Assets AddressのフォーマットについてはOpen Assets Address Formatの仕様(訳) - Develop with pleasure!参照。
- 既存のクエリパラメータ(rとかamountとか)に加えて、Asset IDを判別するたのassetを追加する。
注意:通常のBitcoinでの支払いとOpen Assetsでの支払い両方ともサポートしている売り手は、bitcoin:スキーマを使い、Accept:を使ってクライアントの意図を検出する必要がある。Open Assetsw認識しないウォレットによってそのようなURIが公開された場合、互換性のないアドレスエンコーディングを検出し支払いを拒否する。