Last updated

Basic Data Types

Different types of objects are uniquely identified in different ways:

Accounts are identified by their Address, for example "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59". Addresses always start with "r". Many rippled methods also accept a hexadecimal representation.

Transactions are identified by a Hash of the transaction's binary format. You can also identify a transaction by its sending account and Sequence Number.

Each closed Ledger has a Ledger Index and a Hash value. When Specifying Ledgers you can use either one.

Addresses

Accounts in the XRP Ledger are identified by an address in the XRP Ledger's [base58][] format. The address is derived from the account's master public key, which is in turn derived from a secret key. An address is represented as a string in JSON and has the following characteristics:

  • Between 25 and 35 characters in length
  • Starts with the character r
  • Uses alphanumeric characters, excluding the number "0" capital letter "O", capital letter "I", and lowercase letter "l"
  • Case-sensitive
  • Includes a 4-byte checksum so that the probability of generating a valid address from random characters is approximately 1 in 232
Note

There is also an X-address format that "packs" a destination tag into the address. These addresses start with an X (for Mainnet) or a T (for test networks). Exchanges and wallets can use X-addresses to represent all the data a customer needs to know in one value. For more information, see the X-address format site and codec.

The XRP Ledger protocol only supports "classic" addresses natively, but many client libraries support X-addresses too.

Hashes

