Skip to content

Commit 6f27b62

Browse files
authored
Merge pull request #2908 from XRPLF/mpt_concept_and_refs
Add MPTs to xrpl.org docs
2 parents 3e918ae + f5e9a88 commit 6f27b62

File tree

16 files changed

+825
-3
lines changed

16 files changed

+825
-3
lines changed

docs/_snippets/common-links.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@
134134
[LedgerHashesエントリ]: /docs/references/protocol/ledger-data/ledger-entry-types/ledgerhashes.md
135135
[LedgerHashesオブジェクト]: /docs/references/protocol/ledger-data/ledger-entry-types/ledgerhashes.md
136136
[Marker]: /docs/references/http-websocket-apis/api-conventions/markers-and-pagination.md
137+
[MPToken amendment]: /resources/known-amendments.md#mptokensv1
137138
[MultiSign amendment]: /resources/known-amendments.md#multisign
138139
[MultiSignReserve amendment]: /resources/known-amendments.md#multisignreserve
139140
[NFTokenAcceptOffer transaction]: /docs/references/protocol/transactions/types/nftokenacceptoffer.md

docs/_snippets/mpts-disclaimer.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{% admonition type="info" name="Attention" %}
2+
Multi-purpose Token functionality is part of the proposed XLS-33d extension to the XRP Ledger protocol. You can use these functions on test networks for now. Until there is an amendment in a stable release, the details documented on these pages are subject to change.
3+
{% /admonition %}

docs/concepts/tokens/fungible-tokens/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Fungible tokens are interchangeable and indistinguishable from one another. They
1616

1717
Trust lines are structures in the XRP Ledger for holding fungible [tokens](../index.md). Trust lines enforce the XRP Ledger's rule that you cannot cause someone else to hold a token they don't want. This precaution is necessary to enable the XRP Ledger's use case for [community credit](../index.md#community-credit) among other benefits.
1818

19-
A trust line is defined as a [RippleState](../../references/protocol/ledger-data/ledger-entry-types/ripplestate) object. Each trust line is a _bidirectional_ relationship consisting of:
19+
A trust line is defined as a [RippleState](../../../references/protocol/ledger-data/ledger-entry-types/ripplestate) object. Each trust line is a _bidirectional_ relationship consisting of:
2020

