This website is no longer actively supported. Please see the Ripple Developer Center for up-to-date documentation and other resources.

Currency format

From Ripple Wiki
(Redirected from Currency Format)
Jump to: navigation, search


There are two types of currencies on Ripple:

  • Ripple's native currency XRP, also known as ripples and
  • Fiat currencies, issued by participants of the Ripple network.

Fiat currencies further split into different types such as standard, interest-bearing and custom currencies as described below.

We use the first byte of the currency code to distinguish different types of currency:

  • 0x00 is a standard currency. If the currency code is all zeros it refers to native currency, i.e. XRP.
  • 0x01 is a demurrage/interest-bearing currency.
  • 0x02-0x7F are reserved for other special currency types.
  • 0x80-0xFF are used for custom currencies.


The native currency, XRP, is handled by the absence of a currency indicator. If there is ever a case where a currency ID is needed, native currency will use all zero bits:

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

National currency (ISO codes)

National currencies (without special behaviors such as demurrage/interest) will be handled by a naming convention that species the three-letter currency code, a version (in case the currency is fundamentally changed), and a scaling factor. Currencies that differ only by a scaling factor can automatically be converted as transactions are processed. (So whole dollars and millionths of a penny can both be traded and inter-converted automatically.)

The 160-bit identifier for national currencies will be assembled as follows:

00 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __
RESERVED--------------------------- CURCODE- V- RESERVED
  • CURCODE is the 3-byte ISO or pseudo-ISO currency code, such as "USD"
  • V(ERSION) is a version byte that can be incremented if a currency is reissued.
  • RESERVED is reserved for future use. It should always be given as 0, but other values should be accepted for forward-compatibility.

See also:

Demurrage/interest-bearing currency

Demurraging and interest-bearing currencies use a currency code following the format:

01 __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __ __
CURCODE- DATE------- RATE------------------- RESERVED---
  • CURCODE is the 3-byte ISO or pseudo-ISO currency code, such as "USD"
  • DATE is no longer used, and should always be 0.
  • RATE is the e-folding time, formatted as an IEEE Double, represented in hex. For example, -6291418827.045599 becomes "C1F76FF6ECB0BAC6".
  • RESERVED is reserved for future use. It should always be given as 0, but other values should be accepted for forward-compatibility.

For more information please see the article about Gateway demurrage.

Custom Currencies

Custom currencies will use as their ID the 160-bit hash of their currency definition node with the first bit always set. In other words, if the first byte is 0x80 - 0xFF the code refers to a custom currency. (Note that custom currencies are not treated in any special way by Ripple.)

In the future we may create a special ledger entry for retrieving additional information about custom currencies which contains: Domain of issuer. Issuer's account. Auditor's account (if any). Client display information. Hash of policy document.



The Ripple code uses a specialized internal and wire format to represent amounts of currency. Because the server code does not rely on a central authority, it can have no idea what ranges are sensible with currencies. In addition, it's handy to be able to use the same code both to handle currencies that have inflated to the point that you need billions of units to buy a loaf of bread and to handle currencies that have become extremely valuable and so extremely small amounts need to be tracked.

The design goals are:

  • Accuracy - 15 decimal digits
  • Wide representation range - 10^80 units of currency to 10^-80 units
  • Deterministic - no vague rounding by unspecified rules.
  • Fast - Integer math only.

Internal Format

The format used internally is an integer exponent and a 64-bit integer mantissa. The number of units of currency represented is the mantissa multiplied by ten raised to the power of the exponent.

The legal exponent range is -96 to +80. With the exception of 0 (which is represented as a mantissa of zero), the legal mantissa range is 10^15 to 10^16 -1.

Wire Format

The wire format is a single unsigned 64-bit integer. It is formed by adding 124 to the exponent and placing that in the upper 8 bits. The mantissa is placed in the lower 56 bits. This ensures that comparisons on numbers in wire format work.

Display Format

The display/Json format is exact in all cases. If the range is sensible for decimal display (which it almost always will be), the display is in standard currency format with no extra digits. Typical examples of this format are: 1, 2.25, and .001432.

If the display is out of range for sensible display in this form, the exact internal representation is displayed. The display consists of the mantissa, followed by the letter e, followed by the exponent.

It is expected that any client would have a table of currency formats and would know to display US dollars with two decimal digits unless the user desired more precision.


Core operations are: canonicalize, +, -, * and /.

The canonicalize operation adjusts a value to comply with the mantissa range rules. This is needed when accepting values in another format and when fixing up values after other operations. It must start with a value whose mantissa is in the range of zero to 2^64 - 1.

The + operation adds two currency values. After testing both values for zero and handling those special cases, the value with the smaller exponent is shifted until they have the same exponents. The mantissas are added in a 64-bit register (so overflow is impossible). The final result is then canonicalized.

The - operation subtracts one currency value from another. If either or both numbers are zero, that special case is handled appropriately. If the number subtracted has a larger exponent, an error is generated. Then the number subtracted is shifted until the exponents are equal. Then the subtraction is performed and the result is canonicalized.

