Files
xrpl-dev-portal/concept-accounts.html

365 lines
24 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width">
<title>Accounts - Ripple Developer Portal</title>
<!-- favicon -->
<link rel="icon" href="favicon.ico" type="image/x-icon">
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
<!-- jQuery -->
<script src="assets/vendor/jquery-1.11.1.min.js"></script>
<!-- Custom Stylesheets. ripple.css includes bootstrap, font stuff -->
<link href="assets/css/ripple.css" rel="stylesheet" />
<link href="assets/css/devportal.css" rel="stylesheet" />
<!-- Bootstrap JS -->
<script src="assets/vendor/bootstrap.min.js"></script>
<!-- syntax highlighting -->
<link rel="stylesheet" href="assets/vendor/docco.min.css" />
<script src="assets/vendor/highlight.min.js"></script>
<!-- syntax selection js -->
<script src="assets/js/multicodetab.js"></script>
<script>
$(document).ready(function() {
$(".multicode").minitabs();
hljs.initHighlighting();
make_code_expandable();
});
</script>
<script src="assets/js/expandcode.js"></script>
<script src="assets/js/fixsidebarscroll.js"></script>
<!-- fontawesome icons -->
<link rel="stylesheet" href="assets/vendor/fontawesome/css/font-awesome.min.css" />
</head>
<body class="page page-template page-template-template-dev-portal page-template-template-dev-portal-php sidebar-primary wpb-js-composer js-comp-ver-3.6.2 vc_responsive">
<header role="banner" class="banner navbar navbar-default navbar-fixed-top initial_header">
<div class="container">
<div class="navbar-header">
<a href="index.html" class="navbar-brand"><img src="assets/img/ripple-logo-color.png" class="logo"></a>
</div><!-- /.navbar-header -->
<div class="nav">
<div class="draft-warning">DRAFT PAGE</div>
</div><!-- /.nav -->
</div><!-- /.container -->
<div class="subnav dev_nav">
<div class="container">
<ul id="menu-dev-menu" class="menu">
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">References <span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<li><a href="reference-rippleapi.html">RippleAPI</a></li>
<li><a href="reference-rippled.html">rippled</a></li>
<li><a href="reference-transaction-format.html">Transaction Format</a></li>
<li><a href="reference-ledger-format.html">Ledger Format</a></li>
<li><a href="reference-data-api.html">Ripple Data API v2</a></li>
</ul>
</li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Tutorials <span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<li><a href="tutorial-multisign.html">How to Multi-Sign</a></li>
<li><a href="tutorial-paychan.html">Payment Channels Tutorial</a></li>
<li><a href="concept-issuing-and-operational-addresses.html">Issuing and Operational Addresses</a></li>
<li><a href="tutorial-reliable-transaction-submission.html">Reliable Transaction Submission</a></li>
<li><a href="tutorial-rippleapi-beginners-guide.html">RippleAPI Beginners Guide</a></li>
<li><a href="tutorial-rippled-setup.html">rippled Setup</a></li>
<li><a href="tutorial-gateway-guide.html">Gateway Guide</a></li>
<li><a href="tutorial-listing-xrp.html">Listing XRP as an Exchange</a></li>
</ul>
</li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Features <span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<li><a href="concept-accounts.html">Accounts</a></li>
<li><a href="concept-amendments.html">Amendments</a></li>
<li><a href="concept-consensus.html">Consensus Process</a></li>
<li><a href="concept-reaching-consensus.html">Reaching Consensus in the XRP Ledger</a></li>
<li><a href="concept-fee-voting.html">Fee Voting</a></li>
<li><a href="concept-fees.html">Fees (Disambiguation)</a></li>
<li><a href="concept-freeze.html">Freeze</a></li>
<li><a href="concept-partial-payments.html">Partial Payments</a></li>
<li><a href="concept-paths.html">Paths</a></li>
<li><a href="concept-reserves.html">Reserves</a></li>
<li><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
<li><a href="concept-transaction-cost.html">Transaction Cost</a></li>
<li><a href="concept-transfer-fees.html">Transfer Fees</a></li>
<li><a href="concept-noripple.html">Understanding the NoRipple flag</a></li>
</ul>
</li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Gateway Bulletins <span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<li><a href="gb-2015-06.html">GB-2015-06: Corrections to Autobridging</a></li>
<li><a href="gb-2015-05.html">GB-2015-05: Historical Ledger Query Migration</a></li>
</ul>
</li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">API Tools <span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<li><a href="ripple-api-tool.html">WebSocket API Tool</a></li>
<li><a href="data-api-v2-tool.html">Data API v2 Tool</a></li>
<li><a href="tool-jsonrpc.html">rippled JSON-RPC Tool</a></li>
</ul>
</li>
<li><a href="https://github.com/ripple/ripple-dev-portal" title="GitHub">Site Source</a></li>
</ul><!-- /#dev-menu -->
</div><!-- /.subnav .container -->
</div><!-- /.subnav -->
</header>
<div class="wrap container" role="document">
<aside class="sidebar" role="complementary">
<div class="dev_nav_wrapper">
<div id="cont">
<h5>In this category:</h5>
<ul class="dev_nav_sidebar">
<li class="level-1"><a href="index.html">Category: Features</a></li>
<li class="level-2"><a href="concept-accounts.html">Accounts</a></li>
<li class="level-2"><a href="concept-amendments.html">Amendments</a></li>
<li class="level-2"><a href="concept-consensus.html">Consensus Process</a></li>
<li class="level-2"><a href="concept-reaching-consensus.html">Reaching Consensus in the XRP Ledger</a></li>
<li class="level-2"><a href="concept-fee-voting.html">Fee Voting</a></li>
<li class="level-2"><a href="concept-fees.html">Fees (Disambiguation)</a></li>
<li class="level-2"><a href="concept-freeze.html">Freeze</a></li>
<li class="level-2"><a href="concept-partial-payments.html">Partial Payments</a></li>
<li class="level-2"><a href="concept-paths.html">Paths</a></li>
<li class="level-2"><a href="concept-reserves.html">Reserves</a></li>
<li class="level-2"><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
<li class="level-2"><a href="concept-transaction-cost.html">Transaction Cost</a></li>
<li class="level-2"><a href="concept-transfer-fees.html">Transfer Fees</a></li>
<li class="level-2"><a href="concept-noripple.html">Understanding the NoRipple flag</a></li>
</ul>
<hr />
<h5>In this page:</h5>
<ul class="dev_nav_sidebar" id="dactyl_toc_sidebar">
<li class="level-1"><a href="#xrp-ledger-accounts">XRP Ledger Accounts</a></li>
<li class="level-2"><a href="#addresses">Addresses</a></li>
<li class="level-3"><a href="#special-addresses">Special Addresses</a></li>
<li class="level-2"><a href="#permanence-of-accounts">Permanence of Accounts</a></li>
<li class="level-2"><a href="#transaction-history">Transaction History</a></li>
<li class="level-2"><a href="#address-encoding">Address Encoding</a></li>
</ul>
</div>
</div>
</aside>
<main class="main" role="main">
<div class='content'>
<h1 id="xrp-ledger-accounts">XRP Ledger Accounts</h1>
<p>An "Account" in the XRP Ledger represents a holder of XRP and a sender of <a href="reference-transaction-format.html">transactions</a>. The core elements of an account are:</p>
<ul>
<li>An identifying <strong>address</strong>, such as <code>rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn</code></li>
<li>An <strong>XRP balance</strong>. Some of this XRP is set aside for the <a href="concept-reserves.html">Reserve</a>.</li>
<li>A <strong>sequence number</strong>, starting at 1 and increasing with each transaction sent from this account. No transaction can be included in a ledger unless the transaction's sequence number matches its sender's next sequence number.</li>
<li>A <strong>history of transactions</strong> that affected this account and its balances.</li>
<li>One or more ways to <a href="reference-transaction-format.html#authorizing-transactions">authorize transactions</a>, possibly including:<ul>
<li>A master key pair intrinsic to the account. (This can be <a href="reference-transaction-format.html#accountset-flags">disabled</a> but not changed.)</li>
<li>A "regular" key pair that <a href="reference-transaction-format.html#setregularkey">can be rotated</a>.</li>
<li>A signer list for <a href="reference-transaction-format.html#multi-signing">multi-signing</a>. (Stored separately from the account's core data.)</li>
</ul>
</li>
</ul>
<p>In the ledger's data tree, an account's core data is stored in the <a href="reference-ledger-format.html#accountroot">AccountRoot</a> ledger node type. An account can also be the owner (or partial owner) of several other types of data.</p>
<p class="devportal-callout tip"><strong>Tip:</strong> An "Account" in the XRP Ledger is somewhere between the financial usage (like "bank account") and the computing usage (like "UNIX account"). Non-XRP currencies and assets aren't stored in an XRP Ledger Account itself; each such asset is stored in an accounting relationship called a "Trust Line" that connects two parties.</p>
<h2 id="addresses">Addresses</h2>
<p>Accounts in the XRP Ledger are identified by a base58 Ripple Address. The address is derived from the account's master <a href="https://en.wikipedia.org/wiki/Public-key_cryptography">public key</a>, which is in turn derived from a secret key. An address is represented as a string in JSON and has the following characteristics:</p>
<ul>
<li>Between 25 and 35 characters in length</li>
<li>Starts with the character <code>r</code></li>
<li>Uses alphanumeric characters, excluding the number "<code>0</code>" capital letter "<code>O</code>", capital letter "<code>I</code>", and lowercase letter "<code>l</code>"</li>
<li>Case-sensitive</li>
<li>Includes a 4-byte checksum so that the probability of generating a valid address from random characters is approximately 1 in 2^32</li>
</ul>
<p>Any valid address can become an account in the XRP Ledger by receiving a <a href="reference-transaction-format.html#payment">Payment</a> of XRP, as long as the amount of XRP delivered is greater than or equal to the <a href="concept-reserves.html">account reserve</a>. This is called <em>funding</em> the account. You can also use an address that has not been funded to represent a <a href="reference-transaction-format.html#setregularkey">regular key</a> or a member of a <a href="reference-transaction-format.html#multi-signing">signer list</a>. Only a funded account can be the sender of a transaction.</p>
<p>Creating a valid address is a strictly mathematical task starting with a key pair. You can generate a key pair and calculate its address entirely offline without communicating to the XRP Ledger or any other party. The conversion from a public key to an address involves a one-way hash function, so it is possible to confirm that a public key matches an address but it is impossible to derive the public key from the address alone. (This is part of the reason why signed transactions include the public key <em>and</em> the address of the sender.)</p>
<p>For more technical details of how to calculate a Ripple address, see <a href="#address-encoding">Address Encoding</a>.</p>
<h3 id="special-addresses">Special Addresses</h3>
<p>Some addresses have special meaning, or historical uses, in the XRP Ledger. In many cases, these are "black hole" addresses, meaning the address is not derived from a known secret key. Since it is effectively impossible to guess a secret key from only an address, any XRP possessed by black hole addresses is lost forever.</p>
<table>
<thead>
<tr>
<th>Address</th>
<th>Name</th>
<th>Meaning</th>
<th>Black Hole?</th>
</tr>
</thead>
<tbody>
<tr>
<td>rrrrrrrrrrrrrrrrrrrrrhoLvTp</td>
<td>ACCOUNT_ZERO</td>
<td>An address that is the base58 encoding of the value <code>0</code>. In peer-to-peer communications, <code>rippled</code> uses this address as the issuer for XRP.</td>
<td>Yes</td>
</tr>
<tr>
<td>rrrrrrrrrrrrrrrrrrrrBZbvji</td>
<td>ACCOUNT_ONE</td>
<td>An address that is the base58 encoding of the value <code>1</code>. In the ledger, <a href="reference-ledger-format.html#ripplestate">RippleState entries</a> use this address as a placeholder for the issuer of a trust line balance.</td>
<td>Yes</td>
</tr>
<tr>
<td>rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh</td>
<td>The genesis account</td>
<td>When <code>rippled</code> starts a new genesis ledger from scratch (for example, in stand-alone mode), this account holds all the XRP. This address is generated from the seed value "masterpassphrase" which is <a href="https://github.com/ripple/rippled/blob/94ed5b3a53077d815ad0dd65d490c8d37a147361/src/ripple/app/ledger/Ledger.cpp#L184">hard-coded</a>.</td>
<td>No</td>
</tr>
<tr>
<td>rrrrrrrrrrrrrrrrrNAMEtxvNvQ</td>
<td>Ripple Name reservation black-hole</td>
<td>In the past, Ripple asked users to send XRP to this account to reserve Ripple Names.</td>
<td>Yes</td>
</tr>
<tr>
<td>rrrrrrrrrrrrrrrrrrrn5RM1rHd</td>
<td>NaN Address</td>
<td>Previous versions of <a href="https://github.com/ripple/ripple-lib">ripple-lib</a> generated this address when base58 encoding the value <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN">NaN</a>.</td>
<td>Yes</td>
</tr>
</tbody>
</table>
<h2 id="permanence-of-accounts">Permanence of Accounts</h2>
<p>Once created, an account exists in the XRP Ledger's data tree forever. This is because the current sequence number for a transaction must be tracked forever, so that old transactions cannot be processed a second time.</p>
<p>Unlike Bitcoin and many other crypto-currencies, each new version of the XRP Ledger's public ledger chain contains the full state of the ledger, which increases in size with each new account. For that reason, Ripple discourages creating new accounts unless entirely necessary. Institutions who send and receive value on behalf of many users can use <a href="tutorial-gateway-guide.html#source-and-destination-tags"><strong>Source Tags</strong> and <strong>Destination Tags</strong></a> to distinguish payments from and to their customers while only using one (or a handful) of accounts in the Ripple Consensus Ledger.</p>
<h2 id="transaction-history">Transaction History</h2>
<p>In the XRP Ledger, transaction history is tracked by a "thread" of transactions linked by a transaction's identifying hash and the ledger index. The <code>AccountRoot</code> ledger node has the identifying hash and ledger of the transaction that most recently modified it; the metadata of that transaction includes the previous state of the <code>AccountRoot</code> node, so it is possible to iterate through the history of a single account this way. This transaction history includes any transactions that modify the <code>AccountRoot</code> node directly, including:</p>
<ul>
<li>Transactions sent by the account, because they modify the account's <code>Sequence</code> number. These transactions also modify the account's XRP balance because of the <a href="concept-transaction-cost.html">transaction cost</a>.</li>
<li>Transactions that modified the account's XRP balance, including incoming <a href="reference-transaction-format.html#payment">Payment transactions</a> and other types of transactions such as <a href="reference-transaction-format.html#paymentchannelclaim">PaymentChannelClaim</a> and <a href="reference-transaction-format.html#escrowfinish">EscrowFinish</a>.</li>
</ul>
<p>The <em>conceptual</em> transaction history of an account also includes transactions that modified the account's owned objects and non-XRP balances. These objects are separate ledger nodes, each with their own thread of transactions that affected them. If you have an account's full ledger history, you can follow it forward to find the ledger node objects created or modified by it. A "complete" transaction history includes the history of objects owned by a transaction, such as:</p>
<ul>
<li><code>RippleState</code> objects (Trust Lines) connected to the account.</li>
<li><code>DirectoryNode</code> objects, especially the owner directory tracking the account's owned objects.</li>
<li><code>Offer</code> objects, representing the account's outstanding currency-exchange orders in the decentralized exchange</li>
<li><code>PayChannel</code> objects, representing asynchronous payment channels to and from the account</li>
<li><code>Escrow</code> objects, representing held payments to or from the account that are locked by time or a crypto-condition.</li>
<li><code>SignerList</code> objects, representing lists of addresses that can authorize transactions for the account by <a href="reference-transaction-format.html#multi-signing">multi-signing</a>.</li>
</ul>
<p>For more information on each of these objects, see the <a href="reference-ledger-format.html">Ledger Format Reference</a>.</p>
<h2 id="address-encoding">Address Encoding</h2>
<p class="devportal-callout tip"><strong>Tip:</strong> These technical details are only relevant for people building low-level library software for XRP Ledger compatibility!</p>
<p><a href="https://github.com/ripple/rippled/blob/35fa20a110e3d43ffc1e9e664fc9017b6f2747ae/src/ripple/protocol/impl/AccountID.cpp#L109-L140" title="Source">[Source]<br/></a></p>
<p>Ripple addresses are encoded using <a href="https://en.wikipedia.org/wiki/Base58">base58</a> with the Ripple <em>dictionary</em>: <code>rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz</code>. Since Ripple encodes several types of keys with base58, Ripple prefixes the encoded data with a one-byte "type prefix" (also called a "version prefix") to distinguish them. The type prefix causes addresses to usually start with different letters in base58 format.</p>
<p>The following diagram shows the relationship between keys and addresses:</p>
<p><img alt="Passphrase → Secret Key → Public Key + Type Prefix → Account ID + Checksum → Address" src="img/key-address-rels.png"/></p>
<p>The formula for calculating a Ripple address is as follows. For the complete example code, see <a href="https://github.com/ripple/ripple-dev-portal/blob/master/content/code_samples/address_encoding/encode_address.js"><code>encode_address.js</code></a>.</p>
<ol>
<li>
<p>Import required algorithms: SHA-256, RIPEMD160, and base58. Set the dictionary for base58.</p>
<pre><code>'use strict';
const assert = require('assert');
const crypto = require('crypto');
const R_B58_DICT = 'rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz';
const base58 = require('base-x')(R_B58_DICT);
assert(crypto.getHashes().includes('sha256'));
assert(crypto.getHashes().includes('ripemd160'));
</code></pre>
</li>
<li>
<p>Start with a 33-byte ECDSA secp256k1 public key, or a 32-byte Ed25119 public key. For Ed25519 keys, prefix the key with the byte <code>0xED</code>.</p>
<pre><code>const pubkey_hex =
'ED9434799226374926EDA3B54B1B461B4ABF7237962EAE18528FEA67595397FA32';
const pubkey = Buffer.from(pubkey_hex, 'hex');
assert(pubkey.length == 33);
</code></pre>
</li>
<li>
<p>Calculate the <a href="https://en.wikipedia.org/wiki/RIPEMD">RIPEMD160</a> hash of the SHA-256 hash of the public key. This value is the "Account ID".</p>
<pre><code>const pubkey_inner_hash = crypto.createHash('sha256').update(pubkey);
const pubkey_outer_hash = crypto.createHash('ripemd160');
pubkey_outer_hash.update(pubkey_inner_hash.digest());
const account_id = pubkey_outer_hash.digest();
</code></pre>
</li>
<li>
<p>Calculate the SHA-256 hash of the SHA-256 hash of the Account ID; take the first 4 bytes. This value is the "checksum".</p>
<pre><code>const address_type_prefix = Buffer.from([0x00]);
const payload = Buffer.concat([address_type_prefix, account_id]);
const chksum_hash1 = crypto.createHash('sha256').update(payload).digest();
const chksum_hash2 = crypto.createHash('sha256').update(chksum_hash1).digest();
const checksum = chksum_hash2.slice(0,4);
</code></pre>
</li>
<li>
<p>Concatenate the payload and the checksum. Calculate the base58 value of the concatenated buffer. The result is the address.</p>
<pre><code>const dataToEncode = Buffer.concat([payload, checksum]);
const address = base58.encode(dataToEncode);
console.log(address);
// rDTXLQ7ZKZVKz33zJbHjgVShjsBnqMBhmN
</code></pre>
</li>
</ol>
<!-- -->
</div>
</main>
</div>
<footer class="content-info" role="contentinfo">
<div class="container">
<div class="row">
<section class="col-sm-3 widget nav_menu-3 widget_nav_menu">
<h4>Resources<hr></h4>
<ul id="menu-resources" class="menu">
<li class="menu-insights"><a href="https://ripple.com/insights/">Insights</a></li>
<li class="menu-events"><a href="https://ripple.com/events/">Events</a></li>
<li class="menu-collateral"><a href="https://ripple.com/collateral/">Collateral</a></li>
<li class="menu-press-center"><a href="https://ripple.com/press-center/">Press Center</a></li>
<li class="menu-media-kit"><a href="https://ripple.com/media-kit/">Media Kit</a></li>
<li class="menu-xrp-portal"><a href="https://ripple.com/xrp-portal/">XRP Portal</a></li>
</ul>
</section>
<section class="col-sm-3 widget nav_menu-5 widget_nav_menu">
<h4>Regulators<hr></h4>
<ul id="menu-compliance-regulatory-relations" class="menu">
<li class="menu-compliance"><a href="https://ripple.com/compliance/">Compliance</a></li>
<li class="menu-policy-framework"><a href="https://ripple.com/policy-framework/">Policy Framework</a></li>
</ul>
</section>
<section class="col-sm-3 widget nav_menu-4 widget_nav_menu">
<h4>Support<hr></h4>
<ul id="menu-dev-footer-menu" class="menu">
<li class="menu-contact-us"><a href="https://ripple.com/contact/">Contact Us</a></li>
<li class="active menu-developer-center"><a href="https://ripple.com/build/">Developer Center</a></li>
<li class="menu-knowledge-center"><a href="https://ripple.com/learn/">Knowledge Center</a></li>
<li class="menu-ripple-forum"><a target="_blank" href="https://forum.ripple.com/">Ripple Forum</a></li>
</ul>
</section>
<section class="col-sm-3 widget nav_menu-2 widget_nav_menu">
<h4>About<hr></h4>
<ul id="menu-company-footer" class="menu">
<li class="menu-our-company"><a href="https://ripple.com/company/">Our Company</a></li>
<li class="menu-careers"><a href="https://ripple.com/company/careers/">Careers</a></li>
</ul>
</section>
<div class="col-sm-12 absolute_bottom_footer">
<div class="col-sm-8">
<span>&copy; 2013 - 2016 Ripple Labs, Inc. All Rights Reserved.</span>
<span><a href="/terms-of-use/">Terms</a></span>
<span><a href="/privacy-policy/">Privacy</a></span>
</div>
</div><!-- /.absolute_bottom_footer -->
</div><!-- /.row -->
</div><!-- /.container -->
</footer>
</body>
</html>