Skip to content

Commit f5b8342

Browse files
authored
Merge pull request #3024 from XRPLF/add_dynamic_nfts
Add Dynamic NFTs concept and reference
2 parents 24e24f0 + ebfab59 commit f5b8342

File tree

6 files changed

+97
-2
lines changed

6 files changed

+97
-2
lines changed

docs/_snippets/common-links.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@
116116
[DirectoryNodeエントリ]: /docs/references/protocol/ledger-data/ledger-entry-types/directorynode.md
117117
[DirectoryNodeオブジェクト]: /docs/references/protocol/ledger-data/ledger-entry-types/directorynode.md
118118
[DisallowIncoming amendment]: /resources/known-amendments.md#disallowincoming
119+
[DynamicNFT amendment]: /resources/known-amendments.md#dynamicnft
119120
[EnableAmendment pseudo-transaction]: /docs/references/protocol/transactions/pseudo-transaction-types/enableamendment.md
120121
[EnableAmendment pseudo-transactions]: /docs/references/protocol/transactions/pseudo-transaction-types/enableamendment.md
121122
[EnableAmendment]: /docs/references/protocol/transactions/pseudo-transaction-types/enableamendment.md
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
---
2+
seo:
3+
description: Create NFTs with the option of changing the URI to update its referenced data object.
4+
labels:
5+
- Non-fungible Tokens, NFTs
6+
---
7+
8+
# Dynamic Non-Fungible Tokens (dNFTs)
9+
10+
Standard NFTs are immutable. Some use cases would benefit from the capability to update the referenced data object after the initial minting of an NFT. For example, a concert ticket for a postponed event could be updated with an alternate date, or a virtual trading card for an athlete could be periodically updated with current statistics. Dynamic Non-Fungible Tokens (dNFTs) provide the flexibility required for these use cases.
11+
12+
## Creating a dNFT
13+
14+
When minting a new NFT, set the `tfMutable` flag (`0x00000010`) to enable the ability to update the NFT's `URI` field.
15+
16+
## Modifying a dNFT
17+
18+
Use the `NFTokenModify` transaction to update the URI field of a dNFT. Provide the `Account` of the issuer or an authorized minter, the `Owner` of the dNFT (if different than the `Account` address), the `NFTokenID`, and the `URI` to the new object data.
19+
20+
### Sample NFTokenModify Transaction
21+
22+
```json
23+
{
24+
"TransactionType": "NFTokenModify",
25+
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
26+
"Owner": "rogue5HnPRSszD9CWGSUz8UGHMVwSSKF6",
27+
"Fee": "10",
28+
"Sequence": 33,
29+
"NFTokenID": “0008C350C182B4F213B82CCFA4C6F59AD76F0AFCFBDF04D5A048C0A300000007",
30+
"URI": "697066733A2F2F62616679626569636D6E73347A736F6C686C6976346C746D6E356B697062776373637134616C70736D6C6179696970666B73746B736D3472746B652F5665742E706E67",
31+
}
32+
```

