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 XAG Ledger are identified by an address in the XAG 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 2^32

For more information, see Accounts and base58 Encodings.

Hashes

Many objects in the XAG 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 XAG 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 XAG 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 XAG 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 XAG Ledger uses:

Object Type API Fields Hash Prefix (Hex) Hash Prefix (Text)
Consensus proposal N/A 0x50525000 PRP\0
Ledger Version ledger_hash 0x4C575200 LWR\0
Ledger state data account_state in ledger header 0x4D4C4E00 MLN\0
Ledger data inner node N/A 0x4D494E00 MIN\0
Ledger data inner node (SHAMapv2) N/A 0x494E5200 INR\0
Payment Channel Claim N/A 0x434C4D00 CLM\0
Signed Transaction hash of transactions 0x54584E00 TXN\0
Transaction with metadata N/A 0x534E4400 SND\0
Unsigned Transaction (Single-signing) N/A 0x53545800 STX\0
Unsigned Transaction (Multi-signing) N/A 0x534D5400 SMT\0
Validation vote N/A 0x56414C00 VAL\0
Validator subkey authorization ("validator manifest") N/A 0x4D414E00 MAN\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 XAG 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.

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 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).

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.)
  2. Specify a ledger by its Hash value in the ledger_hash parameter.
  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 the whole network
    • 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 current (in-progress) ledger is chosen by default. If you provide more than one field specifying ledgers, the deprecated ledger field is used first if it exists, falling back to ledger_hash. The ledger_index field is ignored unless neither of the other two are present.

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

Specifying Currency Amounts

There are two kinds of currencies in the XAG Ledger: XAG, and issued currencies. 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 XAG specifically, such as the Fee field (transaction cost).

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

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

    "Amount": "13100000"
    
  • Issued Currency - 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.