Protocol06

Ripple Distributed Transaction Protocol v0.6

Purpose

Real-time value transfer through a mutual-credit trust network of hubs that issue IOUs and accept other hubs' IOUs in exchange for their own.

HTTP

Ripple is built on HTTP. Not all common HTTP headers are included in the Ripple message descriptions here when they don't add any information, but that does not mean they should be omitted by an implementation.

Content-Type

Ripple requests and responses have semantically-important content types, of the form

application/x-ripple-*+json; version=X.Y

where (*) gives the type of message contained in the body, and X.Y gives the version of the Ripple protocol being used. Messages are encoded as JSON, which implies UTF-8. Care should be taken to decode numerical values as decimals, not as floating point values, which many JSON packages default to.

From

The URL of the hub that sent the message.

Date

Time and date the message was generated, in GMT (UTC), as specified by HTTP.

Encoding Binary Data

Binary data is encoded to UTF-8 using base64url encoding.

Hashing

Whenever a hash is needed here or in protocol extensions, it is suggested to prefix the value with the hashing algorithm used and a colon, to allow new algorithms to be adopted as vulnerabilities are discovered in older algorithms. For example:

sha1:s-6Gz4gF8G7DPEyV2vaqSL8H9i4=

Available hash algorithms:

  • sha1
  • sha256
  • sha512
  • rmd160

Encryption and Authentication

HTTPS with both client and server certificates. Client cert should match domain of From header, server cert should match server domain, as usual.

Decentralized certificate validation of some sort would be preferable to a centralized certificate authority infrastructure, but both can work.

Signing for Non-Repudiation

In addition to being encrypted, certain requests and responses must be signed for non-repudiation, so the receiver can prove to a third party what was sent. These are indicated by including the Signature header in the description. Signatures are performed using the same certificate as used in HTTPS.

To sign a request or response, make an ordered list of headers that should be signed. To perform the signature, concatenate the following CRLF-separated lines of text:

  • the HTTP status line
  • the headers to be signed, with the header names in lowercase, in the order determined above, with no whitespace around the colon for each header, each on a separate line
  • an empty line
  • the request/response body

Sign the concatenated text with a suitable algorithm and base64url-encode the result. The Signature header contains a sequence of semicolon-separated key-value pairs:

  • a=(signature algorithm)
  • h=(header list)
  • s=(signature)

Example:

Signature: a=rsa-sha256; h=content-type,from,date,content-length;
s=ux_1j86NxE9J5DZ94-sSSlAe8yibrQ4__Xv-ZccW7WWlFMhHU6ZN7_Jne2LGBT
eoX66J8CmkNKvnbsfLRAoLJv3HOGEZaQvQJoY_A6ZTKm_AbpN3XRObZdRTS-J_FL
4Lv89MUXjKOW8Vbkb4Tw_LeUCeadpPDhuwkCdgSEURjuweWr927cxBqFBU6rlAiF
Sav7hYgHRBUkPfUuMg85fuBZMzUsUlMLSbKdsjgDSVAB9jfolF-bp2frCtDTc-R0
8RpoXlznBtajvdkAtlJ_T57PgTDtlDktvheCIbUXZJmkMhSHWsvLsVywrkTVmJo7
gD-00aWkLbHfYs7DSu-JW1ow==

(Line breaks are for formatting purposes only -- HTTP headers cannot contain line breaks.)

Available signature algorithms:

  • rsa-sha256: RSASSA-PSS with SHA256.

UUIDs

UUIDs are encoded as strings with lowercase hexidecimal digits, in the form:

6876cb7f-313c-4986-8c22-5f85988717bf

Network & Routing

Exchange Hubs

Exchange hubs (or just "hubs") are the nodes in the Ripple trust network. A hub accepts IOUs (aka obligations/currency) from other hubs, issues its own IOUs, and is identified by a URL.

Hub Info

Hubs publish information for helping other hubs interact with it.

GET (hub URL)/info/ HTTP/1.x
Accept: application/x-ripple-info+json; version=0.6

The response is:

HTTP/1.x 200 OK
Content-Type: application/x-ripple-info+json; version=0.6
Signature: h=content-type,from,date,content-length; ...

