Merge branch 'add_batch_minting' of github.com:XRPLF/xrpl-dev-portal into add_batch_minting

This commit is contained in:
ddawson
2022-09-19 16:11:55 -07:00
72 changed files with 21383 additions and 193 deletions

View File

@@ -0,0 +1,67 @@
from typing import Union, List
from hashlib import sha256
import hashlib
R58dict = b'rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz'
def scrub_input(input: Union[str, bytes]) -> bytes:
if isinstance(input, str):
input = input.encode('ascii')
return input
def b58encode_int(
integer: int, default_one: bool = True, alphabet: bytes = R58dict
) -> bytes:
"""
Encode an integer using Base58
"""
if not integer and default_one:
return alphabet[0:1]
string = b""
base = len(alphabet)
while integer:
integer, idx = divmod(integer, base)
string = alphabet[idx:idx + 1] + string
return string
def b58encode(
v: Union[str, bytes], alphabet: bytes = R58dict
) -> bytes:
"""
Encode a string using Base58
"""
v = scrub_input(v)
origlen = len(v)
v = v.lstrip(b'\0')
newlen = len(v)
acc = int.from_bytes(v, byteorder='big')
result = b58encode_int(acc, default_one=False, alphabet=alphabet)
return alphabet[0:1] * (origlen - newlen) + result
_CLASSIC_ADDRESS_PREFIX: List[int] = [0x0]
# Public Key -> AccountID
# Ed25519 key:
public_key = "ED9434799226374926EDA3B54B1B461B4ABF7237962EAE18528FEA67595397FA32"
# Calculate the RIPEMD160 hash of the SHA-256 hash of the public key
# This is the "Account ID"
sha_hash = hashlib.sha256(bytes.fromhex(public_key)).digest()
account_id = hashlib.new("ripemd160", sha_hash).digest()
encoded_prefix = bytes(_CLASSIC_ADDRESS_PREFIX)
payload = encoded_prefix + account_id
v = scrub_input(payload)
digest = sha256(sha256(v).digest()).digest()
check = b58encode(v + digest[:4], alphabet=R58dict)
print(check.decode("utf-8"))
# rDTXLQ7ZKZVKz33zJbHjgVShjsBnqMBhmN (Ed25519)

View File

@@ -0,0 +1,33 @@
from xrpl.clients import JsonRpcClient
from xrpl.models.transactions import AccountSet
from xrpl.transaction import safe_sign_and_autofill_transaction, send_reliable_submission
from xrpl.wallet import Wallet, generate_faucet_wallet
# Connect to a testnet node
JSON_RPC_URL = "https://s.altnet.rippletest.net:51234/"
client = JsonRpcClient(JSON_RPC_URL)
# Generate a wallet and request faucet
test_wallet = generate_faucet_wallet(client=client)
myAddr = test_wallet.classic_address
# Construct AccountSet transaction
tx = AccountSet(
account=myAddr
)
# Sign the transaction locally
my_tx_payment_signed = safe_sign_and_autofill_transaction(transaction=tx, wallet=test_wallet, client=client)
# Submit transaction and verify its validity on the ledger
response = send_reliable_submission(transaction=my_tx_payment_signed, client=client)
result = response.result["meta"]["TransactionResult"]
print(f"Account: {myAddr}")
if result == "tesSUCCESS":
print("Transaction successful!")
elif result == "tefMAX_LEDGER":
print("Transaction failed to achieve consensus")
elif result == "unknown":
print("Transaction status unknown")
else:
print(f"Transaction failed with code {result}")

View File

@@ -9,7 +9,7 @@ labels:
[Introduced in: rippled 0.31.0][]
The Amendments system provides a means of introducing new features to the decentralized XRP Ledger network without causing disruptions. The amendments system works by utilizing the core consensus process of the network to approve any changes by showing continuous support before those changes go into effect. An amendment normally requires **80% support for two weeks** before it can apply.
The Amendments system provides a means of introducing new features to the decentralized XRP Ledger network without causing disruptions. The amendments system works by utilizing the core consensus process of the network to approve any changes by showing continuous support before those changes go into effect. An amendment normally requires **more than 80% support for two weeks** before it can apply.
When an Amendment has been enabled, it applies permanently to all ledger versions after the one that included it. You cannot disable an Amendment, unless you introduce a new Amendment to do so.
@@ -41,8 +41,8 @@ Every 256th ledger is called a "flag" ledger. The process of approving an amendm
The flag ledger itself has no special contents. However, during that time, the servers look at the votes of the validators they trust, and decide whether to insert an [`EnableAmendment` pseudo-transaction](enableamendment.html) into the following ledger. The flags of an EnableAmendment pseudo-transaction show what the server thinks happened:
* The `tfGotMajority` flag means that support for the amendment has increased to at least 80% of trusted validators.
* The `tfLostMajority` flag means that support for the amendment has decreased to less than 80% of trusted validators.
* The `tfGotMajority` flag means that support for the amendment has increased to more than 80% of trusted validators.
* The `tfLostMajority` flag means that support for the amendment has decreased to 80% of trusted validators or less.
* An EnableAmendment pseudo-transaction with no flags means that support for the amendment has been enabled. (The change in transaction processing applies to every ledger after this one.)
A server only inserts the pseudo-transaction to enable an amendment if all of the following conditions are met:
@@ -59,7 +59,7 @@ Theoretically, a `tfLostMajority` EnableAmendment pseudo-transaction could be in
Each version of `rippled` is compiled with a list of known amendments and the code to implement those amendments. Operators of `rippled` validators [configure their servers](configure-amendment-voting.html) to vote in favor or against each inactive amendment. Server operators can change their votes at any time. If the operator does not choose a setting for a particular amendment, the server uses a default vote which is defined in the source code. The default can change in new software releases. For example, version 2.0 of the server might understand a new amendment but vote against it by default; then version 2.1 of the server might vote in favor of the same amendment by default. [Updated in: rippled 1.8.1][]
To become enabled, an amendment must be supported by at least 80% of trusted validators continuously for two weeks. If support for an amendment goes below 80% of trusted validators, the amendment is temporarily rejected. The two week period starts over if the amendment regains support of at least 80% of trusted validators. (This can occur if validators vote differently, or if there is a change in which validators are trusted.) An amendment can gain and lose a majority any number of times before it becomes permanently enabled.
To become enabled, an amendment must be supported by more than 80% of trusted validators continuously for two weeks. If support for an amendment goes below 80% of trusted validators, the amendment is temporarily rejected. The two week period starts over if the amendment regains support of more than 80% of trusted validators. (This can occur if validators vote differently, or if there is a change in which validators are trusted.) An amendment can gain and lose a majority any number of times before it becomes permanently enabled.
An amendment cannot be permanently rejected, but it becomes very unlikely for an amendment to become enabled if new versions of `rippled` do not have the amendment in their known amendments list. Amendments that have had their source code removed without becoming enabled are considered "Vetoed" by the network.