docs/references/protocol/transactions/types/nftokenmint.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
---
2-
html: nftokenmint.html
3-
parent: transaction-types.html
42
seo:
53
description: Use TokenMint to issue new NFTs.
64
labels:
@@ -62,6 +60,7 @@ Transactions of the NFTokenMint type support additional values in the [`Flags` f
6260
| `tfOnlyXRP` | `0x00000002` | 2 | The minted `NFToken` can only be bought or sold for XRP. This can be desirable if the token has a transfer fee and the issuer does not want to receive fees in non-XRP currencies. |
6361
| `tfTrustLine` | `0x00000004` | 4 | **DEPRECATED** Automatically create [trust lines](../../../../concepts/tokens/fungible-tokens/index.md) from the issuer to hold transfer fees received from transferring the minted `NFToken`. The [fixRemoveNFTokenAutoTrustLine amendment][] makes it invalid to set this flag. |
6462
| `tfTransferable` | `0x00000008` | 8 | The minted `NFToken` can be transferred to others. If this flag is _not_ enabled, the token can still be transferred _from_ or _to_ the issuer, but a transfer to the issuer must be made based on a buy offer from the issuer and not a sell offer from the NFT holder. |
63+
| `tfMutable` | `0x00000010` | 16 | The `URI` field of the minted `NFToken` can be updated using the `NFTokenModify` transaction. |
6564

6665

6766
## Embedding additional information
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
---
2+
seo:
3+
description: Modify a dynamic NFT.
4+
labels:
5+
- Non-fungible Tokens, NFTs
6+
title:
7+
- NFTokenModify
8+
---
9+
# NFTokenModify
10+
[[Source]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/app/tx/detail/NFTokenMint.cpp "Source")
11+
12+
`NFTokenModify` is used to change the `URI` field of an NFT to point to a different URI in order to update the supporting data for the NFT. The NFT must have been minted with the `tfMutable` flag set. See [Dynamic Non-Fungible Tokens](../../../../concepts/tokens/nfts/dynamic-nfts.md).
13+
14+
## Example {% $frontmatter.seo.title %} JSON
15+
16+
17+
```json
18+
{
19+
"TransactionType": "NFTokenModify",
20+
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
21+
"Owner": "rogue5HnPRSszD9CWGSUz8UGHMVwSSKF6",
22+
"Fee": "10",
23+
"Sequence": 33,
24+
"NFTokenID": "0008C350C182B4F213B82CCFA4C6F59AD76F0AFCFBDF04D5A048C0A300000007",
25+
"URI": "697066733A2F2F62616679626569636D6E73347A736F6C686C6976346C746D6E356B697062776373637134616C70736D6C6179696970666B73746B736D3472746B652F5665742E706E67"
26+
}
27+
```
28+
29+
{% raw-partial file="/docs/_snippets/tx-fields-intro.md" /%}
30+
31+
| Field | JSON Type | [Internal Type][] | Description |
32+
|:------------------|:--------------------|:------------------|:-------------------|
33+
| `TransactionType` | String | UINT16 | Type is `NFTokenModify`. |
34+
| `Account` | String | AccountID | The unique address of either the issuer or an authorized minter of the NFT. |
35+
| `Owner` | String | AccountID | _(Optional)_ Address of the owner of the NFT. If the `Account` and `Owner` are the same address, omit this field. |
36+
| `NFTokenID` | String | Hash 256 | Composite field that uniquely identifies the token. |
37+
| `URI` | String | Blob | _(Optional)_ Up to 256 bytes of arbitrary data. In JSON, this should be encoded as a string of hexadecimal. You can use the [`xrpl.convertStringToHex`](https://js.xrpl.org/modules.html#convertStringToHex) utility to convert a URI to its hexadecimal equivalent. This is intended to be a URI that points to the data or metadata associated with the NFT. The contents could decode to an HTTP or HTTPS URL, an IPFS URI, a magnet link, immediate data encoded as an [RFC 2379 "data" URL](https://datatracker.ietf.org/doc/html/rfc2397), or even an issuer-specific encoding. The URI is not checked for validity. If you do not specify a URI, the existing URI is deleted. |
38+
## Error Cases
39+
Besides errors that can occur for all transactions, {% $frontmatter.seo.title %} transactions can result in the following [transaction result codes](../transaction-results/index.md):
40+
41+
| Error Code | Description |
42+
|:-------------------|:------------|
43+
| `tecNO_PERMISSION` | The `tfMutable` flag wasn't enabled, so you can't update the `URI` field. You can also receive this error if the `Account` field isn't an issuer or authorized minter of the NFT. |
44+
{% raw-partial file="/docs/_snippets/common-links.md" /%}

resources/known-amendments.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ This list is updated manually. For a live view of amendment voting, see the Amen
1717

1818
| Name | Introduced | Status |
1919
|:----------------------------------|:-----------|:------------------------------|
20+
| [DynamicNFT][] | v2.4.0 | {% badge href="https://xrpl.org/blog/2025/rippled-2.4.0" %}Open for Voting: 2025-03-05{% /badge %} |
2021
| [DeepFreeze][] | v2.4.0 | {% badge href="https://xrpl.org/blog/2025/rippled-2.4.0" %}Open for Voting: 2025-03-05{% /badge %} |
2122
| [PermissionedDomains][] | v2.4.0 | {% badge href="https://xrpl.org/blog/2025/rippled-2.4.0" %}Open for Voting: 2025-03-05{% /badge %} |
2223
| [fixFrozenLPTokenTransfer][] | v2.4.0 | {% badge href="https://xrpl.org/blog/2025/rippled-2.4.0" %}Open for Voting: 2025-03-05{% /badge %} |
@@ -423,6 +424,22 @@ Changes transaction processing to check the status of those flags before creatin
423424
Without this amendment, any account can create these objects with any object as the destination; while this is usually harmless, it can block an account from later being deleted, and may also be used as part of scams.
424425

425426

427+
### DynamicNFT
428+
[DynamicNFT]: #dynamicnft
429+
430+
| Amendment | DynamicNFT |
431+
|:-------------|:-----------------|
432+
| Amendment ID | C1CE18F2A268E6A849C27B3DE485006771B4C01B2FCEC4F18356FE92ECD6BB74 |
433+
| Status | Open for Voting |
434+
| Default Vote (Latest stable release) | No |
435+
| Pre-amendment functionality retired? | No |
436+
437+
Adds functionality to update the `URI` field of an `NFToken` ledger entry. This amendment introduces a new transaction type and `NFTokenMint` flag:
438+
439+
1. `NFTokenModify`: New transaction type that updates the `URI` field of an NFT.
440+
2. `tfMutable`: New flag that enables authorized accounts to modify the `URI` of an NFT. This flag must be enabled when the NFT is initially minted.
441+
442+
426443
### EnforceInvariants
427444
[EnforceInvariants]: #enforceinvariants
428445

sidebars.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@
135135
- page: docs/concepts/tokens/nfts/guaranteeing-a-fixed-supply.md
136136
- page: docs/concepts/tokens/nfts/nft-apis.md
137137
- page: docs/concepts/tokens/nfts/non-transferable-tokens.md
138+
- page: docs/concepts/tokens/nfts/dynamic-nfts.md
138139
- page: docs/concepts/tokens/transfer-fees.md
139140
- page: docs/concepts/tokens/decentralized-exchange/index.md
140141
expanded: false
@@ -389,6 +390,7 @@
389390
- page: docs/references/protocol/transactions/types/nftokencanceloffer.md
390391
- page: docs/references/protocol/transactions/types/nftokencreateoffer.md
391392
- page: docs/references/protocol/transactions/types/nftokenmint.md
393+
- page: docs/references/protocol/transactions/types/nftokenmodify.md
392394
- page: docs/references/protocol/transactions/types/offercancel.md
393395
- page: docs/references/protocol/transactions/types/offercreate.md
394396
- page: docs/references/protocol/transactions/types/oracledelete.md

0 commit comments

Comments
 (0)