The * operation multiplies one currency value by another. Internal +5/10 LSB followed by integer truncation rounding is used. After appropriate special cases for zero, the two mantissas are multiplied using 128-bit integer arithmetic and then divided by 10^18. The result must then lie in the range of roughly 10^16 to 10^18. A new amount is formed with a mantissa of the result of the division and an exponent equal to the sum of the two original numbers exponents plus 16. This result is then canonicalized.

To round, each mantissa is multiplied by ten prior to multiplication. After multiplication, 50 is added to the result and the result is divided by 100.

The / operation divides one currency value by another. After appropriate special cases for zero, the mantissa of the numerator is multiplied by 10^16 using 128-bit integer arithmetic. The product is then divided by the denominator. The result must then lie in the range of roughly 10^15 to 10^17. A new amount is formed with a mantissa of the result of the division and an exponent of the numerator's exponent minus the denominator's exponent minus 16. This amount is then canonicalized.


Internal currency values are shown as "mantissa e exponent". Input values are shown as "mantissa , exponent". Display values are shown normally.

One dollar can be expressed non-canonically as 1,0 (one dollar) or 100,-2 (100 pennies). Either way, it canonicalizes to 1000000000000000e-15 and displays as "1".

One penny can be input as 1,-2. It canonicalizes to 1000000000000000e-17 and displays as ".01".


Some divisions are shown below. The number to the right of the equals sign is the actual answer from the current code in display format, which is also the exact internal value. (The internal value is always an integer. The decimal point is added for display.) For the first three, exact values (calculated with an arbitrary precision calculator, not this code) are shown for comparison.

4034,0 / 9081,0 = 0.4442242043827772 (exact: .4442242043827772271...) 9081,0 / 4034,0 = 2.251115518096182 (exact: 2.251115518096182449...) 9082,0 / 4034,0 = 2.251363411006445 (exact: 2.251363411006445215...) 11,0 / 1,70 = 1100000000000000e-84 1,70 / 11,0 = 9090909090909090e53 11,0 / 1,-70 = 1100000000000000e56 1,-70 / 11,0 = 9090909090909090e-87


This shows the offer logic. An offer is made. A few takes are placed against it. One shows an example of calculating how much you have to offer to get a desired output. Then a test is made offering slightly less. Then a full take (for more than the offer) is shown. (What the offeror gets is always equal to what the taker pays.)

Offer Logic:
Offer: For 17.3 sprockets, I will give 2340 widgets Someone offers 1 sprockets Offerror gets 1 sprockets and they get 135.2601156069364 widgets Offer: For 16.3 sprockets, I will give 2204.739884393064 widgets Jack needs 100 widgets. He should give 0.7393162393162391 sprockets Someone offers 0.7393162393162391 sprockets Offerror gets 0.7393162393162391 sprockets and they get 100 widgets Offer: For 15.56068376068377 sprockets, I will give 2104.739884393064 widgets Someone offers 0.739316239316239 sprockets Offerror gets 0.739316239316239 sprockets and they get 99.99999999999987 widgets Offer: For 14.82136752136754 sprockets, I will give 2004.739884393065 widgets Someone offers 5000 sprockets Offerror gets 14.82136752136754 sprockets and they get 2004.739884393065 widgets Offer: For 0 sprockets, I will give 0 widgets Offer is fully taken

Creating your currencies

Ripple will support three types of currencies:

  • XRP
    • Ripple's native currency.
  • ISO 4217 (3 Letter currencies)
    • The commonly used codes such as USD, EUR, JPY, etc...
    • Not currently enforced.
  • Custom currencies
    • Client currently supports arbitrary three letter currency codes and strings
      • If not entered as three capital letters, client automatically assigns a three capital letter currency code.
    • Forthcoming - Currency resolution, intrinsic rates, or term length

Ripple has no particular support for any of the 3 letter currencies. Ripple requires its users to agree on meaning of these codes. In particular, the person trusting or accepting a balance of a particular currency from an issuer, must agree to the issuer's meaning.

As result, any 3 letter code can be used for represent currencies on the Ripple network as long the involved parties agree.

However, it is illegal to use XRP as 3 letter currency code in the 160 bit encoding. In the 160 bit encoding, XRP must be specified as zero. For convenience, syntactically "XRP" is often allowed as an alternative to specifying zero.


User interfaces can use either BTC or XBT. Internally on the Ripple network, to allow rippling, use BTC for Bitcoin.

Walk through of creating and paying with a made up currency

Suppose Alice commonly issues a currency ALC. And, Bob wants to hold ALC.

  1. Bob trust Alice's Ripple account for, say, 100 ALC.
    • In the client, Bob goes to the trust tab and types in ALC for the currency when setting trust.
  2. Alice may now make a payment to Bob for 20 ALC.
    • Alice manually types in ALC when sending the payment.

See also: