XRP LedgerのMulti-Purpose Tokensとは?
はじめに
この記事はXLS-33dとして提案されているMulti-Purpose Tokens (MPT)を紹介するものです。
元々はCompact Fungible Token(CFT)として提案されていましたが、その後MPTと変更されています。
この提案はまだ確定しているものではないため、今後変更される可能性があります。
1. Multi-Purpose Tokens (MPTs)
1.1. 概要
トラストラインは、CBDCやフィアット担保ステーブルコインを含む、多くのXRP Ledgerのトークン化機能の基本的な構成要素です。しかし、より多くのトークン発行者がXRP Ledgerを採用するにつれて、各トラストラインの現在のサイズは、レジャーの安定性とスケーラビリティの障害となるでしょう。
本提案では、より多目的なトークン(MPT)をサポートするために、XRP Ledgerの拡張と、そのようなトークンの列挙、購入、売却、保持のための操作を導入します。
トラストラインとは異なり、MPTは双方向の債務関係を表すものではありません。その代わり、MPTは残高が1つしかない一方向のトラストラインのように機能します。そのため、一般的なトークン化の要件をサポートしやすくなり、オンライン・ゲームでの評価ポイントの追跡のような非貨幣的なユースケースもサポートできます。
しかし、おそらく同じくらい重要なのは、MPTはトラストラインよりもかなり少ないスペースしか必要としないということです。トラストラインは1つにつき 少なくとも 234バイトですが、MPTは1つにつき最大52バイトです。(詳細な比較は付録1をご覧ください)
1.1.1. メリットとデメリット
メリット
- 浮動小数点表現の代わりに固定小数点での残高表現を使用しているため、次のような利点があります。
- MPT 残高金額は、エスクロー、小切手、支払いチャネル、AMMなどの他のレジャーオブジェクトに簡単に追加できます。
- 信頼性が高く、簡単に不変チェックを実施し、手数料を簡単に追跡できます。
- 期待される等式条件に違反する非常に少額の浮動小数点演算のエッジケースを排除(例えば、MPTは、非ゼロの
B
に対してA+B=A
や、(A+B)+C != A+(B+C)
のようなケースを扱う必要がありません)。
- よりシンプルな概念モデル(トラストラインとリップリングは開発者がシステムを推論することを難しくし、エラーや価値損失のリスクを高めます)。
- より少ないコストでより多くのトークンを保持するためのより多くのアカウントを可能にするトラストラインのストレージ要件を削減します。
- ノードオペレータの長期的なインフラとストレージの負担を軽減し、ネットワークの回復力を高めます。
- 大量のMPTトランザクションを処理する際のノードパフォーマンスの向上。
デメリット
- MPTはXRPとIOUに続く第三の資産タイプをレジャーに導入することになり、ペイメントエンジンの実装が複雑になります。
- 新しい取引やデータ型は、クライアントライブラリやウォレットが読み取り、表示、取引するための新しい実装コードを必要とします。
- MPTは、トラストライン(トラストラインは、およそ10^-96から10^-80の間の膨大な範囲を表すことができます)と比較して、全体的な残高額が小さくなります。
1.1.2. 前提
この提案では、データを最もコンパクトに表現するために、既存のトラストラインの使用状況の観測に基づき、さまざまな前提を置いています。これらの仮定には以下が含まれます。
- 単方向のみ: ほとんどのトークン発行者は、トラストラインの上限をデフォルトの0に設定している(つまり、発行者はデフォルトでトークン保有者との債務関係を許可していない)ことを前提として、本提案では双方向のトラストライン構築をサポートしません。従って、MPTには、トラストラインに見られるような「残高相殺」の機能はありません。なぜなら、トラストラインでは2つの残高があるのに対し、MPTでは1つの残高しかないからです。
- 発行体ごとの発行数が少ない: 最も一般的なトークンの例では、規制のオーバーヘッドを伴うため、一般的なケースでは、発行者が多くのトークンを発行することはあまりありません。さらに、既存のxrpl.orgに関するガイダンスでは、グローバルフリーズの行動に対応するため、トークン発行者はトークン発行ごとに異なるアドレスを使用するようアドバイスしています。このため、個々の発行者が同じアドレスを使用して多くの異なるトークンを発行することはないと想定しています。特に、この仕様では、1つの発行アカウントにつき、ユニークなMPTの発行数を32個に制限しています。発行者がこの数以上のMPTをサポートしたい場合、追加のアドレスを使用することができます。
- トラスト上限なし: 現在のトラストラインの機能では、どちらか一方の当事者によってトラスト量の上限を設定することができますが、この提案では、トークン保有者が最初にオフレジャーのトラスト決定を行わずにMPTを取得することはないという前提の下、この機能を排除します。例えば、MPT の一般的なユースケースは、法定通貨を裏付けとするステーブルコインであり、トークン保有者は、自分が安心して保有できる以上のステーブルコインを購入することはないでしょう。
- リップリングなし: 既存のレジャーのいくつかの機能とは異なり、MPTはリップリングの対象ではないため、その機能に関する設定もありません。
1.1.3 リリーススケジュールと範囲
XLS-33では、MPTの新しいデータ構造の追加、ユーザがMPTからMPTへの支払いを行えるようにするための Payment
トランザクションとの統合(つまり、異なる種類の通貨をまたいだ支払いはできません)、アカウント削除に関する新しい要件(後述)のような他のいくつかの付随的な追加のみをカバーする予定です。今後のAmendmentでは、MPTをDEXなどXRPLの他の機能と統合する予定です。
1.2. Multi-Purpose Tokenの作成
1.2.1. オンレジャーのデータ構造
2つの新しいオブジェクトと1つの新しいレジャー構造を提案します。
-
MPTokenIssuance
は、発行者が作成したトークンを定義する新しいオブジェクトです。 -
MPToken
は、ひとつのアカウントが保有するトークンを表す新しいオブジェクトです。
MPTokenIssuance
オブジェクト
1.2.1.1. MPTokenIssuance
オブジェクトはMPTの発行を表し、発行そのものに関連するデータを保持します。トークンは MPTokenIssuanceCreate
トランザクションで作成され、オプションで MPTokenIssuanceDestroy
トランザクションで破棄することができます。
1.2.1.1.1. MPTokenIssuance
のレジャー識別子
MPTokenIssuance
オブジェクトのキーは、以下の値のSHA512-Halfを順番に連結したものです。
- MPTokenIssuanceスペースキー(0x007E)。
- トランザクションのシーケンス番号。
- 発行者のAccountID。
MPTokenIssuance
オブジェクトのID(別名MPTokenIssuanceID
)は192ビットの整数で、順番に連結されます。
- トランザクションのシーケンス番号。
- 発行者のAccountID。
┌──────────────────────────┐┌──────────────────────────┐
│ ││ │
│ シーケンス ││ 発行者のAccountID │
│ (32 bits) ││ (160 bits) │
│ ││ │
└──────────────────────────┘└──────────────────────────┘
注記: MPTokenIssuanceID
は、ユーザーがインターフェイスに入力するものです。内部的には、レジャーはMPTokenIssuanceID
をsequence
とissuer
アドレスの2つの要素に分割します。
1.2.1.1.2. フィールド
MPTokenIssuance
オブジェクトはレジャーに保存され、発行者が所有するオーナーディレクトリで追跡されます。発行には、以下の必須フィールドとオプショナルフィールドがあります。
フィールド名 | 必須? | JSONの型 | 内部の型 |
---|---|---|---|
LedgerEntryType |
✅ | number |
UINT16 |
Flags |
✅ | number |
UINT32 |
Issuer |
✅ | string |
ACCOUNTID |
AssetScale |
(default) | number |
UINT8 |
MaximumAmount |
✅ | string |
UINT64 |
OutstandingAmount |
✅ | string |
UINT64 |
LockedAmount |
️(default) | string |
UINT64 |
TransferFee |
️(default) | number |
UINT16 |
MPTokenMetadata |
string |
BLOB |
|
PreviousTxnID |
✅ | string |
HASH256 |
PreviousTxnLgrSeq |
️✅ | number |
UINT32 |
OwnerNode |
(default) | number |
UINT64 |
Sequence |
✅ | number |
UINT32 |
1.2.1.1.2.1. LedgerEntryType
値0x007E
は文字列MPTokenIssuance
にマッピングされ、このオブジェクトが多目的トークン(MPT)であることを示します。
1.2.1.1.2.2. Flags
この MPTokenIssuance
オブジェクトに関連付けられたプロパティやその他のオプションを示すフラグのセットです。型特有のフラグを指定します。
フラグ名 | フラグ値 | 説明 |
---|---|---|
lsfMPTLocked |
️0x0001
|
設定されている場合、すべての残高がロックされていることを示します。 |
lsfMPTCanLock |
️0x0002
|
設定されている場合、発行者がこのMPTの個々の残高またはすべての残高をロックできることを示します。設定されていない場合、MPTはいかなる方法でもロックできません。 |
lsfMPTRequireAuth |
️0x0004
|
設定されている場合、_ 個々の_ 保有者が認可されなければならないことを示します。これにより、発行者は資産を保有できる人を制限することができます。 |
lsfMPTCanEscrow |
0x0008 |
設定されている場合、個々の保有者が残高をエスクローに預けることができることを示します。 |
lsfMPTCanTrade |
0x0010 |
設定されている場合、XRP LedgerのDEXまたはAMMを使用して、 個々の 保有者が残高を取引できることを示します。 |
lsfMPTCanTransfer |
️0x0020
|
設定されている場合、発行者以外が保有するトークンを他のアカウントに転送できることを示します。設定されていない場合、発行者以外が保有するトークンは発行者に返却する以外には転送できないことを示します。 |
lsfMPTCanClawback |
️0x0040
|
設定されている場合、発行者がClawback トランザクションを使用して、個々の 保有者から価値を取り戻すことができることを示します。 |
MPTokenIssuanceSet
トランザクションで変更できるlsfMPTLocked
を除き、これらのフラグは変更不可です。MPTokenIssuanceCreateトランザクションでのみ設定でき、後で変更することはできません。
1.2.1.1.2.3. Issuer
特定のトークンの発行量と性質を管理するアカウントのアドレス。
1.2.1.1.2.4. AssetScale
資産スケールとは、標準単位と対応する分数単位との間の桁数の差のことです。より正式には、資産スケールは、1つの標準単位が対応する端数単位の10^(-スケール)に等しくなるような非負整数(0, 1, 2, ...)です。端数単位が標準単位に等しい場合、資産スケールは0です。
1.2.1.1.2.5. MaximumAmount
この値はMPTを発行していないアカウント(つまりminted
)に配布できる最大数を指定する符号なし数値です。最大数を持たない発行の場合、この値は0xFFFFFFFFFFFFFFに設定されます。
1.2.1.1.2.6. OutstandingAmount
すべてのトークン保有者に発行されたすべてのトークンの金額の合計を指定します。この値はdefault
型としてレジャーに保存することができます。この値は、発行者が非発行者アカウントにMPTを支払うたびに増加し、非発行者が発行者アカウントにMPTを支払うたびに減少します。
1.2.1.1.2.7. TransferFee
この値は、トークンの二次売買が許可されている場合に、発行者がその二次売買に課す手数料を、basis pointの10分の1で指定します。このフィールドの有効な値は0から50,000です。1の値は1/10 basis pointまたは0.001%に相当し、0%から50%の間の送金手数料を設定することができます。50,000のTransferFee
は50%に相当します。送金手数料の小数点以下は切り捨てられるため、支払いが少額の場合は手数料をゼロに切り捨てることができます。発行者はMPTのAssetScale
が十分大きいことを確認してください。
1.2.1.1.2.8. PreviousTxnID
このオブジェクトを最も最近変更したトランザクションのトランザクションIDを表します。
1.2.1.1.2.9. PreviousTxnLgrSeq
このオブジェクトを最近変更したトランザクションを含むレジャーのシーケンス番号を表します。
1.2.1.1.2.10. OwnerNode
このアイテムが参照されているオーナーディレクトリのページを表します。
1.2.1.1.2.11. Sequence
MPTokenIssuance
の識別子で、MPTokenIssuanceID
を作成するために使用します。
1.2.1.1.3. Example MPTokenIssuance
JSON
{
"LedgerEntryType": "MPTokenIssuance",
"Flags": 131072,
"Issuer": "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW",
"AssetScale": "2",
"MaximumAmount": "100000000",
"OutstandingAmount": "5",
"TransferFee": 50000,
"MPTokenMetadata": "",
"OwnerNode": "74"
}
1.2.1.1.4. MPTokenIssuance
オブジェクトはどのように機能しますか?
どのアカウントでも、任意の数の多目的トークンを発行できます。
1.2.1.1.4.1. MPTokenIssuance
オブジェクトの検索
MPTokenIssuanceオブジェクトは、タイプ固有の接頭辞、発行者アドレス、およびトランザクションシーケンス番号の組み合わせによって一意に識別されます。特定の MPTokenIssuance
を見つけるには、まず発行者のオーナーディレクトリを検索します。次にMPTokenIssuance
のレジャーオブジェクトを保持しているディレクトリを見つけ、各エントリを繰り返し検索して目的のキーを持つインスタンスを見つけます。そのエントリが存在しない場合、 MPTokenIssuance
は指定されたアカウントに存在しません。
1.2.1.1.4.2. MPTokenIssuance
オブジェクトの追加
MPTokenIssuance
オブジェクトを追加するには、同じ方法で MPTokenIssuance
を見つけ、そのディレクトリに追加します。追加後、ディレクトリ内のMPTの数が32を超えるようであれば、その操作は失敗しなければなりません。
1.2.1.1.4.3. MPTokenIssuance
オブジェクトの削除
MPTokenIssuance
も同じ方法で削除することができますが、 OutstandingAmount
が0に等しい場合に限ります。
1.2.1.1.4.4. MPTokenIssuance
オブジェクトの準備金
それぞれの MPTokenIssuance
には、オーナーアカウントへの準備金の増分がかかります。
MPToken
オブジェクト
1.2.1.2. MPToken
オブジェクトはトークン発行者ではないアカウントが保有するトークンの量を表します。MPTは通常のPaymentまたはDEXトランザクションによって得られるもので、任意でこれらの同じタイプのトランザクションを使用して償還または交換することができます。MPToken
のオブジェクトキーは、スペースキー、保有者のアドレス、およびMPTokenIssuanceID
をハッシュして生成されます。
1.2.1.2.1. MPToken
のレジャー識別子
MPTokenオブジェクトのID(別名MPTokenID
)は、以下の値のSHA512-Halfを順番に連結したものです。
- MPTokenスペースキー(0x0074)。
- 保有するトークンの
MPTokenIssuanceID
。 - トークン保有者のAccountID
1.2.1.2.2. フィールド
MPToken
オブジェクトは以下のフィールドを持つことができます。各MPTokenのキーはMPToken
を保持するアカウントのオーナーディレクトリに格納されます。
フィールド名 | 必須? | JSONの型 | 内部の型 |
---|---|---|---|
LedgerEntryType |
✅ | number |
UINT16 |
Account |
✅ | string |
ACCOUNTID |
MPTokenIssuanceID |
✅ | string |
UINT192 |
MPTAmount |
✅ | string |
UINT64 |
LockedAmount |
default | string |
UINT64 |
Flags |
default | number |
UINT32 |
PreviousTxnID |
✅ | string |
HASH256 |
PreviousTxnLgrSeq |
✅ | number |
UINT32 |
OwnerNode |
default | number |
UINT64 |
MPTokenNode |
default | number |
UINT64 |
1.2.1.2.2.1. LedgerEntryType
値0x007F
は文字列MPToken
にマップされ、このオブジェクトが個々のアカウントがMPTを保有を表します。
1.2.1.2.2.2. Account
MPToken
の所有者を表します。
1.2.1.2.2.3. MPTokenIssuanceID
MPTokenIssuance`の識別子を表します。
1.2.1.2.2.4. MPTAmount
この値は、オーナーが現在保持しているトークンの正の量を指定します。このフィールドの有効な値は、0x0から0xFFFFFFFFFFFFの間です。
1.2.1.2.2.5. LockedAmount
この値は、トークン保有者のアカウントに現在保有されているが、トークン保有者が使用することができないトークンの量を指定します。ロックされたトークンは、例えば、現在エスクローで保持されている値や、トークン保持者がアクセスできない値を表します。
この値は、空のMPTを保持するためのレジャーのスペースを節約するために、デフォルト
値として0
が格納されます。
1.2.1.2.2.6. Flags
この MPTokenIssuance
オブジェクトに関連付けられたプロパティやその他のオプションを示すフラグのセットです。型固有のフラグを表します。
フラグ名 | フラグ値 | 説明 |
---|---|---|
lsfMPTLocked |
0x0001 |
このフラグがセットされている場合、このアカウントが所有するMPTは現在ロックされており、発行者に値を送り返す以外のXRPトランザクションでは使用できないことを示します。このフラグがセットされている場合、LockedAmount は MPTAmount と等しくなければなりません。 |
lsfMPTAuthorized |
0x0002 |
(許可されている場合にのみ適用可能)セットされていれば、発行者がMPTの所持者を認可したことを示します。このフラグはMPTokenAuthorize トランザクションを使用して設定することができ、tfMPTUnauthorize フラグを指定したMPTokenAuthorize トランザクションを使用して「設定解除」することもできます。 |
1.2.1.2.2.7. PreviousTxnID
このオブジェクトを最も最近変更したトランザクションのトランザクションIDを表します。
1.2.1.2.2.8. PreviousTxnLgrSeq
このオブジェクトを最近変更したトランザクションを含むレジャーのシーケンス番号を表します。
1.2.1.2.2.9. OwnerNode
このアイテムが参照されているオーナーディレクトリのページを表します。
1.2.1.2.2.10. MPTokenNode
MPTディレクトリはOwner Directoryとまったく同じ構造をしていますが、1つのMPTokenIssuance
に対してMPTokens
だけをインデックスする新しいタイプのディレクトリです。このディレクトリの所有権については、MPTokenNodeディレクトリで引き続き議論されます。
1.2.1.2.3. MPTokenのJSON例
{
"LedgerEntryType": "MPToken",
"Account": "rajgkBmMxmz161r8bWYH7CQAFZP5bA9oSG",
"MPTokenIssuanceID": "00070C4495F14B0E44F78A264E41713C64B5F89242540EE255534400000000000000",
"Flags": 0,
"MPTAmount": "100000000",
"LockedAmount": "0",
"OwnerNode": 1,
"MPTokenNode": 1
}
1.2.1.2.4. MPToken
オブジェクトの準備金
それぞれの MPToken
は、所有者アカウントに増分準備金を必要とします。
1.3 トランザクション
本提案では、MPT発行の作成と削除を可能にするために、いくつかの新しいトランザクションを導入します。同様に、本提案では、MPTの個別のインスタンスを作成および償還するための新しいトランザクションをいくつか導入します。本提案で導入されるすべてのトランザクションは、すべてのトランザクションで共有される共通トランザクションフィールドを組み込んでいます。共通フィールドは、本提案がそのようなフィールドに新しい可能な値を導入するため、必要でない限り、本提案では文書化されません。
1.3.1 XRPLにおける多目的トークンの作成と破棄のためのトランザクション
MPT発行に関連する3つのトランザクションを定義します。
MPTokenIssuanceCreate
と MPTokenIssuanceDestroy
と MPTokenIssuanceSet
で、それぞれXRPL上でMPT Issuance を作成、破棄、更新します。
MPTokenIssuanceCreate
トランザクション
1.3.1.1 MPTokenIssuanceCreate
トランザクションは MPTokenIssuance
オブジェクトを作成し、作成者アカウントの関連するディレクトリノードに追加します。このトランザクションはissuer
が不変と定義されているトークンのフィールド(MPTフラグなど)を指定する唯一の手段です。
トランザクションが成功すると、新しく作成されたトークンはトランザクションを実行したアカウント(作成者アカウント)が所有することになります。
1.3.1.1.1 トランザクションのフィールド
フィールド名 | 必須? | JSONの型 | 内部の型 |
---|---|---|---|
TransactionType |
️ ✅ | object |
UINT16 |
新しいトランザクションタイプ MPTokenIssuanceCreate
を表します。
フィールド名 | 必須? | JSONの型 | 内部の型 |
---|---|---|---|
AssetScale |
️ | number |
UINT8 |
アセットスケールとは、標準単位と対応する分数単位との間の桁数の差のことです。より正式には、資産スケールは非負の整数(0, 1, 2, ...)で、1つの標準単位が対応する端数単位の10^(-1*スケール)に相当します。端数単位が標準単位と等しい場合、資産スケールは0となります。この値はオプションであり、指定しなかった場合のデフォルトは0
となることに注意してください。
フィールド名 | 必須? | JSONの型 | 内部の型 |
---|---|---|---|
Flags |
️ | number |
UINT16 |
このトランザクションのフラグを指定します。すべてのトランザクションに適用される共通のトランザクションフラグ(tfullyCanonicalSig
など)に加えて、以下のトランザクション固有のフラグが定義され、トークンの適切なフィールドを設定するために使用されます。
フラグ名 | フラグ値 | 説明 |
---|---|---|
lsfMPTLocked |
️0x0001
|
設定されている場合、すべての残高がロックされていることを示します。 |
lsfMPTCanLock |
️0x0002
|
設定されている場合、発行者がこのMPTの個々の残高またはすべての残高をロックできることを示します。設定されていない場合、MPTはいかなる方法でもロックできません。 |
lsfMPTRequireAuth |
️0x0004
|
設定されている場合、_ 個々の_ 保有者が認可されなければならないことを示します。これにより、発行者は資産を保有できる人を制限することができます。 |
lsfMPTCanEscrow |
0x0008 |
設定されている場合、個々の保有者が残高をエスクローに預けることができることを示します。 |
lsfMPTCanTrade |
0x0010 |
設定されている場合、XRP LedgerのDEXまたはAMMを使用して、 個々の 保有者が残高を取引できることを示します。 |
lsfMPTCanTransfer |
️0x0020
|
設定されている場合、発行者以外が保有するトークンを他のアカウントに転送できることを示します。設定されていない場合、発行者以外が保有するトークンは発行者に返却する以外には転送できないことを示します。 |
lsfMPTCanClawback |
️0x0040
|
設定されている場合、発行者がClawback トランザクションを使用して、個々の 保有者から価値を取り戻すことができることを示します。 |
フィールド名 | 必須? | JSONの型 | 内部の型 |
---|---|---|---|
TransferFee |
number |
UINT16 |
この値は、トークンの二次売買が許可されている場合に、発行者が請求する手数料を指定します。このフィールドの有効な値は0から50,000の間で、0.001刻みで0.000%から50.000%の転送レートを許容します。
tfMPTCanTransfer
フラグが設定されていない場合、このフィールドは存在してはなりません(MUST NOT)。もし設定されていれば、そのトランザクションは失敗します。
フィールド名 | 必須? | JSONの型 | 内部の型 |
---|---|---|---|
MaximumAmount |
string |
UINT64 |
このトークンの発行可能な最大資産額。
フィールド名 | 必須? | JSONの型 | 内部の型 |
---|---|---|---|
MPTokenMetadata |
string |
BLOB |
このトークンに関する任意のメタデータ。このフィールドの上限は1024バイトです。
1.3.1.1.2 MPTokenIssuanceCreate
トランザクションの例
{
"TransactionType": "MPTokenIssuanceCreate",
"Account": "rajgkBmMxmz161r8bWYH7CQAFZP5bA9oSG",
"AssetScale": "2",
"TransferFee": 314,
"MaxAmount": "50000000",
"Flags": 83659,
"MPTokenMetadata": "FOO",
"Fee": 10
}
このトランザクションは、トークンの発行者がトランザクションの署名者であることを前提としています。
MPTokenIssuanceDestroy
トランザクション
1.3.2 MPTokenIssuanceDestroy
トランザクションは、 MPTokenIssuance
オブジェクトを保持しているディレクトリノードから削除するために使用されます。
この操作が成功すると、対応する MPTokenIssuance
が削除され、所有者の準備金が1つ減ります。該当するMPTの所有者がいる場合、この操作は失敗しなければなりません。
1.3.2.1 トランザクションのフィールド
フィールド名 | 必須? | JSONの型 | 内部の型 |
---|---|---|---|
TransactionType |
✅ | string |
UINT16 |
新しいトランザクション・タイプ MPTokenIssuanceDestroy
を表します。
フィールド名 | 必須? | JSONの型 | 内部の型 |
---|---|---|---|
MPTokenIssuanceID |
✅ | string |
UINT192 |
トランザクションによって削除される MPTokenIssuance
オブジェクトを表します。
MPTokenIssuanceDestroy
のJSON例
1.3.2.2 {
"TransactionType": "MPTokenIssuanceDestroy",
"Fee": 10,
"MPTokenIssuanceID": "00070C4495F14B0E44F78A264E41713C64B5F89242540EE255534400000000000000"
}
MPTokenIssuanceSet
トランザクション
1.3.3 1.3.3.1 MPTokenIssuanceSet
フィールド名 | 必須? | JSONの型 | 内部の型 |
---|---|---|---|
TransactionType |
️ ✅ | object |
UINT16 |
新しいトランザクション・タイプ MPTokenIssuanceSet
を表します。
フィールド名 | 必須? | JSONの型 | 内部の型 |
---|---|---|---|
MPTokenIssuanceID |
✅ | string |
UINT192 |
MPTokenIssuance
の識別子を表します。
フィールド名 | 必須? | JSONの型 | 内部の型 |
---|---|---|---|
MPTokenHolder |
string |
ACCOUNTID |
ロック/アンロックする個々のトークン保有者の残高のオプションのXRPLアドレス。省略された場合、このトランザクションはMPTを保持するすべてのアカウントに適用されます。
フィールド名 | 必須? | JSONの型 | 内部の型 |
---|---|---|---|
Flag |
✅ | string |
UINT64 |
MPTokenIssuanceSet
のJSON例
1.3.3.2 {
"TransactionType": "MPTokenIssuanceSet",
"Fee": 10,
"MPTokenIssuanceID": "00070C4495F14B0E44F78A264E41713C64B5F89242540EE255534400000000000000",
"Flags": 1
}
1.3.3.1.1 MPTokenIssuanceSetのフラグ
MPTokenLock
のトランザクションでは、以下のようにFlagsフィールドに追加の値を指定することができます。
フラグ名 | フラグ値 | 説明 |
---|---|---|
tfMPTLock |
️0x0001
|
設定されている場合、この資産のすべてのMPT残高をロックすることを表します。 |
tfMPTUnlock |
️0x0002
|
設定されている場合、この資産のすべてのMPT残高をアンロックすることを表します。 |
Payment
トランザクション
1.3.4 既存のPayment
トランザクションには新しいトップレベルフィールドやフラグは追加されません。しかし、既存のamount
フィールドをMPTの金額に対応するように拡張します。
amount
フィールド
1.3.4.1 現在、金額フィールドは2つの形式のいずれかをとります。下記は1ドロップのXRPを表しています。
"amount": "1"
以下は、1米ドルの金額を表しています。
"amount": {
"issuer": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
"currency": "USD",
"value": "1"
}
MPTの金額については、以下のフォーマットを使用することを提案します。
"amount": {
"mpt_issuance_id": "00070C4495F14B0E44F78A264E41713C64B5F89242540EE255534400000000000000",
"value": "1"
}
注: MPTokenIssuanceID
は、支払いトランザクション中にMPTを一意に識別するために使用されます。
MPTokenAuthorize
トランザクション
1.3.5 このトランザクションにより、アカウントは特定のMPT額を保持できるようになります。このトランザクションが正常に適用されると、初期残高がゼロのMPToken
オブジェクトが作成されます。
発行者がMPTokenIssuance
にlsfMPTRequireAuth
(許可リスト)を設定している場合、発行者はホルダーに許可を与えるためにMPTokenAuthorize
トランザクションも送信する必要があります。lsfMPTRequireAuth
が設定されておらず、発行者がこのトランザクションを送信しようとすると失敗します。
1.3.5.1 MPTokenAuthorize
フィールド名 | 必須? | JSONの型 | 内部の型 |
---|---|---|---|
Account |
✅ | string |
ACCOUNTID |
このアドレスは、MPTの発行者または潜在的な保有者のいずれかを表します。
フィールド名 | 必須? | JSONの型 | 内部の型 |
---|---|---|---|
TransactionType |
️ ✅ | object |
UINT16 |
新しいトランザクションタイプ MPTokenAuthorize` を表します。
フィールド名 | 必須? | JSONの型 | 内部の型 |
---|---|---|---|
MPTokenIssuanceID |
✅ | string |
UINT192 |
当該 MPT の ID を表します。
フィールド名 | 必須? | JSONの型 | 内部の型 |
---|---|---|---|
MPTokenHolder |
string |
ACCOUNTID |
発行者が認可したい保有者のアドレスを指定します。認可/許可リストにのみ使用されます。保有者から送信された場合は空でなければなりません。
フィールド名 | 必須? | JSONの型 | 内部の型 |
---|---|---|---|
Flag |
✅ | string |
UINT64 |
1.3.3.5.12 MPTokenAuthorizeのフラグ
MPTokenAuthorize
のトランザクションでは、次のようにFlagsフィールドに追加の値を指定できます。
フラグ名 | フラグ値 | 説明 |
---|---|---|
tfMPTUnauthorize |
️0x0001
|
このフラグが設定され、ホルダーからトランザクションが送信された場合、そのホルダーはMPToken を保持したくないことを示し、結果としてMPToken は削除されます。このフラグをセットしようとしているときに、保有者のMPToken の残高がゼロでない場合、トランザクションは失敗します。一方、このフラグが設定された状態でトランザクションが発行者から送信された場合、発行者は保有者の承認を解除したいことを意味します(保有許可にのみ適用されます)。 |
AccountDelete
トランザクション
1.3.6 AccountDelete
トランザクションの構造に変更はありません。ただし、MPTokenIssuance
を持つアカウントは削除できません。これらのアカウントは、アカウントを削除する前に、まずMPTokenIssuanceDestroy
を使用してMPTokenIssuance
を破棄する必要があります。この制限(または同様の制限)がないと、発行者はMPTの残高をどの保有者にとっても無意味/不安定なものにしてしまう可能性があります。
1.4.0 MPTのロックの詳細
1.4.0.1 個々の残高のロック
個々のMPTの個々の残高をロックするには、発行者はMPTokenIssuanceSet
トランザクションを送信し、ロックしたいMPTと保有者のアカウントを示し、tfMPTLock
フラグを設定します。以下の場合、この操作は失敗します。
- MPTに
lsfMPTCanLock
フラグが設定されていない場合。
発行者はtfMPTUnlock
フラグをセットした別のMPTokenIssuanceSet
トランザクションを送信することで、残高のロックを解除できます。
1.4.0.2 全てのMPTをロック
この操作は、ロックまたはアンロック時にMPTokenIssuanceSet
トランザクションで所有者アカウントが指定されないことを除いて、上記と同じように動作します。以下の場合、この操作は失敗します。
- MPTの発行者のアカウントに
lsfMPTCanLock
フラグが設定されていない場合。
発行者が発行した他の資産をロックせずにMPT全体をロックすることは、MPTの新しい機能です。
1.5.0 MPTのClawbackの詳細
MPT保有者から資金をクローバックするには、発行者はMPTokenIssuanceCreate
トランザクションを使用してMPTを作成するときにtfMPTCanClawback
フラグを設定することで、MPTがクローバックを許可していることを指定する必要があります。このフラグが設定されたMPTが作成されたと仮定すると、クローバックはClawback
トランザクションを使用して許可されます(このトランザクションが新しい値に対応するためにどのように変更されるかについての詳細は後述します)。
1.6.0 API
この機能のためにいくつかの新しいAPIを提案します。すべての新しいAPIはclio
でのみ利用可能です。
mpts_by_issuer
1.6.0.1 指定されたアカウントとレジャーに対して、削除されたMPTokenIssuances
を含め、そのアカウントが作成したすべてのMPTokenIssuance
が表示されます。削除されたMPTokenIssuanceは、新しいMPTokenIssuanceと同じIDを持つ可能性があります。
1.6.0.1.1 リクエストのフィールド
{
"command": "mpts_by_isssuer",
"issuer": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
"ledger_index": "validated",
"include_deleted": true
}
フィールド名 | 必須? | JSONの型 |
---|---|---|
issuer |
✅ | string |
MPTを照会したいMPT発行者を示します。
フィールド名 | 必須? | JSONの型 |
---|---|---|
ledger_index |
string または number (正の整数) |
使用する最大のレジャーインデックス、またはレジャーを自動的に選択するためのショートカット文字列。ledger_index
またはledger_hash
のどちらかを指定する必要があります。
フィールド名 | 必須? | JSONの型 |
---|---|---|
ledger_hash |
string |
使用する最大レジャーバージョンを表す20バイトの16進文字列。ledger_index
またはledger_hash
のどちらかを指定する必要があります。
フィールド名 | 必須? | JSONの型 |
---|---|---|
include_deleted |
boolean |
デフォルトはfalse
です。もしtrue
なら、削除されたMPTも含まれます。
フィールド名 | 必須? | JSONの型 |
---|---|---|
marker |
string |
ページ分割の際に、前回終了したところからクエリを続行するために使用します。
フィールド名 | 必須? | JSONの型 |
---|---|---|
limit |
number (正の整数) |
返される MPT の数の上限を指定します。
1.6.0.1.2 レスポンスのフィールド
{
"id": 5,
"status": "success",
"type": "response",
"result": {
"mpt_issuances": [
{
"MPTokenIssuanceID": "00070C4495F14B0E44F78A264E41713C64B5F89242540EE255534400000000000000",
"Flags": 83659,
"Issuer": ......,
"AssetScale": .....,
"MaximumAmount": .....,
"OutstandingAmount": ....,
"LockedAmount": .....,
"TransferFee": .....,
"MPTokenMetadata": ....,
"ledger_index": 11231
}
],
"validated": true
}
}
フィールド名 | JSONの型 |
---|---|
mpt_issuances |
array |
指定したアカウントが作成したMPTokenIssuanceオブジェクトの配列。既存の基本オブジェクトのすべてのフィールド、このMPTが最後に変更されたインデックスのledger_index
を含みます。削除されたオブジェクトの場合は、このMPTが削除されたインデックスのMPTokenIssuanceID
とdeleted_ledger_index
だけが表示されます。
フィールド名 | JSONの型 |
---|---|
marker |
string |
ページ分割の際に、中断したところからクエリを続行するために使用されます。この結果の後に項目がない場合は省略されます。
account_mpts
1.6.0.2 指定されたアカウントとレジャーに対して、account_mpts
はそのアカウントが保持しているすべてのMPTの残高を返します。
1.6.0.2.1 リクエストのフィールド
{
"command": "account_mpts",
"account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
"ledger_index": "validated"
}
フィールド名 | 必須? | JSONの型 |
---|---|---|
account |
✅ | string |
MPT 残高を照会するアカウントを表します。
フィールド名 | 必須? | JSONの型 |
---|---|---|
ledger_index |
string または number (正の整数) |
使用する最大のレジャーインデックス、またはレジャーを自動的に選択するためのショートカット文字列。ledger_index
またはledger_hash
のどちらかを指定する必要があります。
フィールド名 | 必須? | JSONの型 |
---|---|---|
ledger_hash |
string |
デフォルトはfalse
です。もしtrue
なら、削除されたMPTも含まれます。
フィールド名 | 必須? | JSONの型 |
---|---|---|
marker |
string |
ページ分割の際に、前回終了したところからクエリを続行するために使用します。
フィールド名 | 必須? | JSONの型 |
---|---|---|
limit |
number (正の整数) |
返されるMPTの数の上限を指定します。
1.6.0.2.2 レスポンスのフィールド
{
"id": 5,
"status": "success",
"type": "response",
"result": {
"account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
"mpts": [
{
"MPTokenIssuanceID": "00070C4495F14B0E44F78A264E41713C64B5F89242540EE255534400000000000000",
"Flags": 83659,
"MPTAmount": "1000",
"LockedAmount": "0"
}
],
"validated": true
}
}
フィールド名 | JSONの型 |
---|---|
mpts |
array |
指定したアカウントが所有するMPTokenオブジェクトの配列。基礎となるオブジェクトのすべてのフィールドを含みます。
フィールド名 | JSONの型 |
---|---|
marker |
string |
ページ分割の際に、中断したところからクエリを続行するために使用されます。この結果の後に項目がない場合は省略されます。
mpt_holders
1.6.0.3 与えられたMPTokenIssuanceIDとレジャーシーケンスに対して、mpt_holders
はそのMPTのすべての保有者とその残高を返します。このAPIは非常に大きなデータセットを返すので、ユーザはmarker
フィールドを使用してページングを実装する必要があります。
1.6.0.3.1 リクエストのフィールド
{
"command": "mpt_holders",
"mpt_id": "00070C4495F14B0E44F78A264E41713C64B5F89242540EE255534400000000000000",
"ledger_index": "validated"
}
フィールド名 | 必須? | JSONの型 |
---|---|---|
mpt_id |
✅ | string |
照会したい MPTokenIssuance を表します。
フィールド名 | 必須? | JSONの型 |
---|---|---|
ledger_index |
string またはnumber (正の整数) |
使用する最大のレジャーインデックス、またはレジャーを自動的に選択するためのショートカット文字列。ledger_index
またはledger_hash
のどちらかを指定する必要があります。
フィールド名 | 必須? | JSONの型 |
---|---|---|
ledger_hash |
string |
デフォルトは false
です。もし true
なら、削除された MPT も含まれます。
フィールド名 | 必須? | JSONの型 |
---|---|---|
marker |
string |
ページ分割の際に、前回終了したところからクエリを続行するために使用します。
フィールド名 | 必須? | JSONの型 |
---|---|---|
limit |
number (正の整数) |
返されるMPTの数の上限を指定します。
1.6.0.3.2 レスポンスのフィールド
{
"id": 5,
"status": "success",
"type": "response",
"result": {
"mpt_id": "00070C4495F14B0E44F78A264E41713C64B5F89242540EE255534400000000000000",
"mpt_holders": {
"rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn": {
"MPTokenIssuanceID": "00070C4495F14B0E44F78A264E41713C64B5F89242540EE255534400000000000000",
"Flags": 83659,
"MPTAmount": "1000",
"LockedAmount": "0"
}
},
"validated": true
}
}
フィールド名 | JSONの型 |
---|---|
mpt_id |
string |
照会した MPTokenIssuance を表します。
フィールド名 | JSONの型 |
---|---|
mpt_holders |
object |
MPTokenオブジェクトのアカウントの辞書を表すJSONオブジェクト。基礎となるMPTokenオブジェクトのすべてのフィールドを含みます。
フィールド名 | JSONの型 |
---|---|
marker |
string |
ページ分割の際に、中断したところからクエリを続行するために使用されます。この結果の後に項目がない場合は省略されます。
2. 付録
2.1 付録: FAQs
2.1.1. MPTはトラストラインとは違うのですか?
はい、MPTはトラストラインとは異なります。詳しくは1.1.2節をご覧ください。
とはいえ、両者の機能には重複する部分もあります。例えば、MPTもTrustlinesもステーブルコインを発行するために使うことができます。しかし、MPTとトラストラインの背後にある本来の意図は微妙に異なり、それはそれぞれのオンレッジャー設計に影響を与えます。分かりやすく説明すると、トラストラインは主に「コミュニティクレジット」というアイデアを提供するために発明されました。一方、MPTには、トラストラインとは微妙に異なる3つの主要な設計上の意図があります。(1)レジャー上でできるだけ少ないスペース(バイト数)でトークン化を可能にすること、(2)トークン化プリミティブから浮動小数点数と浮動小数点演算を排除すること、(3)例えば、リップリングを削除し、エスクローやペイメントチャンネルのような場所でMPTをより自然な方法で使用できるようにすることで、決済の実装をよりシンプルにすることです。
2.1.2. MPTはトラストラインを置き換えるものですか?
いいえ、MPTはトラストラインを置き換えるものではありません。むしろ、MPTとトラストラインは微妙に異なるユースケース(特にリップリングに関する部分)を可能にするため、共存可能であり、共存していくでしょう(FAQ 2.1.1.をご覧ください)。
2.1.3 MPTの代わりに、なぜトラストラインをより小さく/より良くしないのですか?
トラストラインをより効率的にする提案があるのは事実ですが(例えば、トラストラインのストレージの最適化、さらには(トラストラインからCustom Math)[https://github.com/XRPLF/rippled/issues/4120]を削除する)、これらはどちらもRippleStateの実装の重要な側面を変更する、ある程度大きな変更です。このような変更を行う場合、既存の機能に予期せぬ影響を与える可能性があります。MPTを構築し実装するという選択は、結局のところ、このリスクとリターンのトレードオフのバランスをとるための選択であり、既存の機能を壊さないために新しいものを導入するということです。
2.1.4. MPTの対象はメインネットですか、それともサイドチェーンですか?
これはまだ検討・議論中ですが、最終的にはバリデータが決めることです。一方では、メインネットでMPTを使用すると、トラストラインが使用された場合に問題となる可能性のある、いくつかの新しいトークン化のユースケースが可能になります(詳細についてはFAQ 2.1.7をご覧ください)。一方、MPTを追加すると、ペイメントエンジンに新しい決済タイプが導入され、rippled自体の実装とXRPLツールの両方が複雑になります。
いずれにせよ、私たちはまずMPT-DevnetでMPTをプレビューし、そこで判明したことに応じてこの問題を再検討します。
2.1.5. MPTはSTAmountにエンコードされるのでしょうか、それとも新しいC++オブジェクト型が必要なのでしょうか?
MPTはSTAmount
にエンコードできるようになります。詳細はthis gistをご覧ください。
MPTokenIssuance
オブジェクトやMPToken
オブジェクトの数に制限はありますか?
2.1.6. 1つのアカウントが保持できる実用的には、制限はありません。どのアカウントでも保持できるMPTokenオブジェクトやMPTokenIssuanceオブジェクトの数は、オーナーディレクトリに格納できるオブジェクトの数によって制限されます。
MPToken
オブジェクトをNFTで使われているようなページング構造に格納していました。なぜその設計は放棄されたのですか?
2.1.7. このMPT提案の初期の草案では、元の設計は、レジャー上のスペースを節約するために最適化されていましたが、この仕様と実装の両方において、複雑さの増大というトレードオフを伴いました。もう1つの考慮点は、多くのNFT開発者がNFTの識別に使用されるメカニズムに苦慮していたというデータポイントで、その一部はNFTのページング構造に起因するものです。
(a)トラストライン、(b)MPTokenPages
、(c)および単純にMPToken
オブジェクトをオーナーディレクトリに格納する場合のレジャー上の必要スペースを分析した結果、典型的なユーザー(つまり~10種類のMPTを保有するユーザー)の場合、より単純な設計で必要とされる全体的なスペースは、より複雑な設計とトラストラインの間でうまくバランスが取れていると判断しました。例えば、より単純な設計は、より複雑な設計よりも、台帳上で~3.2倍のバイトを要求します。しかし、より単純な設計は、トラストラインよりもレジャー上で必要なバイト数が約30%少なくなります。
とはいえ、この決定にはまだ議論の余地があります。例えば、Rippleチームは2024年初頭に、TrustlinesとよりシンプルなMPTデザインに関するリミットテストを実施し、両方のタイプの元帳オブジェクト数の増加が元帳パフォーマンスにどのように影響するかを確認する予定です。そのデータが完了したら、私たちはこの設計の選択を再検討し、それを検証するか変更することになるでしょう。
MPTRedeem
トランザクションがないのですか?
2.1.8. なぜこれは、MPTの保有者は通常の支払いトランザクションを使ってMPTを発行者に送り返すことができるため、MPTを「償還」して保有残高から取り除くことができるからです。もし発行者がそのようなことができるとすれば、送られてくるMPTの支払いがどこに行くべきかが曖昧になるからです(つまり、その支払いは償還となり発行残高の合計を減らすべきなのか、それともその支払いは発行者のMPToken
量に入り、まだ"流通している"とみなされるべきなのか)。シンプルにするために、私たちは前者の設計を選択し、MPT発行者がMPToken
オブジェクトを持つことを制限しました。
2.1.9. なぜMPToken発行者はMPTokenオブジェクトにMPTの残高を保持できないのですか?
上記の質問をご覧ください。この設計は、発行アカウントを発行者の取引アカウントとしても使用してはならないというセキュリティのベストプラクティスを実施するのにも役立ちます。発行者はMPTの発行以外の活動のために別のXRPLアカウントを使うべきです。
DepositPreauth
トランザクションを使用しないのですか?
2.1.10. なぜAuthorized MPT機能にはlsfMPTRequireAuth
フラグが設定されているMPTokenIssuanceについては、DepositPreauthトランザクションを、事前認可されたトラストラインと事前認可されたMPTを区別するために若干の変更を加えて使用することが想定されます。あるいは、トラストラインを制限する単一の発行者が、同じ発行者アカウントから発行されるMPTについても同じ制限をしたいという前提のもとで、deposit_preauth
オブジェクトが両方に適用されるかもしれないと考えるかもしれません。
とはいえ、この設計はまだ未定です。
2.1.11. 「Compact Fungible Token」という名称が「Multi-Purpose Token」に改名されたのはなぜですか?
最初の名称である「Compact Fungible Token」は、このトークン規格の柔軟性と汎用性を効果的に伝えるものではありませんでした。そのため、私たちは「多目的トークン(Multi-Purpose Token)」という新しい名称を導入しました。この名称は、ユーザーのカスタマイズに対応する能力をよりよく反映し、fungible、semi-fungible、そして潜在的にはnon-fungibleトークンのユースケースに対応するものです。この名称変更は、MPTを介して利用可能な広範な機能を強調することを目的としています。
例えば、MPTはNFTよりもセミファンジブルなユースケース(特に各トークンが1以上の数量を持つようなユースケース)に適しているかもしれません。加えて、NFTの発行者の中には、セミファンジブルにするために同じNFTを複数発行する者もいます。これは技術的にNFT仕様の趣旨に反するものであり、すべてのNFTユースケースでうまく機能するとは限りません。
とはいえ、特定のユースケースでNFTかMPTかを選択する前に、将来の要件やトレードオフを考慮する必要があります。例えば、NFTはURI
フィールドを介してオフレジャーのメタデータにリンクする機能を持っており、MPTよりもオンレジャーのストレージバイト数が少なくて済む可能性があります(ただし、これは今後の研究に値します)。
2.2. 付録: 未解決の問題
このセクションでは、本提案でまだ解決されていない未解決または議論の余地のある問題について説明します。
MPTokenIssuanceID
の選択肢
2.2.1. MPTokenIssuanceID
を構成する要素にはさまざまな方法があります。このセクションでは、現在議論されている3つの方法について概説します。
2.2.1.1. 発行者アドレスと通貨コードのハッシュ
トークン保有者は発行者と使用する通貨を知った上で直接取引を行うことができます。しかし、これが実装されると、発行者がMPTokenIssuance
をすべて破棄した後(つまり、誰もそのトークンを保持しなくなった後)、発行者は同じトークンを同じ通貨で再発行できることになり、結果として同じMPTokenIssuanceID
が生成されます。このような動作は、トークン保有者にとって誤解を招きかねません。トークン保有者は、再発行されたトークンではなく、最初のトークンを保持することになります(どちらのトークンも同じMPTokenIssuanceID
を持つため)。実際のユースケース(特に金融)では、トークンを焼却した後、同じ識別子で再作成することは絶対に避けなければなりません。
2.2.1.2. オプションA: 通貨配列とMPT発行数の制限
この方法でも、発行者アドレスと通貨コードをハッシュしてMPTokenIssuanceID
を構築します。しかし、再作成可能なMPTokenIssuanceID
の問題を解決するために、発行者はこれまでに発行されたMPT通貨コードの配列を保存します。こうすることで、発行者が新しいMPTを発行するたびに、台帳はその通貨コードがすでに使われているかどうかをチェックし、もし使われていれば取引は失敗します。しかし、この方法の問題点は、口座がMPTを発行しようとするたびに、台帳が通貨配列を繰り返しチェックする必要があることです。そこで、1つのアカウントが発行できるMPTの総数に制限をかけます(提案されている制限は32MPTです)。
しかし、この方法は問題を解決する上であまりすっきりしていません。口座が発行できるMPTの数には制限があり、発行者は好きなだけMPTを発行したいので、これは理想的ではありません。
2.2.1.3. オプションB: 通貨コードなしでMPTokenIssuanceを構築する(現在のアプローチ)
私たちは、再作成可能なMPTの問題は、MPTを焼いた後に通貨を何度も再利用できるアカウント/通貨ペアに起因していることに気づきました。この問題を解決するために、MPTokenIssuanceID
は発行者アドレスとトランザクションシーケンスの2つのパラメータから構成されるようになりました。トランザクションシーケンスは増加インデックスなので、MPTokenIssuanceID
が再作成されることはありません。したがって、AssetCode/currencyは純粋にメタデータとして使用するオプションのフィールドとすることができます。
この方法を使うと、MPTの支払いトランザクションに通貨コードが含まれなくなり、ユーザーにとって不便になりますが、それでも妥協の産物です。NFTokenはランダムな識別子を持ち、APIサービスにはclioを使用しています。
2.2.2. 許可リスト
特定のユースケースにおいて、発行者は、トラストラインの認可の仕組みと同様に、特定のアカウントにのみMPTの保持を許可するオプションが欲しい場合があります。
2.2.2.1. 許可リストなし
まず、許可リストを使用しない場合のフローを見てみましょう。
- Aliceはアセットコード
USD
のMPTを保持しています。 - Bobはそれを保有したいので、
MPTokenIssuanceID
を指定してMPTokenAuthorize
トランザクションを送信します。これにより、残高ゼロのMPToken
オブジェクトが作成され、余分な準備金が発生する可能性があります。 - Bobは
USD
を使って誰からでも/誰に対しても支払いを受送信できるようになりました。 - BobはもうMPTを使いたくないので、
USD
の全額をPayment
トランザクションを通して発行者に返す必要があります。その結果、残高ゼロのMPToken
オブジェクトが再び生成されます。 - Bobは次に
tfMPTUnauthorize
フラグを設定したMPTokenAuthorize
トランザクションを送信し、MPToken
オブジェクトの削除に成功します。
2.2.2.2. 許可リストを使用する場合
発行者はMPTokenIssuance
にlsfMPTRequireAuth
を設定して、MPTのリストを許可する必要があります。
許可リストでは、保有者と発行者の間に双方向の信頼関係が必要です。上記との違いを比較してみましょう。
- Aliceは通貨
USD
のMPTを持っています(上と同じ)。 - Bobはそれを保有したいので、
MPTokenIssuanceID
を指定してMPTokenAuthorize
トランザクションを送信します。この場合、残高ゼロのMPToken
オブジェクトが作成され、余分な準備金が発生する可能性があります。(上記と同じ)
この時点では、BobはまだUSD
を使用する権限を持っていません。 - Aliceは
MPTokenHolder
フィールドにBobのアドレスを指定してMPTokenAuthorize
トランザクションを送信する必要があり、成功すればBobのMPToken
オブジェクトにlsfMPTAuthorized
フラグを設定します。これでようやくBobがUSD
を使えるようになります。 - 上のステップ4と同じです。
- 上記のステップ5と同じ
上記の例では、AliceがBobより先にMPTokenAuthorize
を送信した場合、ステップ2とステップ3を逆にすることはできません。
発行者は保有者の認証を解除することもできます。その場合、保有者にまだ残高があれば、その資金を回収するのは発行者の責任です。
MPTokenNode
ディレクトリとは?
2.2.3. MPTokenNode
オブジェクトの本来の目的は、1つのMPTokenIssuance
に対して存在するMPTokenID
値(それぞれ32バイト)のリストを格納する一種の"ディレクトリ"(つまりインデックス)になることです。これによって、rippledは与えられた発行のMPToken
オブジェクトのページングされたコレクションを返すRPCエンドポイントや、mpt_holder_balances
と呼ばれるRPCのようなものを持つことができます。理論的には、これによりrippledは、対応するMPTokenIssuance
が削除された後も台帳に残っているMPTokenを削除する(そしてレジャーの準備金をトークン保有者に戻す)"クリーンアップ"操作を行うことができます。
MPTokenNode
ディレクトリを持つべきか?
2.2.3.1 MPTokenNode
の導入は特定のユースケースに対応するものですが、MPTと一般的なユースケースの両方について、そのユースケースを実際に解決したいのかどうか、さらに議論する必要があります。例えば、コミュニティの中には、多くの(ほとんどの?)RPCはrippled自体から削除されるべきであり、特に主にインデックス作成の目的で存在するものは削除されるべきであると考える人もいます。つまり、実際のトランザクタによって使われるのではなく、RPCを介して外部プロセスにサービスを提供するためだけに存在するデータをレジャーに保存することは避けるべきという意見です。例えば、これらのRPCをClioや他のサービスに移行することで、データのインデックス付けや、より高価なインデックス付けの責任をレジャー自体から取り除くことができ、特定のインフラオペレーターの負担を取り除くことができます。
ぶら下がるMPTokenObjects
を削除するというトピックについてですが、この解決策はrippledにバックグラウンドのスレッドを導入することになり、実際のノード操作に意図しない結果をもたらすかもしれません。加えて、レジャーのクリーンアップを行うための最も一般的な方法は、アカウント保有者が削除トランザクションを発行することです。
MPTokenNode
ディレクトリをどのように設計すべきか?
2.2.3.2 新しい"MPTのみの"ディレクトリ構造の提案は、更に考慮されるべき新しいパターンを導入します。例えば、XRP Ledgerには現在2種類の"Directory"があります。"Owner Directory"と"Offer Directory"です。新しいタイプのMPTディレクトリの提案は、MPT専用の新しいタイプのオーナー不在のディレクトリを作成することを提案しています(NFTokenOfferNode
に似ています)。このディレクトリは、所有者がいないという意味では確かに「オファーディレクトリ」に似ていますが、DEXのオファーやNFTokenOfferNode
オブジェクトの場合のように、これらの新しいMPTディレクトリはDEXや取引所の操作を目的としていないという意味で、設計はこのコンセプトから逸脱しています。
別の設計として、(1)発行者が所有し、(2)MPTokenID
値のみを保持するMPTのための新しいタイプの"Owner Directory"を検討することもできます。この新しいタイプのディレクトリは、(オーナーが存在するため)「Owner Directory」に似ていますが、MPTokenID
値のみが格納されるため異なります。
どちらの提案も、現存するものとは多少アーキテクチャが異なるため、トレードオフとその意味を探るために、それぞれについてさらに議論する必要があります。
2.3. 付録: 補足情報
2.3.1 オンレジャーのストレージ要件
RippleState
オブジェクト(バイト単位)
2.3.1.1. Issue#3866で説明されているように、RippleStateオブジェクトのサイズは202バイトから218バイトで、さらにオブジェクトの所有者追跡のために最低32バイトが必要です。さらに、各トラストラインは、両方の参加者のオーナーディレクトリのエントリを必要とします。
このセクションでは、予想されるスペースの節約を予測するために、トラストラインとMPTの両方について、予想されるサイズをバイト単位でカタログ化することを試みます。
必須フィールド
フィールド名 | サイズ(BITS) | サイズ(BYTES) | 備考 |
---|---|---|---|
LedgerEntryType | 16 | 2 | |
Flags | 32 | 4 | (「任意」だが99.99%以上のケースで存在) |
Balance | 384 | 48 | (160–224が無駄) |
LowLimit | 384 | 48 | (160–224が無駄) |
HighLimit | 384 | 48 | (160–224が無駄) |
LowNode | 64 | 8 | (ほとんどの場合0) |
HighNode | 64 | 8 | (ほとんどの場合0) |
PreviousTxnID | 256 | 32 | |
PreviousTxnLgrSeq | 32 | 4 | |
Field+Type Codes | 144 | 18 | 各フィールドにはFieldCode とTypeCode があり、合計で2バイトを使用します(例えばフィールドが4つあれば8バイトを使用します)。ここでは9つのフィールドがあります。 |
--- | -- | --- | |
小計 | 1760 | 220 | |
--- | -- | --- | |
LowQualityIn | 32 | 4 | |
LowQualityOut | 32 | 4 | (「任意」だが99.99%以上のケースで存在) |
HighQualityIn | 32 | 4 | (160–224が無駄) |
HighQualityOut | 32 | 4 | (160–224が無駄) |
Field+Type Codes | 64 | 8 | 各フィールドにはFieldCode とTypeCode があり、合計で2バイトを使用します(例えばフィールドが4つあれば8バイトを使用します)。ここでは4つのフィールドがあります。 |
--- | -- | --- | |
小計 | 192 | 24 | |
--- | -- | --- | |
合計 | 1952 | 244 |
MPToken
オブジェクト(バイト単位)
2.3.1.2. フィールド名 | サイズ(BITS) | サイズ(BYTES) | 備考 |
---|---|---|---|
LedgerEntryType | 16 | 2 | |
MPTokenIssuanceID | 192 | 32 | |
MPTAmount | 64 | 8 | |
LockedAmount | 64 | 8 | |
Flags | 32 | 4 | |
PreviousTxnID | 256 | 32 | |
PreviousTxnLgrSeq | 32 | 4 | |
Field+Type Codes | 112 | 14 | 各フィールドにはFieldCode とTypeCode があり、合計で2バイトを使用します(例えば、フィールドが4つある場合は8バイトを使用します)。ここでは7つのフィールドがあります。 |
--- | -- | --- | |
合計 | 768 | 104 |
2.3.1.3. サイズの比較
以下のサイズ比較表からわかるように、トラストラインはMPTの約2.2倍(バイト)のスペースをレジャー上で占有します。
説明 | # MPTディレクトリ | 合計バイト(MPT) | # トラストラインディレクトリ | 合計バイト(トラストライン) | トラストラインはn倍 |
---|---|---|---|---|---|
Bytes for holding 1 Tokens | 1 | 226 | 2 | 488 | 2.2x |
Bytes for holding 10 Tokens | 1 | 1,450 | 2 | 3,260 | 2.2x |
Bytes for holding 32 Tokens | 2 | 5,556 | 4 | 12,264 | 2.2x |
Bytes for holding 64 Tokens | 3 | 13,070 | 6 | 28,444 | 2.2x |
STAmount
のシリアライズ
2.3.2. https://gist.github.com/sappenin/2c923bb249d4e9dd153e2e5f32f96d92 を参考に一部改変。
バイナリのエンコード
このアイデアをサポートするために、まず現在のSTAmountのバイナリエンコードを活用する方法が必要です。これを実現するために、XRPの最大量(10^17ドロップ)には57ビットしか必要ないことに気づきます。しかし、現在のXRP
の金額エンコーディングでは、62ビットが利用可能です。
バイナリの金額フィールドの読み取りルールは後方互換性があり、以下のようになります。
- フィールドIDをtype_code(
STI_AMOUNT
)でパースします。これは次のバイトがSTAmount
であることを示します。 - 次のビットを検査します。もし
1
なら、これはMPTやXRPではありません。しかし、もし最初のビットが0
なら、続行します。 - 2番目のビットを無視します(これは符号ビットで、XRPでもMPTでも常に1です)。
- 3番目のビットを調べます。もし
0
なら、通常通りXRPの値として解析します。もし1
なら、MPTとしてパースします。
XRP値のエンコーディング(後方互換性)
┌────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ ┌─────────────────┐┌────────────────────────┐┌────────────┐┌─────────────────────────────────────────────┐ │
│ │ 0 ││ 1 ││ 0 ││ │ │
│ │ ││ ││ ││ integer drops │ │
│ │ "Not XRP" bit ││ Sign bit (always 1; ││"IsMPT" bit ││ (61 bits) │ │
│ │0=XRP/MPT; 1=IOU ││ positive) ││0=XRP; 1=MPT││ │ │
│ └─────────────────┘└────────────────────────┘└────────────┘└─────────────────────────────────────────────┘ │
└────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
MPT値のエンコーディング(後方互換性)
このエンコーディングはMPTの最初の3バイトに注目します。
┌────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ ┌─────────────────┐┌────────────────────────┐┌────────────┐┌─────────────────────────────────────────────┐ │
│ │ 0 ││ 1 ││ 1 ││ │ │
│ │ ││ ││ ││ Remaining MPT Bytes │ │
│ │ "Not XRP" bit ││ Sign bit (always 1; ││"IsMPT" bit ││ (389 bits) │ │
│ │0=XRP/MPT; 1=IOU ││ positive) ││0=XRP; 1=MPT││ │ │
│ └─────────────────┘└────────────────────────┘└────────────┘└─────────────────────────────────────────────┘ │
└────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
このエンコーディングは、MPTの残りのバイト(264ビット)に注目します。
┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ ┌─────────────────┐┌──────────────────┐┌──────────────────────┐┌──────────────────────────┐┌──────────────────────────┐│
│ │ [0][1][1] ││ ││ ││ ││ ││
│ │ ││ Reserved ││ MPT Amount Value ││ Sequence ││ Issuer AcountID ││
│ │ IsMPT=true ││ (5 bits) ││ (64 bits) ││ (32 bits) ││ (160 bits) ││
│ │ ││ ││ ││ ││ ││
│ └─────────────────┘└──────────────────┘└──────────────────────┘└──────────────────────────┘└──────────────────────────┘│
└────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Discussion