Many objects in the XRP Ledger, particularly transactions and ledgers, are uniquely identified by a 256-bit hash value. This value is typically calculated as a "SHA-512Half", which calculates a SHA-512 hash from some contents, then takes the first half of the output. (That's 256 bits, which is 32 bytes, or 64 characters of the hexadecimal representation.) Since the hash of an object is derived from the contents in a way that is extremely unlikely to produce collisions, two objects with the same hash can be considered the same.

An XRP Ledger hash value has the following characteristics:

  • Exactly 64 characters in length
  • Hexadecimal character set: 0-9 and A-F.
  • Typically written in upper case.

Note: SHA-512Half has similar security to the officially-defined SHA-512/256 hash function. However, the XRP Ledger's usage predates SHA-512/256 and is also easier to implement on top of an existing SHA-512 function. (As of this writing, SHA-512 support in cryptographic libraries is much more common than for SHA-512/256.)

Hash Prefixes

[Source]

In many cases, the XRP Ledger prefixes an object's binary data with a 4-byte code before calculating its hash, so that objects of different types have different hashes even if their binary formats are the same. The existing 4-byte codes are structured as three alphabetic characters, encoded as ASCII, followed by a zero byte.

Some types of hash appear in API requests and responses. Others are only calculated as the first step of signing a certain type of data, or calculating a higher-level hash. The following table shows all 4-byte hash prefixes the XRP Ledger uses:

Object TypeAPI FieldsHash Prefix (Hex)Hash Prefix (Text)
Consensus proposalN/A0x50525000PRP\0
Ledger Versionledger_hash0x4C575200LWR\0
Ledger state dataaccount_state in ledger header0x4D4C4E00MLN\0
Ledger data inner nodeN/A0x4D494E00MIN\0
Ledger data inner node (SHAMapv2)N/A0x494E5200INR\0
Payment Channel ClaimN/A0x434C4D00CLM\0
Signed Transactionhash of transactions0x54584E00TXN\0
Transaction with metadataN/A0x534E4400SND\0
Unsigned Transaction (Single-signing)N/A0x53545800STX\0
Unsigned Transaction (Multi-signing)N/A0x534D5400SMT\0
Validation voteN/A0x56414C00VAL\0
Validator manifestN/A0x4D414E00MAN\0

Ledger objects IDs are calculated in a similar way, but they use a 2-byte prefix called a "space key" instead of a prefix in the form described here.

Account Sequence

A sequence number is a 32-bit unsigned integer that is used to make sure transactions from a given sender execute only once each, and in the correct order.

Every account in the XRP Ledger has a sequence number in its Sequence field, which increases by 1 whenever that account sends a transaction and that transaction gets included in a validated ledger. Each transaction also has a sequence number in its Sequence field, which must match the account's current sequence number when the transaction executes. For each account, each sequence number can only be used once, in numerical order.

Tickets make some exceptions from these rules so that it is possible to send transactions out of the normal order. Tickets represent sequence numbers reserved for later use; a transaction can use a Ticket instead of a normal sequence number.

With the DeletableAccounts amendment, the starting Sequence number for an account matches the [Ledger Index][] of the ledger version where the account was created. Before DeletableAccounts, every account started with Sequence number 1.

Whenever a transaction is included in a ledger, it uses up a sequence number (or Ticket) regardless of whether the transaction executed successfully or failed with a tec-class error code. Other transaction failures don't get included in ledgers, so they don't change the sender's sequence number (or have any other effects).

Within the ledger, an [Address][] and a sequence number are sometimes used together to identify an object that was created by the validated transaction with that sender and sequence number. Escrows and Offers are examples of objects identified this way.

It is possible for multiple unconfirmed transactions to have the same sender and sequence number. Such transactions are mutually exclusive, and at most one of them can be included in a validated ledger. (Any others ultimately have no effect.)

Ledger Index

A ledger index is a 32-bit unsigned integer used to identify a ledger. The ledger index is sometimes known as the ledger's sequence number. (This is different from an account sequence.) The very first ledger was ledger index 1, and each new ledger has a ledger index that is 1 higher than the ledger index of the ledger immediately before it.

The ledger index indicates the order of the ledgers; the [Hash][] value identifies the exact contents of the ledger. Two ledgers with the same hash are always the same. For validated ledgers, hash values and ledger indexes are equally valid and correlate 1:1. However, this is not true for in-progress ledgers:

  • Two different rippled servers may have different contents for a current ledger with the same ledger index, due to latency in propagating transactions throughout the network.
  • There may be multiple closed ledger versions competing to be validated by consensus. These ledger versions have the same ledger index but different contents (and different hashes). Only one of these closed ledgers can become validated.
  • The current open ledger's hash is not calculated. This is because a current ledger's contents change over time, which would cause its hash to change, even though its ledger index stays the same. The hash of a ledger is only calculated when the ledger is closed.

Specifying Ledgers

Many API methods require you to specify an instance of the ledger, with the data retrieved being considered up-to-date as of that particular version of the shared ledger. The commands that accept a ledger version all work the same way. There are three ways you can specify which ledger you want to use:

  1. Specify a ledger by its Ledger Index in the ledger_index parameter. Each closed ledger has a ledger index that is 1 higher than the previous ledger. (The very first ledger had ledger index 1.)

    "ledger_index": 61546724
    
  2. Specify a ledger by its Hash value in the ledger_hash parameter.

    "ledger_hash": "8BB204CE37CFA7A021A16B5F6143400831C4D1779E6FE538D9AC561ABBF4A929"
    
  3. Specify a ledger by one of the following shortcuts, in the ledger_index parameter:

    • validated for the most recent ledger that has been validated by consensus

      "ledger_index": "validated"
      
    • closed for the most recent ledger that has been closed for modifications and proposed for validation

    • current for the server's current working version of the ledger.

There is also a deprecated ledger parameter which accepts any of the above three formats. Do not use this parameter; it may be removed without further notice.

If you do not specify a ledger, the server decides which ledger to use to serve the request. By default, the server chooses the current (in-progress) ledger. In Reporting Mode, the server uses the most recent validated ledger instead. Do not provide more than one field specifying ledgers.

Note: Do not rely on the default behavior for specifying a ledger; it is subject to change. Always specify a ledger version in the request if you can.

Reporting Mode does not record ledger data until it has been validated. If you make a request to a Reporting Mode server for the current or closed ledger, the server forwards the request to a P2P Mode server. If you request a ledger index or hash that is not validated, a Reporting Mode server responds with a lgrNotFound error.

Specifying Currency Amounts

There are two kinds of currencies in the XRP Ledger: XRP and tokens. These two types of currencies are specified in different formats, with different precision and rounding behavior.

Some fields, such as the destination Amount of a Payment transaction, can be either type. Some fields only accept XRP specifically, such as the Fee field (transaction cost).

XRP is specified as a string containing an integer number of "drops" of XRP, where 1 million drops equals 1 XRP. Tokens are instead specified as an object with fields for the decimal amount, currency code, and issuer. For example:

  • XRP - To specify an Amount field with a value of 13.1 XRP:

    "Amount": "13100000"
    
  • Token - To specify an Amount field with a value of 13.1 FOO issued by or to rf1B...:

    "Amount": {
        "value": "13.1",
        "currency": "FOO",
        "issuer": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn"
    }
    

For more information, see Currency Formats.

Specifying Time

The rippled server and its APIs represent time as an unsigned integer. This number measures the number of seconds since the "Ripple Epoch" of January 1, 2000 (00:00 UTC). This is like the way the Unix epoch works, except the Ripple Epoch is 946684800 seconds after the Unix Epoch.

Don't convert Ripple Epoch times to UNIX Epoch times in 32-bit variables: this could lead to integer overflows.