{"unit": "(value unit)",
 "precision": (integer),
 "scale": (integer),
 "routing_methods": [(routing methods)],
 "commit_methods": [(commit methods)]
}

Unit specifies a reference unit of value that is the denomination of IOUs issued by this hub. Once set, this value cannot change -- a new hub must be created instead.

Precision and scale give the range of numerical values the hub can process. Precision is the maximum number of digits in a numerical value, and scale is the position of the decimal place, counting from the rightmost digit, around which the digits of precision are allocated.

Routing and commit methods specify which of these the hub supports. See Routing Methods and Commit Methods.

Exchanges & Routing Methods

Exchanges are how hubs transfer value to each other. A hub can take an IOU from another hub and convert it to a value in its own IOUs at whatever exchange rate it chooses. Routing methods specify ways for hubs to publish or otherwise make their exchanges available for other hubs to use in transactions, as well as how those exchanges are specified in transactions. A basic routing method is:

Other routing methods might involve querying the network for a route at payment time so that the existence of non-neighbouring hubs and relationships between them can remain secret.

Commit Methods

A commit method is a protocol extension that specifies how a Ripple transaction is committed. As described in this document, transactions involve the voluntary, good-faith passing forward of value without any guarantee that it arrives at its destination. This non-commit method is called null. Other more reliable methods are:

Other commit methods might involve registering transactions (or simply rollbacks) in the Bitcoin block chain, Twitter, or elsewhere.

Transactions

Payment Initiation

The payer hub sends this to the recipient hub to begin the transaction.

POST (recipient hub URL)/payments/ HTTP/1.x
Content-Type: application/x-ripple-payment-init+json; version=0.6
Accept: application/x-ripple-payment-accept+json; version=0.6

{"payment_id": "(uuid)",
 "amount": (amount to be received),
 "unit": "(optional)",
 "memo": "(optional)",
 "commit": {"method": (commit method),
            (method-specific data)
           }
}

The amount represents what is to be received by the recipient hub in its own units. The unit, if present, creates an understanding between payer and recipient as to what that amount represents. The recipient should reject the payment if it doesn't understand or agree with the unit specified by the payer.

If the recipient accepts this payment, it responds with a similar message. This Payment Accept response, which is signed by the recipient, will be the payer's proof of payment once the transaction is committed.

HTTP/1.x 201 Created
Location: (payment URL)
Content-Type: application/x-ripple-payment-accept+json; version=0.6
Signature: h=location,content-type,from,date,content-length; ...

{"payment_id": "(uuid)",
 "amount": (amount to be received),
 "unit": "(optional)",
 "memo": "(optional)",
 "commit": {"method": (commit method),
            (method-specific data)
           },
 "payer": "(payer URL)"
}

A signed DELETE to the payment URL by the payer cancels the payment. The payment URL can also receive payment status requests from the payer.

Promise

Promises bind the promisor to transferring value to the promisee under certain conditions determined by the commit method. For the null commit method, the Promise is the value.

Once all intermediaries have accepted their instructions, the payer sends a Promise forward to the first intermediary or intermediaries, who then pass their own Promises forward along the payment route as directed by the payer's Exchange Requests, until Promises adding up to the full payment amount are received by the recipient.

POST (intermediary/recipient hub URL)/promises/ HTTP/1.x
Location: (promise URL)
Content-Type: application/x-ripple-promise+json; version=0.6
Signature: h=location,content-type,from,date,content-length; ...

{"payment_id": "(uuid)",
 "amount": (promise amount),
 "commit": {"method": (commit method),
            (method-specific data)
           }
}

A signed DELETE to the promise URL by the promisee containing a Promise Release releases the promisor from its Promise.

The response is if accepted:

HTTP/1.x 204 No Content

Promise Release

Any promisee may release the promisor from its Promise by sending a Promise Release to the promisor.

DELETE (promise URL) HTTP/1.x
Content-Type: application/x-ripple-promise-release+json; version=0.6
Signature: h=content-type,from,date,content-length; ...

{"payment_id": "(uuid)"}

Response:

HTTP/1.x 204 No Content

Even if a Promise Release is received after the transaction is committed by whatever commit method is specified, the Promise Release takes precedence in releasing the promisor from any obligation in the transaction.