2121
- The identifiers for the two [accounts](../../accounts/index.md) that the trust line connects.
2222
- A single, shared balance, which is positive from the perspective of one account and negative from the other perspective.
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
---
2+
blurb: Multi-purpose tokens offer a more compact, flexible token type than trust lines.
3+
labels:
4+
- Tokens
5+
- MPTs
6+
- Multi-purpose Tokens
7+
status: not_enabled
8+
---
9+
# Multi-purpose Tokens
10+
11+
_(Requires the [MPToken amendment][] {% not-enabled /%})_
12+
13+
Multi-purpose tokens (MPTs) are a more compact and flexible type of fungible token.
14+
15+
MPTs let you take advantage of ready-to-use tokenization features with a few lines of code. You can create many token experiences from one token program itself. Notable features include:
16+
17+
- MPTs store their metadata directly on the XRPL blockchain.
18+
- A 1024-byte URI field provides a metadata pointer that allows you to use an off-chain source for metadata in addition to the on-chain source. This lets your application access necessary information directly from the chain, prompting higher interoperability for tokens, without losing the ability to attach additional information.
19+
- MPTs can have a fixed token supply where you set a cap on the maximum number of tokens that can be minted.
20+
- You can define MPTs as non-transferable, tokens that can only be transferred back to the issuer, but not among tokenholders. Useful for cases such as issuing airline credits or loyalty rewards.
21+
- Issuers can set transfer fees to collect on-chain revenue each time the token is traded among tokenholders.
22+
- MPTs also have advanced compliance features:
23+
- The ability to lock tokens held by a tokenholder to support compliance requirements.
24+
- The ability to set a global lock for all MPT balances across all tokenholders.
25+
- The issuer can configure MPTs that can be clawed back from tokenholder wallets, either to revoke them, or to reassign them in the case of lost wallet keys.
26+
- An opt-in feature can allow only wallets authorized by the issuer to hold issued tokens.
27+
28+
## MPTs versus Trust Lines
29+
30+
Unlike trust lines, MPTs do not represent bidirectional debt relationships. Instead, MPTs function more like a unidirectional trust line with only one balance. This reduces the overhead to support common tokenization requirements, including non-monetary use cases such as tracking reputation points in an online game.
31+
32+
MPTs offer a less complicated conceptual model than trust lines.
33+
34+
MPTs require significantly less space than trust lines. They require roughly 52 bytes for each MPT held by a token holder, compared to at least 234 bytes for every new trust line.
35+
36+
They reduce the long-term infrastructure and storage burdens for node operators, increasing network resiliency.
37+
38+
MPTs also improve node perfomance when processing large volumes of transactions.
39+
40+
MPTs are unidirectional. While trust lines use "balance netting," MPTs have only a single balance.
41+
42+
An account can issue a maximum of 32 unique MPT issuances. If an issuer wants to support more than this number of MPTs, they can open additional accounts.
43+
44+
Since token holders will not acquire an MPT without first making an off-ledger trust decision, MPTs have no trust limits. For example, a common use case for an MPT is a fiat-backed stablecoin, where a token holder wouldn't purchase more stablecoins than they would feel comfortable holding.
45+
46+
Unlike some existing capabilities of the ledger, MPTs are not subject to rippling, and do not require configurability settings related to that functionality.
47+
48+
## MPTs versus IOUs
49+
50+
On a technical level, MPTs provide a fundamentally different way to represent fungible tokens on the ledger. While IOUs are represented by trustlines and have bilateral debt relationships, MPTs use a simpler, unilateral relationship captured by an MPToken object. This results in substantial space savings on the ledger. The representation of a fungible token as a token object instead of a trustline makes it easier to enable functionality for real-world financial assets on-chain, such as token-level metadata, fixed supply, and fixed-point balance.
51+
52+
On a usage level, MPTs provide a straightforward conceptual model compared to trustlines and rippling. Developers can more easily build web3 applications around `MPToken` and `MPTokenIssuance` objects, with some similarities to the conceptual model of XLS-20 NFTs. It is also simpler for ordinary users to understand what tokens are available, what tokens they have issued, and what they hold in their wallet. For both issuers and holders of MPTs, there will typically be a smaller XRP reserve compared to the equivalent representations with IOU trustlines.
53+
54+
MPTs are intended to be complementary to IOUs. While there might be use cases where either MPTs or IOUs might be suitable, there will likely be a need for both over the long term. There will be use cases such as credit lines for lending and borrowing that might be better represented by IOUs long term. The MPT feature set should evolve in an incremental manner to unlock more common use cases first and deliver additional feature support at a later time. During the MPT development period, some cases might still be better represented by an IOU, then later be better supported with MPTs.
55+
56+
## See Also
57+
58+
- **References:**
59+
- [MPToken](../../../references/protocol/ledger-data/ledger-entry-types/mptoken.md)
60+
- [MPTokenIssuance](../../../references/protocol/ledger-data/ledger-entry-types/mptokenissuance.md)
61+
- [MPTokenAuthorize](../../../references/protocol/transactions/types/mptokenauthorize.md)
62+
- [MPTokenIssuanceCreate](../../../references/protocol/transactions/types/mptokenissuancecreate.md)
63+
- [MPTokenIssuanceDestroy](../../../references/protocol/transactions/types/mptokenissuancedestroy.md)
64+
- [MPTokenIssuanceSet](../../../references/protocol/transactions/types/mptokenissuanceset.md)
65+
66+
{% raw-partial file="/docs/_snippets/common-links.md" /%}
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
---
2+
blurb: Get the holders for a given `MPTokenIssuanceID` and ledger sequence.
3+
labels:
4+
- Accounts
5+
- XRP
6+
---
7+
8+
# mpt_holders
9+
10+
_(Requires the [MPToken amendment][] {% not-enabled /%})_
11+
12+
For a given `MPTokenIssuanceID` and ledger sequence, `mpt_holders` returns all holders of that MPT and their balance. This method likely returns very large data sets, so you should expect to implement paging via the `marker` field. This API is only available using Clio, not rippled.
13+
14+
## Request Format
15+
16+
*Websocket*
17+
18+
```json
19+
{
20+
"command": "mpt_holders",
21+
"mpt_issuance_id": "00070C4495F14B0E44F78A264E41713C64B5F89242540EE255534400000000000000",
22+
"ledger_index": "validated"
23+
}
24+
```
25+
26+
*JSON-RPC*
27+
28+
```json
29+
{
30+
"method": "mpt_holders",
31+
"params": [
32+
{
33+
"mpt_issuance_id": "00070C4495F14B0E44F78A264E41713C64B5F89242540EE255534400000000000000",
34+
"ledger_index": "validated"
35+
}
36+
]
37+
}
38+
```
39+
40+
41+
The request contains the following parameters:
42+
43+
| Field | Type | Required? | Description |
44+
|:------------------|:---------------------|:----------|-------------|
45+
| `mpt_issuance_id` | string | Yes | The `MPTokenIssuance` to query. |
46+
| `ledger_index` | string or number (positive integer) | No | The ledger index of the max ledger to use, ora shortcut string to choose a ledger automatically. You must specify either ledger_index or ledger_hash. |
47+
| `ledger_hash` | string | No | A 32-byte hex string for the ledger version to use. You must specify either ledger_index or ledger_hash. |
48+
| `marker` | string | No | Used to continue your query where it left off in paginating. |
49+
| `limit` | number (positive integer) | No | Specify a limit to the number of MPTs returned. |
50+
51+
## Response Format
52+
53+
```json
54+
{
55+
"mpt_issuance_id": "000004C463C52827307480341125DA0577DEFC38405B0E3E",
56+
"limit":50,
57+
"ledger_index": 2,
58+
"mptokens": [{
59+
"account": "rEiNkzogdHEzUxPfsri5XSMqtXUixf2Yx",
60+
"flags": 0,
61+
"mpt_amount": "20",
62+
"mptoken_index": "36D91DEE5EFE4A93119A8B84C944A528F2B444329F3846E49FE921040DE17E65"
63+
},
64+
{
65+
"account": "rrnAZCqMahreZrKMcZU3t2DZ6yUndT4ubN",
66+
"flags": 0,
67+
"mpt_amount": "1",
68+
"mptoken_index": "D137F2E5A5767A06CB7A8F060ADE442A30CFF95028E1AF4B8767E3A56877205A"
69+
}],
70+
"validated": true
71+
}
72+
```
73+
74+
### Response Fields
75+
76+
The response follows the [standard format][], with the result containing the following fields:
77+
78+
| Field | Type | Description |
79+
|:-----------------------|:--------|:------------------------------------------|
80+
| `mpt_issuance_id` | string | The `MPTokenIssuance` queried |
81+
| `mptokens` | array | An array of mptokens. Includes all relevant fields in the underlying MPToken object. |
82+
| `marker` | string | Used to continue querying where we left off when paginating. Omitted if there are no more entries after this result. |
83+
| `limit` | number | The limit, as specfied in the request
84+
| `ledger_index` | number | The index of the ledger used. |
85+
86+
An `mptoken` object has the following parameters:
87+
88+
| Field | Type | Description |
89+
|:-----------------------|:--------|:------------------------------------------|
90+
| `account` | string | The account address of the holder who owns the `MPToken`. |
91+
| `flags` | number | The flags assigned to the`MPToken` object. |
92+
| `mpt_amount` | string | Base 10-encoded amount of the holder's balance. |
93+
| `mptoken_index` | string | Key of the `MPToken` object. |
94+
95+
##### Example
96+
Example of a `tx` response:
97+
98+
```json
99+
{
100+
"result": {
101+
"Account": "rBT9cUqK6UvpvZhPFNQ2qpUTin8rDokBeL",
102+
"AssetScale": 2,
103+
"Fee": "10",
104+
"Flags": 64,
105+
"Sequence": 303,
106+
"SigningPubKey": "ED39955DEA2D083C6CBE459951A0A84DB337925389ACA057645EE6E6BA99D4B2AE",
107+
"TransactionType": "MPTokenIssuanceCreate",
108+
"TxnSignature": "80D7B7409980BE9854F7217BB8E836C8A2A191E766F24B5EF2EA7609E1420AABE6A1FDB3038468679081A45563B4D0B49C08F4F70F64E41B578F288A208E4206",
109+
"ctid": "C000013100000000",
110+
"date": 760643692,
111+
"hash": "E563D7942E3E4A79AD73EC12E9E4C44B7C9950DF7BF5FDB75FAD0F5CE0554DB3",
112+
"inLedger": 305,
113+
"ledger_index": 305,
114+
"meta": {
115+
"AffectedNodes": [...],
116+
"TransactionIndex": 0,
117+
"TransactionResult": "tesSUCCESS",
118+
"mpt_issuance_id": "0000012F72A341F09A988CDAEA4FF5BE31F25B402C550ABE"
119+
},
120+
"status": "success",
121+
"validated": true
122+
}
123+
}
124+
```
125+
126+
##### Object
127+
An `mpt_issuance_id` field is provided in JSON MPTokenIssuance objects (not available for binary). The following APIs are impacted: `ledger_data` and `account_objects`.
128+
129+
##### Example
130+
Example of an `account_objects` response:
131+
132+
```json
133+
{
134+
"result": {
135+
"account": "rBT9cUqK6UvpvZhPFNQ2qpUTin8rDokBeL",
136+
"account_objects": [
137+
{
138+
"AssetScale": 2,
139+
"Flags": 64,
140+
"Issuer": "rBT9cUqK6UvpvZhPFNQ2qpUTin8rDokBeL",
141+
"LedgerEntryType": "MPTokenIssuance",
142+
"OutstandingAmount": "100",
143+
"OwnerNode": "0",
144+
"PreviousTxnID": "BDC5ECA6B115C74BF4DA83E36325A2F55DF9E2C968A5CC15EB4D009D87D5C7CA",
145+
"PreviousTxnLgrSeq": 308,
146+
"Sequence": 303,
147+
"index": "75EC6F2939ED6C5798A5F369A0221BC4F6DDC50F8614ECF72E3B976351057A63",
148+
"mpt_issuance_id": "0000012F72A341F09A988CDAEA4FF5BE31F25B402C550ABE"
149+
}
150+
],
151+
"ledger_current_index": 309,
152+
"status": "success",
153+
"validated": false
154+
}
155+
}
156+
```
157+
158+
{% raw-partial file="/docs/_snippets/common-links.md" /%}

0 commit comments

Comments
 (0)