XRP LedgerのSponsored Fees and Reserves
はじめに
この記事はXLS-68dとして提案されているSponsored Fees and Reservesを紹介するものです。
この提案はまだ確定しているものではないため、今後変更される可能性があります。
Sponsored Fees and Reserves
概要
ブロックチェーン業界が成長するにつれて、多くのプロジェクトがブロックチェーン上でプロジェクトを行いたいと考え、ブロックチェーンの利用に関する複雑さを抽象化したいと考えています。これはユーザは自分でトランザクションを送信したり、トランザクション手数料を支払う必要がなく、プラットフォームにその複雑さを任せることを意味します。(もちろん、ユーザは自分の鍵を自身で管理します)
また、一部のプロジェクトではユーザをより簡単にオンボーディングしたいと考えており、ユーザが自身のアカウント準備金を支払う必要がなく、また準備金としてXRPを無料でアカウントに譲渡する必要もない方法を求めています(譲渡の方法では悪用された場合にかなり高額になる可能性があります)。
このようなユースケースに対応するため、この提案ではユーザが自身の鍵とアカウントの管理を維持しながら、別のアカウント(例:プラットフォーム)がトランザクション手数料や準備金を代わりに支払うプロセスを追加します。この提案はアカウントとオブジェクトの両方の準備金をサポートします。
他のチェーンでは、同様の機能は"sponsored transactions"、"meta-transactions"、または"relays"と呼ばれることがあります。
1. 概要
アカウントは、トランザクションにスポンサーの署名を含めることができ、これによりスポンサーがトランザクション手数料やトランザクションで作成されるアカウント/オブジェクトの準備金を負担することができます。
私たちは1つのレジャーオブジェクトの変更と1つの新しいトランザクションタイプの追加を提案します。
-
AccountRoot
レジャーオブジェクト -
SponsorTransfer
トランザクションタイプ
また、すべてのレジャーオブジェクトとすべてのトランザクションの共通フィールドも変更されます。
さらに、account_objects
RPCメソッドの変更と、account_sponsoring
という新しいRPCメソッドが追加されます。
この機能には暫定的にfeatureSponsor
と名付けられたAmendmentが必要になります。
1.1. 用語
- Sponsor: 別のアカウントに代わって準備金やトランザクション手数料を負担するアカウント。
- Sponsee: スポンサーがトランザクション手数料や準備金を負担する対象のアカウント。
- Owner: 特定のオブジェクト(またはアカウント自体)を所有するアカウント。多くの場合、Sponseeと同じ。
- Sponsored account: スポンサーが準備金を負担するアカウント(現在1XRPに設定)。
- Sponsored object: スポンサーが準備金を負担するアカウント以外のレジャーオブジェクト(現在0.2XRPに設定)。
- Sponsor relationship: スポンサーとSponseeの関係。
- Sponsorship type: スポンサーシップの種類 - トランザクション手数料のスポンサーシップか準備金のスポンサーシップか。
1.2. スポンサーシップのフロー
このシナリオでは、スポンサーのSpencerがSponseeのAliceのトランザクションの手数料や準備金を負担したいと考えています。
- Aliceはトランザクションを作成し、自動入力(autofill)を行います(手数料やシーケンス番号を含むすべてのフィールドがトランザクションに含まれるようにします)。また、Spencerのアカウントとスポンサーシップタイプをトランザクションに追加します。
- Spencerはトランザクションに署名し、その署名をAliceに提供します。
- AliceはSpencerの公開鍵と署名を自身のトランザクションに追加します。
- Aliceは通常通りトランザクションに署名して送信します。
1.3. スポンサーされたオブジェクトの準備金の回収
このシナリオでは、スポンサーのSpencerが、Aliceのオブジェクトのスポンサーシップによって負担されている準備金を回収したいと考えています。
SpencerはSponsorTransfer
トランザクションを送信することができ、これにより準備金の負担をAliceに戻すか、別のスポンサーに移すことができます。
1.4. スポンサーされたアカウントの準備金の回収
このシナリオでは、スポンサーのSpencerが、Aliceのアカウントのスポンサーシップから自身の準備金を回収したいと考えています。
これを行うには2つの方法があります。
- Aliceがアカウントの使用を終了する場合、
AccountDelete
トランザクションを送信することができ、これによりアカウントに残っているすべての資金がSpencerに返還されます。 - Aliceがアカウントの使用を継続したい場合、または別のプロバイダーに切り替えたい場合、AliceまたはSpencerが
SponsorTransfer
トランザクションを送信して、スポンサーシップを解除するか新しいプロバイダーに移転することができます。
2. レジャーオブジェクト: 共通フィールド
2.1. レジャー
現在すべてのレジャーオブジェクトが持つフィールドは以下の通りです。
フィールド名 | 必須? | JSONの型 | 内部の型 |
---|---|---|---|
LedgerIndex |
✔️ | 文字列 |
Hash256 |
LedgerEntryType |
✔️ | 文字列 |
UInt16 |
Flags |
✔️ | 数値 |
UInt16 |
以下のフィールドの追加を提案します。
フィールド名 | 必須? | JSONの型 | 内部の型 |
---|---|---|---|
SponsorAccount |
文字列 |
AccountID |
SponsorAccount
2.1.1. SponsorAccount
は、このレジャーオブジェクトの準備金を負担するスポンサーです。
AccountRoot
3. レジャーオブジェクト: 3.1. フィールド
参考として、こちらがAccountRoot
レジャーオブジェクトで現在利用可能なフィールドです。
フィールド名 | 必須? | JSONの型 | 内部の型 | 説明 |
---|---|---|---|---|
Account |
✔️ | 文字列 |
AccountID |
このアカウントの識別アドレス |
AccountTxnID |
文字列 |
Hash256 |
このアカウントが最後に送信したトランザクションの識別ハッシュ | |
AMMID |
文字列 |
Hash256 |
このアカウントがAMM疑似アカウントの場合、対応するAMMレジャーエントリーのID | |
Balance |
文字列 |
Amount |
アカウントの現在のXRP残高 | |
BurnedNFTokens |
数値 |
UInt32 |
このアカウントが発行したNFTの合計焼却数 | |
Domain |
文字列 |
Blob |
このアカウントに関連付けられたドメイン | |
EmailHash |
文字列 |
Hash128 |
メールアドレスのmd5ハッシュ | |
FirstNFTokenSequence |
数値 |
UInt32 |
アカウントが最初のNFTを発行した時点のシーケンス番号 | |
LedgerEntryType |
✔️ | 文字列 |
UInt16 |
0x0061 の値で、文字列AccountRoot にマッピングされ、これがAccountRoot オブジェクトであることを示す |
MessageKey |
文字列 |
Blob |
このアカウントに暗号化されたメッセージを送信するために使用できる公開鍵 | |
MintedNFTokens |
数値 |
UInt32 |
このアカウントによって/のために発行されたNFTの総数 | |
NFTokenMinter |
文字列 |
AccountID |
このアカウントの代わりにNFTを発行できる別のアカウント | |
OwnerCount |
✔️ | 数値 |
UInt32 |
このアカウントがレジャー上で所有するオブジェクトの数(オブジェクト準備金に影響) |
PreviousTxnID |
✔️ | 文字列 |
Hash256 |
このオブジェクトを最後に変更したトランザクションの識別ハッシュ |
PreviousTxnLgrSeq |
✔️ | 数値 |
UInt32 |
このオブジェクトを最後に変更したトランザクションを含むレジャーのインデックス |
RegularKey |
文字列 |
AccountID |
マスターキーの代わりにこのアカウントのトランザクションに署名するために使用できるキーペアのアドレス | |
Sequence |
✔️ | 数値 |
UInt32 |
このアカウントの次の有効なトランザクションのシーケンス番号 |
TicketCount |
数値 |
UInt32 |
このアカウントがLedger上で所有するTicketの数 | |
TickSize |
数値 |
UInt8 |
このアドレスが発行する通貨を含むOfferの為替レートに使用する有効桁数 | |
TransferRate |
数値 |
UInt32 |
このアカウントが発行した通貨を他のユーザ間で送信する際に課される転送手数料 | |
WalletLocator |
文字列 |
Hash256 |
ユーザが設定できる任意の256ビット値 | |
WalletSize |
数値 |
UInt32 |
未使用 |
以下の追加フィールドを提案します。
フィールド名 | 必須? | JSONの型 | 内部の型 |
---|---|---|---|
SponsorAccount |
文字列 |
AccountID |
|
SponsoredOwnerCount |
数値 |
UInt32 |
|
SponsoringOwnerCount |
数値 |
UInt32 |
|
SponsoringAccountCount |
数値 |
UInt32 |
SponsorAccount
3.1.1. SponsorAccount
フィールドは既にレジャーの共通フィールドで追加されていますが(セクション2.1.1参照)、AccountRoot
オブジェクトには追加のルールが関連付けられています。
このフィールドは、アカウントがスポンサーによってアカウント準備金が支払われて作成された場合に含まれます。このスポンサーされたアカウントが削除される場合、AccountDelete
トランザクションの送信先はSponsorAccount
と一致する必要があり、これによりスポンサーは手数料を回収できます。
注: アカウントがスポンサーされていない場合、AccountDelete
のDestination
フィールドは従来通り任意のアカウントに設定できます。
SponsoredOwnerCount
3.1.2. これは、アカウントが所有する、スポンサーによってスポンサーされているオブジェクトの数です。
SponsoringOwnerCount
3.1.3. これは、アカウントが準備金をスポンサーしているオブジェクトの数です。
SponsoringAccountCount
3.1.4. これは、アカウントが準備金をスポンサーしているアカウントの数です。
3.2. アカウントの準備金の計算
既存の準備金の計算は以下の通りです。
この提案によるアカウントの準備金は以下のように計算されるべきです。
4. トランザクション: 共通フィールド
4.1. Fields
参考として、こちらが現在すべてのトランザクションが持つフィールドです。
以下の変更を提案します。
フィールド名 | 必須? | JSONの型 | 内部の型 |
---|---|---|---|
Sponsor |
オブジェクト |
STObject |
Sponsor
4.1.1. Sponsor
内部オブジェクトには、トランザクションで発生するスポンサーシップに関するすべての情報が含まれます。
このオブジェクトに含まれるフィールドは以下の通りです。
フィールド名 | 必須? | JSONの型 | 内部の型 |
---|---|---|---|
Account |
✔️ | 文字列 |
AccountID |
Flags |
✔️ | 数値 |
UInt16 |
SigningPubKey |
文字列 |
STBlob |
|
Signature |
文字列 |
STBlob |
|
Signers |
配列 |
STArray |
4.1.1.1. Account
Sponsor.Account
フィールドはスポンサーを表します。
このフィールドは署名フィールドとなります(トランザクション署名に含まれます)。
4.1.1.2. Flags
Flags
フィールドにより、ユーザはスポンサーシップタイプを指定できます。Sponsor
フィールドがトランザクションに含まれる場合、少なくとも1つのフラグを指定する必要があります。
サポートされるフラグ値は次の2つです。
-
0x00000001
:tfSponsorFee
、トランザクション手数料のスポンサー(負担) -
0x00000002
:tfSponsorReserve
、トランザクションで作成されるオブジェクト準備金のスポンサー(負担)
このフィールドは署名フィールドとなります(トランザクション署名に含まれます)。
4.1.1.3. SigningPubKey
とSignature
これらのフィールドは、スポンサーが単一署名で署名する場合に含まれます(マルチシグとは対照的に)。このフィールドには、スポンサーからのトランザクションの署名が含まれ、このトランザクションへの承認を示します。Sponsor.Account
とSponsor.Flags
を含むすべての署名フィールドが署名に含まれる必要があります。
最終的なトランザクションにはSignature
またはSigners
のいずれかが含まれている必要があります。
Signature
フィールドの使用に対して追加のトランザクション手数料は必要ありません。
Signature
は署名フィールドではありません(トランザクション署名には含まれませんが、レジャーに保存されるトランザクションには含まれます)。
4.1.1.4. Signers
このフィールドには、スポンサーの署名者からのトランザクションの署名の配列が含まれ、このトランザクションへの承認を示します。Sponsor.Account
とSponsor.Flags
を含むすべての署名フィールドが含まれる必要があります。
最終的なトランザクションにはSignature
またはSigners
のいずれかが含まれている必要があります。
Signers
フィールドが必要な場合、処理する必要のある追加の署名のため、トランザクションの総手数料は増加します。これはマルチシグの追加手数料と同様です。最小手数料は
署名の総手数料計算は
このフィールドは署名フィールドではありません(トランザクション署名には含まれませんが、レジャーに保存されるトランザクションには含まれます)。
4.2. 失敗条件
4.2.1. 一般的な失敗
-
Sponsor.Signature
が無効 -
Sponsor.Signers
が無効(署名者リストがアカウントに存在しない、定足数に達していない、または署名が無効) - スポンサーアカウントがレジャー上に存在しない
- 無効なスポンサーシップフラグが使用されている
4.2.2. 手数料スポンサーシップの失敗
- スポンサーがトランザクション手数料を支払うのに十分なXRPを持っていない
4.2.3. 準備金スポンサーシップの失敗
- スポンサーが準備金を支払うのに十分なXRPを持っていない(
tecINSUFFICIENT_RESERVE
) - トランザクションが準備金のスポンサーシップをサポートしていない(セクション4.4参照)
4.3. ステートの変更
4.3. 状態変更
4.3.1. 手数料スポンサーシップの状態変更
手数料はSponseeではなくスポンサーから差し引かれます。以上です。
4.3.2. 準備金スポンサーシップの状態変更
トランザクションの一部として作成される任意のアカウント/オブジェクトにはSponsor
フィールドが付与されます。
スポンサーのSponsoringOwnerCount
フィールドは、トランザクションの一部としてスポンサーされるオブジェクトの数だけ増加し、SponsoringAccountCount
フィールドは、トランザクションの一部として新しくスポンサーされるアカウントの数だけ増加します。
SponseeのSponsoredOwnerCount
フィールドは、トランザクションの一部としてスポンサーされるオブジェクトの数だけ増加します。
これらのオブジェクト/アカウントが削除されると、SponsoredOwnerCount
、SponsoringOwnerCount
、およびSponsoringAccountCount
フィールドは減少します。
4.4. スポンサーシップをサポートしないトランザクション
すべてのトランザクション(pseudo-transactionを除く)は手数料が必要なため、tfSponsorFee
フラグを使用できます。
しかし、一部のトランザクションはtfSponsorReserve
フラグをサポートしません。
-
Batch
(XLS-56d)-
Batch
自身がそのフラグをサポートすることには意味がありません。代わりにサブトランザクションがtfSponsorReserve
を使用すべきです。
-
- すべてのpseudo-transaction(現在は
EnableAmendment
、SetFee
、およびUNLModify
)- これらのオブジェクトの準備金は特定のアカウントではなく、ネットワークによってカバーされます。
また、AccountSet
のような新しいオブジェクトやアカウントを作成しないトランザクションの場合、tfSponsorReserve
フラグを使用しても出力に変更はありません。
SponsorTransfer
5. トランザクション: このトランザクションは、特定のレジャーオブジェクトのオブジェクト準備金に対するスポンサー関係を移転します。スポンサー関係は新しいスポンサーに引き継がれるか、完全に解消される(Sponsee本人が準備金を負担する)かのいずれかです。スポンサーまたはSponseeは、いつでもこのトランザクションを送信できます。
5.1. フィールド
フィールド名 | 必須? | JSONの型 | 内部の型 |
---|---|---|---|
TransactionType |
✔️ | 文字列 |
UInt16 |
Account |
✔️ | 文字列 |
AccountID |
LedgerIndex |
文字列 |
UInt256 |
|
Sponsor |
オブジェクト |
STObject |
LedgerIndex
5.1.1. このフィールドは、トランザクションがスポンサーされたアカウントではなくスポンサーされたオブジェクトを扱う場合に含める必要があります。このフィールドは、関係が変更されるオブジェクトを示します。
含まれない場合は、トランザクションを送信するアカウントを指します。
Sponsor
5.1.2. Sponsor
フィールドは既にトランザクションの共通フィールドで追加されていますが(セクション4.1.1参照)、SponsorTransfer
トランザクションには追加のルールが関連付けられています。
Sponsor
がtfSponsorReserve
フラグと共に含まれる場合、提供されたオブジェクトの準備金スポンサーシップは、レジャーオブジェクトの所有者に戻るのではなく、Sponsor.Account
に移転されます。
Sponsor
フィールドがない場合、またはtfSponsorReserve
フラグが含まれていない場合、準備金の負担はレジャーオブジェクトの所有者(以前のSponsee)に戻されます。
5.2. スポンサーされたオブジェクトのスポンサーシップの終了
スポンサーされたレジャーオブジェクトにはSponsor
フィールドが付与されています。スポンサーされたオブジェクトのスポンサー関係を終了するには、LedgerIndex
パラメータが必要で、これによりどのLedgerオブジェクトかを指定します。
スポンサーされたレジャーオブジェクトのスポンサー関係を終了するSponsorTransfer
を送信できるのはそのオブジェクトのスポンサーまたはそのオブジェクトの所有者(Sponsee)の2つのアカウントです。
5.3. スポンサーシップの新しいアカウントへの移行
スポンサーシップは、tfSponsorReserve
フラグと共にSponsor
フィールドを含めることで、新しいアカウントに移行できます。これはスポンサーされたアカウントとスポンサーされたレジャーオブジェクトの両方で可能です。
スポンサー関係を移行するSponsorTransfer
を送信できるのはスポンサーまたはSponseeの2つのアカウントです。
スポンサーがこれを行いたいのは稀でしょう(アカウントを移転する場合など)が、Sponseeはプロバイダーを変更する場合に移行を希望するかもしれません。
5.4. 失敗条件
- スポンサーシップを移転する場合、新しいスポンサーがこのオブジェクト/アカウントの準備金のための十分なXRPを持っていない。
- スポンサーシップを解消する場合、所有者がこのオブジェクト/アカウントの準備金のための十分なXRPを持っていない。
- 新しいスポンサーが存在しない。
5.5. ステートの変更
- オブジェクトの
Sponsor
フィールドが変更または削除されます。 - 古いスポンサーの
SponsoringOwnerCount
/SponsoringAccountCount
が1減少します。 - 新しいスポンサー(該当する場合)の
SponsoringOwnerCount
/SponsoringAccountCount
が1増加します。 - 新しいスポンサーがいない場合、所有者の
SponsoredOwnerCount
が1減少します。
account_objects
6. RPC: 6.1. フィールド
account_objects
RPCメソッドは既にXRP Ledgerに存在します。参考として、account_objects
が現在受け付けるフィールドは以下の通りです。
フィールド名 | 必須? | JSONの型 |
---|---|---|
account |
✔️ | 文字列 |
deletion_blockers_only |
真偽値 |
|
ledger_hash |
文字列 |
|
ledger_index |
数値 または文字列
|
|
limit |
数値 |
|
marker |
任意 |
|
type |
文字列 |
以下の追加フィールドを提案します。
フィールド名 | 必須? | JSONの型 |
---|---|---|
sponsored |
真偽値 |
sponsored
6.2. このフィールドが除外された場合、スポンサーされているかどうかに関わらずすべてのオブジェクトが含まれます。sponsored == true
の場合、スポンサーされたオブジェクトのみが含まれます。sponsored == false
の場合、スポンサーされていないオブジェクトのみが含まれます。
account_sponsoring
7. RPC: account_sponsoring
RPCメソッドは、アカウントがスポンサーとなっているオブジェクトのリストを取得するために使用されます。具体的には、SponsorAccount
が指定されたアカウントであるオブジェクトのリストです。これはaccount_objects
メソッドと非常によく似たAPIを持っています。
フィールド名 | 必須? | JSONの型 | 説明 |
---|---|---|---|
account |
✔️ | 文字列 |
対象となるスポンサー |
deletion_blockers_only |
真偽値 |
true の場合、このアカウントの削除をブロックするオブジェクトのみがレスポンスに含まれます。デフォルトはfalse です |
|
ledger_hash |
文字列 |
使用するレジャーバージョンを表すハッシュ | |
ledger_index |
数値 または文字列
|
使用するレジャーインデックス、またはレジャーを自動的に選択するためのショートカット文字列 | |
limit |
数値 |
結果に含めるオブジェクトの最大数 | |
marker |
任意 |
以前のページネーションレスポンスからの値。そのレスポンスの続きからデータの取得を再開します | |
type |
文字列 |
レジャーエントリータイプによる結果のフィルタリング。例えばoffer やescrow など |
8. セキュリティ
8.1. セキュリティの原則
Sponseeとスポンサーの両方がスポンサー関係を結ぶことに同意する必要があります。Sponseeはスポンサーが準備金を扱うことを了承し、スポンサーはその準備金を引き受けることを承諾する必要があります。両者からの署名により、これが確保されます。
スポンサーは、もはや支援したくないSponseeのアカウントやオブジェクトのスポンサーシップに縛られることはありません。なぜなら、いつでもSponsorTransfer
トランザクションを送信できるからです。
スポンサーの署名には常にAccount
とSequence
フィールドが含まれている必要があります。これは署名のリプレイ攻撃(スポンサーの署名が、スポンサーが支援を望まないオブジェクトやアカウントに再利用される)を防ぐためです。
トランザクション手数料をスポンサーする場合、スポンサーはトランザクションのFee
値を承認する必要があります。これは、スポンサーが支払う金額だからです。
準備金をスポンサーする場合、スポンサーの署名には、アカウント/オブジェクトの準備金に関わる可能性のあるトランザクションのすべての側面が含まれている必要があります。これには、Payment
トランザクションのDestination
フィールド(および新規アカウントかどうか)や、TicketCreate
トランザクションのTicketSequence
フィールド(作成されるTicket
オブジェクトの数を決定し、それぞれがオブジェクト準備金を必要とする)が含まれます。
Sponseeはスポンサーの寛容さを悪用することはできません。なぜなら、スポンサーはレジャーオブジェクトのスポンサーになりたいすべてのトランザクションに署名する必要があるからです。また、Sponseeはスポンサーが望むスポンサーシップタイプを変更することはできません。これは、スポンサーのXRPを最大50まで拘束する可能性があるためです(1つのTicketCreate
トランザクションで250枚のチケットが作成される場合)。
スコープ外の原則: Sponseeはスポンサーシップの移転に対して制御権を持ちません。これは、借り手が銀行による住宅ローンの他社への売却や、貸し手による債権回収会社への債権売却を制御できないのと同様です。
8.2. 署名
手数料スポンサーシップはFee
フィールドを承認する必要があり、準備金スポンサーシップは広範なトランザクションフィールドを承認する必要があるため、スポンサーは常にトランザクション全体に署名する必要があります。これにより、異なるスポンサーシップタイプに対して異なるスポンサーシッププロセスを持つ必要もなくなります。これにはSponsor
オブジェクトの非署名部分(Sponsor.Account
とSponsor.Flags
)も含まれます。Sponseeのトランザクション署名についても同様です。Sponseeはスポンサーとスポンサーシップタイプを承認する必要があります。
スポンサーのSignature
は、別のトランザクションに再利用または添付することはできません。なぜなら、トランザクション全体(Account
とSequence
値を含む)に署名する必要があるからです。
9. 不変条件
不変条件は、XRPLの有効なすべてのステートの変更に対して常に真でなければならない文(通常は方程式)です。不変条件チェックはバグに対する最後の防衛線として機能します。不変条件が違反された場合(理想的には決して起こらないはず)、tecINVARIANT_FAILED
エラーがスローされます。
9.1. Owner Countの追跡
レジャーオブジェクトを作成するトランザクションは、アカウントのOwnerCount
を1増加させるか、2つの別々のアカウントのSponsoringOwnerCount
とSponsoredOwnerCount
を1増加させます。レジャーオブジェクトが削除される場合は、その逆が起こります。
SponsoringAccountCount
についても同様のことが起こります。
SponsoredOwnerCount
とSponsoringOwnerCount
のバランス
9.2. 言い換えると、すべてのアカウントのSponsoredOwnerCount
の合計は、すべてのアカウントのSponsoringOwnerCount
の合計と等しくなければなりません。これにより、スポンサーされている各オブジェクトがスポンサーされているとして記録され、かつスポンサーを持っていることが保証されます。
10. 実装例
各例では、スポンサーとSponseeの両方がトランザクションに署名する前と後の両方のトランザクションの状態を示します。
未署名のトランザクションは、スポンサーに渡される前に自動入力(autofill)される必要があります。ツールは、マルチシグのためのヘルパー関数と同様に、スポンサーとSponseeの署名を組み合わせるように更新できます。
10.1. 手数料スポンサーシップ
10.1.1. 未署名のトランザクション
{
TransactionType: "Payment",
Account: "rOldB3E44wS6SM7KL3T3b6nHX3Jjua62wg",
Destination: "rNewfcu9RJa5W1ncAuEgLH1Xpi4j1vzXjr",
Amount: "20000000",
Sequence: 3,
Fee: "10",
Sponsor: {
Account: "rSponsor1VktvzBz8JF2oJC6qaww6RZ7Lw",
Flags: 1
}
}
10.1.2. 署名済みのトランザクション
{
TransactionType: "Payment",
Account: "rSender7NwD9vmNf5dvTbW4FQDNSRsfPv6",
Destination: "rDestinationT6N5fJdaHnRqLpW1D8oFrZ",
Amount: "20000000",
Sequence: 3,
Fee: "10",
Sponsor: {
Account: "rSponsor1VktvzBz8JF2oJC6qaww6RZ7Lw",
Flags: 1,
SigningPubKey: "03072BBE5F93D4906FC31A690A2C269F2B9A56D60DA9C2C6C0D88FB51B644C6F94", // rSponsor's public key
Signature: "3045022100C15AFB7C0C4F5EDFEC4667B292DAB165B96DAF3FFA6C7BBB3361E9EE19E04BC70220106C04B90185B67DB2C67864EB0A11AE6FB62280588954C6E4D9C1EF3710904D"
},
SigningPubKey: "03A8D0093B0CD730F25E978BF414CA93084B3A2CBB290D5E0E312021ED2D2C1C8B", // rAccount's public key
TxnSignature: "3045022100F2AAF90D8F9BB6C94C0C95BA31E320FC601C7BAFFF536CC07076A2833CB4C7FF02203F3C76EB34ABAD61A71CEBD42307169CDA65D9B3CA0EEE871210BEAB824E524B"
}
10.2. アカウントスポンサーシップ
アカウントを作成する唯一の方法はPayment
トランザクションを通じてです。そのため、スポンサー関係はPayment
トランザクション上で開始される必要があります。
10.2.1. 未署名のトランザクション
{
TransactionType: "Payment",
Account: "rOldB3E44wS6SM7KL3T3b6nHX3Jjua62wg",
Destination: "rNewfcu9RJa5W1ncAuEgLH1Xpi4j1vzXjr",
Amount: "20000000",
Sequence: 3,
Fee: "10",
Sponsor: {
Account: "rSponsor1VktvzBz8JF2oJC6qaww6RZ7Lw",
Flags: 2
}
}
10.2.2. 署名済みのトランザクション
{
TransactionType: "Payment",
Account: "rOldB3E44wS6SM7KL3T3b6nHX3Jjua62wg",
Destination: "rNewfcu9RJa5W1ncAuEgLH1Xpi4j1vzXjr",
Amount: "20000000",
Sequence: 3,
Fee: "10",
Sponsor: {
Account: "rSponsor1VktvzBz8JF2oJC6qaww6RZ7Lw",
Flags: 2,
SigningPubKey: "03072BBE5F93D4906FC31A690A2C269F2B9A56D60DA9C2C6C0D88FB51B644C6F94", // rSponsor's public key
Signature: "30440220702ABC11419AD4940969CC32EB4D1BFDBFCA651F064F30D6E1646D74FBFC493902204E5B451B447B0F69904127F04FE71634BD825A8970B9467871DA89EEC4B021F8"
},
SigningPubKey: "03BC74CA0B765281E31E342017D97B3F6743A05FBA23D2114B98FC8AD26D92856C", // rAccount's public key
TxnSignature: "30440220245217F931FDA0C5E68B935ABB4920211D5B6182878583124DE4663B19F00BEC022070BE036264760551CF40E9DAFC8B84036FA70E7EE7257BB7E39AEB7354B2EB86"
}
10.3. オブジェクトスポンサーシップ
10.3.1. 未署名のトランザクション
{
TransactionType: "TicketCreate",
Account: "rAccount4yjv1j2x79wXxRVXnFbwsjUWXo",
TicketCount: 100,
Sequence: 3,
Fee: "10",
Sponsor: {
Account: "rSponsor1VktvzBz8JF2oJC6qaww6RZ7Lw",
Flags: 2
}
}
10.3.2. 署名済みのトランザクション
{
TransactionType: "TicketCreate",
Account: "rAccount4yjv1j2x79wXxRVXnFbwsjUWXo",
TicketCount: 100,
Sequence: 3,
Fee: "10",
Sponsor: {
Account: "rSponsor1VktvzBz8JF2oJC6qaww6RZ7Lw",
Flags: 2,
SigningPubKey: "03072BBE5F93D4906FC31A690A2C269F2B9A56D60DA9C2C6C0D88FB51B644C6F94", // rSponsor's public key
Signature: "30450221009878F3A321250341886FE344E0B50700C8020ABAA25301925BD84DDB5421D432022002A3C72C54BACB5E7DAEC48E2A1D75DCBB8BA3B2212C7FC22F070CCABAF76EC1"
},
SigningPubKey: "03BC74CA0B765281E31E342017D97B3F6743A05FBA23D2114B98FC8AD26D92856C", // rAccount's public key
TxnSignature: "3044022047CB72DA297B067C0E69045B7828AD660F8198A6FA03982E31CB6D27F0946DDE022055844EB63E3BFF7D9ABFB26645AA4D2502E143F4ABEE2DE57EB87A1E5426E010"
}
付録
付録A: よくある質問
A.1: Sponseeは準備金のためのXRPを受け取りますか?
いいえ、スポンサーシップ関係ではXRPの移転は発生しません。XRPはスポンサーのアカウントに留まります。そのオブジェクト/アカウントの準備金の負担がスポンサーに移転されるだけです。
A.2: スポンサーされたオブジェクトを持っている状態でアカウントを削除しようとするとどうなりますか?
アカウント自体がスポンサーされている場合、削除できますが、AccountDelete
トランザクションの送信先(つまり、残りのXRPの行き先)は必ずスポンサーのアカウントでなければなりません。これにより、スポンサーが準備金を取り戻すことができ、Sponseeがそれらの資金を持ち逃げすることを防ぎます。
Sponseeがまだスポンサーされているオブジェクトを持っている場合、それらのオブジェクトは削除ブロッカーのルールに従います。スポンサーされているかどうかは関係ありません。
スポンサーされているオブジェクトが削除された場合(通常のオブジェクト削除プロセスによる場合や、削除ブロッカーではないオブジェクトの場合は所有者アカウントが削除された場合)、スポンサーの準備金は再び利用可能になります。
A.3: いくつかのオブジェクトをスポンサーしているスポンサーがアカウントを削除したい場合はどうなりますか?
アカウントは、いずれかの既存のアカウントやオブジェクトをスポンサーしている場合、削除できません。それらのオブジェクトを削除する(ように所有者に依頼する)か、SponsorTransfer
トランザクションを使用して制御を放棄する必要があります。
A.4: スポンサーは、準備金を支払っているオブジェクトに対して何か権限を持っていますか?例えば、オブジェクトを削除できますか?
いいえ。スポンサーがオブジェクトのサポートを継続したくない場合は、代わりにSponsorTransfer
トランザクションを使用できます。
A.5: スポンサーがアカウントのサポートを停止したい場合に、Sponseeがアカウントの削除を拒否した場合はどうなりますか?
スポンサーは債務者に連絡を取って支払いを求める一般的な問題に直面することになります。Sponseeが支払いのためのXRPを十分に持っている場合は、SponsorTransfer
トランザクションを使用してSponseeに負担を移すことができます。
SponsorTransfer
を試みたが、Sponseeが準備金をカバーするのに十分な資金を持っていない場合はどうなりますか?
A.6: スポンサーがスポンサーが本当に急いでスポンサー関係から抜け出す必要があり、準備金の価値を取り戻すことを諦める場合は、Sponseeに準備金をカバーするのに必要なXRPを支払うことができます。これらのステップはBatchトランザクションを通じてアトミックに実行でき、SponseeがSponsorTransfer
トランザクションが検証される前に資金を他の目的に使用することを防ぐことができます。
A.7: スポンサーされたアカウントはより低い準備金を持ちますか?
いいえ、現在のレベルで1XRPの準備金を持ち続けます。
A.8: 既存のスポンサーされていないレジャーオブジェクトやアカウントをスポンサーされたレジャーオブジェクトやアカウントにできますか?
はい、SponsorTransfer
トランザクションを使用して可能です。
A.9: スポンサーされたアカウントが他のアカウント/オブジェクトのスポンサーになることはできますか?
いいえ。
A.10: スポンサーされたアカウントはスポンサーされていないオブジェクトや、異なるスポンサーによってスポンサーされたオブジェクトを保持できますか?
はい。
A.11: 同じトランザクションに対して、トランザクション手数料と準備金で異なるスポンサーを持ちたい場合はどうしますか?
この提案ではサポートされません。このニーズがある場合は、ユースケースの例を提供してください。
A.12: トランザクションに2つの署名を追加するのは難しいのではないでしょうか?
これは良いツールで解決できる問題です。マルチシグが様々なツールでサポートされているのと同様に機能する可能性があります。
A.13: なぜ[他のデザイン]ではなくこのデザインなのですか?
検討された代替デザインとこのデザインが選ばれた理由については付録Bをご覧してください。他のデザインをお考えの場合は、コメントで説明していただければ議論できます。
XLS-23d、Liteアカウントとどう違う/優れているのですか?
A.14: このアカウントスポンサーシップモデルは- スポンサーされたアカウントには制限がなく、オブジェクトを保持できます。
- スポンサーされたアカウントは通常のアカウントと同じ準備金を必要とします(これはLiteアカウント提案への反対意見の1つでした)。
- Liteアカウントはスポンサーによって削除できます。
A.15: 複数のアカウントが準備金を保持する可能性のあるトラストラインのようなオブジェクトの場合、これはどのように機能しますか?
この質問への回答はまだ検討中です。考えられる解決策の1つは、他の準備金を処理するために2番目のフィールドSponsor2
を追加することです。
XLS-49dとどのように連携しますか?どの署名者リストが手数料や準備金をスポンサーする権限を持ちますか?
A.16: この提案は現在、グローバル署名者リストのみがサポートされています。スポンサーシップをサポートするために別のSignerListID
値を追加することができます。トランザクション値はTransactionType
フィールドがUInt16
であるためSignerListID
フィールドは
付録B: 代替の設計
Sponsor
を追加する
B.1: アカウントにこのデザインでは、ユーザがアカウントにSponsor
を追加できるようにAccountSet
を更新することを含んでいました(スポンサーからの署名も必要)。スポンサーは、そのフィールドがアクティブな間、そのアカウントからのすべてのオブジェクトをスポンサーすることになり、スポンサーまたはアカウントはいつでもスポンサーシップを解除できました。
これは仕様の以前のバージョンでしたが、関係をトランザクション/トランザクション固有にする方が理にかなっていました。これにより、乱用を防ぐことができます(スポンサーは、サポートしたいオブジェクトとサポートしたくないオブジェクトを決定できます)。
現在のデザインは、異なるオブジェクトに対して異なるスポンサーを持つことも可能にし、ユーザが1つのサービスやプラットフォームにロックインされるのではなく、幅広いサービスやプラットフォームを使用できるようにします。
B.2: ラッパートランザクション
スポンサーが署名するXLS-56dのBatch
に似たラッパートランザクション(仮称Relay
)があり、Sponseeからのサブトランザクションを含むというデザインでした。
以下のような形になります。
フィールド名 | 必須? | JSONの | 内部の型 |
---|---|---|---|
TransactionType |
✔️ | 文字列 |
UInt16 |
Account |
✔️ | 文字列 |
STAccount |
Fee |
✔️ | 文字列 |
STAmount |
Transaction |
✔️ | オブジェクト |
STTx |
これは仕様の以前のバージョンの一部でした(Stellarのサンドイッチトランザクションデザインによって着想を得ました)が、既存のデザインの方がよりクリーンに感じられました。実装の観点からは、手数料支払者を既存のトランザクションの一部として持つ方が、ラッパートランザクションの一部として持つよりも簡単です。その情報をスタックの下層に渡す必要があるためです。また、ラッパートランザクションのパラダイムはXLS-56dで使用されますが、rippled
コードでのフローが複雑になるため、必要な場合にのみ慎重に使用すべきです。
さらに、署名プロセスが複雑になります(XLS-56dの開発過程で発見されたように)。ラッパートランザクションに含めずに、スポンサーが署名済みのトランザクションをそのままネットワークに送信することを何らかの方法で防ぐ必要があります。
B.3: 作成-承認-キャンセルのフロー
このデザインの大まかなアイデアは、スポンサーが既存のオブジェクトの準備金を引き受けることができる新しい一連のトランザクション(例: SponsorCreate
/SponsorAccept
/SponsorCancel
/SponsorFinish
)を持つことでした。
このデザインは真剣に検討されませんでした。複雑すぎると感じられ、いくつかの新しいトランザクションを導入する必要があったためです。また、オブジェクト作成時にスポンサーを追加することをサポートしていませんでした。これは、所有者/Sponseeが一時的に準備金のためのXRPを保持する必要がないため、よりスムーズなUXを提供します。
Discussion