View File

@@ -17,7 +17,7 @@ labels:
| [CryptoConditionsSuite][] | 未定 | [開発中: 未定]( "BADGE_LIGHTGREY") |
| [OwnerPaysFee][] | 未定 | [開発中: 未定]( "BADGE_LIGHTGREY") |
| [fixNFTokenNegOffer][] | v1.9.2 | [投票中: 未定](https://xrpl.org/blog/2022/rippled-1.9.2.html "BADGE_80d0e0") |
| [NonFungibleTokensV1_1][] | v1.9.2 | [投票中: 未定](https://xrpl.org/blog/2022/rippled-1.9.2.html "BADGE_80d0e0") |
| [NonFungibleTokensV1_1][] | v1.9.2 | [予定: 2022/09/13](ttps://xrpl.org/blog/2022/get-ready-for-nfts.html "BADGE_BLUE") |
| [ExpandedSignerList][] | v1.9.1 | [投票中: 未定](https://xrpl.org/blog/2022/rippled-1.9.1.html "BADGE_80d0e0") |
| [fixNFTokenDirV1][] | v1.9.1 | [投票中: 未定](https://xrpl.org/blog/2022/rippled-1.9.1.html "BADGE_80d0e0") |
| [NonFungibleTokensV1][] | v1.9.0 | [投票中: 未定](https://xrpl.org/blog/2022/rippled-1.9.0.html "BADGE_80d0e0") |
@@ -657,7 +657,7 @@ It also modifies the [AccountSet transaction][] type to allow you to set the `NF
| Amendment ID | ステータス |
|:-----------------------------------------------------------------|:---------|
| 32A122F1352A4C7B3A6D790362CC34749C5E57FCE896377BFDC6CCD14F6CD627 | 投票中 |
| 32A122F1352A4C7B3A6D790362CC34749C5E57FCE896377BFDC6CCD14F6CD627 | 予定 |
<!-- TODO: translate description -->
This amendment's only effect is to enable three other amendments at the same time:

View File

@@ -17,7 +17,7 @@ The following is a comprehensive list of all known [amendments](amendments.html)
| [CryptoConditionsSuite][] | TBD | [In Development: TBD]( "BADGE_LIGHTGREY") |
| [OwnerPaysFee][] | TBD | [In Development: TBD]( "BADGE_LIGHTGREY") |
| [fixNFTokenNegOffer][] | v1.9.2 | [Open for Voting: TBD](https://xrpl.org/blog/2022/rippled-1.9.2.html "BADGE_80d0e0") |
| [NonFungibleTokensV1_1][] | v1.9.2 | [Open for Voting: TBD](https://xrpl.org/blog/2022/rippled-1.9.2.html "BADGE_80d0e0") |
| [NonFungibleTokensV1_1][] | v1.9.2 | [Expected: 2022-09-13](https://xrpl.org/blog/2022/get-ready-for-nfts.html "BADGE_BLUE") |
| [ExpandedSignerList][] | v1.9.1 | [Open for Voting: TBD](https://xrpl.org/blog/2022/rippled-1.9.1.html "BADGE_80d0e0") |
| [fixNFTokenDirV1][] | v1.9.1 | [Open for Voting: TBD](https://xrpl.org/blog/2022/rippled-1.9.1.html "BADGE_80d0e0") |
| [NonFungibleTokensV1][] | v1.9.0 | [Open for Voting: TBD](https://xrpl.org/blog/2022/rippled-1.9.0.html "BADGE_80d0e0") |
@@ -77,7 +77,7 @@ The following is a comprehensive list of all known [amendments](amendments.html)
| Amendment | CheckCashMakesTrustLine |
|:----------|:-----------|
| Amendment ID | 98DECF327BF79997AEC178323AD51A830E457BFC6D454DAF3E46E5EC42DC619F |
| Status | In Development |
| Status | Open for Voting |
| Default Vote (Latest stable release) | No |
| Pre-amendment functionality retired? | No |
@@ -185,7 +185,7 @@ Adds a new transaction type, DepositPreauth for adding or removing preauthorizat
Changes the behavior of cross-currency Payments from an account to itself when that account requires deposit authorization. Without this amendment, those payments always fail with the code `tecNO_PERMISSION`. With this amendment, those payments succeed as they would with Deposit Authorization disabled.
TAlso changes the OfferCreate transaction to return `tecEXPIRED` when trying to create an Offer whose expiration time is in the past. Without this amendment, an OfferCreate whose expiration time is in the past returns `tesSUCCESS` but does not create or execute an Offer.
Also changes the OfferCreate transaction to return `tecEXPIRED` when trying to create an Offer whose expiration time is in the past. Without this amendment, an OfferCreate whose expiration time is in the past returns `tesSUCCESS` but does not create or execute an Offer.
## EnforceInvariants
@@ -796,7 +796,7 @@ It also modifies the [AccountSet transaction][] type to allow you to set the `NF
| Amendment | NonFungibleTokensV1_1 |
|:----------|:-----------|
| Amendment ID | 32A122F1352A4C7B3A6D790362CC34749C5E57FCE896377BFDC6CCD14F6CD627 |
| Status | Open for Voting |
| Status | Expected |
| Default Vote (Latest stable release) | No |
| Pre-amendment functionality retired? | No |

View File

@@ -9,7 +9,7 @@ labels:
There is one production XRP Ledger peer-to-peer network, and all business that takes place on the XRP Ledger occurs within the production network—the Mainnet.
To help members of the XRP Ledger community interact with XRP Ledger technology without affecting anything on the Mainnet, Ripple hosts two alternative networks, or altnets: the Testnet and the Devnet. Here's a breakdown of all three networks:
To help members of the XRP Ledger community interact with XRP Ledger technology without affecting anything on the Mainnet, there are alternative networks, or altnets. Here's a breakdown of some public altnets:
| Network | Upgrade Cadence | Description |
|:--------|:----------------|:-------------------------------------------------|
@@ -19,16 +19,16 @@ To help members of the XRP Ledger community interact with XRP Ledger technology
| NFT-Devnet | [XLS-20 pre-release](https://github.com/ripple/rippled/tree/xls20) | A preview of the [XLS-20d](https://github.com/XRPLF/XRPL-Standards/discussions/46) standard for non-fungible tokens on the XRP Ledger. |
| [Hooks Testnet V2](https://hooks-testnet-v2.xrpl-labs.com/) | [Hooks server](https://github.com/XRPL-Labs/xrpld-hooks) | A preview of on-chain smart contract functionality using [hooks](https://write.as/xumm/xrpl-labs-is-working-on-the-transaction-hooks-amendment-for-the-xrp-ledger). |
Each test network has its own separate supply of test XRP, which is [given away for free](xrp-testnet-faucet.html) to parties interested in experimenting with the XRP Ledger and developing applications and integrations. Test XRP does not have real-world value and is lost when the network is reset.
Each altnet has its own separate supply of test XRP, which is [given away for free](xrp-testnet-faucet.html) to parties interested in experimenting with the XRP Ledger and developing applications and integrations. Test XRP does not have real-world value and is lost when the network is reset.
**Caution:** Unlike the XRP Ledger Mainnet, test networks are usually _centralized_ and there are no guarantees about the stability and availability of these networks. They have been and continue to be used to test various properties of server configuration, network topology, and network performance.
## Parallel Networks and Consensus
The main factor in determining which network a server follows is its configured UNL—the list of validators it trusts not to collude. Each server uses its configured UNL to know which ledger to accept as the truth. When different consensus groups of `rippled` instances only trust other members of the same group, each group continues as a parallel network. Even if malicious or misbehaving computers connect to both networks, the consensus process overrides the confusion as long as the members of each network are not configured to trust members of another network in excess of their quorum settings.
The main factor in determining which network a server follows is its configured UNL—the list of validators it trusts not to collude. Each server uses its configured UNL to know which ledger to accept as the truth. When different consensus groups of `rippled` instances only trust other members of the same group, each group continues as a parallel network. Even if malicious or misbehaving computers connect to both networks, the consensus process avoids confusion as long as the members of each network are not configured to trust members of another network in excess of their quorum settings.
Ripple runs the main servers in the Testnet, Devnet, and NFT-Devnet; you can also [connect your own `rippled` server to these networks](connect-your-rippled-to-the-xrp-test-net.html). The Testnet and Devnet do not use diverse, censorship-resistant sets of validators. This makes it possible for Ripple to reset the Testnet or Devnet on a regular basis.
Ripple runs the main servers in the Testnet, Devnet, and NFT-Devnet; you can also [connect your own `rippled` server to these networks](connect-your-rippled-to-the-xrp-test-net.html). The Testnet and Devnet do not use diverse, censorship-resistant sets of validators. This makes it possible for Ripple to reset the Testnet or Devnet at any time.
## See Also

View File

@@ -46,7 +46,7 @@ You create a new `NFToken` using the [NFTokenMint transaction][].
[NFTokenOffer object][] is a new object that describes an offer to buy or sell a single `NFToken`.
You destroy an `NFToken` using the [NFTokenBurn transaction][].
You destroy an `NFToken` using the [NFTokenBurn transaction][]. Token owners can always burn a token they own. If you mint a token with the `tfBurnable` flag set, you have the option of burning the token at any time, regardless of the owner.
## `NFToken` Lifecycle

View File

@@ -15,7 +15,7 @@ Each "trust line" is a _bidirectional_ relationship consisting of:
- A single, shared **balance**, which is positive from the perspective of one account and negative from the other perspective.
- The account with a negative balance is generally considered the "issuer" of the tokens. However, in the [APIs](http-websocket-apis.html), the name `issuer` can refer to either side.
- Various **settings** and metadata. _Each_ of the two accounts can control its own settings on the trust line.
- Most importantly, each side sets a **limit** on the trust line, which is 0 by default. Each account's balance (from its perspective on the trust line) can't go above that account's limit, except [through that account's own actions](#going-below-the-limit).
- Most importantly, each side sets a **limit** on the trust line, which is 0 by default. Each account's balance (from its perspective on the trust line) can't go above that account's limit, except [through that account's own actions](#going-above-the-limit).
Each trust line is specific to a given [currency code][]. Two accounts can have any number of trust lines between them for different currency codes, but only one shared trust line for any particular currency code.
@@ -27,7 +27,7 @@ Any account can unilaterally "trust" another account to issue a token by sending
Trust lines can be implicitly created by some transactions, such as when you buy a token in the [decentralized exchange](decentralized-exchange.html). In this case, the trust line uses entirely default settings.
## Going Below the Limit
## Going Above the Limit
There are three cases where you can hold a balance that is _greater_ than your limit on that trust line:

View File

@@ -101,6 +101,14 @@ Publishers of individual default UNLs set their own policies for when to add or
For recommendations and best practices, see [Run `rippled` as a Validator](run-rippled-as-a-validator.html).
#### If the dUNL has the most influence on the network, then is the XRPL centralized?
Validators can choose to not use the dUNL, or any widely-used UNL for that matter. Anyone can create a new UNL at any time.
There can be multiple UNLs in use on the same network. Each operator can customize their server's own UNL or choose to follow a different recommended list. All these servers can still operate on the same chain and reach consensus with one another.
However, if your UNL does not have sufficient overlap with the UNLs used by others, there is a risk that your server forks away from the rest of the network. As long as your UNL has > 90% overlap with the one used by people you're transacting with, you are completely safe from forking. If you have less overlap, you may still be able to follow the same chain, but the chances of forking increase with lower overlap, worse network connectivity, and the presence of unreliable or malicious validators on your UNL.
## Role of XRP
@@ -141,16 +149,9 @@ Once the pull request passes automated tests and receives approvals from reviewe
No, Ripple does not own or control the XRP Ledger or XRP Ledger network.
Ripple does publish a reference implementation of the core XRP Ledger server ([`rippled`](https://github.com/ripple/rippled)) and employs a team of engineers who contribute to the open-source codebase. Ripple also periodically publishes pre-compiled binary packages of the software as a convenience. Anyone is free to [download and compile the software from source](install-rippled.html), if they prefer.
Ripple contributes to a reference implementation of the core XRP Ledger server ([`rippled`](https://github.com/xrplf/rippled)) and employs a team of engineers who contribute to the open-source codebase. Ripple periodically publishes pre-compiled binary packages of the software for convenience. Anyone can [download and compile the software from source](install-rippled.html).
You don't need to use Ripples version of the XRP Ledger software to interact with the XRP Ledger. `rippled` is open-source software and Ripple grants anyone the ability to use, extend, and modify it as long as they follow the terms of the [ISC license](https://github.com/ripple/rippled/blob/develop/LICENSE.md). The ISC License is very permissive compared to some other open-source licenses that strictly limit how you can extend and adapt the software.
Ripple is also one of several entities who publish recommended UNL settings and runs validators on the network. As of mid-2021, Ripple runs 6 of the 35+ validators in the default UNL.
#### Does Ripple offer a secure method to download their software?
`rippled` source code is available at <https://github.com/ripple/rippled>, where the tip of the `master`, `release` and `develop` branches always contains a version-setting commit signed by a `rippled` developer. Ripple also publishes pre-built binary packages for CentOS, RedHat Enterprise Linux, Fedora, Ubuntu, and Debian Linux. Those packages are digitally signed so that they are tamper-evident and their authenticity can be verified. Lastly, release bulletins are made available over a secure website, and include the commit ID of the repository, as well as the cryptographic hash values of the packages that are published. <!-- STYLE_OVERRIDE: evident -->
Several entities publish recommended validator lists (UNLs). As of September 2022, Ripple runs 3 of the 35 validators in the default UNL.
#### Does the XRP Ledger distinguish between the codebase for validation and the one for user software?

View File

@@ -149,7 +149,7 @@ Each object in the `account_nfts` array represents one [NFToken][] and has the f
| `Flags` | Number | A bit-map of boolean flags enabled for this NFToken. See [NFToken Flags](nftoken.html#nftoken-flags) for possible values. |
| `Issuer` | String - [Address][] | The account that issued this NFToken. |
| `NFTokenID` | String | The unique identifier of this NFToken, in hexadecimal. |
| `NFTokenTaxon` | Number | The unscrambled version of this token's [taxon](nftoken.html#taxon). Several tokens with the same taxon might represent instances of a limited series. |
| `NFTokenTaxon` | Number | The unscrambled version of this token's [taxon](nftoken.html#nftokentaxon). Several tokens with the same taxon might represent instances of a limited series. |
| `URI` | String | The URI data associated with this NFToken, in hexadecimal. |
| `nft_serial` | Number | The token sequence number of this NFToken, which is unique for its issuer. |

View File

@@ -9,13 +9,13 @@ status: not_enabled
# NFToken
{% include '_snippets/nfts-disclaimer.md' %}
The `NFToken` object represents a single non-fungible token (NFT). It is not stored on its own, but is contained in a [NFTokenPage object][] alongside other NFTs.
The `NFToken` object represents a single non-fungible token (NFT). It is not stored on its own, but is contained in a [NFTokenPage object][] alongside other `NFToken` objects.
Example {{currentpage.name}} JSON
```json
{
"TokenID": "000B013A95F14B0044F78A264E41713C64B5F89242540EE208C3098E00000D65",
"NFTokenID": "000B013A95F14B0044F78A264E41713C64B5F89242540EE208C3098E00000D65",
"URI": "ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf4dfuylqabf3oclgtqy55fbzdi"
}
```
@@ -24,23 +24,23 @@ Example {{currentpage.name}} JSON
Unlike other objects, `NFToken` has no field to identify the object type or current owner of the object. `NFToken `objects are grouped into `NFTokenPages` that implicitly define the object type and identify the owner.
## TokenID
## NFTokenID
TokenID, optional, string, Hash256
`NFTokenID`, optional, string, Hash256
This composite field uniquely identifies a token, and consists of the following sections.
1. 16 bits that identify flags or settings specific to the NFT
2. 16 bits that encode the transfer fee associated with this token, if any
1. 16 bits that identify flags or settings specific to the NFToken
2. 16 bits that encode the transfer fee associated with this NFToken, if any
3. A 160-bit account identifier of the issuer
4. A 32-bit issuer-specified [taxon](https://www.merriam-webster.com/dictionary/taxon)
4. A 32-bit issuer-specified [NFTokenTaxon](https://www.merriam-webster.com/dictionary/taxon)
5. An (automatically generated) monotonically increasing 32-bit sequence number.
![Token ID Breakdown](img/nftoken1.png "Token ID Breakdown")
The 16-bit flags, transfer fee fields, the 32-bit taxon, and the sequence number fields are stored in big-endian format.
The 16-bit flags, transfer fee fields, the 32-bit `NFTokenTaxon`, and the sequence number fields are stored in big-endian format.
## NFToken Flags
@@ -86,7 +86,7 @@ Flags are properties or other options associated with the `NFToken` object.
</td>
<td><code>0x0008</code>
</td>
<td>If set, indicates that this NFT can be transferred. This flag has no effect if the token is being transferred <em>from</em> the issuer or <em>to</em> the issuer.
<td>If set, indicates that this <code>NFToken</code> can be transferred. This flag has no effect if the token is being transferred <em>from</em> the issuer or <em>to</em> the issuer.
</td>
</tr>
<tr>
@@ -100,7 +100,7 @@ Flags are properties or other options associated with the `NFToken` object.
</table>
`NFToken `flags are immutable: they can only be set during the `NFTokenMint` transaction and cannot be changed later.
`NFToken` flags are immutable: they can only be set during the `NFTokenMint` transaction and cannot be changed later.
### Example
@@ -112,36 +112,36 @@ The example sets three flags: lsfBurnable (0x0001), lsfOnlyXRP (0x0002), lsfTran
### TransferFee
The TransferFee value specifies the percentage fee, in units of 1/10,000, charged by the issuer for secondary sales of the token. Valid values for this field are between 0 and 50,000, inclusive. A value of 1 is equivalent to 1bps or 0.01%, allowing transfer rates between 0% and 50%.
The `TransferFee` value specifies the percentage fee, in units of 1/10,000, charged by the issuer for secondary sales of the token. Valid values for this field are between 0 and 50,000, inclusive. A value of 1 is equivalent to 1bps or 0.00001%, allowing transfer rates between 0% and 50%.
### Example
This value sets the transfer fee to 314 bps, or 3.14%.
This value sets the transfer fee to 314, or .00314%.
![Txr Fee](img/nftokenb.png "Txr Fee")
![Transfer Fee](img/nftokenb.png "Transfer Fee")
### Issuer Identification
The third section of the TokenID is a big endian representation of the issuers public address.
The third section of the `NFTokenID` is a big endian representation of the issuers public address.
![Issuer Address](img/nftokenc.png "Issuer Address")
### Taxon
### NFTokenTaxon
The fourth section is a taxon created by the issuer.
The fourth section is a `NFTokenTaxon` created by the issuer.
![Taxon](img/nftokend.png "Taxon")
![NFTokenTaxon](img/nftokend.png "NFTokenTaxon")
An issuer might issue several NFTs with the same taxon; to ensure that NFTs are spread across multiple pages, the taxon is scrambled using the fifth section, a dumb sequential number, as the seed for a random number generator. The scrambled value is stored with the `NFToken`, but the unscrambled value is the actual taxon.
An issuer might issue several `NFToken` objects with the same `NFTokenTaxon`; to ensure that `NFToken` objects are spread across multiple pages, the `NFTokenTaxon` is scrambled using the fifth section, a sequential number, as the seed for a random number generator. The scrambled value is stored with the `NFToken`, but the unscrambled value is the actual NFTokenTaxon.
![Dumb Sequential](img/nftokene.png "Dumb Sequential")
Notice that the scrambled version of the taxon is `0xBC8B858E`: the scrambled version of the taxon specified by the issuer. But the _actual_ value of the taxon is the unscrambled value.
Notice that the scrambled version of the `NFTokenTaxon` is `0xBC8B858E`: the scrambled version of the `NFTokenTaxon` specified by the issuer. But the _actual_ value of the `NFTokenTaxon` is the unscrambled value.
### Token Sequence
@@ -172,21 +172,21 @@ The format for a text record is as follows.
```
xrpl-nft-data-token-info-v1 IN TXT "https://host.example.com/api/token-info/{tokenid}"
xrpl-nft-data-token-info-v1 IN TXT "https://host.example.com/api/token-info/{nftokenid}"
```
Replace the string `{tokenid}` with the requested tokens `NFTokenID` as a 64-byte hex string when you attempt to query information.
Replace the string `{nftokenid}` with the requested `NFTokenID` as a 64-byte hex string when you attempt to query information.
Your implementation should check for the presence of `TXT` records and use those query strings if present. If no string is present, implementations should attempt to use a default URL. Assuming the domain is _example.com_, the default URL would be:
```
https://example.com/.well-known/xrpl-nft/{tokenid}
https://example.com/.well-known/xrpl-nft/{nftokenid}
```
You create NFTs using the `NFTokenMint` transaction. You can optionally destroy NFTokens using the `NFTokenBurn` transaction.
You create `NFToken` objects using the `NFTokenMint` transaction. You can optionally destroy `NFToken` objects using the `NFTokenBurn` transaction.
<!--{# common link defs #}-->
{% include '_snippets/rippled-api-links.md' %}

View File

@@ -90,7 +90,7 @@ The unique ID (`NFTokenOfferID`) of the `NFTokenOffer` object is the result of t
</td>
</tr>
<tr>
<td><code>TokenID</code>
<td><code>NFTokenID</code>
</td>
<td>Yes
</td>
@@ -98,7 +98,7 @@ The unique ID (`NFTokenOfferID`) of the `NFTokenOffer` object is the result of t
</td>
<td>Hash256
</td>
<td><code>TokenID</code> of the <code>NFToken</code> object referenced by this offer.
<td><code>NFTokenID</code> of the <code>NFToken</code> object referenced by this offer.
</td>
</tr>
<tr>
@@ -152,7 +152,7 @@ Sell offers that specify assets other than XRP must specify a non-zero amount. S
</td>
</tr>
<tr>
<td><code>OfferNode</code>
<td><code>NFTokenOfferNode</code>
</td>
<td>No
</td>
@@ -192,19 +192,11 @@ Sell offers that specify assets other than XRP must specify a non-zero amount. S
</td>
</tr>
<tr>
<td><code>lsfBuyToken</code>
<td><code>lsfSellNFToken</code>
</td>
<td><code>0x00000001</code>
</td>
<td>If set, the offer is a buy offer. Otherwise, the offer is a sell offer.
</td>
</tr>
<tr>
<td><code>lsfAuthorized</code>
</td>
<td><code>0x00000002</code>
</td>
<td>If set, the offer has been approved by the issuer. This flag can only be set by the <code>Issuer</code> of the token or an account authorized by the issuer (for example, the <code>MintAccount</code> listed in the account root of the <code>Issuer</code>) and only if the token has the flag indicating that authorization is required.
<td>If set, the offer is a sell offer. Otherwise, the offer is a buy offer.
</td>
</tr>
</table>

View File

@@ -11,7 +11,7 @@ status: not_enabled
# NFTokenPage
{% include '_snippets/nfts-disclaimer.md' %}
The `NFTokenPage` object represents a collection of `NFToken` objects owned by the same account. An account can have multiple `NFTokenPage` ledger objects, which form a doubly-linked list (DLL).
The `NFTokenPage` object represents a collection of `NFToken` objects owned by the same account. An account can have multiple `NFTokenPage` ledger objects, which form a doubly linked list.
## Example {{currentpage.name}} JSON
@@ -26,13 +26,12 @@ The `NFTokenPage` object represents a collection of `NFToken` objects owned by t
"95C8761B22894E328646F7A70035E9DFBECC90EDD83E43B7B973F626D21A0822",
"PreviousTxnLgrSeq":
42891441,
"Tokens":
"NFTokens":
{
{
"TokenID":
"NFTokenID":
"000B013A95F14B0044F78A264E41713C64B5F89242540EE208C3098E00000D65",
"URI":
"ipfs://bafybeigdyrzt5sfp7udm7hu76uh7y26nf4dfuylqabf3oclgtqy55fbzdi"
"URI": "697066733A2F2F62616679626569676479727A74357366703775646D37687537367568377932366E6634646675796C71616266336F636C67747179353566627A6469"
},
/* potentially more objects */
}
@@ -123,7 +122,7 @@ An `NFTokenPage` object can have the following required and optional fields:
</td>
</tr>
<tr>
<td><code>NonFungibleTokens</code>
<td><code>NFTokens</code>
</td>
<td>Yes
</td>
@@ -180,15 +179,15 @@ The value of the incremental reserve is, as of this writing, 2 XRP. The table be
<tr>
<td><strong>Incremental Reserve</strong>
</td>
<td><strong>1 NFT</strong>
<td><strong>1 NFToken</strong>
</td>
<td><strong>8 NFTs</strong>
<td><strong>8 NFTokens</strong>
</td>
<td><strong>16 NFTs</strong>
<td><strong>16 NFTokens</strong>
</td>
<td><strong>32 NFTs</strong>
<td><strong>32 NFTokens</strong>
</td>
<td><strong>64 NFTs</strong>
<td><strong>64 NFTokens</strong>
</td>
</tr>
<tr>

View File

@@ -28,7 +28,7 @@ The mode in which the transaction operates depends on the presence of the `NFTok
If neither of those fields is specified, the transaction is malformed and produces a `tem` class error.
The semantics of brokered mode are slightly different than one in direct mode: The account executing the transaction functions as a broker, bringing the two offers together and causing them to be matched, but does not acquire ownership of the involved NFT, which will, if the transaction is successful, be transferred directly from the seller to the buyer.
The semantics of brokered mode are slightly different than one in direct mode: The account executing the transaction functions as a broker, bringing the two offers together and causing them to be matched, but does not acquire ownership of the involved `NFToken`, which will, if the transaction is successful, be transferred directly from the seller to the buyer.
## Execution Details
@@ -39,8 +39,8 @@ The semantics of brokered mode are slightly different than one in direct mode: T
In direct mode, `NFTokenAcceptOffer` transaction fails if:
* The `NFTokenOffer` against which `NFTokenAcceptOffer` transaction is placed is an offer to `buy` the `NFToken` and the account executing the `NFTokenAcceptOffer` is not, at the time of execution, the current owner of the corresponding `NFToken`.
* The `NFTokenOffer` against which `NFTokenAcceptOffer` transaction is placed is an offer to `sell` the `NFToken` and was placed by an account which is not, at the time of execution, the current owner of the `NFToken`
* The `NFTokenOffer` against which `NFTokenAcceptOffer` transaction is placed is an offer to `sell` the `NFToken` and was placed by an account which is not, at the time of execution, the `Account` in the recipient field of the `NFTokenOffer`, if there exist one.
* The `NFTokenOffer` against which `NFTokenAcceptOffer` transaction is placed is an offer to `sell` the `NFToken` and was placed by an account which is not, at the time of execution, the current owner of the `NFToken`.
* The `NFTokenOffer` against which `NFTokenAcceptOffer` transaction is placed is an offer to `sell` the `NFToken` and was placed by an account which is not, at the time of execution, the `Account` in the recipient field of the `NFTokenOffer`, if one exists.
* The `NFTokenOffer` against which `NFTokenAcceptOffer` transaction is placed specifies an `expiration` time and the close time field of the parent of the ledger in which the transaction would be included has already passed.
* The `NFTokenOffer` against which `NFTokenAcceptOffer` transaction is placed to buy or sell the `NFToken `is owned by the account executing the `NFTokenAcceptOffer`.
@@ -49,7 +49,7 @@ A side-effect of such failures is the removal of the `NFTokenOffer` object and t
If the transaction is executed successfully then:
* The relevant `NFTtoken` changes ownership, meaning that the token is removed from the `NFTokenPage` of the existing `owner` and added to the `NFTokenPage` of the new `owner`.
* Funds are transferred from the buyer to the seller, as specified in the `NFTokenOffer`. If the corresponding `NFToken` offer specifies a `TransferRate`, then the `issuer` receives the specified percentage, with the balance going to the seller of the `NFToken`.
* Funds are transferred from the buyer to the seller, as specified in the `NFTokenOffer`. If the corresponding `NFToken` offer specifies a `TransferFee`, then the `issuer` receives the specified percentage, with the balance going to the seller of the `NFToken`.
### Brokered Mode

View File

@@ -37,7 +37,7 @@ This transaction removes the listed `NFTokenOffer` object from the ledger, if pr
| Field | JSON Type | [Internal Type][] | Description |
|:------------------|:----------|:------------------|:-------------------------|
| `TokenOffers` | Array | VECTOR256 | An array of IDs of the `NFTokenOffer` objects to cancel (not the IDs of `NFToken` objects, but the IDs of the `NFTokenOffer` objects). Each entry must be a different [object ID](ledger-object-ids.html) of an [NFTokenOffer](nftokenoffer.html) object; the transaction is invalid if the array contains duplicate entries. |
| `NFTokenOffers` | Array | VECTOR256 | An array of IDs of the `NFTokenOffer` objects to cancel (not the IDs of `NFToken` objects, but the IDs of the `NFTokenOffer` objects). Each entry must be a different [object ID](ledger-object-ids.html) of an [NFTokenOffer](nftokenoffer.html) object; the transaction is invalid if the array contains duplicate entries. |
The transaction can succeed even if one or more of the IDs in the `NFTokenOffers` field do not refer to objects that currently exist in the ledger. (For example, those token offers might already have been deleted.) The transaction fails with an error if one of the IDs points to an object that does exist, but is not a [NFTokenOffer](nftokenoffer.html) object.
@@ -52,8 +52,8 @@ In addition to errors that can occur for all transactions, {{currentpage.name}}
| Error Code | Description |
|:-------------------|:--------------------------------------------------------|
| `temDISABLED` | The [NonFungibleTokensV1 amendment][] is not enabled. |
| `temMALFORMED` | The transaction was not validly formatted. For example, the `TokenOffers` array was empty or contained more than the maximum number of offers that can be canceled at one time. |
| `tecNO_PERMISSION` | At least one of the IDs in the `TokenOffers` field refers to an object that cannot be canceled. For example, the sender of this transaction is not the owner or `Destination` of the offer, or the object was not an `NFTokenOffer` type object. |
| `temMALFORMED` | The transaction was not validly formatted. For example, the `NFTokenOffers` array was empty or contained more than the maximum number of offers that can be canceled at one time. |
| `tecNO_PERMISSION` | At least one of the IDs in the `NFTokenOffers` field refers to an object that cannot be canceled. For example, the sender of this transaction is not the owner or `Destination` of the offer, or the object was not an `NFTokenOffer` type object. |
<!--{# common link defs #}-->
{% include '_snippets/rippled-api-links.md' %}

View File

@@ -41,9 +41,9 @@ If successful, the transaction creates a [NFTokenOffer object][]. Each offer cou
Transactions of the NFTokenCreateOffer type support additional values in the [`Flags` field](transaction-common-fields.html#flags-field), as follows:
| Flag Name | Hex Value | Decimal Value | Description |
|:--------------|:-------------|:--------------|:------------------------------|
| `tfSellToken` | `0x00000001` | `1` | If enabled, indicates that the offer is a sell offer. Otherwise, it is a buy offer. |
| Flag Name | Hex Value | Decimal Value | Description |
|:----------------|:-------------|:--------------|:------------------------------|
| `tfSellNFToken` | `0x00000001` | `1` | If enabled, indicates that the offer is a sell offer. Otherwise, it is a buy offer. |
## Error Cases

View File

@@ -12,8 +12,6 @@ status: not_enabled
The `NFTokenMint` transaction creates a non-fungible token and adds it to the relevant [NFTokenPage object][] of the `NFTokenMinter` as an [NFToken][] object. A required parameter to this transaction is the `Token` field specifying the actual token. This transaction is the only opportunity the `NFTokenMinter` has to specify any token fields that are defined as immutable (for example, the `TokenFlags`).
If the transaction is successful, the newly minted token is owned by the account (the `minter` account) that executed the transaction. If needed, the server creates a new `NFTokenPage` for the account and applies a reserve charge.
## Example {{currentpage.name}} JSON
@@ -22,7 +20,6 @@ If the transaction is successful, the newly minted token is owned by the account
{
"TransactionType": "NFTokenMint",
"Account": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B",
"Issuer": "rNCFjv8Ek5oDrNiMJ3pw6eLLFtMjZLJnf2",
"TransferFee": 314,
"NFTokenTaxon": 0,
"Flags": 8,
@@ -41,9 +38,6 @@ If the transaction is successful, the newly minted token is owned by the account
```
This transaction assumes that the issuer, `rNCFjv8Ek5oDrNiMJ3pw6eLLFtMjZLJnf2`, has set the `NFTokenMinter` field in its `AccountRoot` to `rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B`, thereby authorizing that account to mint tokens on its behalf.
{% include '_snippets/tx-fields-intro.md' %}
| Field | JSON Type | [Internal Type][] | Description |
@@ -86,7 +80,7 @@ If you want to issue an NFT for another account there are two things you must do
"TransactionType": "NFTokenMint",
"Account": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B",
"Issuer": "rNCFjv8Ek5oDrNiMJ3pw6eLLFtMjZLJnf2",
"TransferFee": 314,
"TransferFee": 25000,
"NFTokenTaxon": 0,
"Flags": 8,
"Fee": "10",

View File

@@ -18,13 +18,13 @@ This example shows how to:
1. Authorize an account to create NFTokens for your account.
2. Mint a NFToken for another account, when authorized.
[![Token Test Harness](../../img/quickstart28.png)](../../img/quickstart28.png)
[![Token Test Harness](img/quickstart28.png)](img/quickstart28.png)
# Usage
You can download the [Quickstart Samples](https://github.com/XRPLF/xrpl-dev-portal/tree/master/content/_code-samples/quickstart/js/quickstart.zip) archive to try the sample in your own browser.
## Authorize a Minter
## Get Accounts
1. Open `6.authorized-minter.html` in a browser.
2. Get test accounts.
@@ -43,7 +43,7 @@ To authorize another account to create NFTokens for your account:
2. Paste the **Operational Account** value in the **Authorized Minter** field.
3. Click **Set Minter**.
[![Authorized Minter](../../img/quickstart29.png)](../../img/quickstart29.png)
[![Authorized Minter](img/quickstart29.png)](img/quickstart29.png)
## Mint a NFToken for Another Account
@@ -57,7 +57,7 @@ To mint a non-fungible token for another account:
4. Copy the **Standby Account** value.
5. Paste the **Standby Account** value in the Operational account **Issuer** field.
6. Click the Operational account **Mint Other** button.
[![Minted NFToken for Another Account](../../img/quickstart30.png)](../../img/quickstart30.png)
[![Minted NFToken for Another Account](img/quickstart30.png)](img/quickstart30.png)
Once the item is minted, the authorized minter can sell the NFToken normally. The proceeds go to the authorized minter, less the transfer fee. The minter and the issuer can settle up on a division of the purchase price separately.
@@ -73,7 +73,7 @@ To create a NFToken sell offer:
The important piece of information in the response is the Token Offer Index, labeled as _nft_offer_index,_ which is used to accept the sell offer.
[![NFToken Sell Offer](../../img/quickstart31.png)](../../img/quickstart31.png)
[![NFToken Sell Offer](img/quickstart31.png)](img/quickstart31.png)
## Accept Sell Offer
@@ -86,7 +86,7 @@ To accept an available sell offer:
2. Click **Accept Sell Offer**.
When you examine the results field, you'll find that the Issuer account is credited 25 XRP. The Buyer account is debited the 100 XRP purchase price plus 12 drops as the transaction fee. The Seller (Authorized Minter) account is credited 75 XRP. the Issuer and the Seller can divide the proceeds per their agreement in a separate transaction.
[![Transaction Results](../../img/quickstart32.png)](../../img/quickstart32.png)
[![Transaction Results](img/quickstart32.png)](img/quickstart32.png)
# Code Walkthrough
@@ -121,7 +121,7 @@ Connect to the ledger and get the account wallet.
Define the AccountSet transaction, setting the `NFTokenMinter` account and the `asfAuthorizedNFTokenMinter` flag.
```javascript
tx_blob = {
tx_json = {
"TransactionType": "AccountSet",
"Account": my_wallet.address,
```
@@ -132,10 +132,10 @@ Set `NFTokenMinter` to the account number of the authorized minter.
"NFTokenMinter": standbyMinterField.value,
```
Set flag 10, which is `asfAuthorizedNFTokenMinter`.
Set the `asfAuthorizedNFTokenMinter` flag (the numeric value is _10_).
```javascript
"SetFlag": 10
"SetFlag": xrpl.AccountSetAsfFlags.asfAuthorizedNFTokenMinter
}
```
@@ -149,20 +149,20 @@ Report progress.
Prepare and send the transaction, then wait for results
```javascript
const cst_prepared = await client.autofill(tx_blob)
const cst_signed = my_wallet.sign(cst_prepared)
const cst_result = await client.submitAndWait(cst_signed.tx_blob)
const prepared = await client.autofill(tx_json)
const signed = my_wallet.sign(prepared)
const result = await client.submitAndWait(signed.tx_json)
```
If the transaction succeeds, stringify the results and report. If not, report that the transaction failed.
```javascript
if (cst_result.result.meta.TransactionResult == "tesSUCCESS") {
if (result.result.meta.TransactionResult == "tesSUCCESS") {
results += '\nAccount setting succeeded.'
results += JSON.stringify(cst_result,null,2)
results += JSON.stringify(result,null,2)
document.getElementById('standbyResultField').value = results
} else {
throw 'Error sending transaction: ${cst_result}'
throw 'Error sending transaction: ${result}'
results += '\nAccount setting failed.'
document.getElementById('standbyResultField').value = results
}
@@ -205,7 +205,7 @@ Report success
document.getElementById('standbyResultField').value = results
```
This transaction blob is the same as the one used for the previous `Mint Token` function, with the addition of the `Issuer` field.
This transaction blob is the same as the one used for the previous [`mintToken()` function](mint-and-burn-nftokens.html#mint-token), with the addition of the `Issuer` field.
```javascript
const transactionBlob = {
@@ -219,7 +219,7 @@ The URI is a link to a data file represented by the NFToken.
"URI": xrpl.convertStringToHex(standbyTokenUrlField.value),
```
At a minimum, we recommend that you set the tfTransferable flag (8) to enable accounts to sell and resell the NFToken for testing purposes.
At a minimum, we recommend that you set the `tfTransferable` flag (8) to enable accounts to sell and resell the NFToken for testing purposes.
```javascript
"Flags": parseInt(standbyFlagsField.value),
@@ -291,24 +291,24 @@ async function oPsetMinter(type) {
my_wallet = xrpl.Wallet.fromSeed(operationalSeedField.value)
document.getElementById('operationalResultField').value = results
tx_blob = {
tx_json = {
"TransactionType": "AccountSet",
"Account": my_wallet.address,
"NFTokenMinter": operationalMinterField.value,
"SetFlag": 10
"SetFlag": xrpl.AccountSetAsfFlags.asfAuthorizedNFTokenMinter
}
results += '\n Set Minter.'
document.getElementById('operationalResultField').value = results
const cst_prepared = await client.autofill(tx_blob)
const cst_signed = my_wallet.sign(cst_prepared)
const cst_result = await client.submitAndWait(cst_signed.tx_blob)
if (cst_result.result.meta.TransactionResult == "tesSUCCESS") {
const prepared = await client.autofill(tx_json)
const signed = my_wallet.sign(prepared)
const result = await client.submitAndWait(signed.tx_json)
if (result.result.meta.TransactionResult == "tesSUCCESS") {
results += '\nAccount setting succeeded.'
results += JSON.stringify(cst_result,null,2)
results += JSON.stringify(result,null,2)
document.getElementById('operationalResultField').value = results
} else {
throw 'Error sending transaction: ${cst_result}'
throw 'Error sending transaction: ${result}'
results += '\nAccount setting failed.'
document.getElementById('operationalResultField').value = results
}
@@ -758,4 +758,5 @@ Update the form with fields and buttons to support the new functions.
| Previous | Next |
| :--- | ---: |
| [← Broker a NFToken Sale >](broker-sale.html) | [Batch Mint NFTokens → >](batch-minting.md) |
| [← Broker a NFToken Sale >](broker-sale.html) | [Batch Mint NFTokens → >](batch-minting.md) |

View File

@@ -1043,7 +1043,7 @@ Revise the HTML form to add a new Broker section at the top.
</table>
</form>
</body>
</html>
</html>
```