Merge pull request #174 from mDuo13/simplesigning

[Do not merge yet] Simple Multi-Sign Documentation
This commit is contained in:
Rome Reginelli
2016-04-12 16:41:58 -07:00
36 changed files with 5412 additions and 780 deletions

View File

@@ -202,7 +202,7 @@
}
@media (max-width: 1200px) {
.page-template-template-dev-portal-php .dev_nav_wrapper {
max-width: 300px;
max-width: 290px;
}
}
@media (max-width: 992px) {
@@ -396,7 +396,7 @@
z-index: 1;
padding-left: 10px;
}
.multicode ul {
padding-bottom: 0;
}
@@ -426,14 +426,13 @@
.multicode a.current {
background: #fff;
border-bottom: 1px solid #fff;
border-bottom: 1px solid #fff;
color : black;
}
.multicode a:hover {
color: black;
background: white;
background: white;
}
.multicode a.current:hover {}

369
concept-amendments.html Normal file
View File

@@ -0,0 +1,369 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible">
<meta content="width=device-width" name="viewport">
<title>Amendments - Ripple Developer Portal</title>
<!-- favicon -->
<link href="favicon.ico" rel="icon" type="image/x-icon">
<link href="favicon.ico" rel="shortcut icon" 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 href="assets/vendor/docco.min.css" rel="stylesheet">
<script src="assets/vendor/highlight.min.js"></script>
<!-- syntax selection js -->
<script src="assets/js/multicodetab.js"></script>
<script>
$(document).ready(function() {
$().multicode_tabs();
hljs.initHighlighting();
make_code_expandable();
});
</script>
<script src="assets/js/expandcode.js"></script>
<script src="assets/js/fixsidebarscroll.js"></script>
</link></link></link></meta></meta></meta></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 class="banner navbar navbar-default navbar-fixed-top initial_header" role="banner">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="index.html"><img class="logo" src="assets/img/ripple-logo-color.png"/></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 class="menu" id="menu-dev-menu">
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">References <span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<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-rippleapi.html">RippleAPI</a></li>
<li><a href="reference-data-api.html">Ripple Data API v2</a></li>
</ul>
</li>
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">Tutorials <span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<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-reliable-transaction-submission.html">Reliable Transaction Submission</a></li>
<li><a href="tutorial-multisign.html">Multi-Signing Transactions</a></li>
</ul>
</li>
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">Concepts <span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<li><a href="concept-paths.html">Paths</a></li>
<li><a href="concept-fees.html">Fees (Disambiguation)</a></li>
<li><a href="concept-transfer-fees.html">Transfer Fees</a></li>
<li><a href="concept-transaction-cost.html">Transaction Cost</a></li>
<li><a href="concept-fee-voting.html">Fee Voting</a></li>
<li><a href="concept-reserves.html">Reserves</a></li>
<li><a href="concept-freeze.html">Freeze</a></li>
<li><a href="concept-amendments.html">Amendments</a></li>
<li><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
</ul>
</li>
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">Best Practices <span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<li><a href="concept-issuing-and-operational-addresses.html">Issuing and Operational Addresses</a></li>
<li><a href="tutorial-gateway-guide.html">Gateway Guide</a></li>
</ul>
</li>
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">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 class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">Resources <span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<li><a href="https://forum.ripple.com/viewforum.php?f=2">Forums</a></li>
<li><a href="https://www.bountysource.com/teams/ripple/bounties">Bounties</a></li>
<li><a href="https://ripplelabs.atlassian.net/">Bug Tracking</a></li>
<li><a href="https://ripple.com/category/dev-blog/">Dev Blog</a></li>
<li><a href="https://ripple.com/press-releases/">Press Center</a></li>
<li><a href="https://ripple.com/brand-guidelines/">Brand Guidelines</a></li>
</ul>
<li><a href="https://github.com/ripple/ripple-dev-portal" title="GitHub">Site Source</a></li>
</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">
<ul class="dev_nav_sidebar">
<li class="level-1"><a href="index.html">Category: Concepts</a></li>
<li class="level-2"><a href="concept-paths.html">Paths</a></li>
<li class="level-2"><a href="concept-fees.html">Fees (Disambiguation)</a></li>
<li class="level-2"><a href="concept-transfer-fees.html">Transfer Fees</a></li>
<li class="level-2"><a href="concept-transaction-cost.html">Transaction Cost</a></li>
<li class="level-2"><a href="concept-fee-voting.html">Fee Voting</a></li>
<li class="level-2"><a href="concept-reserves.html">Reserves</a></li>
<li class="level-2"><a href="concept-freeze.html">Freeze</a></li>
<li class="level-2"><a href="concept-amendments.html">Amendments</a></li>
<li class="level-2"><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
</ul>
<hr/>
<h5>In this page:</h5>
</div>
<script src="assets/js/jquery.gensidebar.js" type="text/javascript"></script>
</div>
</aside>
<main class="main" role="main">
<div class="content">
<h1 id="amendments">Amendments</h1>
<p><em>(New in <a href="https://wiki.ripple.com/Rippled-0.31.0">version 0.31.0</a>)</em></p>
<p>The Amendments system provides a means of introducing new features to the decentralized Ripple consensus network without causing disruptions. The amendments system works by utilizing the core consensus process of the network to approve any changes by showing continuous support before those changes go into effect. An amendment normally requires <strong>80% support for two weeks</strong> before it can apply.</p>
<p>When an Amendment has been enabled, it applies permanently to all ledger versions after the one that included it. You cannot disable an Amendment, unless you introduce a new Amendment to do so.</p>
<h2 id="background">Background</h2>
<p>Any changes to transaction processing could cause servers to build a different ledger with the same set of transactions. If only a portion of <em>validators</em> (<code>rippled</code> servers <a href="tutorial-rippled-setup.html#reasons-to-run-a-validator">participating in consensus</a>) have upgraded to a new version of the software, this could cause anything from minor inconveniences to full outages. In the minor case, a minority of servers spend more time and bandwidth fetching the actual consensus ledger because they cannot build it using the transaction processing rules they already know. In the worst case, <a href="https://ripple.com/knowledge_center/the-ripple-ledger-consensus-process/">the consensus process</a> might be unable to validate new ledger versions because servers with different rules could not reach a consensus on the exact ledger to build.</p>
<p>Amendments provide a solution to this problem, so that new features can be enabled only when enough validators support those features.</p>
<p>Users and businesses who rely on the Ripple Consensus Ledger can also use Amendments to provide advance notice of changes in transaction processing that might affect their business. However, API changes that do not impact transaction processing or <a href="https://ripple.com/knowledge_center/the-ripple-ledger-consensus-process/">the consensus process</a> do not require Amendments.</p>
<h2 id="about-amendments">About Amendments</h2>
<p>An amendment is a fully-functional feature or change, waiting to be enabled by the peer-to-peer network as a part of the consensus process. A <code>rippled</code> server that wants to use an amendment has code for two modes: without the amendment (previous behavior) and with the amendment (new behavior).</p>
<p>Every amendment has a unique identifying hex value and a short name. The short name is for human use, and is not used in the amendment process. Two servers can support the same amendment ID while using different names to describe it. An amendment's name is not guaranteed to be unique.</p>
<p>See also: <a href="#known-amendments">Known Amendments</a></p>
<h2 id="amendment-process">Amendment Process</h2>
<p>Every 256th ledger is called a "flag" ledger. The process of approving an amendment starts in the ledger version immediately before the flag ledger. When <code>rippled</code> validator servers send validation messages for that ledger, those servers also submit votes in favor of specific amendments. (<a href="concept-fee-voting.html">Fee Voting</a> also occurs around flag ledgers.)</p>
<p>The flag ledger itself has no special contents. However, during that time, the servers look at the votes of the validators they trust, and decide whether to insert an <a href="reference-transaction-format.html#enableamendment"><code>EnableAmendment</code> pseudo-transaction</a> into the following ledger. The flags of an EnableAmendment pseudo-transaction indicate what the server thinks happened:</p>
<ul>
<li>The <code>tfGotMajority</code> flag means that support for the amendment has increased to at least 80% of trusted validators.</li>
<li>The <code>tfLostMajority</code> flag means that support for the amendment has decreased to less than 80% of trusted validators.</li>
<li>An EnableAmendment pseudo-transaction with no flags means that support for the amendment has been enabled. (The change in transaction processing applies to every ledger after this one.)</li>
</ul>
<p>A server only inserts the pseudo-transaction to enable an amendment if all of the following conditions are met:</p>
<ul>
<li>The amendment has not already been enabled.</li>
<li>A previous ledger includes an EnableAmendment pseudo-transaction for this amendment with the <code>tfGotMajority</code> flag enabled.</li>
<li>The previous ledger in question is an ancestor of the current ledger.</li>
<li>The previous ledger in question has a close time that is at least <strong>two weeks</strong> before the close time of the latest flag ledger.</li>
<li>There are no EnableAmendment pseudo-transactions for this amendment with the <code>tfLostMajority</code> flag enabled in the consensus ledgers between the <code>tfGotMajority</code> pseudo-transaction and the current ledger.</li>
</ul>
<p>It is theoretically possible (but extremely unlikely) that a <code>tfLostMajority</code> EnableAmendment pseudo-transaction could be included in the same ledger as the pseudo-transaction to enable an amendment. In this case, the pseudo-transaction with the <code>tfLostMajority</code> pseudo-transaction has no effect.</p>
<h2 id="amendment-voting">Amendment Voting</h2>
<p>Operators of <code>rippled</code> validators can choose which amendments to support or reject using the <a href="reference-rippled.html#feature"><code>feature</code> command</a>. This decides which amendments the validator votes for in the <a href="#amendment-process">amendment process</a>. By default, <code>rippled</code> votes in favor of every amendment it knows about.</p>
<p>The operator of a <code>rippled</code> validator can "veto" an amendment. In this case, that validator never sends a vote in favor of the amendment. If enough servers veto an amendment, that prevents it from reaching consistent 80% support, so the amendment does not apply.</p>
<p>As with all aspects of the consensus process, amendment votes are only taken into account by servers that trust the validators sending those votes. Currently, Ripple (the company) recommends only trusting the 5 default validators that Ripple (the company) operates. For now, trusting only those validators is sufficient to coordinate with Ripple (the company) on releasing new features.</p>
<h3 id="configuring-amendment-voting">Configuring Amendment Voting</h3>
<p>You can temporarily configure an amendment using the <a href="reference-rippled.html#feature"><code>feature</code> command</a>. To make a persistent change to your server's support for an amendment, modify your server's <code>rippled.cfg</code> file.</p>
<p>Use the <code>[veto_amendments]</code> stanza to list amendments you do not want the server to vote for. Each line should contain one amendment's unique ID, optionally followed by the short name for the amendment. For example:</p>
<pre><code>[veto_amendments]
C1B8D934087225F509BEB5A8EC24447854713EE447D277F69545ABFA0E0FD490 Tickets
DA1BD556B42D85EA9C84066D028D355B52416734D3283F85E216EA5DA6DB7E13 SusPay
</code></pre>
<p>Use the <code>[amendments]</code> stanza to list amendments you want to vote for. (Even if you do not list them here, by default a server votes for all the amendments it knows how to apply.) Each line should contain one amendment's unique ID, optionally followed by the short name for the amendment. For example:</p>
<pre><code>[amendments]
4C97EBA926031A7CF7D7B36FDE3ED66DDA5421192D63DE53FFB46E43B9DC8373 MultiSign
42426C4D4F1009EE67080A9B7965B44656D7714D104A72F9B4369F97ABF044EE FeeEscalation
</code></pre>
<h2 id="testing-amendments">Testing Amendments</h2>
<p>If you want to see how <code>rippled</code> behaves with an amendment enabled, before that amendment gets enabled on the production network, you can run use <code>rippled</code>'s configuration file to forcibly enable a feature. This is intended for development purposes only.</p>
<p>Because other members of the consensus network probably do not have the feature enabled, you should not use this feature while connecting to the production network. While testing with features forcibly enabled, you should run <code>rippled</code> in <a href="concept-stand-alone-mode.html">Stand-Alone Mode</a>.</p>
<p>To forcibly enable a feature, add a <code>[features]</code> stanza to your <code>rippled.cfg</code> file. In this stanza, add the short names of the features to enable, one per line. For example:</p>
<pre><code>[features]
MultiSign
TrustSetAuth
</code></pre>
<h1 id="known-amendments">Known Amendments</h1>
<p>The following is a comprehensive list of all known amendments and their status on the production Ripple Consensus Ledger:</p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Introduced</th>
<th>Enabled</th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="#tickets">Tickets</a></td>
<td>v0.31.0</td>
<td>TBD</td>
</tr>
<tr>
<td><a href="#suspay">SusPay</a></td>
<td>v0.31.0</td>
<td>TBD</td>
</tr>
<tr>
<td><a href="#trustsetauth">TrustSetAuth</a></td>
<td>v0.30.0</td>
<td>TBD</td>
</tr>
<tr>
<td><a href="#multisign">MultiSign</a></td>
<td>v0.31.0</td>
<td>TBD</td>
</tr>
<tr>
<td><a href="#feeescalation">FeeEscalation</a></td>
<td>v0.31.0</td>
<td>TBD</td>
</tr>
</tbody>
</table>
<p><strong>Note:</strong> In many cases, an incomplete version of the code for an amendment is present in previous versions of the software. The "Introduced" version in the table above is the first stable version.</p>
<h2 id="feeescalation">FeeEscalation</h2>
<table>
<thead>
<tr>
<th>Amendment ID</th>
</tr>
</thead>
<tbody>
<tr>
<td>42426C4D4F1009EE67080A9B7965B44656D7714D104A72F9B4369F97ABF044EE</td>
</tr>
</tbody>
</table>
<p>Changes the way the <a href="concept-transaction-cost.html">transaction cost</a> applies to proposed transactions. Modifies the consensus process to prioritize transactions that pay a higher transaction cost.</p>
<p>This amendment introduces a fixed-size transaction queue for transactions that were not able to be included in the previous consensus round. If the <code>rippled</code> servers in the consensus network are under heavy load, they queue the transactions with the lowest transaction cost for later ledgers. Each consensus round prioritizes transactions from the queue with the largest transaction cost (<code>Fee</code> value), and includes as many transactions as the consensus network can process. If the transaction queue is full, transactions drop from the queue entirely, starting with the ones that have the lowest transaction cost.</p>
<p>While the consensus network is under heavy load, legitimate users can pay a higher transaction cost to make sure their transactions get processed. The situation persists until the entire backlog of cheap transactions is processed or discarded.</p>
<p>A transaction remains in the queue until one of the following happens:</p>
<ul>
<li>It gets applied to a validated ledger (regardless of success or failure)</li>
<li>It becomes invalid (for example, the <a href="reference-transaction-format.html#lastledgersequence"><code>LastLedgerSequence</code></a> causes it to expire)</li>
<li>It gets dropped because there are too many transactions in the queue with a higher transaction cost.</li>
</ul>
<h2 id="multisign">MultiSign</h2>
<table>
<thead>
<tr>
<th>Amendment ID</th>
</tr>
</thead>
<tbody>
<tr>
<td>4C97EBA926031A7CF7D7B36FDE3ED66DDA5421192D63DE53FFB46E43B9DC8373</td>
</tr>
</tbody>
</table>
<p>Introduces simple <a href="reference-transaction-format.html#multi-signing">multi-signing</a> as a way to authorize transactions. Creates the <a href="reference-ledger-format.html#signerlist"><code>SignerList</code> ledger node type</a> and the <a href="reference-transaction-format.html#signerlistset"><code>SignerListSet</code> transaction type</a>. Adds the optional <code>Signers</code> field to all transaction types. Modifies some transaction result codes.</p>
<p>This amendment allows addresses to have a list of signers who can authorize transactions from that address in a multi-signature. The list has a quorum and 1 to 8 weighted signers. This allows various configurations, such as "any 3-of-5" or "signature from A plus any other two signatures."</p>
<p>Signers can be funded or unfunded addresses. Funded addresses in a signer list can sign using a regular key (if defined) or master key (unless disabled). Unfunded addresses can sign with a master key. Multi-signed transactions have the same permissions as transactions signed with a regular key.</p>
<p>An address with a SignerList can disable the master key even if a regular key is not defined. An address with a SignerList can also remove a regular key even if the master key is disabled. Therefore, the <code>tecMASTER_DISABLED</code> transaction result code is renamed <code>tecNO_ALTERNATIVE_KEY</code>. The <code>tecNO_REGULAR_KEY</code> transaction result is retired and replaced with <code>tecNO_ALTERNATIVE_KEY</code>. Additionally, this amendment adds the following new <a href="reference-transaction-format.html#result-categories">transaction result codes</a>:</p>
<ul>
<li><code>temBAD_SIGNER</code></li>
<li><code>temBAD_QUORUM</code></li>
<li><code>temBAD_WEIGHT</code></li>
<li><code>tefBAD_SIGNATURE</code></li>
<li><code>tefBAD_QUORUM</code></li>
<li><code>tefNOT_MULTI_SIGNING</code></li>
<li><code>tefBAD_AUTH_MASTER</code></li>
</ul>
<h2 id="suspay">SusPay</h2>
<table>
<thead>
<tr>
<th>Amendment ID</th>
</tr>
</thead>
<tbody>
<tr>
<td>DA1BD556B42D85EA9C84066D028D355B52416734D3283F85E216EA5DA6DB7E13</td>
</tr>
</tbody>
</table>
<p>Provides "Suspended Payments" for XRP as a means of escrow within the Ripple Consensus Ledger. Creates the <code>SuspendedPayment</code> ledger node type and the new transaction types <code>SuspendedPaymentCreate</code>, <code>SuspendedPaymentFinish</code>, and <code>SuspendedPaymentCancel</code>.</p>
<p>This amendment is still in development. The current version is enabled on the <a href="https://ripple.com/build/ripple-test-net/">Ripple Test Net</a>.</p>
<h2 id="trustsetauth">TrustSetAuth</h2>
<table>
<thead>
<tr>
<th>Amendment ID</th>
</tr>
</thead>
<tbody>
<tr>
<td>6781F8368C4771B83E8B821D88F580202BCB4228075297B19E4FDC5233F1EFDC</td>
</tr>
</tbody>
</table>
<p>Allows pre-authorization of accounting relationships (zero-balance trust lines) when using <a href="tutorial-gateway-guide.html#authorized-accounts">Authorized Accounts</a>.</p>
<p>With this amendment enabled, a <code>TrustSet</code> transaction with <a href="reference-transaction-format.html#trustset-flags"><code>tfSetfAuth</code> enabled</a> can create a new <a href="reference-ledger-format.html#ripplestate"><code>RippleState</code> ledger node</a> even if it keeps all the other values of the <code>RippleState</code> node in their default state. The new <code>RippleState</code> node has the <a href="reference-ledger-format.html#ripplestate-flags"><code>lsfLowAuth</code> or <code>lsfHighAuth</code> flag</a> enabled accordingly. The sender of the transaction must have <a href="reference-ledger-format.html#accountroot-flags"><code>lsfRequireAuth</code> enabled</a>.</p>
<h2 id="tickets">Tickets</h2>
<table>
<thead>
<tr>
<th>Amendment ID</th>
</tr>
</thead>
<tbody>
<tr>
<td>C1B8D934087225F509BEB5A8EC24447854713EE447D277F69545ABFA0E0FD490</td>
</tr>
</tbody>
</table>
<p>Introduces Tickets as a way to reserve a transaction sequence number for later execution. Creates the <code>Ticket</code> ledger node type and the transaction types <code>TicketCreate</code> and <code>TicketCancel</code>.</p>
<p>This amendment is still in development.</p>
</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 class="menu" id="menu-resources">
<li class="menu-insights"><a href="https://ripple.com/insights/">Insights</a></li>
<li class="menu-press-center"><a href="https://ripple.com/press-center/">Press Center</a></li>
<li class="menu-media-resources"><a href="https://ripple.com/media-resources/">Media Resources</a></li>
<li class="menu-videos"><a href="https://ripple.com/videos/">Videos</a></li>
<li class="menu-whitepapers-reports"><a href="https://ripple.com/whitepapers-reports/">Whitepapers &amp; Reports</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 class="menu" id="menu-compliance-regulatory-relations"><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 class="menu" id="menu-dev-footer-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 href="https://forum.ripple.com/" target="_blank">Ripple Forum</a></li>
</ul>
</section>
<section class="col-sm-3 widget nav_menu-2 widget_nav_menu">
<h4>About<hr/></h4>
<ul class="menu" id="menu-company-footer">
<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>© 2013-2015 Ripple Labs, Inc. All Rights Reserved.</span>
<span><a href="https://ripple.com/terms-of-use/">Terms</a></span>
<span><a href="https://ripple.com/privacy-policy/">Privacy</a></span>
</div>
</div><!-- /.absolute_bottom_footer -->
</div><!-- /.row -->
</div><!-- /.container -->
</footer>
</body>
</html>

View File

@@ -60,6 +60,7 @@
<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-reliable-transaction-submission.html">Reliable Transaction Submission</a></li>
<li><a href="tutorial-multisign.html">Multi-Signing Transactions</a></li>
</ul>
</li>
<li class="dropdown">
@@ -72,6 +73,8 @@
<li><a href="concept-fee-voting.html">Fee Voting</a></li>
<li><a href="concept-reserves.html">Reserves</a></li>
<li><a href="concept-freeze.html">Freeze</a></li>
<li><a href="concept-amendments.html">Amendments</a></li>
<li><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
</ul>
</li>
<li class="dropdown">
@@ -117,6 +120,8 @@
<li class="level-2"><a href="concept-fee-voting.html">Fee Voting</a></li>
<li class="level-2"><a href="concept-reserves.html">Reserves</a></li>
<li class="level-2"><a href="concept-freeze.html">Freeze</a></li>
<li class="level-2"><a href="concept-amendments.html">Amendments</a></li>
<li class="level-2"><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
</ul>
<hr/>
<h5>In this page:</h5>

View File

@@ -60,6 +60,7 @@
<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-reliable-transaction-submission.html">Reliable Transaction Submission</a></li>
<li><a href="tutorial-multisign.html">Multi-Signing Transactions</a></li>
</ul>
</li>
<li class="dropdown">
@@ -72,6 +73,8 @@
<li><a href="concept-fee-voting.html">Fee Voting</a></li>
<li><a href="concept-reserves.html">Reserves</a></li>
<li><a href="concept-freeze.html">Freeze</a></li>
<li><a href="concept-amendments.html">Amendments</a></li>
<li><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
</ul>
</li>
<li class="dropdown">
@@ -117,6 +120,8 @@
<li class="level-2"><a href="concept-fee-voting.html">Fee Voting</a></li>
<li class="level-2"><a href="concept-reserves.html">Reserves</a></li>
<li class="level-2"><a href="concept-freeze.html">Freeze</a></li>
<li class="level-2"><a href="concept-amendments.html">Amendments</a></li>
<li class="level-2"><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
</ul>
<hr/>
<h5>In this page:</h5>

View File

@@ -60,6 +60,7 @@
<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-reliable-transaction-submission.html">Reliable Transaction Submission</a></li>
<li><a href="tutorial-multisign.html">Multi-Signing Transactions</a></li>
</ul>
</li>
<li class="dropdown">
@@ -72,6 +73,8 @@
<li><a href="concept-fee-voting.html">Fee Voting</a></li>
<li><a href="concept-reserves.html">Reserves</a></li>
<li><a href="concept-freeze.html">Freeze</a></li>
<li><a href="concept-amendments.html">Amendments</a></li>
<li><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
</ul>
</li>
<li class="dropdown">
@@ -117,6 +120,8 @@
<li class="level-2"><a href="concept-fee-voting.html">Fee Voting</a></li>
<li class="level-2"><a href="concept-reserves.html">Reserves</a></li>
<li class="level-2"><a href="concept-freeze.html">Freeze</a></li>
<li class="level-2"><a href="concept-amendments.html">Amendments</a></li>
<li class="level-2"><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
</ul>
<hr/>
<h5>In this page:</h5>
@@ -217,7 +222,7 @@
</tr>
</tbody>
</table>
<p>Set the <code>Fee</code>, <code>Sequence</code>, and <code>LastLedgerSequence</code> parameters <a href="reference-transaction-format.html#signing-and-sending-transactions">in the typical way</a>.</p>
<p>Set the <code>Fee</code>, <code>Sequence</code>, and <code>LastLedgerSequence</code> parameters <a href="reference-transaction-format.html#signing-and-submitting-transactions">in the typical way</a>.</p>
<p>Example of submitting a TrustSet transaction to enable an individual freeze using the <a href="reference-rippled.html#websocket-api">WebSocket API</a>:</p>
<pre><code>{
"id": 12,

View File

@@ -60,6 +60,7 @@
<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-reliable-transaction-submission.html">Reliable Transaction Submission</a></li>
<li><a href="tutorial-multisign.html">Multi-Signing Transactions</a></li>
</ul>
</li>
<li class="dropdown">
@@ -72,6 +73,8 @@
<li><a href="concept-fee-voting.html">Fee Voting</a></li>
<li><a href="concept-reserves.html">Reserves</a></li>
<li><a href="concept-freeze.html">Freeze</a></li>
<li><a href="concept-amendments.html">Amendments</a></li>
<li><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
</ul>
</li>
<li class="dropdown">

View File

@@ -60,6 +60,7 @@
<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-reliable-transaction-submission.html">Reliable Transaction Submission</a></li>
<li><a href="tutorial-multisign.html">Multi-Signing Transactions</a></li>
</ul>
</li>
<li class="dropdown">
@@ -72,6 +73,8 @@
<li><a href="concept-fee-voting.html">Fee Voting</a></li>
<li><a href="concept-reserves.html">Reserves</a></li>
<li><a href="concept-freeze.html">Freeze</a></li>
<li><a href="concept-amendments.html">Amendments</a></li>
<li><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
</ul>
</li>
<li class="dropdown">
@@ -117,6 +120,8 @@
<li class="level-2"><a href="concept-fee-voting.html">Fee Voting</a></li>
<li class="level-2"><a href="concept-reserves.html">Reserves</a></li>
<li class="level-2"><a href="concept-freeze.html">Freeze</a></li>
<li class="level-2"><a href="concept-amendments.html">Amendments</a></li>
<li class="level-2"><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
</ul>
<hr/>
<h5>In this page:</h5>

View File

@@ -60,6 +60,7 @@
<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-reliable-transaction-submission.html">Reliable Transaction Submission</a></li>
<li><a href="tutorial-multisign.html">Multi-Signing Transactions</a></li>
</ul>
</li>
<li class="dropdown">
@@ -72,6 +73,8 @@
<li><a href="concept-fee-voting.html">Fee Voting</a></li>
<li><a href="concept-reserves.html">Reserves</a></li>
<li><a href="concept-freeze.html">Freeze</a></li>
<li><a href="concept-amendments.html">Amendments</a></li>
<li><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
</ul>
</li>
<li class="dropdown">
@@ -117,6 +120,8 @@
<li class="level-2"><a href="concept-fee-voting.html">Fee Voting</a></li>
<li class="level-2"><a href="concept-reserves.html">Reserves</a></li>
<li class="level-2"><a href="concept-freeze.html">Freeze</a></li>
<li class="level-2"><a href="concept-amendments.html">Amendments</a></li>
<li class="level-2"><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
</ul>
<hr/>
<h5>In this page:</h5>
@@ -141,6 +146,7 @@
<ul>
<li><a href="reference-ledger-format.html#offer">Offers</a> are owned by the account that placed them. An Offer can be automatically removed from the ledger if it is fully consumed or if it is found unfunded during transaction processing. Alternatively, the owner can cancel an offer by sending an <a href="reference-transaction-format.html#offercancel">OfferCancel transaction</a>, or by sending an <a href="reference-transaction-format.html#offercreate">OfferCreate transaction</a> that contains an <code>OfferSequence</code> parameter.</li>
<li><a href="reference-ledger-format.html#ripplestate">Trust lines</a> are shared between two accounts. The owner reserve can apply to one or both of the accounts, depending on whether the fields that account controls are in their default state. See <a href="reference-ledger-format.html#contributing-to-the-owner-reserve">Contributing to the Owner Reserve</a> for details.</li>
<li>A single <a href="reference-ledger-format.html#signerlist">SignerList</a> counts as 3 to 10 objects for purposes of the owner reserve, depending on how many members it has. See also: <a href="reference-ledger-format.html#signerlists-and-reserves">SignerLists and Reserves</a>.</li>
<li><a href="reference-ledger-format.html#directorynode">Owner directories</a> list all the ledger nodes that contribute to an account's owner reserve. However, the owner directory itself does not count towards the reserve.</li>
</ul>
<h4 id="owner-reserve-edge-cases">Owner Reserve Edge Cases</h4>

View File

@@ -0,0 +1,241 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible">
<meta content="width=device-width" name="viewport">
<title>Stand-Alone Mode - Ripple Developer Portal</title>
<!-- favicon -->
<link href="favicon.ico" rel="icon" type="image/x-icon">
<link href="favicon.ico" rel="shortcut icon" 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 href="assets/vendor/docco.min.css" rel="stylesheet">
<script src="assets/vendor/highlight.min.js"></script>
<!-- syntax selection js -->
<script src="assets/js/multicodetab.js"></script>
<script>
$(document).ready(function() {
$().multicode_tabs();
hljs.initHighlighting();
make_code_expandable();
});
</script>
<script src="assets/js/expandcode.js"></script>
<script src="assets/js/fixsidebarscroll.js"></script>
</link></link></link></meta></meta></meta></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 class="banner navbar navbar-default navbar-fixed-top initial_header" role="banner">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="index.html"><img class="logo" src="assets/img/ripple-logo-color.png"/></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 class="menu" id="menu-dev-menu">
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">References <span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<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-rippleapi.html">RippleAPI</a></li>
<li><a href="reference-data-api.html">Ripple Data API v2</a></li>
</ul>
</li>
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">Tutorials <span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<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-reliable-transaction-submission.html">Reliable Transaction Submission</a></li>
<li><a href="tutorial-multisign.html">Multi-Signing Transactions</a></li>
</ul>
</li>
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">Concepts <span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<li><a href="concept-paths.html">Paths</a></li>
<li><a href="concept-fees.html">Fees (Disambiguation)</a></li>
<li><a href="concept-transfer-fees.html">Transfer Fees</a></li>
<li><a href="concept-transaction-cost.html">Transaction Cost</a></li>
<li><a href="concept-fee-voting.html">Fee Voting</a></li>
<li><a href="concept-reserves.html">Reserves</a></li>
<li><a href="concept-freeze.html">Freeze</a></li>
<li><a href="concept-amendments.html">Amendments</a></li>
<li><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
</ul>
</li>
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">Best Practices <span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<li><a href="concept-issuing-and-operational-addresses.html">Issuing and Operational Addresses</a></li>
<li><a href="tutorial-gateway-guide.html">Gateway Guide</a></li>
</ul>
</li>
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">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 class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">Resources <span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<li><a href="https://forum.ripple.com/viewforum.php?f=2">Forums</a></li>
<li><a href="https://www.bountysource.com/teams/ripple/bounties">Bounties</a></li>
<li><a href="https://ripplelabs.atlassian.net/">Bug Tracking</a></li>
<li><a href="https://ripple.com/category/dev-blog/">Dev Blog</a></li>
<li><a href="https://ripple.com/press-releases/">Press Center</a></li>
<li><a href="https://ripple.com/brand-guidelines/">Brand Guidelines</a></li>
</ul>
<li><a href="https://github.com/ripple/ripple-dev-portal" title="GitHub">Site Source</a></li>
</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">
<ul class="dev_nav_sidebar">
<li class="level-1"><a href="index.html">Category: Concepts</a></li>
<li class="level-2"><a href="concept-paths.html">Paths</a></li>
<li class="level-2"><a href="concept-fees.html">Fees (Disambiguation)</a></li>
<li class="level-2"><a href="concept-transfer-fees.html">Transfer Fees</a></li>
<li class="level-2"><a href="concept-transaction-cost.html">Transaction Cost</a></li>
<li class="level-2"><a href="concept-fee-voting.html">Fee Voting</a></li>
<li class="level-2"><a href="concept-reserves.html">Reserves</a></li>
<li class="level-2"><a href="concept-freeze.html">Freeze</a></li>
<li class="level-2"><a href="concept-amendments.html">Amendments</a></li>
<li class="level-2"><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
</ul>
<hr/>
<h5>In this page:</h5>
</div>
<script src="assets/js/jquery.gensidebar.js" type="text/javascript"></script>
</div>
</aside>
<main class="main" role="main">
<div class="content">
<h1 id="stand-alone-mode">Stand-Alone Mode</h1>
<p>You can run <code>rippled</code> in stand-alone mode without a consensus of trusted servers. In stand-alone mode, <code>rippled</code> does not communicate with any other servers in the Ripple peer-to-peer network, but you can do most of the same actions on your local server only. Stand-alone provides a method for testing <code>rippled</code> behavior without being tied to the live network. For example, you can <a href="concept-amendments.html#testing-amendments">test the effects of Amendments</a> before those Amendments have gone into effect across the decentralized network.</p>
<p>When you run <code>rippled</code> in stand-alone mode, you have to tell it what ledger version to start from:</p>
<ul>
<li>Create a <a href="#new-genesis-ledger">new genesis ledger</a> from scratch.</li>
<li><a href="#load-saved-ledger">Load an existing ledger version</a> from disk.</li>
</ul>
<p><strong>Caution:</strong> In stand-alone mode, you must <a href="#advancing-ledgers-in-stand-alone-mode">manually advance the ledger</a>.</p>
<h2 id="new-genesis-ledger">New Genesis Ledger</h2>
<p>In stand-alone mode, you can have <code>rippled</code> create a new genesis ledger. This provides a known state, with none of the ledger history from the production Ripple Consensus Ledger. (This is very useful for unit tests, among other things.)</p>
<ul>
<li>To start <code>rippled</code> in stand-alone mode with a new genesis ledger, use the <code>-a</code> and <code>--start</code> options:</li>
</ul>
<pre><code>rippled -a --start --conf=/path/to/rippled.cfg
</code></pre>
<p>In a genesis ledger, the <a href="reference-rippled.html#special-addresses">genesis address</a> holds all 100 billion XRP. The keys of the genesis address are <a href="https://github.com/ripple/rippled/blob/94ed5b3a53077d815ad0dd65d490c8d37a147361/src/ripple/app/ledger/Ledger.cpp#L184">hardcoded</a> as follows:</p>
<p><strong>Address:</strong> <code>rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh</code></p>
<p><strong>Secret:</strong> <code>snoPBrXtMeMyMHUVTgbuqAfg1SUTb</code> ("masterpassphrase")</p>
<p><strong>Caution:</strong> If you create a new genesis ledger, the hard-coded default <a href="concept-reserves.html">Reserve</a> is <strong>200 XRP</strong> minimum for funding a new address, with an increment of <strong>50 XRP</strong> per object in the ledger. These values are higher than the current reserve requirements of the production network. (See also: <a href="concept-fee-voting.html">Fee Voting</a>)</p>
<h2 id="load-saved-ledger">Load Saved Ledger</h2>
<p>You can start with a ledger version that was saved to disk if your <code>rippled</code> server was previously synced with the Ripple peer-to-peer network (either the production network or the <a href="tutorial-rippled-setup.html#parallel-networks">Test Net</a>).</p>
<h3 id="1-start-rippled-normally">1. Start <code>rippled</code> normally.</h3>
<p>To load an existing ledger, you must first retrieve that ledger from the network. Start <code>rippled</code> in networked mode as normal:</p>
<pre><code>rippled --conf=/path/to/rippled.cfg
</code></pre>
<h3 id="2-wait-until-rippled-is-synced">2. Wait until <code>rippled</code> is synced.</h3>
<p>Use the <a href="reference-rippled.html#server-info"><code>server_info</code> command</a> to check the state of your server relative to the network. Your server is synced when the <code>server_state</code> value shows any of the following values:</p>
<ul>
<li><code>full</code></li>
<li><code>proposing</code></li>
<li><code>validating</code>.</li>
</ul>
<h3 id="3-optional-retrieve-specific-ledger-versions">3. (Optional) Retrieve specific ledger versions.</h3>
<p>If you only want the most recent ledger, you can skip this step.</p>
<p>If you want to load a specific historical ledger version, use the <a href="reference-rippled.html#ledger-request"><code>ledger_request</code> command</a> to make <code>rippled</code> fetch it. If <code>rippled</code> does not already have the ledger version, you may have to run the <code>ledger_request</code> command multiple times until it has finished retrieving the ledger.</p>
<p>If you want to replay a specific historical ledger version, you must fetch both the ledger version to replay and the ledger version immediately before it.</p>
<h3 id="4-shut-down-rippled">4. Shut down <code>rippled</code>.</h3>
<p>Use the <a href="reference-rippled.html#stop"><code>stop</code> command</a>:</p>
<pre><code>rippled stop --conf=/path/to/rippled.cfg
</code></pre>
<h3 id="5-start-rippled-in-stand-alone-mode">5. Start <code>rippled</code> in stand-alone mode.</h3>
<p>To load the most recent ledger version, you can use the <code>-a</code> and <code>--load</code> options when starting the server:</p>
<pre><code>rippled -a --load --conf=/path/to/rippled.cfg
</code></pre>
<p>To instead load a specific historical ledger, use the <code>--load</code> parameter along with the <code>--ledger</code> parameter, providing the ledger index or identifying hash of the ledger version to load:</p>
<pre><code>rippled -a --load --ledger 19860944 --conf=/path/to/rippled.cfg
</code></pre>
<h3 id="6-manually-advance-the-ledger">6. Manually advance the ledger.</h3>
<p>When you load a ledger with <code>--ledger</code> in stand-alone mode, it goes to the current open ledger, so you must <a href="#advancing-ledgers-in-stand-alone-mode">manually advance the ledger</a>:</p>
<pre><code>rippled ledger_accept --conf=/path/to/rippled.cfg
</code></pre>
<h2 id="advancing-ledgers-in-stand-alone-mode">Advancing Ledgers in Stand-Alone Mode</h2>
<p>In stand-alone mode, <code>rippled</code> does not communicate to other members of the peer-to-peer network or participate in a consensus process. Instead, you must manually advance the ledger index using the <a href="reference-rippled.html#ledger-accept"><code>ledger_accept</code> command</a>:</p>
<pre><code>rippled ledger_accept --conf=/path/to/rippled.cfg
</code></pre>
<p>In stand-alone mode, <code>rippled</code> makes no distinction between a "closed" ledger version and a "validated" ledger version. (For more information about the difference, see <a href="https://ripple.com/knowledge_center/the-ripple-ledger-consensus-process/">The Ripple Ledger Consensus Process</a>.)</p>
<p>Whenever <code>rippled</code> closes a ledger, it reorders the transactions according to a deterministic but hard-to-game algorithm. (This is an important part of consensus, since transactions may arrive at different parts of the network in different order.) When using <code>rippled</code> in stand-alone mode, you should manually advance the ledger before submitting a transaction that depends on the result of a previous transaction. Otherwise, the second transaction might be executed before the first transaction when you manually advance the ledger. <strong>Note:</strong> You can safely submit multiple transactions from a single address to a single ledger, because <code>rippled</code> sorts transactions from the same address in ascending order by <code>Sequence</code> number.</p>
</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 class="menu" id="menu-resources">
<li class="menu-insights"><a href="https://ripple.com/insights/">Insights</a></li>
<li class="menu-press-center"><a href="https://ripple.com/press-center/">Press Center</a></li>
<li class="menu-media-resources"><a href="https://ripple.com/media-resources/">Media Resources</a></li>
<li class="menu-videos"><a href="https://ripple.com/videos/">Videos</a></li>
<li class="menu-whitepapers-reports"><a href="https://ripple.com/whitepapers-reports/">Whitepapers &amp; Reports</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 class="menu" id="menu-compliance-regulatory-relations"><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 class="menu" id="menu-dev-footer-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 href="https://forum.ripple.com/" target="_blank">Ripple Forum</a></li>
</ul>
</section>
<section class="col-sm-3 widget nav_menu-2 widget_nav_menu">
<h4>About<hr/></h4>
<ul class="menu" id="menu-company-footer">
<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>© 2013-2015 Ripple Labs, Inc. All Rights Reserved.</span>
<span><a href="https://ripple.com/terms-of-use/">Terms</a></span>
<span><a href="https://ripple.com/privacy-policy/">Privacy</a></span>
</div>
</div><!-- /.absolute_bottom_footer -->
</div><!-- /.row -->
</div><!-- /.container -->
</footer>
</body>
</html>

View File

@@ -60,6 +60,7 @@
<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-reliable-transaction-submission.html">Reliable Transaction Submission</a></li>
<li><a href="tutorial-multisign.html">Multi-Signing Transactions</a></li>
</ul>
</li>
<li class="dropdown">
@@ -72,6 +73,8 @@
<li><a href="concept-fee-voting.html">Fee Voting</a></li>
<li><a href="concept-reserves.html">Reserves</a></li>
<li><a href="concept-freeze.html">Freeze</a></li>
<li><a href="concept-amendments.html">Amendments</a></li>
<li><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
</ul>
</li>
<li class="dropdown">
@@ -117,6 +120,8 @@
<li class="level-2"><a href="concept-fee-voting.html">Fee Voting</a></li>
<li class="level-2"><a href="concept-reserves.html">Reserves</a></li>
<li class="level-2"><a href="concept-freeze.html">Freeze</a></li>
<li class="level-2"><a href="concept-amendments.html">Amendments</a></li>
<li class="level-2"><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
</ul>
<hr/>
<h5>In this page:</h5>
@@ -130,14 +135,63 @@
<p>In order to protect the Ripple Consensus Ledger from being disrupted by spam and denial-of-service attacks, each transaction must destroy a small amount of <a href="https://ripple.com/knowledge_center/math-based-currency-2/">XRP</a>. This <em>transaction cost</em> is designed to increase along with the load on the network, making it very expensive to deliberately or inadvertently overload the network.</p>
<p>Every transaction must <a href="#specifying-the-transaction-cost">specify how much XRP it will destroy</a> in order to pay the transaction cost.</p>
<h2 id="current-transaction-cost">Current Transaction Cost</h2>
<p>The current transaction cost required by the network is typically <strong>0.01 XRP</strong> (10,000 drops), although it sometimes increases due to network load.</p>
<p>The current transaction cost required by the network for a standard transaction is typically <strong>0.01 XRP</strong> (10,000 drops), although it sometimes increases due to network load.</p>
<p>You can also <a href="#querying-the-transaction-cost">query <code>rippled</code> for the current transaction cost</a>.</p>
<h3 id="special-transaction-costs">Special Transaction Costs</h3>
<p>Some transactions have different transaction costs:</p>
<table>
<thead>
<tr>
<th>Transaction</th>
<th>Cost Before Load Scaling</th>
</tr>
</thead>
<tbody>
<tr>
<td>Reference Transaction (Standard cost of most transactions)</td>
<td>10 drops</td>
</tr>
<tr>
<td><a href="#key-reset-transaction">Key Reset Transaction</a></td>
<td>0</td>
</tr>
<tr>
<td><a href="reference-transaction-format.html#multi-signing">Multi-signed transaction</a></td>
<td>10 drops × (1 + Number of Signatures Provided)</td>
</tr>
</tbody>
</table>
<h2 id="beneficiaries-of-the-transaction-cost">Beneficiaries of the Transaction Cost</h2>
<p>The transaction cost is not paid to any party: the XRP is irrevocably destroyed. Since no new XRP can ever be created, this makes XRP more scarce, and consequently benefits all holders of XRP by making XRP more valuable.</p>
<h2 id="load-scaling">Load Scaling</h2>
<p>Each <code>rippled</code> server independently scales the transaction cost based on its current load. If you submit a transaction with a <code>Fee</code> value that is lower than current load-based transaction cost of the <code>rippled</code> server, that server neither applies nor relays the transaction. (<strong>Note:</strong> If you submit a transaction through an <a href="reference-rippled.html#connecting-to-rippled">admin connection</a>, the server applies and relays the transaction as long as the transaction cost meets the overall minimum.) A transaction is very unlikely to survive <a href="https://ripple.com/knowledge_center/the-ripple-ledger-consensus-process/">the consensus process</a> unless its <code>Fee</code> value meets the requirements of a majority of servers.</p>
<h2 id="load-cost-and-open-ledger-cost">Load Cost and Open Ledger Cost</h2>
<p>When the <a href="concept-amendments.html#feeescalation">FeeEscalation amendment</a> is enabled, there are two thresholds for the transaction cost:</p>
<ul>
<li>If the transaction cost does not meet a <code>rippled</code> server's <a href="#local-load-cost">load-based transaction cost threshold</a>, the server ignores the transaction completely. (This logic is essentially unchanged with or without the amendment.)</li>
<li>If the transaction cost does not meet a <code>rippled</code> server's <a href="#open-ledger-cost">open ledger cost threshold</a>, the server queues the transaction for a later ledger.</li>
</ul>
<p>This divides transactions into roughly three categories:</p>
<ul>
<li>Transactions that specify a transaction cost so low that they get rejected by the load-based transaction cost.</li>
<li>Transactions that specify a transaction cost high enough to be included in the current open ledger.</li>
<li>Transactions in between, which get <a href="#queued-transactions">queued for a later ledger version</a>.</li>
</ul>
<h2 id="local-load-cost">Local Load Cost</h2>
<p>Each <code>rippled</code> server maintains a cost threshold based on its current load. If you submit a transaction with a <code>Fee</code> value that is lower than current load-based transaction cost of the <code>rippled</code> server, that server neither applies nor relays the transaction. (<strong>Note:</strong> If you submit a transaction through an <a href="reference-rippled.html#connecting-to-rippled">admin connection</a>, the server applies and relays the transaction as long as the transaction cost meets the overall minimum.) A transaction is very unlikely to survive <a href="https://ripple.com/knowledge_center/the-ripple-ledger-consensus-process/">the consensus process</a> unless its <code>Fee</code> value meets the requirements of a majority of servers.</p>
<h2 id="open-ledger-cost">Open Ledger Cost</h2>
<p>A <code>rippled</code> server with the <a href="concept-amendments.html#feeescalation">FeeEscalation amendment</a> enabled has a second mechanism for enforcing the transaction cost, called the <em>open ledger cost</em>. The open ledger cost starts out equal to the minimum transaction cost, but increases exponentially when an in-progress ledger has more transactions than the previous one. Only transactions which pay more than the open ledger cost can be included in the current open ledger.
Transactions that do not meet the open ledger cost are <a href="#queued-transactions">queued for a following ledger</a> instead.</p>
<p>The open ledger cost requirement is proportional to the normal cost of the transaction, not the absolute transaction cost. Transaction types that have a higher-than-normal requirement, such as <a href="reference-transaction-format.html#multi-signing">multi-signed transactions</a> must pay more to meet the open ledger cost than transactions which have minimum transaction cost requirements.</p>
<p>See also: <a href="https://github.com/ripple/rippled/blob/release/src/ripple/app/misc/FeeEscalation.md">Fee Escalation explanation in <code>rippled</code> repository</a>.</p>
<h3 id="queued-transactions">Queued Transactions</h3>
<p>(Requires the <a href="concept-amendments.html#feeescalation">FeeEscalation amendment</a>)</p>
<p>When <code>rippled</code> receives a transaction that meet the server's local load cost but not the open ledger cost, the server checks the transaction to see if it is "likely to be included" in a later ledger. If so, the server adds the transaction to the transaction queue and relays the transaction to other members of the network. Otherwise, the server discards the transaction. The server tries minimize the amount of network load caused by transactions that would not pay a transaction cost, since <a href="#transaction-costs-and-failed-transactions">the transaction cost only applies when a transaction is included in a validated ledger</a>.</p>
<p>The <code>rippled</code> server uses a variety of heuristics to determine which transactions are "likely to be included in a ledger." Most importantly, those transactions must be properly-formed and <a href="reference-transaction-format.html#authorizing-transactions">authorized</a> with valid signatures.</p>
<p>When the current open ledger closes and the server starts a new open ledger, the server starts taking transactions from the queue to include in the new open ledger. The transaction queue is sorted with the transactions that would pay the highest transaction cost first, proportional to the un-scaled cost of those transactions. Transactions that pay the same transaction cost are queued in the order the server receives them.</p>
<p><strong>Note:</strong> As of <code>rippled</code> <strong>version 0.31.0</strong>, the transaction queue supports at most 1 transaction per sending address. This is expected to change in later versions.</p>
<p><strong>Caution:</strong> The current implementation does not allow transactions with an <code>AccountTxnID</code> field in the transaction queue.</p>
<h2 id="querying-the-transaction-cost">Querying the Transaction Cost</h2>
<p>The <code>rippled</code> APIs have two ways to query the transaction cost: the <code>server_info</code> command (intended for humans) and the <code>server_state</code> command (intended for machines).</p>
<p>The <code>rippled</code> APIs have two ways to query the local load-based transaction cost: the <code>server_info</code> command (intended for humans) and the <code>server_state</code> command (intended for machines).</p>
<p>If the <a href="concept-amendments.html#feeescalation">FeeEscalation amendment</a> is enabled, you can use the <a href="reference-rippled.html#fee"><code>fee</code> command</a> to check the open ledger cost.</p>
<h3 id="server-info">server_info</h3>
<p>The <a href="reference-rippled.html#server-info"><code>server_info</code> command</a> reports the unscaled minimum XRP cost, as of the previous ledger, as <code>validated_ledger.base_fee_xrp</code>, in the form of decimal XRP. The actual cost necessary to relay a transaction is scaled by multiplying that <code>base_fee_xrp</code> value by the <code>load_factor</code> parameter in the same response, which represents the server's current load level. In other words:</p>
<p><strong>Current Transaction Cost in XRP = <code>base_fee_xrp</code> × <code>load_factor</code></strong></p>
@@ -156,10 +210,11 @@
</ul>
</li>
<li>You do not know in advance exactly what value you are signing for the <code>Fee</code> field.<ul>
<li>If you are using <code>rippled</code>, you can also use the <code>fee_mult_max</code> parameter of the <a href="reference-rippled.html#sign"><code>sign</code> command</a> to set a limit to the load scaling you are willing to sign.</li>
<li>If you are using <code>rippled</code>, you can also use the <code>fee_mult_max</code> and <code>fee_div_max</code> parameters of the <a href="reference-rippled.html#sign"><code>sign</code> command</a> to set a limit to the load scaling you are willing to sign.</li>
</ul>
</li>
<li>You cannot look up the current transaction cost from an offline machine.</li>
<li>You cannot automatically specify the transaction cost when <a href="reference-transaction-format.html#multi-signing">multi-signing</a>.</li>
</ul>
<h2 id="transaction-costs-and-failed-transactions">Transaction Costs and Failed Transactions</h2>
<p>Since the purpose of the transaction cost is to protect the peer-to-peer Ripple network from excessive load, it should apply to any transaction that gets distributed to the network, regardless of whether or not that transaction succeeds. However, in order to affect the shared global ledger, a transaction must be included in a validated ledger. Thus, <code>rippled</code> servers attempt to include failed transactions in ledgers, with <a href="reference-transaction-format.html#result-categories"><code>tec</code> status codes</a> ("tec" stands for "Transaction Engine - Claimed fee only").</p>
@@ -172,6 +227,7 @@
<p>As a special case, an account can send a <a href="reference-transaction-format.html#setregularkey">SetRegularKey</a> transaction with a transaction cost of <code>0</code>, as long as the account's <a href="reference-ledger-format.html#accountroot-flags">lsfPasswordSpent flag</a> is disabled. This transaction must be signed by the account's <em>master key</em>. Sending this transaction enables the lsfPasswordSpent flag.</p>
<p>This feature is designed to allow you to recover an account if the regular key is compromised, without worrying about whether the compromised account has any XRP available. This way, you can regain control of the account before you send additional XRP to it.</p>
<p>The <a href="reference-ledger-format.html#accountroot-flags">lsfPasswordSpent flag</a> starts out disabled. If enabled, it gets disabled again when the account receives a <a href="reference-transaction-format.html#payment">Payment</a> of XRP.</p>
<p>When the <a href="concept-amendments.html#feeescalation">FeeEscalation amendment</a> is enabled, <code>rippled</code> prioritizes key reset transactions above other transactions even though the nominal transaction cost of a key reset transaction is zero.</p>
<h2 id="changing-the-transaction-cost">Changing the Transaction Cost</h2>
<p>In addition to short-term scaling to account for load, the Ripple Consensus Ledger has a mechanism for changing the minimum transaction cost in order to account for long-term changes in the value of XRP. Any changes have to be approved by the consensus process. See <a href="concept-fee-voting.html">Fee Voting</a> for more information.</p>
</div>

View File

@@ -60,6 +60,7 @@
<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-reliable-transaction-submission.html">Reliable Transaction Submission</a></li>
<li><a href="tutorial-multisign.html">Multi-Signing Transactions</a></li>
</ul>
</li>
<li class="dropdown">
@@ -72,6 +73,8 @@
<li><a href="concept-fee-voting.html">Fee Voting</a></li>
<li><a href="concept-reserves.html">Reserves</a></li>
<li><a href="concept-freeze.html">Freeze</a></li>
<li><a href="concept-amendments.html">Amendments</a></li>
<li><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
</ul>
</li>
<li class="dropdown">
@@ -117,6 +120,8 @@
<li class="level-2"><a href="concept-fee-voting.html">Fee Voting</a></li>
<li class="level-2"><a href="concept-reserves.html">Reserves</a></li>
<li class="level-2"><a href="concept-freeze.html">Freeze</a></li>
<li class="level-2"><a href="concept-amendments.html">Amendments</a></li>
<li class="level-2"><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
</ul>
<hr/>
<h5>In this page:</h5>

View File

@@ -0,0 +1,174 @@
# Amendments #
_(New in [version 0.31.0](https://wiki.ripple.com/Rippled-0.31.0))_
The Amendments system provides a means of introducing new features to the decentralized Ripple consensus network without causing disruptions. The amendments system works by utilizing the core consensus process of the network to approve any changes by showing continuous support before those changes go into effect. An amendment normally requires **80% support for two weeks** before it can apply.
When an Amendment has been enabled, it applies permanently to all ledger versions after the one that included it. You cannot disable an Amendment, unless you introduce a new Amendment to do so.
## Background ##
Any changes to transaction processing could cause servers to build a different ledger with the same set of transactions. If only a portion of _validators_ (`rippled` servers [participating in consensus](tutorial-rippled-setup.html#reasons-to-run-a-validator)) have upgraded to a new version of the software, this could cause anything from minor inconveniences to full outages. In the minor case, a minority of servers spend more time and bandwidth fetching the actual consensus ledger because they cannot build it using the transaction processing rules they already know. In the worst case, [the consensus process](https://ripple.com/knowledge_center/the-ripple-ledger-consensus-process/) might be unable to validate new ledger versions because servers with different rules could not reach a consensus on the exact ledger to build.
Amendments provide a solution to this problem, so that new features can be enabled only when enough validators support those features.
Users and businesses who rely on the Ripple Consensus Ledger can also use Amendments to provide advance notice of changes in transaction processing that might affect their business. However, API changes that do not impact transaction processing or [the consensus process](https://ripple.com/knowledge_center/the-ripple-ledger-consensus-process/) do not require Amendments.
## About Amendments ##
An amendment is a fully-functional feature or change, waiting to be enabled by the peer-to-peer network as a part of the consensus process. A `rippled` server that wants to use an amendment has code for two modes: without the amendment (previous behavior) and with the amendment (new behavior).
Every amendment has a unique identifying hex value and a short name. The short name is for human use, and is not used in the amendment process. Two servers can support the same amendment ID while using different names to describe it. An amendment's name is not guaranteed to be unique.
See also: [Known Amendments](#known-amendments)
## Amendment Process ##
Every 256th ledger is called a "flag" ledger. The process of approving an amendment starts in the ledger version immediately before the flag ledger. When `rippled` validator servers send validation messages for that ledger, those servers also submit votes in favor of specific amendments. ([Fee Voting](concept-fee-voting.html) also occurs around flag ledgers.)
The flag ledger itself has no special contents. However, during that time, the servers look at the votes of the validators they trust, and decide whether to insert an [`EnableAmendment` pseudo-transaction](reference-transaction-format.html#enableamendment) into the following ledger. The flags of an EnableAmendment pseudo-transaction indicate what the server thinks happened:
* The `tfGotMajority` flag means that support for the amendment has increased to at least 80% of trusted validators.
* The `tfLostMajority` flag means that support for the amendment has decreased to less than 80% of trusted validators.
* An EnableAmendment pseudo-transaction with no flags means that support for the amendment has been enabled. (The change in transaction processing applies to every ledger after this one.)
A server only inserts the pseudo-transaction to enable an amendment if all of the following conditions are met:
* The amendment has not already been enabled.
* A previous ledger includes an EnableAmendment pseudo-transaction for this amendment with the `tfGotMajority` flag enabled.
* The previous ledger in question is an ancestor of the current ledger.
* The previous ledger in question has a close time that is at least **two weeks** before the close time of the latest flag ledger.
* There are no EnableAmendment pseudo-transactions for this amendment with the `tfLostMajority` flag enabled in the consensus ledgers between the `tfGotMajority` pseudo-transaction and the current ledger.
It is theoretically possible (but extremely unlikely) that a `tfLostMajority` EnableAmendment pseudo-transaction could be included in the same ledger as the pseudo-transaction to enable an amendment. In this case, the pseudo-transaction with the `tfLostMajority` pseudo-transaction has no effect.
## Amendment Voting ##
Operators of `rippled` validators can choose which amendments to support or reject using the [`feature` command](reference-rippled.html#feature). This decides which amendments the validator votes for in the [amendment process](#amendment-process). By default, `rippled` votes in favor of every amendment it knows about.
The operator of a `rippled` validator can "veto" an amendment. In this case, that validator never sends a vote in favor of the amendment. If enough servers veto an amendment, that prevents it from reaching consistent 80% support, so the amendment does not apply.
As with all aspects of the consensus process, amendment votes are only taken into account by servers that trust the validators sending those votes. Currently, Ripple (the company) recommends only trusting the 5 default validators that Ripple (the company) operates. For now, trusting only those validators is sufficient to coordinate with Ripple (the company) on releasing new features.
### Configuring Amendment Voting ###
You can temporarily configure an amendment using the [`feature` command](reference-rippled.html#feature). To make a persistent change to your server's support for an amendment, modify your server's `rippled.cfg` file.
Use the `[veto_amendments]` stanza to list amendments you do not want the server to vote for. Each line should contain one amendment's unique ID, optionally followed by the short name for the amendment. For example:
```
[veto_amendments]
C1B8D934087225F509BEB5A8EC24447854713EE447D277F69545ABFA0E0FD490 Tickets
DA1BD556B42D85EA9C84066D028D355B52416734D3283F85E216EA5DA6DB7E13 SusPay
```
Use the `[amendments]` stanza to list amendments you want to vote for. (Even if you do not list them here, by default a server votes for all the amendments it knows how to apply.) Each line should contain one amendment's unique ID, optionally followed by the short name for the amendment. For example:
```
[amendments]
4C97EBA926031A7CF7D7B36FDE3ED66DDA5421192D63DE53FFB46E43B9DC8373 MultiSign
42426C4D4F1009EE67080A9B7965B44656D7714D104A72F9B4369F97ABF044EE FeeEscalation
```
## Testing Amendments ##
If you want to see how `rippled` behaves with an amendment enabled, before that amendment gets enabled on the production network, you can run use `rippled`'s configuration file to forcibly enable a feature. This is intended for development purposes only.
Because other members of the consensus network probably do not have the feature enabled, you should not use this feature while connecting to the production network. While testing with features forcibly enabled, you should run `rippled` in [Stand-Alone Mode](concept-stand-alone-mode.html).
To forcibly enable a feature, add a `[features]` stanza to your `rippled.cfg` file. In this stanza, add the short names of the features to enable, one per line. For example:
```
[features]
MultiSign
TrustSetAuth
```
# Known Amendments #
The following is a comprehensive list of all known amendments and their status on the production Ripple Consensus Ledger:
| Name | Introduced | Enabled |
|---------------------------------|------------|---------|
| [Tickets](#tickets) | v0.31.0 | TBD |
| [SusPay](#suspay) | v0.31.0 | TBD |
| [TrustSetAuth](#trustsetauth) | v0.30.0 | TBD |
| [MultiSign](#multisign) | v0.31.0 | TBD |
| [FeeEscalation](#feeescalation) | v0.31.0 | TBD |
**Note:** In many cases, an incomplete version of the code for an amendment is present in previous versions of the software. The "Introduced" version in the table above is the first stable version.
## FeeEscalation ##
| Amendment ID |
|--------------|
| 42426C4D4F1009EE67080A9B7965B44656D7714D104A72F9B4369F97ABF044EE |
Changes the way the [transaction cost](concept-transaction-cost.html) applies to proposed transactions. Modifies the consensus process to prioritize transactions that pay a higher transaction cost.
This amendment introduces a fixed-size transaction queue for transactions that were not able to be included in the previous consensus round. If the `rippled` servers in the consensus network are under heavy load, they queue the transactions with the lowest transaction cost for later ledgers. Each consensus round prioritizes transactions from the queue with the largest transaction cost (`Fee` value), and includes as many transactions as the consensus network can process. If the transaction queue is full, transactions drop from the queue entirely, starting with the ones that have the lowest transaction cost.
While the consensus network is under heavy load, legitimate users can pay a higher transaction cost to make sure their transactions get processed. The situation persists until the entire backlog of cheap transactions is processed or discarded.
A transaction remains in the queue until one of the following happens:
* It gets applied to a validated ledger (regardless of success or failure)
* It becomes invalid (for example, the [`LastLedgerSequence`](reference-transaction-format.html#lastledgersequence) causes it to expire)
* It gets dropped because there are too many transactions in the queue with a higher transaction cost.
## MultiSign ##
| Amendment ID |
|--------------|
| 4C97EBA926031A7CF7D7B36FDE3ED66DDA5421192D63DE53FFB46E43B9DC8373 |
Introduces simple [multi-signing](reference-transaction-format.html#multi-signing) as a way to authorize transactions. Creates the [`SignerList` ledger node type](reference-ledger-format.html#signerlist) and the [`SignerListSet` transaction type](reference-transaction-format.html#signerlistset). Adds the optional `Signers` field to all transaction types. Modifies some transaction result codes.
This amendment allows addresses to have a list of signers who can authorize transactions from that address in a multi-signature. The list has a quorum and 1 to 8 weighted signers. This allows various configurations, such as "any 3-of-5" or "signature from A plus any other two signatures."
Signers can be funded or unfunded addresses. Funded addresses in a signer list can sign using a regular key (if defined) or master key (unless disabled). Unfunded addresses can sign with a master key. Multi-signed transactions have the same permissions as transactions signed with a regular key.
An address with a SignerList can disable the master key even if a regular key is not defined. An address with a SignerList can also remove a regular key even if the master key is disabled. Therefore, the `tecMASTER_DISABLED` transaction result code is renamed `tecNO_ALTERNATIVE_KEY`. The `tecNO_REGULAR_KEY` transaction result is retired and replaced with `tecNO_ALTERNATIVE_KEY`. Additionally, this amendment adds the following new [transaction result codes](reference-transaction-format.html#result-categories):
* `temBAD_SIGNER`
* `temBAD_QUORUM`
* `temBAD_WEIGHT`
* `tefBAD_SIGNATURE`
* `tefBAD_QUORUM`
* `tefNOT_MULTI_SIGNING`
* `tefBAD_AUTH_MASTER`
## SusPay ##
| Amendment ID |
|--------------|
| DA1BD556B42D85EA9C84066D028D355B52416734D3283F85E216EA5DA6DB7E13 |
Provides "Suspended Payments" for XRP as a means of escrow within the Ripple Consensus Ledger. Creates the `SuspendedPayment` ledger node type and the new transaction types `SuspendedPaymentCreate`, `SuspendedPaymentFinish`, and `SuspendedPaymentCancel`.
This amendment is still in development. The current version is enabled on the [Ripple Test Net](https://ripple.com/build/ripple-test-net/).
## TrustSetAuth ##
| Amendment ID |
|--------------|
| 6781F8368C4771B83E8B821D88F580202BCB4228075297B19E4FDC5233F1EFDC |
Allows pre-authorization of accounting relationships (zero-balance trust lines) when using [Authorized Accounts](tutorial-gateway-guide.html#authorized-accounts).
With this amendment enabled, a `TrustSet` transaction with [`tfSetfAuth` enabled](reference-transaction-format.html#trustset-flags) can create a new [`RippleState` ledger node](reference-ledger-format.html#ripplestate) even if it keeps all the other values of the `RippleState` node in their default state. The new `RippleState` node has the [`lsfLowAuth` or `lsfHighAuth` flag](reference-ledger-format.html#ripplestate-flags) enabled accordingly. The sender of the transaction must have [`lsfRequireAuth` enabled](reference-ledger-format.html#accountroot-flags).
## Tickets ##
| Amendment ID |
|--------------|
| C1B8D934087225F509BEB5A8EC24447854713EE447D277F69545ABFA0E0FD490 |
Introduces Tickets as a way to reserve a transaction sequence number for later execution. Creates the `Ticket` ledger node type and the transaction types `TicketCreate` and `TicketCancel`.
This amendment is still in development.

View File

@@ -82,7 +82,7 @@ To enable or disable Individual Freeze on a specific trust line, send a `TrustSe
| LimitAmount.value | String | The amount of currency you trust this counterparty to issue to you, as a quoted number. From the perspective of a gateway, this is typically `"0"`. |
| Flags | Number | To enable a freeze, use a value with the bit `0x00100000` (tfSetFreeze) enabled. To disable a freeze, use a value with the bit `0x00200000` (tfClearFreeze) enabled instead. |
Set the `Fee`, `Sequence`, and `LastLedgerSequence` parameters [in the typical way](reference-transaction-format.html#signing-and-sending-transactions).
Set the `Fee`, `Sequence`, and `LastLedgerSequence` parameters [in the typical way](reference-transaction-format.html#signing-and-submitting-transactions).
Example of submitting a TrustSet transaction to enable an individual freeze using the [WebSocket API](reference-rippled.html#websocket-api):

View File

@@ -21,6 +21,7 @@ Many objects in the ledger are owned by a particular account, and therefore coun
* [Offers](reference-ledger-format.html#offer) are owned by the account that placed them. An Offer can be automatically removed from the ledger if it is fully consumed or if it is found unfunded during transaction processing. Alternatively, the owner can cancel an offer by sending an [OfferCancel transaction](reference-transaction-format.html#offercancel), or by sending an [OfferCreate transaction](reference-transaction-format.html#offercreate) that contains an `OfferSequence` parameter.
* [Trust lines](reference-ledger-format.html#ripplestate) are shared between two accounts. The owner reserve can apply to one or both of the accounts, depending on whether the fields that account controls are in their default state. See [Contributing to the Owner Reserve](reference-ledger-format.html#contributing-to-the-owner-reserve) for details.
* A single [SignerList](reference-ledger-format.html#signerlist) counts as 3 to 10 objects for purposes of the owner reserve, depending on how many members it has. See also: [SignerLists and Reserves](reference-ledger-format.html#signerlists-and-reserves).
* [Owner directories](reference-ledger-format.html#directorynode) list all the ledger nodes that contribute to an account's owner reserve. However, the owner directory itself does not count towards the reserve.
#### Owner Reserve Edge Cases ####
@@ -40,4 +41,3 @@ When an account has less XRP than its current reserve requirement, it cannot sen
## Changing the Reserve Requirements ##
The Ripple Consensus Ledger has a mechanism for changing the reserve requirements in order to account for long-term changes in the value of XRP. Any changes have to be approved by the consensus process. See [Fee Voting](concept-fee-voting.html) for more information.

View File

@@ -0,0 +1,103 @@
Stand-Alone Mode
===============================================================================
You can run `rippled` in stand-alone mode without a consensus of trusted servers. In stand-alone mode, `rippled` does not communicate with any other servers in the Ripple peer-to-peer network, but you can do most of the same actions on your local server only. Stand-alone provides a method for testing `rippled` behavior without being tied to the live network. For example, you can [test the effects of Amendments](concept-amendments.html#testing-amendments) before those Amendments have gone into effect across the decentralized network.
When you run `rippled` in stand-alone mode, you have to tell it what ledger version to start from:
* Create a [new genesis ledger](#new-genesis-ledger) from scratch.
* [Load an existing ledger version](#load-saved-ledger) from disk.
**Caution:** In stand-alone mode, you must [manually advance the ledger](#advancing-ledgers-in-stand-alone-mode).
New Genesis Ledger
-------------------------------------------------------------------------------
In stand-alone mode, you can have `rippled` create a new genesis ledger. This provides a known state, with none of the ledger history from the production Ripple Consensus Ledger. (This is very useful for unit tests, among other things.)
* To start `rippled` in stand-alone mode with a new genesis ledger, use the `-a` and `--start` options:
```
rippled -a --start --conf=/path/to/rippled.cfg
```
In a genesis ledger, the [genesis address](reference-rippled.html#special-addresses) holds all 100 billion XRP. The keys of the genesis address are [hardcoded](https://github.com/ripple/rippled/blob/94ed5b3a53077d815ad0dd65d490c8d37a147361/src/ripple/app/ledger/Ledger.cpp#L184) as follows:
**Address:** `rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh`
**Secret:** `snoPBrXtMeMyMHUVTgbuqAfg1SUTb` ("masterpassphrase")
**Caution:** If you create a new genesis ledger, the hard-coded default [Reserve](concept-reserves.html) is **200 XRP** minimum for funding a new address, with an increment of **50 XRP** per object in the ledger. These values are higher than the current reserve requirements of the production network. (See also: [Fee Voting](concept-fee-voting.html))
Load Saved Ledger
-------------------------------------------------------------------------------
You can start with a ledger version that was saved to disk if your `rippled` server was previously synced with the Ripple peer-to-peer network (either the production network or the [Test Net](tutorial-rippled-setup.html#parallel-networks)).
### 1. Start `rippled` normally. ###
To load an existing ledger, you must first retrieve that ledger from the network. Start `rippled` in networked mode as normal:
```
rippled --conf=/path/to/rippled.cfg
```
### 2. Wait until `rippled` is synced. ###
Use the [`server_info` command](reference-rippled.html#server-info) to check the state of your server relative to the network. Your server is synced when the `server_state` value shows any of the following values:
* `full`
* `proposing`
* `validating`.
### 3. (Optional) Retrieve specific ledger versions. ###
If you only want the most recent ledger, you can skip this step.
If you want to load a specific historical ledger version, use the [`ledger_request` command](reference-rippled.html#ledger-request) to make `rippled` fetch it. If `rippled` does not already have the ledger version, you may have to run the `ledger_request` command multiple times until it has finished retrieving the ledger.
If you want to replay a specific historical ledger version, you must fetch both the ledger version to replay and the ledger version immediately before it.
### 4. Shut down `rippled`. ###
Use the [`stop` command](reference-rippled.html#stop):
```
rippled stop --conf=/path/to/rippled.cfg
```
### 5. Start `rippled` in stand-alone mode. ###
To load the most recent ledger version, you can use the `-a` and `--load` options when starting the server:
```
rippled -a --load --conf=/path/to/rippled.cfg
```
To instead load a specific historical ledger, use the `--load` parameter along with the `--ledger` parameter, providing the ledger index or identifying hash of the ledger version to load:
```
rippled -a --load --ledger 19860944 --conf=/path/to/rippled.cfg
```
### 6. Manually advance the ledger. ###
When you load a ledger with `--ledger` in stand-alone mode, it goes to the current open ledger, so you must [manually advance the ledger](#advancing-ledgers-in-stand-alone-mode):
```
rippled ledger_accept --conf=/path/to/rippled.cfg
```
Advancing Ledgers in Stand-Alone Mode
-------------------------------------------------------------------------------
In stand-alone mode, `rippled` does not communicate to other members of the peer-to-peer network or participate in a consensus process. Instead, you must manually advance the ledger index using the [`ledger_accept` command](reference-rippled.html#ledger-accept):
```
rippled ledger_accept --conf=/path/to/rippled.cfg
```
In stand-alone mode, `rippled` makes no distinction between a "closed" ledger version and a "validated" ledger version. (For more information about the difference, see [The Ripple Ledger Consensus Process](https://ripple.com/knowledge_center/the-ripple-ledger-consensus-process/).)
Whenever `rippled` closes a ledger, it reorders the transactions according to a deterministic but hard-to-game algorithm. (This is an important part of consensus, since transactions may arrive at different parts of the network in different order.) When using `rippled` in stand-alone mode, you should manually advance the ledger before submitting a transaction that depends on the result of a previous transaction. Otherwise, the second transaction might be executed before the first transaction when you manually advance the ledger. **Note:** You can safely submit multiple transactions from a single address to a single ledger, because `rippled` sorts transactions from the same address in ascending order by `Sequence` number.

View File

@@ -7,24 +7,74 @@ Every transaction must [specify how much XRP it will destroy](#specifying-the-tr
## Current Transaction Cost ##
The current transaction cost required by the network is typically **0.01 XRP** (10,000 drops), although it sometimes increases due to network load.
The current transaction cost required by the network for a standard transaction is typically **0.01 XRP** (10,000 drops), although it sometimes increases due to network load.
You can also [query `rippled` for the current transaction cost](#querying-the-transaction-cost).
### Special Transaction Costs ###
Some transactions have different transaction costs:
| Transaction | Cost Before Load Scaling |
|-----------------------|--------------------------|
| Reference Transaction (Standard cost of most transactions) | 10 drops |
| [Key Reset Transaction](#key-reset-transaction) | 0 |
| [Multi-signed transaction](reference-transaction-format.html#multi-signing) | 10 drops × (1 + Number of Signatures Provided) |
## Beneficiaries of the Transaction Cost ##
The transaction cost is not paid to any party: the XRP is irrevocably destroyed. Since no new XRP can ever be created, this makes XRP more scarce, and consequently benefits all holders of XRP by making XRP more valuable.
## Load Scaling ##
## Load Cost and Open Ledger Cost ##
When the [FeeEscalation amendment](concept-amendments.html#feeescalation) is enabled, there are two thresholds for the transaction cost:
* If the transaction cost does not meet a `rippled` server's [load-based transaction cost threshold](#local-load-cost), the server ignores the transaction completely. (This logic is essentially unchanged with or without the amendment.)
* If the transaction cost does not meet a `rippled` server's [open ledger cost threshold](#open-ledger-cost), the server queues the transaction for a later ledger.
This divides transactions into roughly three categories:
* Transactions that specify a transaction cost so low that they get rejected by the load-based transaction cost.
* Transactions that specify a transaction cost high enough to be included in the current open ledger.
* Transactions in between, which get [queued for a later ledger version](#queued-transactions).
## Local Load Cost ##
Each `rippled` server maintains a cost threshold based on its current load. If you submit a transaction with a `Fee` value that is lower than current load-based transaction cost of the `rippled` server, that server neither applies nor relays the transaction. (**Note:** If you submit a transaction through an [admin connection](reference-rippled.html#connecting-to-rippled), the server applies and relays the transaction as long as the transaction cost meets the overall minimum.) A transaction is very unlikely to survive [the consensus process](https://ripple.com/knowledge_center/the-ripple-ledger-consensus-process/) unless its `Fee` value meets the requirements of a majority of servers.
## Open Ledger Cost ##
A `rippled` server with the [FeeEscalation amendment](concept-amendments.html#feeescalation) enabled has a second mechanism for enforcing the transaction cost, called the _open ledger cost_. The open ledger cost starts out equal to the minimum transaction cost, but increases exponentially when an in-progress ledger has more transactions than the previous one. Only transactions which pay more than the open ledger cost can be included in the current open ledger.
Transactions that do not meet the open ledger cost are [queued for a following ledger](#queued-transactions) instead.
The open ledger cost requirement is proportional to the normal cost of the transaction, not the absolute transaction cost. Transaction types that have a higher-than-normal requirement, such as [multi-signed transactions](reference-transaction-format.html#multi-signing) must pay more to meet the open ledger cost than transactions which have minimum transaction cost requirements.
See also: [Fee Escalation explanation in `rippled` repository](https://github.com/ripple/rippled/blob/release/src/ripple/app/misc/FeeEscalation.md).
### Queued Transactions ###
(Requires the [FeeEscalation amendment](concept-amendments.html#feeescalation))
When `rippled` receives a transaction that meet the server's local load cost but not the open ledger cost, the server checks the transaction to see if it is "likely to be included" in a later ledger. If so, the server adds the transaction to the transaction queue and relays the transaction to other members of the network. Otherwise, the server discards the transaction. The server tries minimize the amount of network load caused by transactions that would not pay a transaction cost, since [the transaction cost only applies when a transaction is included in a validated ledger](#transaction-costs-and-failed-transactions).
The `rippled` server uses a variety of heuristics to determine which transactions are "likely to be included in a ledger." Most importantly, those transactions must be properly-formed and [authorized](reference-transaction-format.html#authorizing-transactions) with valid signatures.
When the current open ledger closes and the server starts a new open ledger, the server starts taking transactions from the queue to include in the new open ledger. The transaction queue is sorted with the transactions that would pay the highest transaction cost first, proportional to the un-scaled cost of those transactions. Transactions that pay the same transaction cost are queued in the order the server receives them.
**Note:** As of `rippled` **version 0.31.0**, the transaction queue supports at most 1 transaction per sending address. This is expected to change in later versions.
**Caution:** The current implementation does not allow transactions with an `AccountTxnID` field in the transaction queue.
Each `rippled` server independently scales the transaction cost based on its current load. If you submit a transaction with a `Fee` value that is lower than current load-based transaction cost of the `rippled` server, that server neither applies nor relays the transaction. (**Note:** If you submit a transaction through an [admin connection](reference-rippled.html#connecting-to-rippled), the server applies and relays the transaction as long as the transaction cost meets the overall minimum.) A transaction is very unlikely to survive [the consensus process](https://ripple.com/knowledge_center/the-ripple-ledger-consensus-process/) unless its `Fee` value meets the requirements of a majority of servers.
## Querying the Transaction Cost ##
The `rippled` APIs have two ways to query the transaction cost: the `server_info` command (intended for humans) and the `server_state` command (intended for machines).
The `rippled` APIs have two ways to query the local load-based transaction cost: the `server_info` command (intended for humans) and the `server_state` command (intended for machines).
If the [FeeEscalation amendment](concept-amendments.html#feeescalation) is enabled, you can use the [`fee` command](reference-rippled.html#fee) to check the open ledger cost.
### server_info ###
@@ -57,8 +107,9 @@ When you sign a transaction online, you can omit the `Fee` field. In this case,
* If the network's transaction cost goes up between signing and distributing the transaction, the transaction may not be confirmed.
* In the worst case, the transaction may be stuck in a state of being neither definitively confirmed or rejected, unless it included a `LastLedgerSequence` parameter or until you cancel it with a new transaction that uses the same `Sequence` number. See [reliable transaction submission](tutorial-reliable-transaction-submission.html) for best practices.
* You do not know in advance exactly what value you are signing for the `Fee` field.
* If you are using `rippled`, you can also use the `fee_mult_max` parameter of the [`sign` command](reference-rippled.html#sign) to set a limit to the load scaling you are willing to sign.
* If you are using `rippled`, you can also use the `fee_mult_max` and `fee_div_max` parameters of the [`sign` command](reference-rippled.html#sign) to set a limit to the load scaling you are willing to sign.
* You cannot look up the current transaction cost from an offline machine.
* You cannot automatically specify the transaction cost when [multi-signing](reference-transaction-format.html#multi-signing).
@@ -85,6 +136,8 @@ This feature is designed to allow you to recover an account if the regular key i
The [lsfPasswordSpent flag](reference-ledger-format.html#accountroot-flags) starts out disabled. If enabled, it gets disabled again when the account receives a [Payment](reference-transaction-format.html#payment) of XRP.
When the [FeeEscalation amendment](concept-amendments.html#feeescalation) is enabled, `rippled` prioritizes key reset transactions above other transactions even though the nominal transaction cost of a key reset transaction is zero.
## Changing the Transaction Cost ##

View File

@@ -4,20 +4,20 @@ The point of the Ripple software is to maintain a shared, global ledger that is
![Diagram: Each ledger is the result of applying transactions to the previous ledger version.](img/ledger-process.png)
The shared global ledger is actually a series of individual ledgers, or ledger versions, which `rippled` keeps in its internal database. Every ledger version has a sequence number (also called a ledger index), starting at 1 and incrementing with each new version. Every closed ledger also has an identifying hash value, which uniquely identifies the contents of that ledger. At any given time, a `rippled` instance has an in-progress "current" open ledger, plus some number of closed ledgers that have not yet been approved by consensus, and any number of historical ledgers that have been validated by consensus. Only the validated ledgers are certain to be accurate and immutable.
The shared global ledger is actually a series of individual ledgers, or ledger versions, which `rippled` keeps in its internal database. Every ledger version has a [ledger index](#ledger-index) which identifies the order in which ledgers occur. Each closed ledger version also has an identifying hash value, which uniquely identifies the contents of that ledger. At any given time, a `rippled` instance has an in-progress "current" open ledger, plus some number of closed ledgers that have not yet been approved by consensus, and any number of historical ledgers that have been validated by consensus. Only the validated ledgers are certain to be accurate and immutable.
A single ledger version consists of several components:
![Diagram: A ledger has transactions, a state node, and a header with the close time and validation info](img/ledger-components.png)
* A **header** - The ledger's unique index (sequence number), hashes of the other contents, and other metadata.
* A **header** - The [ledger index](#ledger-index), hashes of its other contents, and other metadata.
* A **transaction tree** - The [transactions](reference-transaction-format.html) that were applied to the previous ledger to make this one. Transactions are the _only_ way to modify the ledger.
* A **state tree** - All the [ledger nodes](#ledger-node-types) that contain the settings, balances, and objects in the ledger as of this version.
## Tree Format ##
As its name might suggest, a ledger's state tree is a tree data structure, with each node identified by a 256-bit value called an `index`. In JSON, a ledger node's index value is represented as a 64-character hexadecimal string like `"193C591BF62482468422313F9D3274B5927CA80B4DD3707E42015DD609E39C94"`. Every node in the state tree has an index that you can use as a key to look up the node in the state tree; every transaction has an indentifying hash that you can use to look up the transaction in the transaction tree. Do not confuse the `index` (key) of a ledger node with the `ledger_index` (sequence number) of a ledger.
As its name might suggest, a ledger's state tree is a tree data structure, with each node identified by a 256-bit value called an `index`. In JSON, a ledger node's index value is represented as a 64-character hexadecimal string like `"193C591BF62482468422313F9D3274B5927CA80B4DD3707E42015DD609E39C94"`. Every node in the state tree has an index that you can use as a key to look up the node in the state tree; every transaction has an indentifying hash that you can use to look up the transaction in the transaction tree. Do not confuse the `index` (key) of a ledger node with the [`ledger_index` (sequence number) of a ledger](#ledger-index).
In the case of transactions, the identifying hash is based on the signed transaction instructions, but the contents of the transaction object when you look it up also contain the results and metadata of the transaction, which are not taken into account when generating the hash.
@@ -33,19 +33,24 @@ Every ledger version has a unique header that describes the contents. You can lo
| Field | JSON Type | [Internal Type][] | Description |
|-----------------|-----------|-------------------|-------------|
| ledger\_index | String | UInt32 | The sequence number of the ledger. Some API methods display this as a quoted integer; some display it as a native JSON number. |
| [ledger\_index](#ledger-index) | String | UInt32 | The sequence number of the ledger. Some API methods display this as a quoted integer; some display it as a native JSON number. |
| ledger\_hash | String | Hash256 | The SHA-512Half of the ledger header, excluding the `ledger_hash` itself. This serves as a unique identifier for this ledger and all its contents. |
| account\_hash | String | Hash256 | The SHA-512Half of this ledger's state tree information. |
| close\_time | Number | UInt32 | The approximate time this ledger closed, as the number of seconds since the Ripple Epoch of 2000-01-01 00:00:00. This value is rounded based on the `close_time_resolution`, so it is possible for subsequent ledgers to have the same value. |
| closed | Boolean | bool | If true, this transaction is no longer accepting new transactions. (However, unless this ledger is validated, it might be replaced by a different ledger with a different set of transactions.) |
| parent\_hash | String | Hash256 | The `ledger_hash` value of the previous ledger that was used to build this one. If there are different versions of the previous ledger by sequence number, this indicates from which one the ledger was derived. |
| parent\_hash | String | Hash256 | The `ledger_hash` value of the previous ledger that was used to build this one. If there are different versions of the previous ledger index, this indicates from which one the ledger was derived. |
| total\_coins | String | UInt64 | The total number of drops of XRP owned by accounts in the ledger. This subtracts XRP that has been destroyed by transaction fees. The actual amount of XRP in circulation is lower because some accounts are "black holes" whose keys are not known by anyone. |
| transaction\_hash | String | Hash256 | The SHA-512Half of the transactions included in this ledger. |
| close\_time\_resolution | Number | Uint8 | An integer in the range \[2,120\] indicating the maximum number of seconds by which the `close_time` could be rounded. |
| closeFlags | (Omitted) | UInt8 | A bit-map of flags relating to the closing of this ledger. |
| [closeFlags](#close-flags) | (Omitted) | UInt8 | A bit-map of flags relating to the closing of this ledger. |
[Internal Type]: https://wiki.ripple.com/Binary_Format
### Ledger Index ###
{% include 'data_types/ledger_index.md' %}
[Hash]: reference-rippled.html#hashes
### Close Flags ###
Currently, the ledger has only one flag defined for closeFlags: **sLCF_NoConsensusTime** (value `1`). If this flag is enabled, it means that validators were in conflict regarding the correct close time for the ledger, but built otherwise the same ledger, so they declared consensus while "agreeing to disagree" on the close time. In this case, the consensus ledger contains a `close_time` value that is 1 second after that of the previous ledger. (In this case, there is no official close time, but the actual real-world close time is probably 3-6 seconds later than the specified `close_time`.)
@@ -100,7 +105,7 @@ The `AccountRoot` node has the following fields:
| Balance | String | Amount | The account's current XRP balance in drops, represented as a string. |
| OwnerCount | Number | UInt32 | The number of objects this account owns in the ledger, which contributes to its owner reserve. |
| PreviousTxnID | String | Hash256 | The identifying hash of the transaction that most recently modified this node. |
| PreviousTxnLgrSeq | Number | UInt32 | The sequence number (`ledger_index`) of the ledger that contains the transaction that most recently modified this node. |
| PreviousTxnLgrSeq | Number | UInt32 | The [index of the ledger](#ledger-index) that contains the transaction that most recently modified this node. |
| AccountTxnID | String | Hash256 | (Optional) The identifying hash of the transaction most recently submitted by this account. |
| RegularKey | String | AccountID | (Optional) The address of a keypair that can be used to sign transactions for this account instead of the master key. Use a [SetRegularKey transaction](reference-transaction-format.html#setregularkey) to change this value. |
| EmailHash | String | Hash128 | (Optional) The md5 hash of an email address. Clients can use this to look up an avatar through services such as [Gravatar](https://en.gravatar.com/). |
@@ -127,7 +132,7 @@ AccountRoot nodes can have the following flag values:
| lsfGlobalFreeze | 0x00400000 | 4194304 | All assets issued by this account are frozen. | asfGlobalFreeze |
| lsfDefaultRipple | 0x00800000 | 8388608 | Enable [rippling](https://ripple.com/knowledge_center/understanding-the-noripple-flag/) on this account's trust lines by default. Required for gateways; discouraged for other accounts. | asfDefaultRipple |
### AccountRoot index format ###
### AccountRoot Index Format ###
The `index` of an AccountRoot node is the SHA-512Half of the following values put together:
@@ -201,7 +206,7 @@ Example Directories:
| TakerGetsCurrency | String | Hash160 | (Offer Directories only) The currency code of the TakerGets amount from the offers in this directory. |
| TakerGetsIssuer | String | Hash160 | (Offer Directories only) The issuer of the TakerGets amount from the offers in this directory. |
### Directory index formats ###
### Directory Index Formats ###
There are three different formulas for creating the index of a DirectoryNode, depending on whether the DirectoryNode represents:
@@ -275,7 +280,7 @@ An Offer node has the following fields:
| BookNode | String | UInt64 | A hint indicating which page of the offer directory links to this node, in case the directory consists of multiple nodes. |
| OwnerNode | String | UInt64 | A hint indicating which page of the owner directory links to this node, in case the directory consists of multiple nodes. **Note:** The offer does not contain a direct link to the owner directory containing it, since that value can be derived from the `Account`. |
| PreviousTxnID | String | Hash256 | The identifying hash of the transaction that most recently modified this node. |
| PreviousTxnLgrSeq | Number | UInt32 | The sequence number (`ledger_index`) of the ledger that contains the transaction that most recently modified this node. |
| PreviousTxnLgrSeq | Number | UInt32 | The [index of the ledger](#ledger-index) that contains the transaction that most recently modified this node. |
| Expiration | Number | UInt32 | (Optional) Indicates the time after which this offer will be considered unfunded. See [Specifying Time](reference-rippled.html#specifying-time) for details. |
### Offer Flags ###
@@ -289,7 +294,7 @@ Offer nodes can have the following flag values:
| lsfPassive | 0x00010000 | 65536 | The node was placed as a passive offer. This has no effect on the node in the ledger. | tfPassive |
| lsfSell | 0x00020000 | 131072 | The node was placed as a sell offer. This has no effect on the node in the ledger (because tfSell only matters if you get a better rate than you asked for, which cannot happen after the node enters the ledger). | tfSell |
### Offer index format ###
### Offer Index Format ###
The `index` of an Offer node is the SHA-512Half of the following values put together:
@@ -344,7 +349,7 @@ A RippleState node has the following fields:
| LowLimit | Object | Amount | The limit that the low account has set on the trust line. The `issuer` is the address of the low account that set this limit. |
| HighLimit | Object | Amount | The limit that the high account has set on the trust line. The `issuer` is the address of the high account that set this limit. |
| PreviousTxnID | String | Hash256 | The identifying hash of the transaction that most recently modified this node. |
| PreviousTxnLgrSeq | Number | UInt32 | The sequence number (`ledger_index`) of the ledger that contains the transaction that most recently modified this node. |
| PreviousTxnLgrSeq | Number | UInt32 | The [index of the ledger](#ledger-index) that contains the transaction that most recently modified this node. |
| LowNode | String | UInt64 | (Omitted in some historical ledgers) A hint indicating which page of the low account's owner directory links to this node, in case the directory consists of multiple nodes. |
| HighNode | String | UInt64 | (Omitted in some historical ledgers) A hint indicating which page of the high account's owner directory links to this node, in case the directory consists of multiple nodes. |
| LowQualityIn | Number | UInt32 | (Optional) The inbound quality set by the low account, as an integer in the implied ratio LowQualityIn:1,000,000,000. The value 0 is equivalent to 1 billion, or face value. |
@@ -390,7 +395,7 @@ The default state of the two NoRipple flags depends on the state of the [lsfDefa
Fortunately, `rippled` uses lazy evaluation to calculate the owner reserve. This means that even if an account changes the default state of all its trust lines by changing the DefaultRipple flag, that account's reserve stays the same initially. If an account modifies a trust line, `rippled` re-evaluates whether that individual trust line is in its default state and should contribute the owner reserve.
### RippleState index format ###
### RippleState Index Format ###
The `index` of a RippleState node is the SHA-512Half of the following values put together:
@@ -398,3 +403,72 @@ The `index` of a RippleState node is the SHA-512Half of the following values put
* The AccountID of the low account
* The AccountID of the high account
* The 160-bit currency code of the trust line(s)
## SignerList ##
[[Source]<br>](https://github.com/ripple/rippled/blob/6d2e3da30696bd10e3bb11a5ff6d45d2c4dae90f/src/ripple/protocol/impl/LedgerFormats.cpp#L127 "Source")
The `SignerList` node type represents a list of parties that, as a group, are authorized to sign a transaction in place of an individual account. You can create, replace, or remove a SignerList using the [SignerListSet transaction type](reference-transaction-format.html#signerlistset) This node type is introduced by the [MultiSign amendment](concept-amendments.html#multisign). _(New in [version 0.31.0][])_
Example SignerList node:
```
{
"Flags": 0,
"LedgerEntryType": "SignerList",
"OwnerNode": "0000000000000000",
"PreviousTxnID": "5904C0DC72C58A83AEFED2FFC5386356AA83FCA6A88C89D00646E51E687CDBE4",
"PreviousTxnLgrSeq": 16061435,
"SignerEntries": [
{
"SignerEntry": {
"Account": "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW",
"SignerWeight": 2
}
},
{
"SignerEntry": {
"Account": "raKEEVSGnKSD9Zyvxu4z6Pqpm4ABH8FS6n",
"SignerWeight": 1
}
},
{
"SignerEntry": {
"Account": "rUpy3eEg8rqjqfUoLeBnZkscbKbFsKXC3v",
"SignerWeight": 1
}
}
],
"SignerListID": 0,
"SignerQuorum": 3,
"index": "A9C28A28B85CD533217F5C0A0C7767666B093FA58A0F2D80026FCC4CD932DDC7"
}
```
A SignerList node has the following fields:
| Name | JSON Type | Internal Type | Description |
|-----------------|-----------|---------------|-------------|
| OwnerNode | String | UInt64 | A hint indicating which page of the owner directory links to this node, in case the directory consists of multiple nodes. |
| SignerQuorum | Number | UInt32 | A target number for signer weights. To produce a valid signature for the owner of this SignerList, the signers must provide valid signatures whose weights sum to this value or more. |
| SignerEntries | Array | Array | An array of SignerEntry objects representing the parties who are part of this signer list. |
| SignerListID | Number | UInt32 | An ID for this signer list. Currently always set to `0`. If a future [amendment](concept-amendments.html) allows multiple signer lists for an account, this may change. |
| PreviousTxnID | String | Hash256 | The identifying hash of the transaction that most recently modified this node. |
| PreviousTxnLgrSeq | Number | UInt32 | The [index of the ledger](#ledger-index) that contains the transaction that most recently modified this node. |
The `SignerEntries` may be any combination of funded and unfunded addresses that use either secp256k1 or ed25519 keys.
### SignerEntry Object ###
Each member of the `SignerEntries` field is an object that describes that signer in the list. A SignerEntry has the following fields:
| Name | JSON Type | Internal Type | Description |
|-----------------|-----------|---------------|-------------|
| Account | String | AccountID | A Ripple address whose signature contributes to the multi-signature. It does not need to be a funded address in the ledger. |
| SignerWeight | Number | UInt16 | The weight of a signature from this signer. A multi-signature is only valid if the sum weight of the signatures provided meets or exceeds the SignerList's `SignerQuorum` value. |
When processing a multi-signed transaction, the server dereferences the `Account` values with respect to the ledger at the time of transaction execution. If the address _does not_ correspond to a funded [AccountRoot node](#accountroot), then only the master secret associated with that address can be used to produce a valid signature. If the account _does_ exist in the ledger, then it depends on the state of that account. If the account has a Regular Key configured, the Regular Key can be used. The account's master key can only be used if it is not disabled. A multi-signature cannot be used as a component of another multi-signature.
### SignerLists and Reserves ###
A SignerList contributes to its owner's [reserve requirement](concept-reserves.html). The SignerList itself counts as two objects, and each member of the list counts as one. As a result, the total owner reserve associated with a SignerList is anywhere from 3 times to 10 times the reserve required by a single trust line ([RippleState](#ripplestate)) or [Offer](#offer) node in the ledger.

1332
content/reference-rippled.md Normal file → Executable file

File diff suppressed because it is too large Load Diff

View File

@@ -12,27 +12,50 @@ There are several different types of transactions that perform different actions
* [OfferCreate - Submit an order to exchange currency](#offercreate)
* [OfferCancel - Withdraw a currency-exchange order](#offercancel)
* [TrustSet - Add or modify a trust line](#trustset)
* [SignerListSet - Set multi-signing settings](#signerlistset)
Additionally, there are *Psuedo-Transactions* that are not created and submitted in the usual way, but may appear in ledgers:
Additionally, there are *Pseudo-Transactions* that are not created and submitted in the usual way, but may appear in ledgers:
* [SetFee - Adjust the minimum transaction cost or account reserve](#setfee)
* [EnableAmendment - Apply a change to transaction processing](#enableamendment)
Transactions are only valid if signed, submitted, and accepted into a validated ledger version. There are many ways a transaction can fail.
* [Signing and Sending Transactions](#signing-and-sending-transactions)
* [Authorized Transactions](#authorizing-transactions)
* [Reliable Transaction Submission](#reliable-transaction-submission)
* [Transaction Results - How to find and interpret transaction results](#transaction-results)
* [Full Transaction Response List - Complete table of all error codes](#full-transaction-response-list)
## Signing and Sending Transactions ##
## Authorizing Transactions ##
Signing a transaction cryptographically proves that the person in charge of the account sending the transaction is authorized to do so. Only signed transactions can be submitted to the network and included in a validated ledger. A signed transaction is immutable: its contents cannot change, and the signature is not valid for any other transaction.
In the decentralized Ripple Consensus Ledger, a digital signature proves that a transaction is authorized to perform a specific set of actions. Only signed transactions can be submitted to the network and included in a validated ledger. A signed transaction is immutable: its contents cannot change, and the signature is not valid for any other transaction.
You can sign a transaction using a secret key: either the master secret, or a regular secret if the account has a regular key pair associated with it. (See [SetRegularKey](#setregularkey) for details.)
A transaction can be authorized by any of the following types of signatures:
Multi-signature transactions are [in development](https://wiki.ripple.com/Multisign).
* A single signature from the master secret key that is mathematically associated with the sending address. You can disable or enable the master key using an [AccountSet transaction](#accountset).
* A single signature that matches a regular key associated with the address. You can add, remove, or replace a regular key using a [SetRegularKey transaction](#setregularkey).
* A [multi-signature](#multi-signing) that matches a list of signers owned by the address. You can add, remove, or replace a list of signers using a [SignerListSet transaction](#signerlistset).
Typically, you create a transaction in JSON format first. Here is an example of an unsigned Payment-type transaction in JSON:
Any signature type can authorize any type of transaction, with the following exceptions:
* Only the master key can [disable the master key](#accountset-flags).
* Only the master key can [permanently give up the ability to freeze](concept-freeze.html#no-freeze).
* You can never remove the last method of signing transactions from an address.
## Signing and Submitting Transactions ##
Sending a transaction to the Ripple Consensus Ledger involves several steps:
1. Create an [unsigned transaction in JSON format](#unsigned-transaction-format).
2. Use one or more signatures to [authorize the transaction](#authorizing-transactions).
3. Submit a transaction to a `rippled` server. If the transaction is properly formed, the server provisionally applies the transaction to its current version of the ledger and relays the transaction to other members of the peer-to-peer network.
4. The [consensus process](https://ripple.com/knowledge_center/the-ripple-ledger-consensus-process/) determines which provisional transactions get included in the next validated ledger.
5. The `rippled` servers apply those transactions to the previous ledger in a canonical order and share their results.
6. If enough [trusted validators](tutorial-rippled-setup.html#reasons-to-run-a-validator) created the exact same ledger, that ledger is declared _validated_ and the [results of the transactions](#transaction-results) in that ledger are immutable.
### Unsigned Transaction Format ###
Here is an example of an unsigned [Payment-type transaction](#payment) in JSON:
```
{
@@ -50,11 +73,11 @@ Typically, you create a transaction in JSON format first. Here is an example of
}
```
After doing that, you generate the signed binary format for the transaction. There are two ways to do this:
The Ripple Consensus Ledger only relays and executes a transaction if the transaction object has been authorized by the sending address (in the `Account`) field. For transactions authorized by only a single signature, you have two options:
1. Convert it to a binary blob and sign it offline. This is preferable, since it means that the account secret used for signing the transaction is never transmitted over any network connection.
* You can use [RippleAPI](reference-rippleapi.html#sign) to perform offline signing.
2. Have a `rippled` server sign the transaction for you. The [sign command](reference-rippled.html#sign) takes a JSON-format transaction and secret and returns the signed binary transaction format ready for submission. (Transmitting your account secret is dangerous, so you should only do this from within a trusted and encrypted sub-net, to a server you control.)
2. Have a `rippled` server sign the transaction for you. The [sign command](reference-rippled.html#sign) takes a JSON-format transaction and secret and returns the signed binary transaction format ready for submission. (Transmitting your account secret is dangerous, so you should only do this from within a trusted and encrypted connection, or through a local connection, and only to a server you control.)
* As a shortcut, you can use the [submit command](reference-rippled.html#submit) with a `tx_json` object to sign and submit a transaction all at once. This is only recommended for testing and development purposes.
In either case, signing a transaction generates a binary blob that can be submitted to the network. This means using `rippled`'s [submit command](reference-rippled.html#submit). Here is an example of the same transaction, as a signed blob, being submitted with the WebSocket API:
@@ -67,7 +90,11 @@ In either case, signing a transaction generates a binary blob that can be submit
}
```
After a transaction has been submitted, if it gets accepted into a validated ledger, you can view the final transaction using the API. For example, here is what the WebSocket API [tx command](reference-rippled.html#tx) shows for the same transaction. The field names that begin with capital letters are part of the ledger object; the fields that begin with lower-case letters are additional information generated by the server for the request:
After a transaction has been submitted, you can check its status using the API, for example using the [tx command](reference-rippled.html#tx).
**Caution:** The success of a transaction is not final unless the transaction appears in a **validated** ledger with the result code `tesSUCCESS`. See also: [Finality of Results](#finality-of-results).
Example response from the `tx` command:
```
{
@@ -157,6 +184,27 @@ After a transaction has been submitted, if it gets accepted into a validated led
}
```
### Multi-Signing ###
Multi-signing in Ripple is the act of [authorizing transactions](#authorizing-transactions) for the Ripple Consensus Ledger by using a combination of multiple secret keys. Multi-signing is due to be enabled by an [Amendment](concept-amendments.html) to the Ripple Consensus Protocol. You can have any combination of authorization methods enabled for your address, including multi-signing, a master key, and a [regular key](#setregularkey). (The only requirement is that _at least one_ method must be enabled.)
The [SignerListSet transaction](#signerlistset) defines which addresses can authorize transactions from your address. You can include up to 8 addresses in a SignerList. You can control how many signatures are needed, in which combinations, by using the quorum and weight values of the SignerList.
To successfully submit a multi-signed transaction, you must do all of the following:
* The address sending the transaction (specified in the `Account` field) must own a [`SignerList` in the ledger](reference-ledger-format.html#signerlist).
* The transaction must include the `SigningPubKey` field as an empty string.
* The transaction must include a [`Signers` field](#signers-field) containing an array of signatures.
* The signatures present in the `Signers` array must match signers defined in the SignerList.
* For the provided signatures, the total `weight` associated with those signers must be equal or greater than the `quorum` for the SignerList.
* The [transaction cost](concept-transaction-cost.html) (specified in the `Fee` field) must be at least (N+1) times the normal transaction cost, where N is the number of signatures provided.
* All fields of the transaction must be defined before collecting signatures. You cannot [auto-fill](#auto-fillable-fields) any fields.
* If presented in binary form, the `Signers` array must be sorted based on the numeric value of the signer addresses, with the lowest value first. (If submitted as JSON, the [`submit_multisigned` command](reference-rippled.html#submit-multisigned) handles this automatically.)
For more information, see [How to Multi-Sign](tutorial-multisign.html).
### Reliable Transaction Submission ###
Reliably submitting transactions is the process of achieving both of the following:
@@ -169,7 +217,7 @@ To accomplish both of these, your application should:
1. Construct and sign the transaction first, including a [`LastLedgerSequence`](#lastledgersequence) parameter that gives the transaction a limited viable lifespan.
2. Persist details of the transaction before submitting.
3. Submit the transaction.
4. Confirm that the transaction was either included in a validated ledger, or that it has expired due to `LastLedgerSequence`.
4. Confirm that the transaction was either included in a validated ledger, or that it has expired due to `LastLedgerSequence`.
5. If a transaction fails or expires, you can modify and resubmit it.
Main article: [Reliable Transaction Submission](tutorial-reliable-transaction-submission.html)
@@ -193,9 +241,10 @@ Every transaction type has the same set of fundamental fields:
| [LastLedgerSequence](#lastledgersequence) | Number | UInt32 | (Optional, but strongly recommended) Highest ledger sequence number that a transaction can appear in. |
| [Memos](#memos) | Array of Objects | Array | (Optional) Additional arbitrary information used to identify this transaction. |
| [Sequence](#canceling-or-skipping-a-transaction) | Unsigned Integer | UInt32 | (Required, but [auto-fillable](#auto-fillable-fields)) The sequence number, relative to the initiating account, of this transaction. A transaction is only valid if the `Sequence` number is exactly 1 greater than the last-valided transaction from the same account. |
| SigningPubKey | String | PubKey | (Automatically added when signing) Hex representation of the public key that corresponds to the private key used to sign this transaction. |
| SigningPubKey | String | PubKey | (Automatically added when signing) Hex representation of the public key that corresponds to the private key used to sign this transaction. If an empty string, indicates a multi-signature is present in the `Signers` field instead. |
| [Signers](#signers-field) | Array | Array | (Optional) Array of objects that represent a [multi-signature](#multi-signing) which authorizes this transaction. |
| SourceTag | Unsigned Integer | UInt32 | (Optional) Arbitrary integer used to identify the reason for this payment, or the hosted wallet on whose behalf this transaction is made. Conventionally, a refund should specify the initial payment's `SourceTag` as the refund payment's `DestinationTag`. |
| TransactionType | String | UInt16 | The type of transaction. Valid types include: `Payment`, `OfferCreate`, `OfferCancel`, `TrustSet`, `AccountSet`, and `SetRegularKey`. |
| TransactionType | String | UInt16 | The type of transaction. Valid types include: `Payment`, `OfferCreate`, `OfferCancel`, `TrustSet`, `AccountSet`, `SetRegularKey`, and `SignerListSet`. |
| TxnSignature | String | VariableLength | (Automatically added when signing) The signature that verifies this transaction as originating from the account it says it is from. |
**Note:** The deprecated `PreviousTxnID` transaction parameter was removed entirely in [rippled 0.28.0][]. Use `AccountTxnID` instead.
@@ -211,13 +260,16 @@ Some fields can be automatically filled in before the transaction is signed, eit
For a production system, we recommend *not* leaving these fields to be filled by the server. For example, if transaction costs become high due to a temporary spike in network load, you may want to wait for the cost to decrease before sending some transactions, instead of paying the temporarily-high cost.
The [`Paths` field](#paths) of the [Payment](#payment) transaction type can also be automatically filled in.
The [`Paths` field](#paths) of the [Payment](#payment) transaction type can also be automatically filled in.
### Transaction Cost ###
In order to protect the Ripple Consensus Ledger from being disrupted by spam and denial-of-service attacks, each transaction must destroy a small amount of XRP. This transaction cost is designed to increase along with the load on the network, making it very expensive to deliberately or inadvertently overload the network.
In order to protect the Ripple Consensus Ledger from being disrupted by spam and denial-of-service attacks, each transaction must destroy a small amount of XRP. This _[transaction cost](concept-transaction-cost.html)_ is designed to increase along with the load on the network, making it very expensive to deliberately or inadvertently overload the network.
The `Fee` field specifies an amount, in [drops of XRP](reference-rippled.html#specifying-currency-amounts), to destroy as the cost for this transaction. If the transaction is included in a validated leger (whether or not it achieves its intended purpose), then the amount of XRP specified in the `Fee` parameter is destroyed forever. You can [look up the transaction cost](concept-transaction-cost.html#querying-the-transaction-cost) in advance, or [let `rippled` set it automatically](concept-transaction-cost.html#automatically-specifying-the-transaction-cost) when you sign a transaction.
The `Fee` field specifies an amount, in [drops of XRP](reference-rippled.html#specifying-currency-amounts), to destroy as the cost for relaying this transaction. If the transaction is included in a validated ledger (whether or not it achieves its intended purpose), then the amount of XRP specified in the `Fee` parameter is destroyed forever. You can [look up the transaction cost](concept-transaction-cost.html#querying-the-transaction-cost) in advance, or [let `rippled` set it automatically](concept-transaction-cost.html#automatically-specifying-the-transaction-cost) when you sign a transaction.
**Note:** [Multi-signed transactions](#multi-signing) require additional fees to relay to the network.
### Canceling or Skipping a Transaction ###
@@ -248,7 +300,7 @@ In order to use AccountTxnID, you must first set the [asfAccountTxnID](#accounts
### Memos ###
The Memos field allows for arbitrary messaging data that can accompany the transaction. It is presented as an array of objects. Each object has only one field, `Memo`, which in turn contains another object with *one or more* of the following fields:
The `Memos` field allows for arbitrary messaging data that can accompany the transaction. It is presented as an array of objects. Each object has only one field, `Memo`, which in turn contains another object with *one or more* of the following fields:
| Field | Type | [Internal Type](https://wiki.ripple.com/Binary_Format) | Description |
|-------|------|--------------------------------------------------------|-------------|
@@ -279,10 +331,25 @@ Example of a transaction with a Memos field:
}
```
### Signers Field ###
The `Signers` field contains a [multi-signature](#multi-signing), which has signatures from up to 8 key pairs, that together should authorize the transaction. The `Signers` list is an array of objects, each with one field, `Signer`. The `Signer` field has the following nested fields:
| Field | Type | [Internal Type](https://wiki.ripple.com/Binary_Format) | Description |
|-------|------|--------------------------------------------------------|-------------|
| Account | String | AccountID | The address associated with this signature, as it appears in the SignerList. |
| TxnSignature | String | Blob | A signature for this transaction, verifiable using the `SigningPubKey`. |
| SigningPubKey | String | PubKey | The public key used to create this signature. |
The `SigningPubKey` must be a key that is associated with the `Account` address. If the referenced `Account` is a funded account in the ledger, then the SigningPubKey can be that account's current Regular Key if one is set. It could also be that account's Master Key, unless the [lsfDisableMaster](reference-ledger-format.html#accountroot-flags) flag is enabled. If the referenced `Account` address is not a funded account in the ledger, then the `SigningPubKey` must be the master key associated with that address.
Because signature verification is a compute-intensive task, multi-signed transactions cost additional XRP to relay to the network. Each signature included in the multi-signature increases the [transaction cost](concept-transaction-cost.html) required for the transaction. For example, if the current minimum transaction cost to relay a transaction to the network is `10000` drops, then a multi-signed transaction with 3 entries in the `Signers` array would need a `Fee` value of at least `40000` drops to relay.
### Flags ###
The Flags field allows for additional boolean options regarding the behavior of a transaction. They are represented as binary values that can be combined with bitwise-or operations to set multiple flags at once.
The `Flags` field allows for additional boolean options regarding the behavior of a transaction. They are represented as binary values that can be combined with bitwise-or operations to set multiple flags at once.
Most flags only have meaning for a specific transaction type. The same bitwise value may be reused for flags on different transaction types, so it is important to pay attention to the `TransactionType` field when setting and reading flags.
@@ -334,7 +401,7 @@ Example payment:
Most of the time, the `issuer` field of a non-XRP [currency amount](reference-rippled.html#specifying-currency-amounts) indicates the account of the gateway that issues that currency. However, when describing payments, there are special rules for the `issuer` field in the `Amount` and `SendMax` fields of a payment.
* There is only ever one balance for the same currency between two accounts. This means that, sometimes, the `issuer` field of an amount actually refers to a counterparty that is redeeming issuances, instead of the account that created the issuances.
* When the `issuer` field of the destination `Amount` field matches the `Destination` account address, it is treated as a special case meaning "any issuer that the destination accepts." This includes all accounts to which the destination has extended trust lines, as well as issuances created by the destination which may be held on other trust lines.
* When the `issuer` field of the destination `Amount` field matches the `Destination` account address, it is treated as a special case meaning "any issuer that the destination accepts." This includes all accounts to which the destination has extended trust lines, as well as issuances created by the destination which may be held on other trust lines.
* When the `issuer` field of the `SendMax` field matches the source account's address, it is treated as a special case meaning "any issuer that the source can use." This includes creating new issuances on trust lines that other accounts have extended to the source account, as well as issuances from other accounts that the source account possesses.
### Creating Accounts ###
@@ -391,11 +458,11 @@ When the [*tfPartialPayment* flag](#payment-flags) is enabled, the `Amount` fiel
Ripple defines the "quality" of a currency exchange as the ratio of the numeric amount in to the numeric amount out. For example, if you spend $2 USD to receive £1 GBP, then the "quality" of that exchange is `0.5`.
The [*tfLimitQuality* flag](#payment-flags) allows you to set a minimum quality of conversions that you are willing to take. This limit quality is defined as the destination `Amount` divided by the `SendMax` amount (just the numeric amounts, regardless of currency). When set, the payment processing engine avoids using any paths whose quality (conversion rate) is worse (numerically lower) than the limit quality.
The [*tfLimitQuality* flag](#payment-flags) allows you to set a minimum quality of conversions that you are willing to take. This limit quality is defined as the destination `Amount` divided by the `SendMax` amount (just the numeric amounts, regardless of currency). When set, the payment processing engine avoids using any paths whose quality (conversion rate) is worse (numerically lower) than the limit quality.
By itself, the tfLimitQuality flag reduces the number of situations in which a transaction can succeed. Specifically, it rejects payments where some part of the payment uses an unfavorable conversion, even if the overall average *average* quality of conversions in the payment is equal or better than the limit quality. If a payment is rejected in this way, the [transaction result](#transaction-results) is `tecPATH_DRY`.
Consider the following example. If I am trying to send you 100 Chinese Yuan (`Amount` = 100 CNY) for 20 United States dollars (`SendMax` = 20 USD) or less, then the limit quality is `5`. Imagine one market maker is offering ¥95 for $15 (a ratio of about `6.3` CNY per USD), but the next best offer in the market is ¥5 for $2 (a ratio of `2.5` CNY per USD). If I were to take both offers in order to send you 100 CNY, then it would cost me 17 USD, for an average quality of about `5.9`.
Consider the following example. If I am trying to send you 100 Chinese Yuan (`Amount` = 100 CNY) for 20 United States dollars (`SendMax` = 20 USD) or less, then the limit quality is `5`. Imagine one market maker is offering ¥95 for $15 (a ratio of about `6.3` CNY per USD), but the next best offer in the market is ¥5 for $2 (a ratio of `2.5` CNY per USD). If I were to take both offers in order to send you 100 CNY, then it would cost me 17 USD, for an average quality of about `5.9`.
Without the tfLimitQuality flag set, this transaction would succeed, because the $17 it costs me is within my specified `SendMax`. However, with the tfLimitQuality flag enabled, the transaction would fail instead, because the path to take the second offer has a quality of `2.5`, which is worse than the limit quality of `5`.
@@ -465,13 +532,13 @@ The available AccountSet flags are:
| asfRequireDest | 1 | Require a destination tag to send transactions to this account. | lsfRequireDestTag |
| asfRequireAuth | 2 | Require authorization for users to hold balances issued by this account. (This prevents users unknown to a gateway from holding funds issued by that gateway.) | lsfRequireAuth |
| asfDisallowXRP | 3 | XRP should not be sent to this account. (Enforced by client applications, not by `rippled`) | lsfDisallowXRP |
| asfDisableMaster | 4 | Disallow use of the master key. Can only be enabled if the account has a [RegularKey](#setregularkey) configured. | lsfDisableMaster |
| asfDisableMaster | 4 | Disallow use of the master key. Can only be enabled if the account has configured another way to sign transactions, such as a [Regular Key](#setregularkey) or a [Signer List](#signerlistset). | lsfDisableMaster |
| asfAccountTxnID | 5 | Track the ID of this account's most recent transaction. Required for [AccountTxnID](#accounttxnid) | (None) |
| asfNoFreeze | 6 | Permanently give up the ability to [freeze individual trust lines or disable Global Freeze](concept-freeze.html). This flag can never be disabled after being enabled. | lsfNoFreeze |
| asfGlobalFreeze | 7 | [Freeze](concept-freeze.html) all assets issued by this account. | lsfGlobalFreeze |
| asfDefaultRipple | 8 | Enable [rippling](https://ripple.com/knowledge_center/understanding-the-noripple-flag/) on this account's trust lines by default. _(New in [rippled 0.27.3](https://github.com/ripple/rippled/releases/tag/0.27.3))_ | lsfDefaultRipple |
_New in [rippled 0.28.0][]:_ You cannot send a transaction that enables `asfDisableMaster` or `asfNoFreeze` using a [regular key](#setregularkey). You must use the master key to sign the transaction.
_New in [rippled 0.28.0][]:_ In order to enable the `asfDisableMaster` or `asfNoFreeze` flags, you must [authorize the transaction](#authorizing-transactions) by signing it with the master key. You cannot use a regular key or a multi-signature.
The following [Transaction flags](#flags), specific to the AccountSet transaction type, serve the same purpose, but are discouraged:
@@ -506,7 +573,7 @@ In rippled's WebSocket and JSON-RPC APIs, the TransferRate is represented as an
[[Source]<br>](https://github.com/ripple/rippled/blob/4239880acb5e559446d2067f00dabb31cf102a23/src/ripple/app/transactors/SetRegularKey.cpp "Source")
A SetRegularKey transaction changes the regular key used by the account to sign future transactions.
A SetRegularKey transaction changes the regular key associated with an address.
```
{
@@ -520,13 +587,15 @@ A SetRegularKey transaction changes the regular key used by the account to sign
| Field | JSON Type | [Internal Type](https://wiki.ripple.com/Binary_Format) | Description |
|-------|-----------|--------------------------------------------------------|-------------|
| RegularKey | String | Account | (Optional) The public key of a new keypair, to use as the regular key to this account, as a base-58-encoded string in the same format as an account address. If omitted, removes the existing regular key. |
| RegularKey | String | AccountID | (Optional) A base-58-encoded [Ripple address](reference-rippled.html#addresses) to use as the regular key. If omitted, removes the existing regular key. |
Instead of using an account's master key to sign transactions, you can set an alternate key pair, called the "Regular Key". As long as the public key for this key pair is set in the `RegularKey` field of an account this way, then the secret of the Regular Key pair can be used to sign transactions. (The master secret can still be used, too, unless you set the [asfDisableMaster account flag](#accountset-flags).)
In addition to the master key, which is mathematically-related to an address, you can associate **at most 1 additional key pair** with an address using this type of transaction. The additional key pair is called a _regular key_. If your address has a regular key pair defined, you can use the secret key of the regular key pair to [authorize transactions](#authorizing-transactions).
A Regular Key pair is generated in the same way as any other Ripple keys (for example, with [wallet_propose](reference-rippled.html#wallet-propose)), but it can be changed. A Master Key pair is an intrinsic part of the account's identity (the address is derived from the master public key) so the Master Key cannot be changed. Therefore, using a Regular Key to sign transactions instead of the master key whenever possible is beneficial to security.
A regular key pair is generated in the same way as any other Ripple keys (for example, with [wallet_propose](reference-rippled.html#wallet-propose)), but it can be changed. A master key pair is an intrinsic part of an address's identity (the address is derived from the master public key). You can [disable](#accountset-flags) a master key but you cannot change it.
If your regular key is compromised, but the master key is not, you can use this method to regain control of your account. In some cases, you can even send a [key reset transaction](concept-transaction-cost.html#key-reset-transaction) without paying the [transaction cost](#transaction-cost).
You can protect your master secret by using a regular key instead of the master key to sign transactions whenever possible. If your regular key is compromised, but the master key is not, you can use a SetRegularKey transaction to regain control of your address. In some cases, you can even send a [key reset transaction](concept-transaction-cost.html#key-reset-transaction) without paying the [transaction cost](#transaction-cost).
For even greater security, you can use [multi-signing](#multi-signing), but multi-signing requires additional XRP for the [transaction cost](concept-transaction-cost.html) and [reserve](concept-reserves.html).
@@ -715,7 +784,7 @@ A trust line with settings in the default state is equivalent to no trust line.
The default state of all flags is off, except for the [NoRipple flag](https://ripple.com/knowledge_center/understanding-the-noripple-flag/), whose default state depends on the DefaultRipple flag.
The Auth flag of a trust line does not determine whether the trust line counts towards its owner's XRP reserve requirement. However, an enabled Auth flag prevents the trust line from being in its default state. An authorized trust line can never be deleted. _(New in [rippled 0.30.0](https://github.com/ripple/rippled/releases/tag/0.30.0))_: You can pre-authorize a trust line with the `tfSetfAuth` flag only, even if the limit and balance of the trust line are 0.
The Auth flag of a trust line does not determine whether the trust line counts towards its owner's XRP reserve requirement. However, an enabled Auth flag prevents the trust line from being in its default state. An authorized trust line can never be deleted. _(New in [rippled 0.30.0](https://github.com/ripple/rippled/releases/tag/0.30.0))_: The [`TrustSetAuth` Amendment](concept-amendments.html#trustsetauth) would allow you to pre-authorize a trust line with the `tfSetfAuth` flag only, even if the limit and balance of the trust line are 0. This Amendment is not currently enabled.
### TrustSet Flags ###
@@ -730,6 +799,58 @@ Transactions of the TrustSet type support additional values in the [`Flags` fiel
| tfClearFreeze | 0x00200000 | 2097152 | [Unfreeze](concept-freeze.html) the trustline. |
## SignerListSet ##
[[Source]<br>](https://github.com/ripple/rippled/blob/ef511282709a6a0721b504c6b7703f9de3eecf38/src/ripple/app/tx/impl/SetSignerList.cpp "Source")
The SignerListSet transaction creates, replaces, or removes a list of signers that can be used to [multi-sign](#multi-signing) a transaction. This transaction type is introduced by the [MultiSign amendment](concept-amendments.html#multisign). _(New in [version 0.31.0][])_
Example SignerListSet:
```
{
"Flags": 0,
"TransactionType": "SignerListSet",
"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
"Fee": "10000",
"SignerQuorum": 3,
"SignerEntries": [
{
"SignerEntry": {
"Account": "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW",
"SignerWeight": 2
}
},
{
"SignerEntry": {
"Account": "rUpy3eEg8rqjqfUoLeBnZkscbKbFsKXC3v",
"SignerWeight": 1
}
},
{
"SignerEntry": {
"Account": "raKEEVSGnKSD9Zyvxu4z6Pqpm4ABH8FS6n",
"SignerWeight": 1
}
}
]
}
```
| Field | JSON Type | [Internal Type](https://wiki.ripple.com/Binary_Format) | Description |
|-------|-----------|--------------------------------------------------------|-------------|
| SignerQuorum | Number | UInt32 | A target number for the signer weights. A multi-signature from this list is valid only if the sum weights of the signatures provided is greater than or equal to this value. To delete a SignerList, use the value `0`. |
| SignerEntries | Array | Array | (Omitted when deleting) Array of [SignerEntry objects](reference-ledger-format.html#signerentry-object), indicating the addresses and weights of signers in this list. A SignerList must have at least 1 member and no more than 8 members. No address may appear more than once in the list, nor may the `Account` submitting the transaction appear in the list. |
An account may not have more than one SignerList. A successful SignerListSet transaction replaces the existing SignerList, if one exists. To delete a SignerList, you must set `SignerQuorum` to `0` _and_ omit the `SignerEntries` field. Otherwise, the transaction fails with the error [temMALFORMED](#tem-codes). A transaction to delete a SignerList is considered successful even if there was no SignerList to delete.
You cannot create a SignerList such that the SignerQuorum could never be met. The SignerQuorum must be greater than 0 but less than or equal to the sum of the `SignerWeight` values in the list. Otherwise, the transaction fails with the error [temMALFORMED](#tem-codes).
You can create, update, or remove a SignerList using the master key, regular key, or the current SignerList, if those methods of signing transactions are available.
You cannot remove the last method of signing transactions from an account. If an account's master key is disabled (it has the [`lsfDisableMaster` flag](reference-ledger-format.html#accountroot-flags) enabled) and the account does not have a [Regular Key](#setregularkey) configured, then you cannot delete the SignerList from the account. Instead, the transaction fails with the error [tecNO\_ALTERNATIVE\_KEY](#tec-codes).
# Pseudo-Transactions #
Pseudo-Transactions are never submitted by users, nor propagated through the network. Instead, a server may choose to inject them in a proposed ledger directly. If enough servers inject an equivalent pseudo-transaction for it to pass consensus, then it becomes included in the ledger, and appears in ledger data thereafter.
@@ -746,9 +867,9 @@ Some of the fields that are mandatory for normal transactions do not make sense
## SetFee ##
A change in [transaction cost](concept-transaction-cost.html) or [account reserve](concept-reserves.html) requirements. This is typically in response to changes in the load on the network.
A change in [transaction cost](concept-transaction-cost.html) or [account reserve](concept-reserves.html) requirements as a result of [Fee Voting](concept-fee-voting.html).
*Note:* You cannot send a pseudo-transaction, but you may encounter one when processing ledgers.
**Note:** You cannot send a pseudo-transaction, but you may encounter one when processing ledgers.
```
{
@@ -773,6 +894,29 @@ A change in [transaction cost](concept-transaction-cost.html) or [account reserv
| ReferenceFeeUnits | Unsigned Integer | UInt32 | The cost, in fee units, of the reference transaction |
| ReserveBase | Unsigned Integer | UInt32 | The base reserve, in drops |
| ReserveIncrement | Unsigned Integer | UInt32 | The incremental reserve, in drops |
| LedgerSequence | Number | UInt32 | The index of the ledger version where this pseudo-transaction appears. This distinguishes the pseudo-transaction from other occurrences of the same change. |
## EnableAmendment ##
Tracks the progress of the [amendment process](concept-amendments.html#amendment-process) for changes in transaction processing. This can indicate that a proposed amendment gained or lost majority approval, or that an amendment has been enabled.
**Note:** You cannot send a pseudo-transaction, but you may encounter one when processing ledgers.
| Field | JSON Type | [Internal Type](https://wiki.ripple.com/Binary_Format) | Description |
|-------|-----------|--------------------------------------------------------|-------------|
| Amendment | String | Hash256 | A unique identifier for the amendment. This is not intended to be a human-readable name. See [Amendments](concept-amendments.html) for a list of known amendments. |
| LedgerSequence | Number | UInt32 | The index of the ledger version where this amendment appears. This distinguishes the pseudo-transaction from other occurrences of the same change. |
### EnableAmendment Flags ###
The `Flags` value of the EnableAmendment pseudo-transaction indicates the status of the amendment at the time of the ledger including the pseudo-transaction.
A `Flags` value of `0` (no flags) indicates that the amendment has been enabled, and applies to all ledgers afterward. Other `Flags` values are as follows:
| Flag Name | Hex Value | Decimal Value | Description |
|-----------|-----------|---------------|-------------|
| tfGotMajority | 0x00010000 | 65536 | Support for this amendment increased to at least 80% of trusted validators starting with this ledger version. |
| tfLostMajority | 0x00020000 | 131072 | Support for this amendment decreased to less than 80% of trusted validators starting with this ledger version. |
@@ -780,7 +924,7 @@ A change in [transaction cost](concept-transaction-cost.html) or [account reserv
## Immediate Response ##
The response from the [`submit` command](reference-rippled.html#submit) contains a provisional result from the `rippled` server indicating what happened during local processing of the transaction.
The response from the [`submit` command](reference-rippled.html#submit) contains a provisional result from the `rippled` server indicating what happened during local processing of the transaction.
The response from `submit` contains the following fields:
@@ -802,7 +946,7 @@ __*Note:*__ A successful result at this stage does not indicate that the transac
## Looking up Transaction Results ##
To see the final result of a transaction, use the [`tx` command](reference-rippled.html#tx), [`account_tx` command](reference-rippled.html#account-tx), or other response from `rippled`. Look for `"validated": true` to indicate that this response uses a ledger version that has been validated by consensus.
To see the final result of a transaction, use the [`tx` command](reference-rippled.html#tx), [`account_tx` command](reference-rippled.html#account-tx), or other response from `rippled`. Look for `"validated": true` to indicate that this response uses a ledger version that has been validated by consensus.
| Field | Value | Description |
|-------|-------|-------------|
@@ -901,12 +1045,12 @@ These codes indicate an error in the local server processing the transaction; it
| Code | Explanation |
|------|-------------|
| telLOCAL_ERROR | Unspecified local error. |
| telBAD\_DOMAIN | The transaction specified a domain value (for example, the `Domain` field of an [AccountSet transaction](#accountset)) that cannot be used, probably because it is too long to store in the ledger. |
| telBAD\_PATH_COUNT | The transaction contains too many paths for the local server to process. |
| telBAD\_PUBLIC\_KEY | The transaction specified a public key value (for example, as the `MessageKey` field of an [AccountSet transaction](#accountset)) that cannot be used, probably because it is too long. |
| telFAILED\_PROCESSING | An unspecified error occurred when processing the transaction. |
| telINSUF\_FEE_P | The `Fee` from the transaction is not high enough to meet the server's current [transaction cost](concept-transaction-cost.html) requirement, which is derived from its load level. |
| telLOCAL_ERROR | Unspecified local error. |
| telNO\_DST\_PARTIAL | The transaction is an XRP payment that would fund a new account, but the [tfPartialPayment flag](#partial-payments) was enabled. This is disallowed. |
### tem Codes ###
@@ -915,7 +1059,6 @@ These codes indicate that the transaction was malformed, and cannot succeed acco
| Code | Explanation |
|------|-------------|
| temMALFORMED | Unspecified problem with the format of the transaction. |
| temBAD\_AMOUNT | An amount specified by the transaction (for example the destination `Amount` or `SendMax` values of a [Payment](#payment)) was invalid, possibly because it was a negative number. |
| temBAD\_AUTH\_MASTER | The key used to sign this transaction does not match the master key for the account sending it, and the account does not have a [Regular Key](#setregularkey) set. |
| temBAD\_CURRENCY | The transaction improperly specified a currency field. See [Specifying Currency Amounts](reference-rippled.html#specifying-currency-amounts) for the correct format. |
@@ -935,13 +1078,21 @@ These codes indicate that the transaction was malformed, and cannot succeed acco
| temBAD\_SIGNATURE | The signature to authorize this transaction is either missing, or formed in a way that is not a properly-formed signature. (See [tecNO_PERMISSION](#tec-codes) for the case where the signature is properly formed, but not authorized for this account.) |
| temBAD\_SRC\_ACCOUNT | The `Account` on whose behalf this transaction is being sent (the "source account") is not a properly-formed Ripple account. |
| temBAD\_TRANSFER\_RATE | The [`TransferRate` field of an AccountSet transaction](#transferrate) is not properly formatted. |
| temDST\_IS\_SRC | The [TrustSet](#trustset) transaction improperly specified the destination of the trustline (the `issuer` field of `LimitAmount`) as the `Account` sending the transaction. You cannot extend a trustline to yourself. (In the future, this code could also apply to other cases where the destination of a transaction is not allowed to be the account sending it.) |
| temDST\_IS\_SRC | The [TrustSet](#trustset) transaction improperly specified the destination of the trust line (the `issuer` field of `LimitAmount`) as the `Account` sending the transaction. You cannot extend a trust line to yourself. (In the future, this code could also apply to other cases where the destination of a transaction is not allowed to be the account sending it.) |
| temDST\_NEEDED | The transaction improperly omitted a destination. This could be the `Destination` field of a [Payment](#payment) transaction, or the `issuer` sub-field of the `LimitAmount` field fo a `TrustSet` transaction. |
| temINVALID | The transaction is otherwise invalid. For example, the transaction ID may not be the right format, the signature may not be formed properly, or something else went wrong in understanding the transaction. |
| temINVALID\_FLAG | The transaction includes a [Flag](#flags) that does not exist, or includes a contradictory combination of flags. |
| temMALFORMED | Unspecified problem with the format of the transaction. |
| temREDUNDANT | The transaction would accomplish nothing; for example, it is sending a payment directly to the sending account, or creating an offer to buy and sell the same currency from the same issuer. |
| temREDUNDANT\_SEND\_MAX | _(Removed in [rippled 0.28.0][])_ |
| temRIPPLE\_EMPTY | The [Payment](#payment) transaction includes an empty `Paths` field, but paths are necessary to complete this payment. |
| temBAD_WEIGHT | The [SignerListSet](#signerlistset) transaction includes a `SignerWeight` that is invalid, for example a zero or negative value. |
| temBAD_SIGNER | The [SignerListSet](#signerlistset) transaction includes a signer who is invalid. For example, there may be duplicate entries, or the owner of the SignerList may also be a member. |
| temBAD_QUORUM | The [SignerListSet](#signerlistset) transaction has an invalid `SignerQuorum` value. Either the value is not greater than zero, or it is more than the sum of all signers in the list. |
| temUNCERTAIN | Used internally only. This code should never be returned. |
| temUNKNOWN | Used internally only. This code should never be returned. |
| temDISABLED | The transaction requires logic that is currently disabled. Typically this means you are trying to use an [amendment](concept-amendments.html) that is not enabled for the current ledger. |
### tef Codes ###
@@ -949,19 +1100,23 @@ These codes indicate that the transaction failed to apply, but the transaction c
| Code | Explanation |
|------|-------------|
| tefFAILURE | Unspecified failure in applying the transaction. |
| tefALREADY | The same exact transaction has already been applied. |
| tefBAD\_ADD\_AUTH | Deprecated. This code should never be returned. |
| tefBAD\_ADD\_AUTH | **DEPRECATED.** |
| tefBAD\_AUTH | The key used to sign this account is not authorized to modify this account. (It could be authorized if the account had the same key set as the [Regular Key](#setregularkey).) |
| tefBAD\_LEDGER | While processing the transaction, the ledger was discovered in an unexpected state. If you can reproduce this error, please [file a bug](https://ripplelabs.atlassian.net/secure/CreateIssueDetails!init.jspa?pid=10800&issuetype=1) to get it fixed. |
| tefCREATED | Deprecated. This code should never be returned. |
| tefEXCEPTION | While processing the transaction, the server entered an unexpected state. This may be caused by unexpected inputs, for example if the binary data for the transaction is grossly malformed. If you can reproduce this error, please [file a bug](https://ripplelabs.atlassian.net/secure/CreateIssueDetails!init.jspa?pid=10800&issuetype=1) to get it fixed. |
| tefINTERNAL | While attempting to apply the transaction, the server entered an unexpected state. If you can reproduce this error, please [file a bug](https://ripplelabs.atlassian.net/secure/CreateIssueDetails!init.jspa?pid=10800&issuetype=1) to get it fixed. |
| tefNO\_AUTH\_REQUIRED | The [TrustSet](#trustset) transaction attempted to mark a trustline as authorized, but the `lsfRequireAuth` flag is not enabled for the corresponding account, so authorization is not necessary. |
| tefPAST\_SEQ | The sequence number of the transaction is lower than the current sequence number of the account sending the transaction. |
| tefWRONG\_PRIOR | The transaction contained an `AccountTxnID` field (or the deprecated `PreviousTxnID` field), but the transaction specified there does not match the account's previous transaction. |
| tefBAD\_AUTH\_MASTER | The single signature provided to authorize this transaction does not match the master key, but no regular key is associated with this address. |
| tefBAD\_LEDGER | While processing the transaction, the ledger was discovered in an unexpected state. If you can reproduce this error, please [report an issue](https://github.com/ripple/rippled/issues) to get it fixed. |
| tefBAD\_QUORUM | The transaction was [multi-signed](#multi-signing), but the total weights of all included signatures did not meet the quorum. |
| tefBAD\_SIGNATURE | The transaction was [multi-signed](#multi-signing), but contained a signature for an address not part of a SignerList associated with the sending account. |
| tefCREATED |**DEPRECATED.** |
| tefEXCEPTION | While processing the transaction, the server entered an unexpected state. This may be caused by unexpected inputs, for example if the binary data for the transaction is grossly malformed. If you can reproduce this error, please [report an issue](https://github.com/ripple/rippled/issues) to get it fixed. |
| tefFAILURE | Unspecified failure in applying the transaction. |
| tefINTERNAL | While attempting to apply the transaction, the server entered an unexpected state. If you can reproduce this error, please [report an issue](https://github.com/ripple/rippled/issues) to get it fixed. |
| tefMASTER\_DISABLED | The transaction was signed with the account's master key, but the account has the `lsfDisableMaster` field set. |
| tefMAX\_LEDGER | The transaction included a [`LastLedgerSequence`](#lastledgersequence) parameter, but the current ledger's sequence number is already higher than the specified value. |
| tefNO\_AUTH\_REQUIRED | The [TrustSet](#trustset) transaction attempted to mark a trustline as authorized, but the `lsfRequireAuth` flag is not enabled for the corresponding account, so authorization is not necessary. |
| tefNOT\_MULTI\_SIGNING | The transaction was [multi-signed](#multi-signing), but the sending account has no SignerList defined. |
| tefPAST\_SEQ | The sequence number of the transaction is lower than the current sequence number of the account sending the transaction. |
| tefWRONG\_PRIOR | The transaction contained an `AccountTxnID` field (or the deprecated `PreviousTxnID` field), but the transaction specified there does not match the account's previous transaction. |
### ter Codes ###
@@ -969,16 +1124,16 @@ These codes indicate that the transaction failed to apply, but it could apply su
| Code | Explanation |
|------|-------------|
| terRETRY | Unspecified retriable error. |
| terFUNDS\_SPENT | Deprecated. This code should never be returned. |
| terFUNDS\_SPENT | **DEPRECATED.** |
| terINSUF\_FEE\_B | The account sending the transaction does not have enough XRP to pay the `Fee` specified in the transaction. |
| terNO\_ACCOUNT | The account sending the transaction does not exist in the ledger (yet). |
| terNO\_AUTH | The transaction would involve adding currency issued by an account with `lsfRequireAuth` enabled to a trustline that is not authorized. For example, you placed an offer to buy a currency you aren't authorized to hold. |
| terLAST | Used internally only. This code should never be returned. |
| terNO\_ACCOUNT | The address sending the transaction is not funded in the ledger (yet). |
| terNO\_AUTH | The transaction would involve adding currency issued by an account with `lsfRequireAuth` enabled to a trust line that is not authorized. For example, you placed an offer to buy a currency you aren't authorized to hold. |
| terNO\_LINE | Used internally only. This code should never be returned. |
| terNO\_RIPPLE | Used internally only. This code should never be returned. |
| terOWNERS | The transaction requires that account sending it has a nonzero "owners count", so the transaction cannot succeed. For example, an account cannot enable the [`lsfRequireAuth`](#accountset-flags) flag if it has any trust lines or available offers. |
| terPRE\_SEQ | The `Sequence` number of the current transaction is higher than the current sequence number of the account sending the transaction. |
| terLAST | Used internally only. This code should never be returned. |
| terNO\_RIPPLE | Used internally only. This code should never be returned. |
| terRETRY | Unspecified retriable error. |
### tes Success ###
@@ -995,40 +1150,39 @@ These codes indicate that the transaction failed, but it was applied to a ledger
| Code | Value | Explanation |
|------|-------|-------------|
| tecCLAIM | 100 | Unspecified failure, with transaction cost destroyed. |
| tecPATH\_PARTIAL | 101 | The transaction failed because the provided paths did not have enough liquidity to send the full amount. |
| tecUNFUNDED\_ADD | 102 | **DEPRECATED.** |
| tecUNFUNDED\_OFFER | 103 | The [OfferCreate transaction](#offercreate) failed because the account creating the offer does not have any of the `TakerGets` currency. |
| tecUNFUNDED\_PAYMENT | 104 | The transaction failed because the sending account is trying to send more XRP than it holds, not counting the reserve. (See: [Reserves](concept-reserves.html)) |
| tecDIR\_FULL | 121 | The address sending the transaction cannot own any more objects in the ledger. |
| tecDST\_TAG\_NEEDED | 143 | The [Payment](#payment) transaction omitted a destination tag, but the destination account has the `lsfRequireDestTag` flag enabled. _(New in [rippled 0.28.0][])_ |
| tecFAILED\_PROCESSING | 105 | An unspecified error occurred when processing the transaction. |
| tecDIR\_FULL | 121 | The "owners count" of the account sending the transaction is already maxed out. |
| tecFROZEN | 137 | The [OfferCreate transaction](#offercreate) failed because one or both of the assets involved are subject to a [global freeze](concept-freeze.html). |
| tecINSUF\_RESERVE\_LINE | 122 | The transaction failed because the sending account does not have enough XRP to create a new trust line. (See: [Reserves](concept-reserves.html)) This error occurs when the counterparty already has a trust line in a non-default state to the sending account for the same currency. (See tecNO\_LINE\_INSUF\_RESERVE for the other case.) |
| tecINSUF\_RESERVE\_OFFER | 123 | The transaction failed because the sending account does not have enough XRP to create a new Offer. (See: [Reserves](concept-reserves.html)) |
| tecINSUFFICIENT\_RESERVE | 141 | The [SignerListSet](#signerlistset) or other transaction would increase the [reserve requirement](concept-reserves.html) higher than the sending account's balance. See [SignerLists and Reserves](reference-ledger-format.html#signerlists-and-reserves) for more information. |
| tecINTERNAL | 144 | Unspecified internal error, with transaction cost applied. This error code should not normally be returned. |
| tecNEED\_MASTER\_KEY | 142 | This transaction attempted to cause changes that require the master key, such as [disabling the master key or giving up the ability to freeze balances](#accountset-flags). _(New in [rippled 0.28.0](https://github.com/ripple/rippled/releases/tag/0.28.0-rc1))_ |
| tecNO\_ALTERNATIVE\_KEY | 130 | The transaction tried to remove the only available method of [authorizing transactions](#authorizing-transactions). This could be a [SetRegularKey transaction](#setregularkey) to remove the regular key, a [SignerListSet transaction](#signerlistset) to delete a SignerList, or an [AccountSet transaction](#accountset) to disable the master key. (Prior to [rippled 0.30.0](https://github.com/ripple/rippled/releases/tag/0.30.0), this was called `tecMASTER_DISABLED`.) |
| tecNO\_AUTH | 134 | The transaction failed because it needs to add a balance on a trust line to an account with the `lsfRequireAuth` flag enabled, and that trust line has not been authorized. If the trust line does not exist at all, tecNO\_LINE occurs instead. |
| tecNO\_DST | 124 | The account on the receiving end of the transaction does not exist. This includes Payment and TrustSet transaction types. (It could be created if it received sufficient XRP.) |
| tecNO\_DST\_INSUF_XRP | 125 | The account on the receiving end of the transaction does not exist, and the transaction is not sending enough XRP to create it. |
| tecNO\_ENTRY | 140 | Reserved for future use. |
| tecNO\_ISSUER | 133 | The account specified in the `issuer` field of a currency amount does not exist. |
| tecNO\_LINE | 135 | The `TakerPays` field of the [OfferCreate transaction](#offercreate) specifies an asset whose issuer has `lsfRequireAuth` enabled, and the account making the offer does not have a trust line for that asset. (Normally, making an offer implicitly creates a trust line if necessary, but in this case it does not bother because you cannot hold the asset without authorization.) If the trust line exists, but is not authorized, `tecNO_AUTH` occurs instead. |
| tecNO\_LINE\_INSUF\_RESERVE | 126 | The transaction failed because the sending account does not have enough XRP to create a new trust line. (See: [Reserves](concept-reserves.html)) This error occurs when the counterparty does not have a trust line to this account for the same currency. (See tecINSUF\_RESERVE\_LINE for the other case.) |
| tecNO\_LINE\_REDUNDANT | 127 | The transaction failed because it attempted to set a trust line to its default state, but the trust line did not exist. |
| tecPATH\_DRY | 128 | The transaction failed because the provided paths did not have enough liquidity to send anything at all. This could mean that the source and destination accounts are not linked by trust lines. |
| tecUNFUNDED | 129 | **DEPRECATED.** Replaced by tecUNFUNDED\_OFFER and tecUNFUNDED\_PAYMENT. |
| tecMASTER\_DISABLED | 130 | The [SetRegularKey transaction](#setregularkey) tried to unset the Regular Key, but the account has the `lsfDisableMaster` flag enabled. (Unsetting the Regular Key while also leaving the Master Key disabled would make the account unusable.) |
| tecNO\_REGULAR\_KEY | 131 | The [AccountSet transaction](#accountset) tried to disable the Master Key, but the account does not have a Regular Key set. (Disabling the Master Key without having a Regular Key configured would make the account unusable.) |
| tecOWNERS | 132 | The transaction requires that account sending it has a nonzero "owners count", so the transaction cannot succeed. For example, an account cannot enable the [`lsfRequireAuth`](#accountset-flags) flag if it has any trust lines or available offers. |
| tecNO\_ISSUER | 133 | The account specified in the `issuer` field of a currency amount does not exist. |
| tecNO\_AUTH | 134 | The transaction failed because it needs to add a balance on a trust line to an account with the `lsfRequireAuth` flag enabled, and that trust line has not been authorized. If the trust line does not exist at all, tecNO\_LINE occurs instead. |
| tecNO\_LINE | 135 | The `TakerPays` field of the [OfferCreate transaction](#offercreate) specifies an asset whose issuer has `lsfRequireAuth` enabled, and the account making the offer does not have a trust line for that asset. (Normally, making an offer implicitly creates a trust line if necessary, but in this case it does not bother because you cannot hold the asset without authorization.) If the trust line exists, but is not authorized, tecNO\_AUTH occurs instead. |
| tecINSUFF\_FEE | 136 | The account sending the transaction does not possess enough XRP to pay the specified `Fee`. This error only occurs if the transaction has already been propagated through the network to achieve consensus, |
| tecFROZEN | 137 | The [OfferCreate transaction](#offercreate) failed because one or both of the assets involved are subject to a [global freeze](concept-freeze.html). |
| tecNO\_TARGET | 138 | **FORTHCOMING** Part of multi-signature transactions. |
| tecNO\_PERMISSION | 139 | **FORTHCOMING** Part of multi-signature transactions. |
| tecNO\_ENTRY | 140 | **FORTHCOMING** Part of multi-signature transactions. |
| tecINSUFFICIENT\_RESERVE | 141 | **FORTHCOMING** Part of multi-signature transactions. (Code may change; see [RIPD-743](https://ripplelabs.atlassian.net/browse/RIPD-743) for status.) |
| tecNEED\_MASTER\_KEY | 142 | This transaction attempted to cause changes that require the master key, such as [disabling the master key or giving up the ability to freeze balances](#accountset-flags). _(New in [rippled 0.28.0](https://github.com/ripple/rippled/releases/tag/0.28.0-rc1))_ |
| tecDST\_TAG\_NEEDED | 143 | The [Payment](#payment) transaction omitted a destination tag, but the destination account has the `lsfRequireDestTag` flag enabled. _(New in [rippled 0.28.0][])_ |
| tecINTERNAL | 144 | Unspecified internal error, with transaction cost applied. This error code should not normally be returned. |
| tecNO\_PERMISSION | 139 | Reserved for future use. |
| tecNO\_REGULAR\_KEY | 131 | The [AccountSet transaction](#accountset) tried to disable the master key, but the account does not have another way to [authorize transactions](#authorizing-transactions). If [multi-signing](#multi-signing) is enabled, this code is deprecated and `tecNO_ALTERNATIVE_KEY` is used instead. |
| tecNO\_TARGET | 138 | Reserved for future use. |
| tecOVERSIZE | 145 | This transaction could not be processed, because attempted transaction processing created an excessively large amount of metadata. _(New in [rippled 0.29.0-hf1](https://github.com/ripple/rippled/releases/tag/0.29.0-hf1) )_ |
| tecOWNERS | 132 | The transaction requires that account sending it has a nonzero "owners count", so the transaction cannot succeed. For example, an account cannot enable the [`lsfRequireAuth`](#accountset-flags) flag if it has any trust lines or available offers. |
| tecPATH\_DRY | 128 | The transaction failed because the provided paths did not have enough liquidity to send anything at all. This could mean that the source and destination accounts are not linked by trust lines. |
| tecPATH\_PARTIAL | 101 | The transaction failed because the provided paths did not have enough liquidity to send the full amount. |
| tecUNFUNDED | 129 | **DEPRECATED.** Replaced by tecUNFUNDED\_OFFER and tecUNFUNDED\_PAYMENT. |
| tecUNFUNDED\_ADD | 102 | **DEPRECATED.** |
| tecUNFUNDED\_PAYMENT | 104 | The transaction failed because the sending account is trying to send more XRP than it holds, not counting the reserve. (See: [Reserves](concept-reserves.html)) |
| tecUNFUNDED\_OFFER | 103 | The [OfferCreate transaction](#offercreate) failed because the account creating the offer does not have any of the `TakerGets` currency. |
### tej Codes ###
These codes are only ever returned by the `ripple-lib` client library, not by `rippled` itself.
These codes are only ever returned by the `ripple-lib` client library, not by `rippled` itself.
| Code | Explanation |
|------|-------------|
@@ -1042,4 +1196,3 @@ These codes are only ever returned by the `ripple-lib` client library, not by `r
| tejSecretUnknown | The secret for a given account was omitted from the transaction, and ripple-lib was unable to automatically fill it in from saved data. |
| tejServerUntrusted | The application attempted to submit an account secret to an untrusted server for transaction signing. |
| tejUnconnected | The application is not connected to a `rippled` server, but it needs to be in order to process the transaction. |

View File

@@ -0,0 +1,605 @@
How to Multi-Sign
=============================
Multi-signing is one of three ways to authorize transactions for the Ripple Consensus Ledger, alongside signing with [regular keys](reference-transaction-format.html#setregularkey) and master keys. You can configure your address to allow any combination of the three methods to authorize transactions.
Benefits of multi-signing include:
* You can require keys from different devices, so that a malicious actor must compromise multiple machines to send transactions on your behalf.
* You can share custody of an address between multiple people, each of whom only has one of several keys necessary to send transactions from that address.
* You can delegate the power to send transactions from your address to a group of people, who can control your address if you are unavailable or unable to sign normally.
* ... and more.
To use multi-signing:
1. [The Ripple peer-to-peer network must have multi-signing enabled.](#availability-of-multi-signing)
2. [Set up a list of signers on your account.](#setting-up-multi-signing)
3. [Send transactions using multiple signatures.](#sending-a-multi-signed-transaction)
Availability of Multi-Signing
-----------------------------
Multi-signing is built into `rippled` starting with [version 0.31.0](https://wiki.ripple.com/Rippled-0.31.0). Because multi-signing is a change in transaction processing, the change is due to be enabled by an **Amendment** to the Ripple Consensus Protocol. This Amendment must be approved by a consensus of validators showing consistent support for the feature over a period of time. For more information, see [Amendments](concept-amendments.html).
If you want to test multi-signing before it becomes available in the production network, or without risking real money, you can do so by running `rippled` in [stand-alone mode](concept-stand-alone-mode.html) with the MultiSign feature enabled. To enable multi-signing for testing, add the following stanza to your `rippled.cfg`:
[features]
MultiSign
Setting up Multi-Signing
------------------------
Before you can set up multi-signing, first check that [multi-signing is available](#availability-of-multi-signing).
To multi-sign transactions from a particular address, you must create a list of addresses that can contribute to a multi-signature for your address. This list is stored in the Ripple Consensus Ledger as a [SignerList node](reference-ledger-format.html#signerlist). The following procedure demonstrates how to set up a SignerList for your address:
### 1. Prepare a funded address ###
You need a Ripple address that can send transactions, and has enough XRP available. Multi-signing requires more than the usual amount of XRP for the [account reserve](concept-reserves.html) and [transaction cost](concept-transaction-cost.html), increasing with the number of signers and signatures you use.
If you started `rippled` in [stand-alone mode](concept-stand-alone-mode.html) with a new genesis ledger, you must:
1. Generate keys for a new address, or reuse keys you already have.
2. Submit a Payment transaction to fund the new address from the genesis account. (Send at least 100,000,000 [drops of XRP](reference-rippled.html#specifying-currency-amounts).)
3. Manually close the ledger.
### 2. Prepare member keys ###
You need several sets of Ripple keys (address and secret) to include as members of your SignerList. These can be funded addresses that exist in the ledger, or you can generate new addresses using the [`wallet_propose` command](reference-rippled.html#wallet-propose). For example:
$ rippled wallet_propose
Loading: "/home/mduo13/.config/ripple/rippled.cfg"
Connecting to 127.0.0.1:5005
{
"result" : {
"account_id" : "rnRJ4dpSBKDR2M1itf4Ah6tZZm5xuNZFPH",
"key_type" : "secp256k1",
"master_key" : "FLOG SEND GOES CUFF GAGE FAT ANTI DEL GUM TIRE ISLE BEAR",
"master_seed" : "snheH5UUjU4CWqiNVLny2k21TyKPC",
"master_seed_hex" : "A9F859765EB8614D26809836382AFB82",
"public_key" : "aBR4hxFXcDNHnGYvTiqb2KU8TTTV1cYV9wXTAuz2DjBm7S8TYEBU",
"public_key_hex" : "03C09A5D112B393D531E4F092E3A5769A5752129F0A9C55C61B3A226BB9B567B9B",
"status" : "success"
}
}
Take note of the `account_id` (Ripple Address) and `master_seed` (Ripple secret key) for each one you generate.
### 3. Send SignerListSet transaction ###
[Sign and submit](reference-transaction-format.html#signing-and-submitting-transactions) a [SignerListSet transaction](reference-transaction-format.html#signerlistset) in the normal (single-signature) way. This associates a SignerList with your Ripple address, so that a combination of signatures from the members of that SignerList can multi-sign later transactions on your behalf.
In this example, the SignerList has 3 members, with the weights and quorum set up such that multi-signed transactions need a signature from rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW plus at least one signature from the other two members of the list.
**Caution:** Never submit a secret key to a server you do not control. Do not transmit a secret key unencrypted over the network.
$ rippled submit shqZZy2Rzs9ZqWTCQAdqc3bKgxnYq '{
> "Flags": 0,
> "TransactionType": "SignerListSet",
> "Account": "rnBFvgZphmN39GWzUJeUitaP22Fr9be75H",
> "Fee": "10000",
> "SignerQuorum": 3,
> "SignerEntries": [
> {
> "SignerEntry": {
> "Account": "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW",
> "SignerWeight": 2
> }
> },
> {
> "SignerEntry": {
> "Account": "rUpy3eEg8rqjqfUoLeBnZkscbKbFsKXC3v",
> "SignerWeight": 1
> }
> },
> {
> "SignerEntry": {
> "Account": "raKEEVSGnKSD9Zyvxu4z6Pqpm4ABH8FS6n",
> "SignerWeight": 1
> }
> }
> ]
> }'
Loading: "/home/mduo13/.config/ripple/rippled.cfg"
Connecting to 127.0.0.1:5005
{
"result" : {
"engine_result" : "tesSUCCESS",
"engine_result_code" : 0,
"engine_result_message" : "The transaction was applied. Only final in a validated ledger.",
"status" : "success",
"tx_blob" : "12000C2200000000240000000120230000000368400000000000271073210303E20EC6B4A39A629815AE02C0A1393B9225E3B890CAE45B59F42FA29BE9668D74473045022100BEDFA12502C66DDCB64521972E5356F4DB965F553853D53D4C69B4897F11B4780220595202D1E080345B65BAF8EBD6CA161C227F1B62C7E72EA5CA282B9434A6F04281142DECAB42CA805119A9BA2FF305C9AFA12F0B86A1F4EB1300028114204288D2E47F8EF6C99BCC457966320D12409711E1EB13000181147908A7F0EDD48EA896C3580A399F0EE78611C8E3E1EB13000181143A4C02EA95AD6AC3BED92FA036E0BBFB712C030CE1F1",
"tx_json" : {
"Account" : "rnBFvgZphmN39GWzUJeUitaP22Fr9be75H",
"Fee" : "10000",
"Flags" : 0,
"Sequence" : 1,
"SignerEntries" : [
{
"SignerEntry" : {
"Account" : "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW",
"SignerWeight" : 2
}
},
{
"SignerEntry" : {
"Account" : "rUpy3eEg8rqjqfUoLeBnZkscbKbFsKXC3v",
"SignerWeight" : 1
}
},
{
"SignerEntry" : {
"Account" : "raKEEVSGnKSD9Zyvxu4z6Pqpm4ABH8FS6n",
"SignerWeight" : 1
}
}
],
"SignerQuorum" : 3,
"SigningPubKey" : "0303E20EC6B4A39A629815AE02C0A1393B9225E3B890CAE45B59F42FA29BE9668D",
"TransactionType" : "SignerListSet",
"TxnSignature" : "3045022100BEDFA12502C66DDCB64521972E5356F4DB965F553853D53D4C69B4897F11B4780220595202D1E080345B65BAF8EBD6CA161C227F1B62C7E72EA5CA282B9434A6F042",
"hash" : "3950D98AD20DA52EBB1F3937EF32F382D74092A4C8DF9A0B1A06ED25200B5756"
}
}
}
Make sure that the [Transaction Result](reference-transaction-format.html#transaction-results) is [**tesSUCCESS**](reference-transaction-format.html#tes-success). Otherwise, the transaction failed.
**Note:** The more members in the SignerList, the more XRP your address must have for purposes of the [owner reserve](concept-reserves.html#owner-reserves). If your address does not have enough XRP, the transaction fails with [tecINSUFFICIENT_RESERVE](reference-transaction-format.html#tec-codes). See also: [SignerLists and Reserves](reference-ledger-format.html#signerlists-and-reserves).
### 4. Close the ledger ###
On the live network, you can wait 4-7 seconds for the ledger to close automatically.
If you're running `rippled` in stand-alone mode, use the [`ledger_accept` command](reference-rippled.html#ledger-accept) to manually close the ledger:
$ rippled ledger_accept
Loading: "/home/mduo13/.config/ripple/rippled.cfg"
Connecting to 127.0.0.1:5005
{
"result" : {
"ledger_current_index" : 6,
"status" : "success"
}
}
### 5. Confirm the new signer list ###
Use the [`account_objects` command](reference-rippled.html#account-objects) to confirm that the SignerList is associated with the address in the latest validated ledger.
Normally, an account can own many objects of different types (such as trust lines and offers). If you funded a new address for this tutorial, the SignerList is the only object in the response.
$ rippled account_objects rEuLyBCvcw4CFmzv8RepSiAoNgF8tTGJQC validated
Loading: "/home/mduo13/.config/ripple/rippled.cfg"
Connecting to 127.0.0.1:5005
{
"result" : {
"account" : "rEuLyBCvcw4CFmzv8RepSiAoNgF8tTGJQC",
"account_objects" : [
{
"Flags" : 0,
"LedgerEntryType" : "SignerList",
"OwnerNode" : "0000000000000000",
"PreviousTxnID" : "8FDC18960455C196A8C4DE0D24799209A21F4A17E32102B5162BD79466B90222",
"PreviousTxnLgrSeq" : 5,
"SignerEntries" : [
{
"SignerEntry" : {
"Account" : "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW",
"SignerWeight" : 2
}
},
{
"SignerEntry" : {
"Account" : "raKEEVSGnKSD9Zyvxu4z6Pqpm4ABH8FS6n",
"SignerWeight" : 1
}
},
{
"SignerEntry" : {
"Account" : "rUpy3eEg8rqjqfUoLeBnZkscbKbFsKXC3v",
"SignerWeight" : 1
}
}
],
"SignerListID" : 0,
"SignerQuorum" : 3,
"index" : "79FD203E4DDDF2EA78B798C963487120C048C78652A28682425E47C96D016F92"
}
],
"ledger_hash" : "56E81069F06492FB410A70218C08169BE3AB3CFD5AEA20E999662D81DC361D9F",
"ledger_index" : 5,
"status" : "success",
"validated" : true
}
}
If the SignerList is present with the expected contents, then your address is ready to multi-sign.
### 6. Further steps ###
At this point, your address is ready to [send a multi-signed transaction](#sending-a-multi-signed-transaction). You may also want to:
* Disable the address's master key by sending an [AccountSet transaction](reference-transaction-format.html#accountset) using the `asfDisableMaster` flag.
* Remove the address's regular key (if you previously set one) by sending a [SetRegularKey transaction](reference-transaction-format.html#setregularkey).
Sending a Multi-Signed Transaction
----------------------------------
Before you can multi-sign a transaction, first [set up multi-signing](#setting-up-multi-signing) for your address. The following procedure demonstrates how to create, sign, and submit a multi-signed transaction.
### 1. Create the transaction ##
Create a JSON object that represents the transaction you want to submit. You have to specify _everything_ about this transaction, including `Fee` and `Sequence`. Also include the field `SigningPubKey` as an empty string, to indicate that the transaction is multi-signed.
Keep in mind that the `Fee` for multi-signed transactions is significantly higher than for regularly-signed transactions. It should be (N+1) times the normal [transaction cost](concept-transaction-cost.html), where N is the number of signatures you plan to provide. Given that it sometimes takes a while to collect signatures from multiple sources, you may want to include additional buffer in case the [transaction cost](concept-transaction-cost.html) increases in that time.
Here's an example transaction ready to be multi-signed:
{
"TransactionType": "TrustSet",
"Account": "rEuLyBCvcw4CFmzv8RepSiAoNgF8tTGJQC",
"Flags": 262144,
"LimitAmount": {
"currency": "USD",
"issuer": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"value": "100"
},
"Sequence": 2,
"SigningPubKey": "",
"Fee": "30000"
}
(This transaction creates an accounting relationship from rEuLyBCvcw4CFmzv8RepSiAoNgF8tTGJQC to rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh with a maximum balance of 100 USD.)
### 2. Get one signature ###
Use the [`sign_for` command](reference-rippled.html#sign-for) with the secret key and address of one of the members of your SignerList to get a signature for that member.
**Caution:** Never submit a secret key to a server you do not control. Do not transmit a secret key unencrypted over the network.
$ rippled sign_for rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW <rsA2L..'s secret> '{
> "TransactionType": "TrustSet",
> "Account": "rEuLyBCvcw4CFmzv8RepSiAoNgF8tTGJQC",
> "Flags": 262144,
> "LimitAmount": {
> "currency": "USD",
> "issuer": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
> "value": "100"
> },
> "Sequence": 2,
> "SigningPubKey": "",
> "Fee": "30000"
> }'
Loading: "/home/mduo13/.config/ripple/rippled.cfg"
Connecting to 127.0.0.1:5005
{
"result" : {
"status" : "success",
"tx_blob" : "1200142200040000240000000263D5038D7EA4C680000000000000000000000000005553440000000000B5F762798A53D543A014CAF8B297CFF8F2F937E868400000000000753073008114A3780F5CB5A44D366520FC44055E8ED44D9A2270F3E010732102B3EC4E5DD96029A647CFA20DA07FE1F85296505552CCAC114087E66B46BD77DF744730450221009C195DBBF7967E223D8626CA19CF02073667F2B22E206727BFE848FF42BEAC8A022048C323B0BED19A988BDBEFA974B6DE8AA9DCAE250AA82BBD1221787032A864E58114204288D2E47F8EF6C99BCC457966320D12409711E1F1",
"tx_json" : {
"Account" : "rEuLyBCvcw4CFmzv8RepSiAoNgF8tTGJQC",
"Fee" : "30000",
"Flags" : 262144,
"LimitAmount" : {
"currency" : "USD",
"issuer" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"value" : "100"
},
"Sequence" : 2,
"Signers" : [
{
"Signer" : {
"Account" : "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW",
"SigningPubKey" : "02B3EC4E5DD96029A647CFA20DA07FE1F85296505552CCAC114087E66B46BD77DF",
"TxnSignature" : "30450221009C195DBBF7967E223D8626CA19CF02073667F2B22E206727BFE848FF42BEAC8A022048C323B0BED19A988BDBEFA974B6DE8AA9DCAE250AA82BBD1221787032A864E5"
}
}
],
"SigningPubKey" : "",
"TransactionType" : "TrustSet",
"hash" : "A94A6417D1A7AAB059822B894E13D322ED3712F7212CE9257801F96DE6C3F6AE"
}
}
}
Save the `tx_json` field of the response: it has the new signature in the `Signers` field. You can discard the value of the `tx_blob` field.
### 3. Get additional signatures ###
You can collect additional signatures in parallel or in serial:
* In parallel: Use the `sign_for` command with the original JSON for the transaction. Each response has a single signature in the `Signers` array.
* In serial: Use the `sign_for` command with the `tx_json` value from the previous `sign_for` response. Each response adds a new signature to the existing `Signers` array.
**Caution:** Never submit a secret key to a server you do not control. Do not transmit a secret key unencrypted over the network.
$ rippled sign_for rUpy3eEg8rqjqfUoLeBnZkscbKbFsKXC3v <rUpy..'s secret> '{
> "Account" : "rEuLyBCvcw4CFmzv8RepSiAoNgF8tTGJQC",
> "Fee" : "30000",
> "Flags" : 262144,
> "LimitAmount" : {
> "currency" : "USD",
> "issuer" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
> "value" : "100"
> },
> "Sequence" : 2,
> "Signers" : [
> {
> "Signer" : {
> "Account" : "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW",
> "SigningPubKey" : "02B3EC4E5DD96029A647CFA20DA07FE1F85296505552CCAC114087E66B46BD77DF",
> "TxnSignature" : "30450221009C195DBBF7967E223D8626CA19CF02073667F2B22E206727BFE848FF42BEAC8A022048C323B0BED19A988BDBEFA974B6DE8AA9DCAE250AA82BBD1221787032A864E5"
> }
> }
> ],
> "SigningPubKey" : "",
> "TransactionType" : "TrustSet",
> "hash" : "A94A6417D1A7AAB059822B894E13D322ED3712F7212CE9257801F96DE6C3F6AE"
> }'
Loading: "/home/mduo13/.config/ripple/rippled.cfg"
Connecting to 127.0.0.1:5005
{
"result" : {
"status" : "success",
"tx_blob" : "1200142200040000240000000263D5038D7EA4C680000000000000000000000000005553440000000000B5F762798A53D543A014CAF8B297CFF8F2F937E868400000000000753073008114A3780F5CB5A44D366520FC44055E8ED44D9A2270F3E010732102B3EC4E5DD96029A647CFA20DA07FE1F85296505552CCAC114087E66B46BD77DF744730450221009C195DBBF7967E223D8626CA19CF02073667F2B22E206727BFE848FF42BEAC8A022048C323B0BED19A988BDBEFA974B6DE8AA9DCAE250AA82BBD1221787032A864E58114204288D2E47F8EF6C99BCC457966320D12409711E1E0107321028FFB276505F9AC3F57E8D5242B386A597EF6C40A7999F37F1948636FD484E25B744630440220680BBD745004E9CFB6B13A137F505FB92298AD309071D16C7B982825188FD1AE022004200B1F7E4A6A84BB0E4FC09E1E3BA2B66EBD32F0E6D121A34BA3B04AD99BC181147908A7F0EDD48EA896C3580A399F0EE78611C8E3E1F1",
"tx_json" : {
"Account" : "rEuLyBCvcw4CFmzv8RepSiAoNgF8tTGJQC",
"Fee" : "30000",
"Flags" : 262144,
"LimitAmount" : {
"currency" : "USD",
"issuer" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"value" : "100"
},
"Sequence" : 2,
"Signers" : [
{
"Signer" : {
"Account" : "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW",
"SigningPubKey" : "02B3EC4E5DD96029A647CFA20DA07FE1F85296505552CCAC114087E66B46BD77DF",
"TxnSignature" : "30450221009C195DBBF7967E223D8626CA19CF02073667F2B22E206727BFE848FF42BEAC8A022048C323B0BED19A988BDBEFA974B6DE8AA9DCAE250AA82BBD1221787032A864E5"
}
},
{
"Signer" : {
"Account" : "rUpy3eEg8rqjqfUoLeBnZkscbKbFsKXC3v",
"SigningPubKey" : "028FFB276505F9AC3F57E8D5242B386A597EF6C40A7999F37F1948636FD484E25B",
"TxnSignature" : "30440220680BBD745004E9CFB6B13A137F505FB92298AD309071D16C7B982825188FD1AE022004200B1F7E4A6A84BB0E4FC09E1E3BA2B66EBD32F0E6D121A34BA3B04AD99BC1"
}
}
],
"SigningPubKey" : "",
"TransactionType" : "TrustSet",
"hash" : "BD636194C48FD7A100DE4C972336534C8E710FD008C0F3CF7BC5BF34DAF3C3E6"
}
}
}
Depending on the SignerList you configured, you may need to repeat this step several times to get signatures from all the necessary parties.
### 4. Combine signatures and submit ###
If you collected the signatures in serial, the `tx_json` from the last `sign_for` response has all the signatures assembled, so you can use that as the argument to the [`submit_multisigned` command](reference-rippled.html#submit-multisigned).
If you collected the signatures in parallel, you must manually construct a `tx_json` object with all the signatures included. Take the `Signers` arrays from all the `sign_for` responses, and combine their contents into a single `Signers` array that has each signature. Add the combined `Signers` array to the original transaction JSON value, and use that as the argument to the [`submit_multisigned` command](reference-rippled.html#submit-multisigned).
$ rippled submit_multisigned '{
> "Account" : "rEuLyBCvcw4CFmzv8RepSiAoNgF8tTGJQC",
> "Fee" : "30000",
> "Flags" : 262144,
> "LimitAmount" : {
> "currency" : "USD",
> "issuer" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
> "value" : "100"
> },
> "Sequence" : 2,
> "Signers" : [
> {
> "Signer" : {
> "Account" : "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW",
> "SigningPubKey" : "02B3EC4E5DD96029A647CFA20DA07FE1F85296505552CCAC114087E66B46BD77DF",
> "TxnSignature" : "30450221009C195DBBF7967E223D8626CA19CF02073667F2B22E206727BFE848FF42BEAC8A022048C323B0BED19A988BDBEFA974B6DE8AA9DCAE250AA82BBD1221787032A864E5"
> }
> },
> {
> "Signer" : {
> "Account" : "rUpy3eEg8rqjqfUoLeBnZkscbKbFsKXC3v",
> "SigningPubKey" : "028FFB276505F9AC3F57E8D5242B386A597EF6C40A7999F37F1948636FD484E25B",
> "TxnSignature" : "30440220680BBD745004E9CFB6B13A137F505FB92298AD309071D16C7B982825188FD1AE022004200B1F7E4A6A84BB0E4FC09E1E3BA2B66EBD32F0E6D121A34BA3B04AD99BC1"
> }
> }
> ],
> "SigningPubKey" : "",
> "TransactionType" : "TrustSet",
> "hash" : "BD636194C48FD7A100DE4C972336534C8E710FD008C0F3CF7BC5BF34DAF3C3E6"
> }'
Loading: "/home/mduo13/.config/ripple/rippled.cfg"
Connecting to 127.0.0.1:5005
{
"result": {
"engine_result": "tesSUCCESS",
"engine_result_code": 0,
"engine_result_message": "The transaction was applied. Only final in a validated ledger.",
"status": "success",
"tx_blob": "1200142200040000240000000263D5038D7EA4C680000000000000000000000000005553440000000000B5F762798A53D543A014CAF8B297CFF8F2F937E868400000000000753073008114A3780F5CB5A44D366520FC44055E8ED44D9A2270F3E010732102B3EC4E5DD96029A647CFA20DA07FE1F85296505552CCAC114087E66B46BD77DF744730450221009C195DBBF7967E223D8626CA19CF02073667F2B22E206727BFE848FF42BEAC8A022048C323B0BED19A988BDBEFA974B6DE8AA9DCAE250AA82BBD1221787032A864E58114204288D2E47F8EF6C99BCC457966320D12409711E1E0107321028FFB276505F9AC3F57E8D5242B386A597EF6C40A7999F37F1948636FD484E25B744630440220680BBD745004E9CFB6B13A137F505FB92298AD309071D16C7B982825188FD1AE022004200B1F7E4A6A84BB0E4FC09E1E3BA2B66EBD32F0E6D121A34BA3B04AD99BC181147908A7F0EDD48EA896C3580A399F0EE78611C8E3E1F1",
"tx_json": {
"Account": "rEuLyBCvcw4CFmzv8RepSiAoNgF8tTGJQC",
"Fee": "30000",
"Flags": 262144,
"LimitAmount": {
"currency": "USD",
"issuer": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"value": "100"
},
"Sequence": 2,
"Signers": [{
"Signer": {
"Account": "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW",
"SigningPubKey": "02B3EC4E5DD96029A647CFA20DA07FE1F85296505552CCAC114087E66B46BD77DF",
"TxnSignature": "30450221009C195DBBF7967E223D8626CA19CF02073667F2B22E206727BFE848FF42BEAC8A022048C323B0BED19A988BDBEFA974B6DE8AA9DCAE250AA82BBD1221787032A864E5"
}
}, {
"Signer": {
"Account": "rUpy3eEg8rqjqfUoLeBnZkscbKbFsKXC3v",
"SigningPubKey": "028FFB276505F9AC3F57E8D5242B386A597EF6C40A7999F37F1948636FD484E25B",
"TxnSignature": "30440220680BBD745004E9CFB6B13A137F505FB92298AD309071D16C7B982825188FD1AE022004200B1F7E4A6A84BB0E4FC09E1E3BA2B66EBD32F0E6D121A34BA3B04AD99BC1"
}
}],
"SigningPubKey": "",
"TransactionType": "TrustSet",
"hash": "BD636194C48FD7A100DE4C972336534C8E710FD008C0F3CF7BC5BF34DAF3C3E6"
}
}
}
Take note of the `hash` value from the response so you can check the results of the transaction later. (In this case, the hash is `BD636194C48FD7A100DE4C972336534C8E710FD008C0F3CF7BC5BF34DAF3C3E6`.)
### 5. Close the ledger ##
If you are using the live network, you can wait 4-7 seconds for the ledger to close automatically.
If you're running `rippled` in stand-alone mode, use the [`ledger_accept` command](reference-rippled.html#ledger-accept) to manually close the ledger:
$ rippled ledger_accept
Loading: "/home/mduo13/.config/ripple/rippled.cfg"
Connecting to 127.0.0.1:5005
{
"result" : {
"ledger_current_index" : 7,
"status" : "success"
}
}
### 6. Confirm transaction results ###
Use the hash value from the response to the `submit_multisigned` command to look up the transaction using the [`tx` command](reference-rippled.html#tx). In particular, check that the `TransactionResult` is the string `tesSUCCESS`.
On the live network, you must also confirm that the `validated` field is set to the boolean `true`. If the field is not `true`, you might need to wait longer for the consensus process to finish; or your transaction may be unable to be included in a ledger for some reason.
In stand-alone mode, the server automatically considers a ledger to be `validated` if it has been manually closed.
$ rippled tx BD636194C48FD7A100DE4C972336534C8E710FD008C0F3CF7BC5BF34DAF3C3E6
Loading: "/home/mduo13/.config/ripple/rippled.cfg"
Connecting to 127.0.0.1:5005
{
"result": {
"Account": "rEuLyBCvcw4CFmzv8RepSiAoNgF8tTGJQC",
"Fee": "30000",
"Flags": 262144,
"LimitAmount": {
"currency": "USD",
"issuer": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"value": "100"
},
"Sequence": 2,
"Signers": [{
"Signer": {
"Account": "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW",
"SigningPubKey": "02B3EC4E5DD96029A647CFA20DA07FE1F85296505552CCAC114087E66B46BD77DF",
"TxnSignature": "30450221009C195DBBF7967E223D8626CA19CF02073667F2B22E206727BFE848FF42BEAC8A022048C323B0BED19A988BDBEFA974B6DE8AA9DCAE250AA82BBD1221787032A864E5"
}
}, {
"Signer": {
"Account": "rUpy3eEg8rqjqfUoLeBnZkscbKbFsKXC3v",
"SigningPubKey": "028FFB276505F9AC3F57E8D5242B386A597EF6C40A7999F37F1948636FD484E25B",
"TxnSignature": "30440220680BBD745004E9CFB6B13A137F505FB92298AD309071D16C7B982825188FD1AE022004200B1F7E4A6A84BB0E4FC09E1E3BA2B66EBD32F0E6D121A34BA3B04AD99BC1"
}
}],
"SigningPubKey": "",
"TransactionType": "TrustSet",
"date": 512172510,
"hash": "BD636194C48FD7A100DE4C972336534C8E710FD008C0F3CF7BC5BF34DAF3C3E6",
"inLedger": 6,
"ledger_index": 6,
"meta": {
"AffectedNodes": [{
"ModifiedNode": {
"LedgerEntryType": "AccountRoot",
"LedgerIndex": "2B6AC232AA4C4BE41BF49D2459FA4A0347E1B543A4C92FCEE0821C0201E2E9A8",
"PreviousTxnID": "B7E1D33DB7DEA3BB65BFAB2C80E02125F47FCCF6C957A7FDECD915B3EBE0C1DD",
"PreviousTxnLgrSeq": 4
}
}, {
"CreatedNode": {
"LedgerEntryType": "RippleState",
"LedgerIndex": "93E317B32022977C77810A2C558FBB28E30E744C68E73720622B797F957EC5FA",
"NewFields": {
"Balance": {
"currency": "USD",
"issuer": "rrrrrrrrrrrrrrrrrrrrBZbvji",
"value": "0"
},
"Flags": 2162688,
"HighLimit": {
"currency": "USD",
"issuer": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"value": "0"
},
"LowLimit": {
"currency": "USD",
"issuer": "rEuLyBCvcw4CFmzv8RepSiAoNgF8tTGJQC",
"value": "100"
}
}
}
}, {
"ModifiedNode": {
"FinalFields": {
"Account": "rEuLyBCvcw4CFmzv8RepSiAoNgF8tTGJQC",
"Balance": "999960000",
"Flags": 0,
"OwnerCount": 6,
"Sequence": 3
},
"LedgerEntryType": "AccountRoot",
"LedgerIndex": "A6B1BA6F2D70813100908EA84ABB7783695050312735E2C3665259F388804EA0",
"PreviousFields": {
"Balance": "999990000",
"OwnerCount": 5,
"Sequence": 2
},
"PreviousTxnID": "8FDC18960455C196A8C4DE0D24799209A21F4A17E32102B5162BD79466B90222",
"PreviousTxnLgrSeq": 5
}
}, {
"ModifiedNode": {
"FinalFields": {
"Flags": 0,
"Owner": "rEuLyBCvcw4CFmzv8RepSiAoNgF8tTGJQC",
"RootIndex": "C2728175908D82FB1DE6676F203D8D3C056995A9FA9B369EF326523F1C65A1DE"
},
"LedgerEntryType": "DirectoryNode",
"LedgerIndex": "C2728175908D82FB1DE6676F203D8D3C056995A9FA9B369EF326523F1C65A1DE"
}
}, {
"CreatedNode": {
"LedgerEntryType": "DirectoryNode",
"LedgerIndex": "D8120FC732737A2CF2E9968FDF3797A43B457F2A81AA06D2653171A1EA635204",
"NewFields": {
"Owner": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"RootIndex": "D8120FC732737A2CF2E9968FDF3797A43B457F2A81AA06D2653171A1EA635204"
}
}
}],
"TransactionIndex": 0,
"TransactionResult": "tesSUCCESS"
},
"status": "success",
"validated": true
}
}

View File

@@ -46,6 +46,7 @@
<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-reliable-transaction-submission.html">Reliable Transaction Submission</a></li>
<li><a href="tutorial-multisign.html">Multi-Signing Transactions</a></li>
</ul>
</li>
<li class="dropdown">
@@ -58,6 +59,8 @@
<li><a href="concept-fee-voting.html">Fee Voting</a></li>
<li><a href="concept-reserves.html">Reserves</a></li>
<li><a href="concept-freeze.html">Freeze</a></li>
<li><a href="concept-amendments.html">Amendments</a></li>
<li><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
</ul>
</li>
<li class="dropdown">

View File

@@ -53,6 +53,7 @@
<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-reliable-transaction-submission.html">Reliable Transaction Submission</a></li>
<li><a href="tutorial-multisign.html">Multi-Signing Transactions</a></li>
</ul>
</li>
<li class="dropdown">
@@ -65,6 +66,8 @@
<li><a href="concept-fee-voting.html">Fee Voting</a></li>
<li><a href="concept-reserves.html">Reserves</a></li>
<li><a href="concept-freeze.html">Freeze</a></li>
<li><a href="concept-amendments.html">Amendments</a></li>
<li><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
</ul>
</li>
<li class="dropdown">
@@ -137,6 +140,7 @@ Ripples distributed settlement network is built on open-source technology tha
<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-reliable-transaction-submission.html">Reliable Transaction Submission</a></li>
<li><a href="tutorial-multisign.html">Multi-Signing Transactions</a></li>
</ul>
</div>
<div class="col-md-3">
@@ -149,6 +153,8 @@ Ripples distributed settlement network is built on open-source technology tha
<li><a href="concept-fee-voting.html">Fee Voting</a></li>
<li><a href="concept-reserves.html">Reserves</a></li>
<li><a href="concept-freeze.html">Freeze</a></li>
<li><a href="concept-amendments.html">Amendments</a></li>
<li><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
</ul>
</div>
<div class="col-md-3">

View File

@@ -60,6 +60,7 @@
<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-reliable-transaction-submission.html">Reliable Transaction Submission</a></li>
<li><a href="tutorial-multisign.html">Multi-Signing Transactions</a></li>
</ul>
</li>
<li class="dropdown">
@@ -72,6 +73,8 @@
<li><a href="concept-fee-voting.html">Fee Voting</a></li>
<li><a href="concept-reserves.html">Reserves</a></li>
<li><a href="concept-freeze.html">Freeze</a></li>
<li><a href="concept-amendments.html">Amendments</a></li>
<li><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
</ul>
</li>
<li class="dropdown">

View File

@@ -60,6 +60,7 @@
<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-reliable-transaction-submission.html">Reliable Transaction Submission</a></li>
<li><a href="tutorial-multisign.html">Multi-Signing Transactions</a></li>
</ul>
</li>
<li class="dropdown">
@@ -72,6 +73,8 @@
<li><a href="concept-fee-voting.html">Fee Voting</a></li>
<li><a href="concept-reserves.html">Reserves</a></li>
<li><a href="concept-freeze.html">Freeze</a></li>
<li><a href="concept-amendments.html">Amendments</a></li>
<li><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
</ul>
</li>
<li class="dropdown">
@@ -127,16 +130,16 @@
<h1 id="the-ledger">The Ledger</h1>
<p>The point of the Ripple software is to maintain a shared, global ledger that is open to all, so that individual participants can trust the integrity of the ledger without having to trust any single institution to manage it. The <code>rippled</code> server software accomplishes this by maintaining a ledger database that can only be updated according to very specific rules. Each instance of <code>rippled</code> maintains a full copy of the ledger, and the peer-to-peer network of <code>rippled</code> servers distributes candidate transactions among themselves. The consensus process determines which transactions get applied to each new version of the ledger. See also: <a href="https://ripple.com/knowledge_center/the-ripple-ledger-consensus-process/">The Consensus Process</a>.</p>
<p><img alt="Diagram: Each ledger is the result of applying transactions to the previous ledger version." src="img/ledger-process.png"/></p>
<p>The shared global ledger is actually a series of individual ledgers, or ledger versions, which <code>rippled</code> keeps in its internal database. Every ledger version has a sequence number (also called a ledger index), starting at 1 and incrementing with each new version. Every closed ledger also has an identifying hash value, which uniquely identifies the contents of that ledger. At any given time, a <code>rippled</code> instance has an in-progress "current" open ledger, plus some number of closed ledgers that have not yet been approved by consensus, and any number of historical ledgers that have been validated by consensus. Only the validated ledgers are certain to be accurate and immutable.</p>
<p>The shared global ledger is actually a series of individual ledgers, or ledger versions, which <code>rippled</code> keeps in its internal database. Every ledger version has a <a href="#ledger-index">ledger index</a> which identifies the order in which ledgers occur. Each closed ledger version also has an identifying hash value, which uniquely identifies the contents of that ledger. At any given time, a <code>rippled</code> instance has an in-progress "current" open ledger, plus some number of closed ledgers that have not yet been approved by consensus, and any number of historical ledgers that have been validated by consensus. Only the validated ledgers are certain to be accurate and immutable.</p>
<p>A single ledger version consists of several components:</p>
<p><img alt="Diagram: A ledger has transactions, a state node, and a header with the close time and validation info" src="img/ledger-components.png"/></p>
<ul>
<li>A <strong>header</strong> - The ledger's unique index (sequence number), hashes of the other contents, and other metadata.</li>
<li>A <strong>header</strong> - The <a href="#ledger-index">ledger index</a>, hashes of its other contents, and other metadata.</li>
<li>A <strong>transaction tree</strong> - The <a href="reference-transaction-format.html">transactions</a> that were applied to the previous ledger to make this one. Transactions are the <em>only</em> way to modify the ledger.</li>
<li>A <strong>state tree</strong> - All the <a href="#ledger-node-types">ledger nodes</a> that contain the settings, balances, and objects in the ledger as of this version.</li>
</ul>
<h2 id="tree-format">Tree Format</h2>
<p>As its name might suggest, a ledger's state tree is a tree data structure, with each node identified by a 256-bit value called an <code>index</code>. In JSON, a ledger node's index value is represented as a 64-character hexadecimal string like <code>"193C591BF62482468422313F9D3274B5927CA80B4DD3707E42015DD609E39C94"</code>. Every node in the state tree has an index that you can use as a key to look up the node in the state tree; every transaction has an indentifying hash that you can use to look up the transaction in the transaction tree. Do not confuse the <code>index</code> (key) of a ledger node with the <code>ledger_index</code> (sequence number) of a ledger.</p>
<p>As its name might suggest, a ledger's state tree is a tree data structure, with each node identified by a 256-bit value called an <code>index</code>. In JSON, a ledger node's index value is represented as a 64-character hexadecimal string like <code>"193C591BF62482468422313F9D3274B5927CA80B4DD3707E42015DD609E39C94"</code>. Every node in the state tree has an index that you can use as a key to look up the node in the state tree; every transaction has an indentifying hash that you can use to look up the transaction in the transaction tree. Do not confuse the <code>index</code> (key) of a ledger node with the <a href="#ledger-index"><code>ledger_index</code> (sequence number) of a ledger</a>.</p>
<p>In the case of transactions, the identifying hash is based on the signed transaction instructions, but the contents of the transaction object when you look it up also contain the results and metadata of the transaction, which are not taken into account when generating the hash.</p>
<p>In the case of state nodes, <code>rippled</code> usually includes the <code>index</code> of the node along with its contents. However, the index itself is not part of the contents. The index is derived by hashing important contents of the node, along with a <a href="https://github.com/ripple/rippled/blob/ceff6bc2713eaf80feafe56a02f4d636827b89a9/src/ripple/protocol/LedgerFormats.h#L94">namespace identifier</a>. The ledger node type determines which namespace identifier to use as well as which contents to include in the hash. This ensures every index is unique. For a hash function, <code>rippled</code> uses SHA-512 and then truncates the result to the first 256 bytes. This algorithm, informally called SHA-512Half, provides an output that has comparable security to SHA-256, but runs faster on 64-bit processors.</p>
<p><img alt="Diagram: rippled uses SHA-512Half to generate indexes for ledger nodes. The space key prevents indexes for different node types from colliding." src="img/ledger-indexes.png"/></p>
@@ -154,7 +157,7 @@
</thead>
<tbody>
<tr>
<td>ledger_index</td>
<td><a href="#ledger-index">ledger_index</a></td>
<td>String</td>
<td>UInt32</td>
<td>The sequence number of the ledger. Some API methods display this as a quoted integer; some display it as a native JSON number.</td>
@@ -187,7 +190,7 @@
<td>parent_hash</td>
<td>String</td>
<td>Hash256</td>
<td>The <code>ledger_hash</code> value of the previous ledger that was used to build this one. If there are different versions of the previous ledger by sequence number, this indicates from which one the ledger was derived.</td>
<td>The <code>ledger_hash</code> value of the previous ledger that was used to build this one. If there are different versions of the previous ledger index, this indicates from which one the ledger was derived.</td>
</tr>
<tr>
<td>total_coins</td>
@@ -208,13 +211,21 @@
<td>An integer in the range [2,120] indicating the maximum number of seconds by which the <code>close_time</code> could be rounded.</td>
</tr>
<tr>
<td>closeFlags</td>
<td><a href="#close-flags">closeFlags</a></td>
<td>(Omitted)</td>
<td>UInt8</td>
<td>A bit-map of flags relating to the closing of this ledger.</td>
</tr>
</tbody>
</table>
<h3 id="ledger-index">Ledger Index</h3>
<p>A ledger index is a 32-bit unsigned integer used to identify a ledger. The ledger index is also known as the ledger's sequence number. The very first ledger was ledger index 1, and each subsequent ledger has a ledger index 1 higher than that of the ledger immediately before it.</p>
<p>The ledger index indicates the order of the ledgers; the <a href="reference-rippled.html#hashes">Hash</a> value identifies the exact contents of the ledger. Two ledgers with the same hash are always identical. For validated ledgers, hash values and sequence numbers are equally valid and correlate 1:1. However, this is not true for in-progress ledgers:</p>
<ul>
<li>Two different <code>rippled</code> servers may have different contents for a current ledger with the same ledger index, due to latency in propagating transactions throughout the network.</li>
<li>There may be multiple closed ledger versions competing to be validated by consensus. These ledger versions have the same sequence number but different contents (and different hashes). Only one of these closed ledgers can become validated.</li>
<li>A current ledger's contents change over time, which would cause its hash to change, even though its ledger index number stays the same. Therefore, the hash of a ledger is not calculated until the ledger is closed.</li>
</ul>
<h3 id="close-flags">Close Flags</h3>
<p>Currently, the ledger has only one flag defined for closeFlags: <strong>sLCF_NoConsensusTime</strong> (value <code>1</code>). If this flag is enabled, it means that validators were in conflict regarding the correct close time for the ledger, but built otherwise the same ledger, so they declared consensus while "agreeing to disagree" on the close time. In this case, the consensus ledger contains a <code>close_time</code> value that is 1 second after that of the previous ledger. (In this case, there is no official close time, but the actual real-world close time is probably 3-6 seconds later than the specified <code>close_time</code>.)</p>
<p>The <code>closeFlags</code> field is not included in any JSON representations of a ledger, but it is a part of the binary representation of a ledger, and is one of the fields that determine the ledger's hash.</p>
@@ -304,7 +315,7 @@
<td>PreviousTxnLgrSeq</td>
<td>Number</td>
<td>UInt32</td>
<td>The sequence number (<code>ledger_index</code>) of the ledger that contains the transaction that most recently modified this node.</td>
<td>The <a href="#ledger-index">index of the ledger</a> that contains the transaction that most recently modified this node.</td>
</tr>
<tr>
<td>AccountTxnID</td>
@@ -428,7 +439,7 @@
</tr>
</tbody>
</table>
<h3 id="accountroot-index-format">AccountRoot index format</h3>
<h3 id="accountroot-index-format">AccountRoot Index Format</h3>
<p>The <code>index</code> of an AccountRoot node is the SHA-512Half of the following values put together:</p>
<ul>
<li>The Account space key (<code>a</code>)</li>
@@ -558,7 +569,7 @@
</tr>
</tbody>
</table>
<h3 id="directory-index-formats">Directory index formats</h3>
<h3 id="directory-index-formats">Directory Index Formats</h3>
<p>There are three different formulas for creating the index of a DirectoryNode, depending on whether the DirectoryNode represents:</p>
<ul>
<li>The first page (also called the root) of an Owner Directory,</li>
@@ -684,7 +695,7 @@
<td>PreviousTxnLgrSeq</td>
<td>Number</td>
<td>UInt32</td>
<td>The sequence number (<code>ledger_index</code>) of the ledger that contains the transaction that most recently modified this node.</td>
<td>The <a href="#ledger-index">index of the ledger</a> that contains the transaction that most recently modified this node.</td>
</tr>
<tr>
<td>Expiration</td>
@@ -724,7 +735,7 @@
</tr>
</tbody>
</table>
<h3 id="offer-index-format">Offer index format</h3>
<h3 id="offer-index-format">Offer Index Format</h3>
<p>The <code>index</code> of an Offer node is the SHA-512Half of the following values put together:</p>
<ul>
<li>The Offer space key (<code>o</code>)</li>
@@ -812,7 +823,7 @@
<td>PreviousTxnLgrSeq</td>
<td>Number</td>
<td>UInt32</td>
<td>The sequence number (<code>ledger_index</code>) of the ledger that contains the transaction that most recently modified this node.</td>
<td>The <a href="#ledger-index">index of the ledger</a> that contains the transaction that most recently modified this node.</td>
</tr>
<tr>
<td>LowNode</td>
@@ -964,7 +975,7 @@
<p>The <strong>lsfLowAuth</strong> and <strong>lsfHighAuth</strong> flags do not count against the default state, because they cannot be disabled.</p>
<p>The default state of the two NoRipple flags depends on the state of the <a href="#accountroot-flags">lsfDefaultRipple flag</a> in their corresponding AccountRoot nodes. If DefaultRipple is disabled (the default), then the default state of the lsfNoRipple flag is <em>enabled</em> for all of an account's trust lines. If an account enables DefaultRipple, then the lsfNoRipple flag is <em>disabled</em> (rippling is enabled) for an account's trust lines by default. <strong>Note:</strong> Prior to the introduction of the DefaultRipple flags in <code>rippled</code> version 0.27.3 (March 10, 2015), the default state for all trust lines was with lsfNoRipple disabled (rippling enabled).</p>
<p>Fortunately, <code>rippled</code> uses lazy evaluation to calculate the owner reserve. This means that even if an account changes the default state of all its trust lines by changing the DefaultRipple flag, that account's reserve stays the same initially. If an account modifies a trust line, <code>rippled</code> re-evaluates whether that individual trust line is in its default state and should contribute the owner reserve.</p>
<h3 id="ripplestate-index-format">RippleState index format</h3>
<h3 id="ripplestate-index-format">RippleState Index Format</h3>
<p>The <code>index</code> of a RippleState node is the SHA-512Half of the following values put together:</p>
<ul>
<li>The RippleState space key (<code>r</code>)</li>
@@ -972,6 +983,120 @@
<li>The AccountID of the high account</li>
<li>The 160-bit currency code of the trust line(s)</li>
</ul>
<h2 id="signerlist">SignerList</h2>
<p><a href="https://github.com/ripple/rippled/blob/6d2e3da30696bd10e3bb11a5ff6d45d2c4dae90f/src/ripple/protocol/impl/LedgerFormats.cpp#L127" title="Source">[Source]<br/></a></p>
<p>The <code>SignerList</code> node type represents a list of parties that, as a group, are authorized to sign a transaction in place of an individual account. You can create, replace, or remove a SignerList using the <a href="reference-transaction-format.html#signerlistset">SignerListSet transaction type</a> This node type is introduced by the <a href="concept-amendments.html#multisign">MultiSign amendment</a>. <em>(New in [version 0.31.0][])</em></p>
<p>Example SignerList node:</p>
<pre><code>{
"Flags": 0,
"LedgerEntryType": "SignerList",
"OwnerNode": "0000000000000000",
"PreviousTxnID": "5904C0DC72C58A83AEFED2FFC5386356AA83FCA6A88C89D00646E51E687CDBE4",
"PreviousTxnLgrSeq": 16061435,
"SignerEntries": [
{
"SignerEntry": {
"Account": "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW",
"SignerWeight": 2
}
},
{
"SignerEntry": {
"Account": "raKEEVSGnKSD9Zyvxu4z6Pqpm4ABH8FS6n",
"SignerWeight": 1
}
},
{
"SignerEntry": {
"Account": "rUpy3eEg8rqjqfUoLeBnZkscbKbFsKXC3v",
"SignerWeight": 1
}
}
],
"SignerListID": 0,
"SignerQuorum": 3,
"index": "A9C28A28B85CD533217F5C0A0C7767666B093FA58A0F2D80026FCC4CD932DDC7"
}
</code></pre>
<p>A SignerList node has the following fields:</p>
<table>
<thead>
<tr>
<th>Name</th>
<th>JSON Type</th>
<th>Internal Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>OwnerNode</td>
<td>String</td>
<td>UInt64</td>
<td>A hint indicating which page of the owner directory links to this node, in case the directory consists of multiple nodes.</td>
</tr>
<tr>
<td>SignerQuorum</td>
<td>Number</td>
<td>UInt32</td>
<td>A target number for signer weights. To produce a valid signature for the owner of this SignerList, the signers must provide valid signatures whose weights sum to this value or more.</td>
</tr>
<tr>
<td>SignerEntries</td>
<td>Array</td>
<td>Array</td>
<td>An array of SignerEntry objects representing the parties who are part of this signer list.</td>
</tr>
<tr>
<td>SignerListID</td>
<td>Number</td>
<td>UInt32</td>
<td>An ID for this signer list. Currently always set to <code>0</code>. If a future <a href="concept-amendments.html">amendment</a> allows multiple signer lists for an account, this may change.</td>
</tr>
<tr>
<td>PreviousTxnID</td>
<td>String</td>
<td>Hash256</td>
<td>The identifying hash of the transaction that most recently modified this node.</td>
</tr>
<tr>
<td>PreviousTxnLgrSeq</td>
<td>Number</td>
<td>UInt32</td>
<td>The <a href="#ledger-index">index of the ledger</a> that contains the transaction that most recently modified this node.</td>
</tr>
</tbody>
</table>
<p>The <code>SignerEntries</code> may be any combination of funded and unfunded addresses that use either secp256k1 or ed25519 keys.</p>
<h3 id="signerentry-object">SignerEntry Object</h3>
<p>Each member of the <code>SignerEntries</code> field is an object that describes that signer in the list. A SignerEntry has the following fields:</p>
<table>
<thead>
<tr>
<th>Name</th>
<th>JSON Type</th>
<th>Internal Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>Account</td>
<td>String</td>
<td>AccountID</td>
<td>A Ripple address whose signature contributes to the multi-signature. It does not need to be a funded address in the ledger.</td>
</tr>
<tr>
<td>SignerWeight</td>
<td>Number</td>
<td>UInt16</td>
<td>The weight of a signature from this signer. A multi-signature is only valid if the sum weight of the signatures provided meets or exceeds the SignerList's <code>SignerQuorum</code> value.</td>
</tr>
</tbody>
</table>
<p>When processing a multi-signed transaction, the server dereferences the <code>Account</code> values with respect to the ledger at the time of transaction execution. If the address <em>does not</em> correspond to a funded <a href="#accountroot">AccountRoot node</a>, then only the master secret associated with that address can be used to produce a valid signature. If the account <em>does</em> exist in the ledger, then it depends on the state of that account. If the account has a Regular Key configured, the Regular Key can be used. The account's master key can only be used if it is not disabled. A multi-signature cannot be used as a component of another multi-signature.</p>
<h3 id="signerlists-and-reserves">SignerLists and Reserves</h3>
<p>A SignerList contributes to its owner's <a href="concept-reserves.html">reserve requirement</a>. The SignerList itself counts as two objects, and each member of the list counts as one. As a result, the total owner reserve associated with a SignerList is anywhere from 3 times to 10 times the reserve required by a single trust line (<a href="#ripplestate">RippleState</a>) or <a href="#offer">Offer</a> node in the ledger.</p>
</div>
</main>
</div>

View File

@@ -60,6 +60,7 @@
<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-reliable-transaction-submission.html">Reliable Transaction Submission</a></li>
<li><a href="tutorial-multisign.html">Multi-Signing Transactions</a></li>
</ul>
</li>
<li class="dropdown">
@@ -72,6 +73,8 @@
<li><a href="concept-fee-voting.html">Fee Voting</a></li>
<li><a href="concept-reserves.html">Reserves</a></li>
<li><a href="concept-freeze.html">Freeze</a></li>
<li><a href="concept-amendments.html">Amendments</a></li>
<li><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
</ul>
</li>
<li class="dropdown">

File diff suppressed because it is too large Load Diff

View File

@@ -60,6 +60,7 @@
<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-reliable-transaction-submission.html">Reliable Transaction Submission</a></li>
<li><a href="tutorial-multisign.html">Multi-Signing Transactions</a></li>
</ul>
</li>
<li class="dropdown">
@@ -72,6 +73,8 @@
<li><a href="concept-fee-voting.html">Fee Voting</a></li>
<li><a href="concept-reserves.html">Reserves</a></li>
<li><a href="concept-freeze.html">Freeze</a></li>
<li><a href="concept-amendments.html">Amendments</a></li>
<li><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
</ul>
</li>
<li class="dropdown">
@@ -137,23 +140,46 @@
<li><a href="#offercreate">OfferCreate - Submit an order to exchange currency</a></li>
<li><a href="#offercancel">OfferCancel - Withdraw a currency-exchange order</a></li>
<li><a href="#trustset">TrustSet - Add or modify a trust line</a></li>
<li><a href="#signerlistset">SignerListSet - Set multi-signing settings</a></li>
</ul>
<p>Additionally, there are <em>Psuedo-Transactions</em> that are not created and submitted in the usual way, but may appear in ledgers:</p>
<p>Additionally, there are <em>Pseudo-Transactions</em> that are not created and submitted in the usual way, but may appear in ledgers:</p>
<ul>
<li><a href="#setfee">SetFee - Adjust the minimum transaction cost or account reserve</a></li>
<li><a href="#enableamendment">EnableAmendment - Apply a change to transaction processing</a></li>
</ul>
<p>Transactions are only valid if signed, submitted, and accepted into a validated ledger version. There are many ways a transaction can fail.</p>
<ul>
<li><a href="#signing-and-sending-transactions">Signing and Sending Transactions</a></li>
<li><a href="#authorizing-transactions">Authorized Transactions</a></li>
<li><a href="#reliable-transaction-submission">Reliable Transaction Submission</a></li>
<li><a href="#transaction-results">Transaction Results - How to find and interpret transaction results</a></li>
<li><a href="#full-transaction-response-list">Full Transaction Response List - Complete table of all error codes</a></li>
</ul>
<h2 id="signing-and-sending-transactions">Signing and Sending Transactions</h2>
<p>Signing a transaction cryptographically proves that the person in charge of the account sending the transaction is authorized to do so. Only signed transactions can be submitted to the network and included in a validated ledger. A signed transaction is immutable: its contents cannot change, and the signature is not valid for any other transaction.</p>
<p>You can sign a transaction using a secret key: either the master secret, or a regular secret if the account has a regular key pair associated with it. (See <a href="#setregularkey">SetRegularKey</a> for details.)</p>
<p>Multi-signature transactions are <a href="https://wiki.ripple.com/Multisign">in development</a>.</p>
<p>Typically, you create a transaction in JSON format first. Here is an example of an unsigned Payment-type transaction in JSON:</p>
<h2 id="authorizing-transactions">Authorizing Transactions</h2>
<p>In the decentralized Ripple Consensus Ledger, a digital signature proves that a transaction is authorized to perform a specific set of actions. Only signed transactions can be submitted to the network and included in a validated ledger. A signed transaction is immutable: its contents cannot change, and the signature is not valid for any other transaction.</p>
<p>A transaction can be authorized by any of the following types of signatures:</p>
<ul>
<li>A single signature from the master secret key that is mathematically associated with the sending address. You can disable or enable the master key using an <a href="#accountset">AccountSet transaction</a>.</li>
<li>A single signature that matches a regular key associated with the address. You can add, remove, or replace a regular key using a <a href="#setregularkey">SetRegularKey transaction</a>.</li>
<li>A <a href="#multi-signing">multi-signature</a> that matches a list of signers owned by the address. You can add, remove, or replace a list of signers using a <a href="#signerlistset">SignerListSet transaction</a>.</li>
</ul>
<p>Any signature type can authorize any type of transaction, with the following exceptions:</p>
<ul>
<li>Only the master key can <a href="#accountset-flags">disable the master key</a>.</li>
<li>Only the master key can <a href="concept-freeze.html#no-freeze">permanently give up the ability to freeze</a>.</li>
<li>You can never remove the last method of signing transactions from an address.</li>
</ul>
<h2 id="signing-and-submitting-transactions">Signing and Submitting Transactions</h2>
<p>Sending a transaction to the Ripple Consensus Ledger involves several steps:</p>
<ol>
<li>Create an <a href="#unsigned-transaction-format">unsigned transaction in JSON format</a>.</li>
<li>Use one or more signatures to <a href="#authorizing-transactions">authorize the transaction</a>.</li>
<li>Submit a transaction to a <code>rippled</code> server. If the transaction is properly formed, the server provisionally applies the transaction to its current version of the ledger and relays the transaction to other members of the peer-to-peer network.</li>
<li>The <a href="https://ripple.com/knowledge_center/the-ripple-ledger-consensus-process/">consensus process</a> determines which provisional transactions get included in the next validated ledger.</li>
<li>The <code>rippled</code> servers apply those transactions to the previous ledger in a canonical order and share their results.</li>
<li>If enough <a href="tutorial-rippled-setup.html#reasons-to-run-a-validator">trusted validators</a> created the exact same ledger, that ledger is declared <em>validated</em> and the <a href="#transaction-results">results of the transactions</a> in that ledger are immutable.</li>
</ol>
<h3 id="unsigned-transaction-format">Unsigned Transaction Format</h3>
<p>Here is an example of an unsigned <a href="#payment">Payment-type transaction</a> in JSON:</p>
<pre><code>{
"TransactionType" : "Payment",
"Account" : "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
@@ -168,13 +194,13 @@
"Sequence": 2,
}
</code></pre>
<p>After doing that, you generate the signed binary format for the transaction. There are two ways to do this:</p>
<p>The Ripple Consensus Ledger only relays and executes a transaction if the transaction object has been authorized by the sending address (in the <code>Account</code>) field. For transactions authorized by only a single signature, you have two options:</p>
<ol>
<li>Convert it to a binary blob and sign it offline. This is preferable, since it means that the account secret used for signing the transaction is never transmitted over any network connection.<ul>
<li>You can use <a href="reference-rippleapi.html#sign">RippleAPI</a> to perform offline signing.</li>
</ul>
</li>
<li>Have a <code>rippled</code> server sign the transaction for you. The <a href="reference-rippled.html#sign">sign command</a> takes a JSON-format transaction and secret and returns the signed binary transaction format ready for submission. (Transmitting your account secret is dangerous, so you should only do this from within a trusted and encrypted sub-net, to a server you control.)<ul>
<li>Have a <code>rippled</code> server sign the transaction for you. The <a href="reference-rippled.html#sign">sign command</a> takes a JSON-format transaction and secret and returns the signed binary transaction format ready for submission. (Transmitting your account secret is dangerous, so you should only do this from within a trusted and encrypted connection, or through a local connection, and only to a server you control.)<ul>
<li>As a shortcut, you can use the <a href="reference-rippled.html#submit">submit command</a> with a <code>tx_json</code> object to sign and submit a transaction all at once. This is only recommended for testing and development purposes.</li>
</ul>
</li>
@@ -186,7 +212,9 @@
"tx_blob" : "120000240000000461D4838D7EA4C6800000000000000000000000000055534400000000004B4E9C06F24296074F7BC48F92A97916C6DC5EA968400000000000000F732103AB40A0490F9B7ED8DF29D246BF2D6269820A0EE7742ACDD457BEA7C7D0931EDB74483046022100982064CDD3F052D22788DB30B52EEA8956A32A51375E72274E417328EBA31E480221008F522C9DB4B0F31E695AA013843958A10DE8F6BA7D6759BEE645F71A7EB240BE81144B4E9C06F24296074F7BC48F92A97916C6DC5EA983143E9D4A2B8AA0780F682D136F7A56D6724EF53754"
}
</code></pre>
<p>After a transaction has been submitted, if it gets accepted into a validated ledger, you can view the final transaction using the API. For example, here is what the WebSocket API <a href="reference-rippled.html#tx">tx command</a> shows for the same transaction. The field names that begin with capital letters are part of the ledger object; the fields that begin with lower-case letters are additional information generated by the server for the request:</p>
<p>After a transaction has been submitted, you can check its status using the API, for example using the <a href="reference-rippled.html#tx">tx command</a>.</p>
<p><strong>Caution:</strong> The success of a transaction is not final unless the transaction appears in a <strong>validated</strong> ledger with the result code <code>tesSUCCESS</code>. See also: <a href="#finality-of-results">Finality of Results</a>.</p>
<p>Example response from the <code>tx</code> command:</p>
<pre><code>{
"id": 6,
"status": "success",
@@ -273,6 +301,21 @@
}
}
</code></pre>
<h3 id="multi-signing">Multi-Signing</h3>
<p>Multi-signing in Ripple is the act of <a href="#authorizing-transactions">authorizing transactions</a> for the Ripple Consensus Ledger by using a combination of multiple secret keys. Multi-signing is due to be enabled by an <a href="concept-amendments.html">Amendment</a> to the Ripple Consensus Protocol. You can have any combination of authorization methods enabled for your address, including multi-signing, a master key, and a <a href="#setregularkey">regular key</a>. (The only requirement is that <em>at least one</em> method must be enabled.)</p>
<p>The <a href="#signerlistset">SignerListSet transaction</a> defines which addresses can authorize transactions from your address. You can include up to 8 addresses in a SignerList. You can control how many signatures are needed, in which combinations, by using the quorum and weight values of the SignerList.</p>
<p>To successfully submit a multi-signed transaction, you must do all of the following:</p>
<ul>
<li>The address sending the transaction (specified in the <code>Account</code> field) must own a <a href="reference-ledger-format.html#signerlist"><code>SignerList</code> in the ledger</a>.</li>
<li>The transaction must include the <code>SigningPubKey</code> field as an empty string.</li>
<li>The transaction must include a <a href="#signers-field"><code>Signers</code> field</a> containing an array of signatures.</li>
<li>The signatures present in the <code>Signers</code> array must match signers defined in the SignerList.</li>
<li>For the provided signatures, the total <code>weight</code> associated with those signers must be equal or greater than the <code>quorum</code> for the SignerList.</li>
<li>The <a href="concept-transaction-cost.html">transaction cost</a> (specified in the <code>Fee</code> field) must be at least (N+1) times the normal transaction cost, where N is the number of signatures provided.</li>
<li>All fields of the transaction must be defined before collecting signatures. You cannot <a href="#auto-fillable-fields">auto-fill</a> any fields.</li>
<li>If presented in binary form, the <code>Signers</code> array must be sorted based on the numeric value of the signer addresses, with the lowest value first. (If submitted as JSON, the <a href="reference-rippled.html#submit-multisigned"><code>submit_multisigned</code> command</a> handles this automatically.)</li>
</ul>
<p>For more information, see <a href="tutorial-multisign.html">How to Multi-Sign</a>.</p>
<h3 id="reliable-transaction-submission">Reliable Transaction Submission</h3>
<p>Reliably submitting transactions is the process of achieving both of the following:</p>
<ul>
@@ -284,7 +327,7 @@
<li>Construct and sign the transaction first, including a <a href="#lastledgersequence"><code>LastLedgerSequence</code></a> parameter that gives the transaction a limited viable lifespan.</li>
<li>Persist details of the transaction before submitting.</li>
<li>Submit the transaction.</li>
<li>Confirm that the transaction was either included in a validated ledger, or that it has expired due to <code>LastLedgerSequence</code>. </li>
<li>Confirm that the transaction was either included in a validated ledger, or that it has expired due to <code>LastLedgerSequence</code>.</li>
<li>If a transaction fails or expires, you can modify and resubmit it.</li>
</ol>
<p>Main article: <a href="tutorial-reliable-transaction-submission.html">Reliable Transaction Submission</a></p>
@@ -349,7 +392,13 @@
<td>SigningPubKey</td>
<td>String</td>
<td>PubKey</td>
<td>(Automatically added when signing) Hex representation of the public key that corresponds to the private key used to sign this transaction.</td>
<td>(Automatically added when signing) Hex representation of the public key that corresponds to the private key used to sign this transaction. If an empty string, indicates a multi-signature is present in the <code>Signers</code> field instead.</td>
</tr>
<tr>
<td><a href="#signers-field">Signers</a></td>
<td>Array</td>
<td>Array</td>
<td>(Optional) Array of objects that represent a <a href="#multi-signing">multi-signature</a> which authorizes this transaction.</td>
</tr>
<tr>
<td>SourceTag</td>
@@ -361,7 +410,7 @@
<td>TransactionType</td>
<td>String</td>
<td>UInt16</td>
<td>The type of transaction. Valid types include: <code>Payment</code>, <code>OfferCreate</code>, <code>OfferCancel</code>, <code>TrustSet</code>, <code>AccountSet</code>, and <code>SetRegularKey</code>.</td>
<td>The type of transaction. Valid types include: <code>Payment</code>, <code>OfferCreate</code>, <code>OfferCancel</code>, <code>TrustSet</code>, <code>AccountSet</code>, <code>SetRegularKey</code>, and <code>SignerListSet</code>.</td>
</tr>
<tr>
<td>TxnSignature</td>
@@ -379,10 +428,11 @@
<li><code>Sequence</code> - Automatically use the next sequence number for the account sending the transaction.</li>
</ul>
<p>For a production system, we recommend <em>not</em> leaving these fields to be filled by the server. For example, if transaction costs become high due to a temporary spike in network load, you may want to wait for the cost to decrease before sending some transactions, instead of paying the temporarily-high cost.</p>
<p>The <a href="#paths"><code>Paths</code> field</a> of the <a href="#payment">Payment</a> transaction type can also be automatically filled in. </p>
<p>The <a href="#paths"><code>Paths</code> field</a> of the <a href="#payment">Payment</a> transaction type can also be automatically filled in.</p>
<h3 id="transaction-cost">Transaction Cost</h3>
<p>In order to protect the Ripple Consensus Ledger from being disrupted by spam and denial-of-service attacks, each transaction must destroy a small amount of XRP. This transaction cost is designed to increase along with the load on the network, making it very expensive to deliberately or inadvertently overload the network.</p>
<p>The <code>Fee</code> field specifies an amount, in <a href="reference-rippled.html#specifying-currency-amounts">drops of XRP</a>, to destroy as the cost for this transaction. If the transaction is included in a validated leger (whether or not it achieves its intended purpose), then the amount of XRP specified in the <code>Fee</code> parameter is destroyed forever. You can <a href="concept-transaction-cost.html#querying-the-transaction-cost">look up the transaction cost</a> in advance, or <a href="concept-transaction-cost.html#automatically-specifying-the-transaction-cost">let <code>rippled</code> set it automatically</a> when you sign a transaction.</p>
<p>In order to protect the Ripple Consensus Ledger from being disrupted by spam and denial-of-service attacks, each transaction must destroy a small amount of XRP. This <em><a href="concept-transaction-cost.html">transaction cost</a></em> is designed to increase along with the load on the network, making it very expensive to deliberately or inadvertently overload the network.</p>
<p>The <code>Fee</code> field specifies an amount, in <a href="reference-rippled.html#specifying-currency-amounts">drops of XRP</a>, to destroy as the cost for relaying this transaction. If the transaction is included in a validated ledger (whether or not it achieves its intended purpose), then the amount of XRP specified in the <code>Fee</code> parameter is destroyed forever. You can <a href="concept-transaction-cost.html#querying-the-transaction-cost">look up the transaction cost</a> in advance, or <a href="concept-transaction-cost.html#automatically-specifying-the-transaction-cost">let <code>rippled</code> set it automatically</a> when you sign a transaction.</p>
<p><strong>Note:</strong> <a href="#multi-signing">Multi-signed transactions</a> require additional fees to relay to the network.</p>
<h3 id="canceling-or-skipping-a-transaction">Canceling or Skipping a Transaction</h3>
<p>An important and intentional feature of the Ripple Network is that a transaction is final as soon as it has been incorporated in a validated ledger.</p>
<p>However, if a transaction has not yet been included in a validated ledger, you can effectively cancel it by rendering it invalid. Typically, this means sending another transaction with the same <code>Sequence</code> value from the same account. If you do not want to perform the same transaction again, you can perform an <a href="#accountset">AccountSet</a> transaction with no options.</p>
@@ -397,7 +447,7 @@
<p>One situation in which this is useful is if you have a primary system for submitting transactions and a passive backup system. If the passive backup system becomes disconnected from the primary, but the primary is not fully dead, and they both begin operating at the same time, you could potentially encounter serious problems like some transactions sending twice and others not at all. Chaining your transactions together with <code>AccountTxnID</code> ensures that, even if both systems are active, only one of them can submit valid transactions at a time.</p>
<p>In order to use AccountTxnID, you must first set the <a href="#accountset-flags">asfAccountTxnID</a> flag, so that the ledger keeps track of the ID for the account's previous transaction.</p>
<h3 id="memos">Memos</h3>
<p>The Memos field allows for arbitrary messaging data that can accompany the transaction. It is presented as an array of objects. Each object has only one field, <code>Memo</code>, which in turn contains another object with <em>one or more</em> of the following fields:</p>
<p>The <code>Memos</code> field allows for arbitrary messaging data that can accompany the transaction. It is presented as an array of objects. Each object has only one field, <code>Memo</code>, which in turn contains another object with <em>one or more</em> of the following fields:</p>
<table>
<thead>
<tr>
@@ -446,8 +496,42 @@
"Amount": "1"
}
</code></pre>
<h3 id="signers-field">Signers Field</h3>
<p>The <code>Signers</code> field contains a <a href="#multi-signing">multi-signature</a>, which has signatures from up to 8 key pairs, that together should authorize the transaction. The <code>Signers</code> list is an array of objects, each with one field, <code>Signer</code>. The <code>Signer</code> field has the following nested fields:</p>
<table>
<thead>
<tr>
<th>Field</th>
<th>Type</th>
<th><a href="https://wiki.ripple.com/Binary_Format">Internal Type</a></th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>Account</td>
<td>String</td>
<td>AccountID</td>
<td>The address associated with this signature, as it appears in the SignerList.</td>
</tr>
<tr>
<td>TxnSignature</td>
<td>String</td>
<td>Blob</td>
<td>A signature for this transaction, verifiable using the <code>SigningPubKey</code>.</td>
</tr>
<tr>
<td>SigningPubKey</td>
<td>String</td>
<td>PubKey</td>
<td>The public key used to create this signature.</td>
</tr>
</tbody>
</table>
<p>The <code>SigningPubKey</code> must be a key that is associated with the <code>Account</code> address. If the referenced <code>Account</code> is a funded account in the ledger, then the SigningPubKey can be that account's current Regular Key if one is set. It could also be that account's Master Key, unless the <a href="reference-ledger-format.html#accountroot-flags">lsfDisableMaster</a> flag is enabled. If the referenced <code>Account</code> address is not a funded account in the ledger, then the <code>SigningPubKey</code> must be the master key associated with that address.</p>
<p>Because signature verification is a compute-intensive task, multi-signed transactions cost additional XRP to relay to the network. Each signature included in the multi-signature increases the <a href="concept-transaction-cost.html">transaction cost</a> required for the transaction. For example, if the current minimum transaction cost to relay a transaction to the network is <code>10000</code> drops, then a multi-signed transaction with 3 entries in the <code>Signers</code> array would need a <code>Fee</code> value of at least <code>40000</code> drops to relay.</p>
<h3 id="flags">Flags</h3>
<p>The Flags field allows for additional boolean options regarding the behavior of a transaction. They are represented as binary values that can be combined with bitwise-or operations to set multiple flags at once.</p>
<p>The <code>Flags</code> field allows for additional boolean options regarding the behavior of a transaction. They are represented as binary values that can be combined with bitwise-or operations to set multiple flags at once.</p>
<p>Most flags only have meaning for a specific transaction type. The same bitwise value may be reused for flags on different transaction types, so it is important to pay attention to the <code>TransactionType</code> field when setting and reading flags.</p>
<p>The only flag that applies globally to all transactions is as follows:</p>
<table>
@@ -545,7 +629,7 @@
<p>Most of the time, the <code>issuer</code> field of a non-XRP <a href="reference-rippled.html#specifying-currency-amounts">currency amount</a> indicates the account of the gateway that issues that currency. However, when describing payments, there are special rules for the <code>issuer</code> field in the <code>Amount</code> and <code>SendMax</code> fields of a payment.</p>
<ul>
<li>There is only ever one balance for the same currency between two accounts. This means that, sometimes, the <code>issuer</code> field of an amount actually refers to a counterparty that is redeeming issuances, instead of the account that created the issuances.</li>
<li>When the <code>issuer</code> field of the destination <code>Amount</code> field matches the <code>Destination</code> account address, it is treated as a special case meaning "any issuer that the destination accepts." This includes all accounts to which the destination has extended trust lines, as well as issuances created by the destination which may be held on other trust lines. </li>
<li>When the <code>issuer</code> field of the destination <code>Amount</code> field matches the <code>Destination</code> account address, it is treated as a special case meaning "any issuer that the destination accepts." This includes all accounts to which the destination has extended trust lines, as well as issuances created by the destination which may be held on other trust lines.</li>
<li>When the <code>issuer</code> field of the <code>SendMax</code> field matches the source account's address, it is treated as a special case meaning "any issuer that the source can use." This includes creating new issuances on trust lines that other accounts have extended to the source account, as well as issuances from other accounts that the source account possesses.</li>
</ul>
<h3 id="creating-accounts">Creating Accounts</h3>
@@ -603,9 +687,9 @@
<p>When the <a href="#payment-flags"><em>tfPartialPayment</em> flag</a> is enabled, the <code>Amount</code> field <strong><em>is not guaranteed to be the amount received</em></strong>. The <a href="#delivered-amount"><code>delivered_amount</code></a> field of a payment's metadata indicates the amount of currency actually received by the destination account. When receiving a payment, use <code>delivered_amount</code> instead of the <code>Amount</code> field to determine how much your account received instead.</p>
<h3 id="limit-quality">Limit Quality</h3>
<p>Ripple defines the "quality" of a currency exchange as the ratio of the numeric amount in to the numeric amount out. For example, if you spend $2 USD to receive £1 GBP, then the "quality" of that exchange is <code>0.5</code>.</p>
<p>The <a href="#payment-flags"><em>tfLimitQuality</em> flag</a> allows you to set a minimum quality of conversions that you are willing to take. This limit quality is defined as the destination <code>Amount</code> divided by the <code>SendMax</code> amount (just the numeric amounts, regardless of currency). When set, the payment processing engine avoids using any paths whose quality (conversion rate) is worse (numerically lower) than the limit quality. </p>
<p>The <a href="#payment-flags"><em>tfLimitQuality</em> flag</a> allows you to set a minimum quality of conversions that you are willing to take. This limit quality is defined as the destination <code>Amount</code> divided by the <code>SendMax</code> amount (just the numeric amounts, regardless of currency). When set, the payment processing engine avoids using any paths whose quality (conversion rate) is worse (numerically lower) than the limit quality.</p>
<p>By itself, the tfLimitQuality flag reduces the number of situations in which a transaction can succeed. Specifically, it rejects payments where some part of the payment uses an unfavorable conversion, even if the overall average <em>average</em> quality of conversions in the payment is equal or better than the limit quality. If a payment is rejected in this way, the <a href="#transaction-results">transaction result</a> is <code>tecPATH_DRY</code>.</p>
<p>Consider the following example. If I am trying to send you 100 Chinese Yuan (<code>Amount</code> = 100 CNY) for 20 United States dollars (<code>SendMax</code> = 20 USD) or less, then the limit quality is <code>5</code>. Imagine one market maker is offering ¥95 for $15 (a ratio of about <code>6.3</code> CNY per USD), but the next best offer in the market is ¥5 for $2 (a ratio of <code>2.5</code> CNY per USD). If I were to take both offers in order to send you 100 CNY, then it would cost me 17 USD, for an average quality of about <code>5.9</code>. </p>
<p>Consider the following example. If I am trying to send you 100 Chinese Yuan (<code>Amount</code> = 100 CNY) for 20 United States dollars (<code>SendMax</code> = 20 USD) or less, then the limit quality is <code>5</code>. Imagine one market maker is offering ¥95 for $15 (a ratio of about <code>6.3</code> CNY per USD), but the next best offer in the market is ¥5 for $2 (a ratio of <code>2.5</code> CNY per USD). If I were to take both offers in order to send you 100 CNY, then it would cost me 17 USD, for an average quality of about <code>5.9</code>.</p>
<p>Without the tfLimitQuality flag set, this transaction would succeed, because the $17 it costs me is within my specified <code>SendMax</code>. However, with the tfLimitQuality flag enabled, the transaction would fail instead, because the path to take the second offer has a quality of <code>2.5</code>, which is worse than the limit quality of <code>5</code>.</p>
<p>The tfLimitQuality flag is most useful when combined with <a href="#partial-payments">partial payments</a>. When both <em>tfPartialPayment</em> and <em>tfLimitQuality</em> are set on a transaction, then the transaction delivers as much of the destination <code>Amount</code> as it can, without using any conversions that are worse than the limit quality.</p>
<p>In the above example with a ¥95/$15 offer and a ¥5/$2 offer, the situation is different if my transaction has both tfPartialPayment and tfLimitQuality enabled. If we keep my <code>SendMax</code> of 20 USD and a destination <code>Amount</code> of 100 CNY, then the limit quality is still <code>5</code>. However, because I am doing a partial payment, the transaction sends as much as it can instead of failing if the full destination amount cannot be sent. This means that my transaction consumes the ¥95/$15 offer, whose quality is about <code>6.3</code>, but it rejects the ¥5/$2 offer because that offer's quality of <code>2.5</code> is worse than the quality limit of <code>5</code>. In the end, my transaction only delivers ¥95 instead of the full ¥100, but it avoids wasting money on poor exchange rates.</p>
@@ -729,7 +813,7 @@
<tr>
<td>asfDisableMaster</td>
<td>4</td>
<td>Disallow use of the master key. Can only be enabled if the account has a <a href="#setregularkey">RegularKey</a> configured.</td>
<td>Disallow use of the master key. Can only be enabled if the account has configured another way to sign transactions, such as a <a href="#setregularkey">Regular Key</a> or a <a href="#signerlistset">Signer List</a>.</td>
<td>lsfDisableMaster</td>
</tr>
<tr>
@@ -758,7 +842,7 @@
</tr>
</tbody>
</table>
<p><em>New in <a href="https://github.com/ripple/rippled/releases/tag/0.28.0-rc1">rippled 0.28.0</a>:</em> You cannot send a transaction that enables <code>asfDisableMaster</code> or <code>asfNoFreeze</code> using a <a href="#setregularkey">regular key</a>. You must use the master key to sign the transaction.</p>
<p><em>New in <a href="https://github.com/ripple/rippled/releases/tag/0.28.0-rc1">rippled 0.28.0</a>:</em> In order to enable the <code>asfDisableMaster</code> or <code>asfNoFreeze</code> flags, you must <a href="#authorizing-transactions">authorize the transaction</a> by signing it with the master key. You cannot use a regular key or a multi-signature.</p>
<p>The following <a href="#flags">Transaction flags</a>, specific to the AccountSet transaction type, serve the same purpose, but are discouraged:</p>
<table>
<thead>
@@ -817,7 +901,7 @@
<p>In rippled's WebSocket and JSON-RPC APIs, the TransferRate is represented as an integer, the amount that must be sent in order for 1 billion units to arrive. For example, a 20% transfer fee is represented as the value <code>1200000000</code>. The value cannot be less than 1000000000. (Less than that would indicate giving away money for sending transactions, which is exploitable.) You can specify 0 as a shortcut for 1000000000, meaning no fee.</p>
<h2 id="setregularkey">SetRegularKey</h2>
<p><a href="https://github.com/ripple/rippled/blob/4239880acb5e559446d2067f00dabb31cf102a23/src/ripple/app/transactors/SetRegularKey.cpp" title="Source">[Source]<br/></a></p>
<p>A SetRegularKey transaction changes the regular key used by the account to sign future transactions.</p>
<p>A SetRegularKey transaction changes the regular key associated with an address.</p>
<pre><code>{
"Flags": 0,
"TransactionType": "SetRegularKey",
@@ -839,14 +923,15 @@
<tr>
<td>RegularKey</td>
<td>String</td>
<td>Account</td>
<td>(Optional) The public key of a new keypair, to use as the regular key to this account, as a base-58-encoded string in the same format as an account address. If omitted, removes the existing regular key.</td>
<td>AccountID</td>
<td>(Optional) A base-58-encoded <a href="reference-rippled.html#addresses">Ripple address</a> to use as the regular key. If omitted, removes the existing regular key.</td>
</tr>
</tbody>
</table>
<p>Instead of using an account's master key to sign transactions, you can set an alternate key pair, called the "Regular Key". As long as the public key for this key pair is set in the <code>RegularKey</code> field of an account this way, then the secret of the Regular Key pair can be used to sign transactions. (The master secret can still be used, too, unless you set the <a href="#accountset-flags">asfDisableMaster account flag</a>.)</p>
<p>A Regular Key pair is generated in the same way as any other Ripple keys (for example, with <a href="reference-rippled.html#wallet-propose">wallet_propose</a>), but it can be changed. A Master Key pair is an intrinsic part of the account's identity (the address is derived from the master public key) so the Master Key cannot be changed. Therefore, using a Regular Key to sign transactions instead of the master key whenever possible is beneficial to security.</p>
<p>If your regular key is compromised, but the master key is not, you can use this method to regain control of your account. In some cases, you can even send a <a href="concept-transaction-cost.html#key-reset-transaction">key reset transaction</a> without paying the <a href="#transaction-cost">transaction cost</a>.</p>
<p>In addition to the master key, which is mathematically-related to an address, you can associate <strong>at most 1 additional key pair</strong> with an address using this type of transaction. The additional key pair is called a <em>regular key</em>. If your address has a regular key pair defined, you can use the secret key of the regular key pair to <a href="#authorizing-transactions">authorize transactions</a>.</p>
<p>A regular key pair is generated in the same way as any other Ripple keys (for example, with <a href="reference-rippled.html#wallet-propose">wallet_propose</a>), but it can be changed. A master key pair is an intrinsic part of an address's identity (the address is derived from the master public key). You can <a href="#accountset-flags">disable</a> a master key but you cannot change it.</p>
<p>You can protect your master secret by using a regular key instead of the master key to sign transactions whenever possible. If your regular key is compromised, but the master key is not, you can use a SetRegularKey transaction to regain control of your address. In some cases, you can even send a <a href="concept-transaction-cost.html#key-reset-transaction">key reset transaction</a> without paying the <a href="#transaction-cost">transaction cost</a>.</p>
<p>For even greater security, you can use <a href="#multi-signing">multi-signing</a>, but multi-signing requires additional XRP for the <a href="concept-transaction-cost.html">transaction cost</a> and <a href="concept-reserves.html">reserve</a>.</p>
<h2 id="offercreate">OfferCreate</h2>
<p><a href="https://github.com/ripple/rippled/blob/master/src/ripple/app/tx/impl/CreateOffer.cpp" title="Source">[Source]<br/></a></p>
<p>An OfferCreate transaction is effectively a <a href="http://en.wikipedia.org/wiki/limit_order">limit order</a>. It defines an intent to exchange currencies, and creates an Offer node in the Ripple Consensus Ledger if not completely fulfilled when placed. Offers can be partially fulfilled.</p>
@@ -1089,7 +1174,7 @@
<p>Since a trust line occupies space in the ledger, <a href="concept-reserves.html">a trust line increases the XRP your account must hold in reserve</a>. This applies to the account extending trust, not to the account receiving it.</p>
<p>A trust line with settings in the default state is equivalent to no trust line.</p>
<p>The default state of all flags is off, except for the <a href="https://ripple.com/knowledge_center/understanding-the-noripple-flag/">NoRipple flag</a>, whose default state depends on the DefaultRipple flag.</p>
<p>The Auth flag of a trust line does not determine whether the trust line counts towards its owner's XRP reserve requirement. However, an enabled Auth flag prevents the trust line from being in its default state. An authorized trust line can never be deleted. <em>(New in <a href="https://github.com/ripple/rippled/releases/tag/0.30.0">rippled 0.30.0</a>)</em>: You can pre-authorize a trust line with the <code>tfSetfAuth</code> flag only, even if the limit and balance of the trust line are 0.</p>
<p>The Auth flag of a trust line does not determine whether the trust line counts towards its owner's XRP reserve requirement. However, an enabled Auth flag prevents the trust line from being in its default state. An authorized trust line can never be deleted. <em>(New in <a href="https://github.com/ripple/rippled/releases/tag/0.30.0">rippled 0.30.0</a>)</em>: The <a href="concept-amendments.html#trustsetauth"><code>TrustSetAuth</code> Amendment</a> would allow you to pre-authorize a trust line with the <code>tfSetfAuth</code> flag only, even if the limit and balance of the trust line are 0. This Amendment is not currently enabled.</p>
<h3 id="trustset-flags">TrustSet Flags</h3>
<p>Transactions of the TrustSet type support additional values in the <a href="#flags"><code>Flags</code> field</a>, as follows:</p>
<table>
@@ -1134,6 +1219,66 @@
</tr>
</tbody>
</table>
<h2 id="signerlistset">SignerListSet</h2>
<p><a href="https://github.com/ripple/rippled/blob/ef511282709a6a0721b504c6b7703f9de3eecf38/src/ripple/app/tx/impl/SetSignerList.cpp" title="Source">[Source]<br/></a></p>
<p>The SignerListSet transaction creates, replaces, or removes a list of signers that can be used to <a href="#multi-signing">multi-sign</a> a transaction. This transaction type is introduced by the <a href="concept-amendments.html#multisign">MultiSign amendment</a>. <em>(New in [version 0.31.0][])</em></p>
<p>Example SignerListSet:</p>
<pre><code>{
"Flags": 0,
"TransactionType": "SignerListSet",
"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
"Fee": "10000",
"SignerQuorum": 3,
"SignerEntries": [
{
"SignerEntry": {
"Account": "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW",
"SignerWeight": 2
}
},
{
"SignerEntry": {
"Account": "rUpy3eEg8rqjqfUoLeBnZkscbKbFsKXC3v",
"SignerWeight": 1
}
},
{
"SignerEntry": {
"Account": "raKEEVSGnKSD9Zyvxu4z6Pqpm4ABH8FS6n",
"SignerWeight": 1
}
}
]
}
</code></pre>
<table>
<thead>
<tr>
<th>Field</th>
<th>JSON Type</th>
<th><a href="https://wiki.ripple.com/Binary_Format">Internal Type</a></th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>SignerQuorum</td>
<td>Number</td>
<td>UInt32</td>
<td>A target number for the signer weights. A multi-signature from this list is valid only if the sum weights of the signatures provided is greater than or equal to this value. To delete a SignerList, use the value <code>0</code>.</td>
</tr>
<tr>
<td>SignerEntries</td>
<td>Array</td>
<td>Array</td>
<td>(Omitted when deleting) Array of <a href="reference-ledger-format.html#signerentry-object">SignerEntry objects</a>, indicating the addresses and weights of signers in this list. A SignerList must have at least 1 member and no more than 8 members. No address may appear more than once in the list, nor may the <code>Account</code> submitting the transaction appear in the list.</td>
</tr>
</tbody>
</table>
<p>An account may not have more than one SignerList. A successful SignerListSet transaction replaces the existing SignerList, if one exists. To delete a SignerList, you must set <code>SignerQuorum</code> to <code>0</code> <em>and</em> omit the <code>SignerEntries</code> field. Otherwise, the transaction fails with the error <a href="#tem-codes">temMALFORMED</a>. A transaction to delete a SignerList is considered successful even if there was no SignerList to delete.</p>
<p>You cannot create a SignerList such that the SignerQuorum could never be met. The SignerQuorum must be greater than 0 but less than or equal to the sum of the <code>SignerWeight</code> values in the list. Otherwise, the transaction fails with the error <a href="#tem-codes">temMALFORMED</a>.</p>
<p>You can create, update, or remove a SignerList using the master key, regular key, or the current SignerList, if those methods of signing transactions are available.</p>
<p>You cannot remove the last method of signing transactions from an account. If an account's master key is disabled (it has the <a href="reference-ledger-format.html#accountroot-flags"><code>lsfDisableMaster</code> flag</a> enabled) and the account does not have a <a href="#setregularkey">Regular Key</a> configured, then you cannot delete the SignerList from the account. Instead, the transaction fails with the error <a href="#tec-codes">tecNO_ALTERNATIVE_KEY</a>.</p>
<h1 id="pseudo-transactions">Pseudo-Transactions</h1>
<p>Pseudo-Transactions are never submitted by users, nor propagated through the network. Instead, a server may choose to inject them in a proposed ledger directly. If enough servers inject an equivalent pseudo-transaction for it to pass consensus, then it becomes included in the ledger, and appears in ledger data thereafter.</p>
<p>Some of the fields that are mandatory for normal transactions do not make sense for pseudo-transactions. In those cases, the pseudo-transaction has the following default values:</p>
@@ -1168,8 +1313,8 @@
</tbody>
</table>
<h2 id="setfee">SetFee</h2>
<p>A change in <a href="concept-transaction-cost.html">transaction cost</a> or <a href="concept-reserves.html">account reserve</a> requirements. This is typically in response to changes in the load on the network.</p>
<p><em>Note:</em> You cannot send a pseudo-transaction, but you may encounter one when processing ledgers.</p>
<p>A change in <a href="concept-transaction-cost.html">transaction cost</a> or <a href="concept-reserves.html">account reserve</a> requirements as a result of <a href="concept-fee-voting.html">Fee Voting</a>.</p>
<p><strong>Note:</strong> You cannot send a pseudo-transaction, but you may encounter one when processing ledgers.</p>
<pre><code>{
"Account": "rrrrrrrrrrrrrrrrrrrrrhoLvTp",
"BaseFee": "000000000000000A",
@@ -1219,11 +1364,71 @@
<td>UInt32</td>
<td>The incremental reserve, in drops</td>
</tr>
<tr>
<td>LedgerSequence</td>
<td>Number</td>
<td>UInt32</td>
<td>The index of the ledger version where this pseudo-transaction appears. This distinguishes the pseudo-transaction from other occurrences of the same change.</td>
</tr>
</tbody>
</table>
<h2 id="enableamendment">EnableAmendment</h2>
<p>Tracks the progress of the <a href="concept-amendments.html#amendment-process">amendment process</a> for changes in transaction processing. This can indicate that a proposed amendment gained or lost majority approval, or that an amendment has been enabled.</p>
<p><strong>Note:</strong> You cannot send a pseudo-transaction, but you may encounter one when processing ledgers.</p>
<table>
<thead>
<tr>
<th>Field</th>
<th>JSON Type</th>
<th><a href="https://wiki.ripple.com/Binary_Format">Internal Type</a></th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>Amendment</td>
<td>String</td>
<td>Hash256</td>
<td>A unique identifier for the amendment. This is not intended to be a human-readable name. See <a href="concept-amendments.html">Amendments</a> for a list of known amendments.</td>
</tr>
<tr>
<td>LedgerSequence</td>
<td>Number</td>
<td>UInt32</td>
<td>The index of the ledger version where this amendment appears. This distinguishes the pseudo-transaction from other occurrences of the same change.</td>
</tr>
</tbody>
</table>
<h3 id="enableamendment-flags">EnableAmendment Flags</h3>
<p>The <code>Flags</code> value of the EnableAmendment pseudo-transaction indicates the status of the amendment at the time of the ledger including the pseudo-transaction.</p>
<p>A <code>Flags</code> value of <code>0</code> (no flags) indicates that the amendment has been enabled, and applies to all ledgers afterward. Other <code>Flags</code> values are as follows:</p>
<table>
<thead>
<tr>
<th>Flag Name</th>
<th>Hex Value</th>
<th>Decimal Value</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>tfGotMajority</td>
<td>0x00010000</td>
<td>65536</td>
<td>Support for this amendment increased to at least 80% of trusted validators starting with this ledger version.</td>
</tr>
<tr>
<td>tfLostMajority</td>
<td>0x00020000</td>
<td>131072</td>
<td>Support for this amendment decreased to less than 80% of trusted validators starting with this ledger version.</td>
</tr>
</tbody>
</table>
<h1 id="transaction-results">Transaction Results</h1>
<h2 id="immediate-response">Immediate Response</h2>
<p>The response from the <a href="reference-rippled.html#submit"><code>submit</code> command</a> contains a provisional result from the <code>rippled</code> server indicating what happened during local processing of the transaction. </p>
<p>The response from the <a href="reference-rippled.html#submit"><code>submit</code> command</a> contains a provisional result from the <code>rippled</code> server indicating what happened during local processing of the transaction.</p>
<p>The response from <code>submit</code> contains the following fields:</p>
<table>
<thead>
@@ -1258,7 +1463,7 @@
</code></pre>
<p><strong><em>Note:</em></strong> A successful result at this stage does not indicate that the transaction has completely succeeded; only that it was successfully applied to the provisional version of the ledger kept by the local server. See <a href="#finality-of-results">Finality of Results</a> for details.</p>
<h2 id="looking-up-transaction-results">Looking up Transaction Results</h2>
<p>To see the final result of a transaction, use the <a href="reference-rippled.html#tx"><code>tx</code> command</a>, <a href="reference-rippled.html#account-tx"><code>account_tx</code> command</a>, or other response from <code>rippled</code>. Look for <code>"validated": true</code> to indicate that this response uses a ledger version that has been validated by consensus. </p>
<p>To see the final result of a transaction, use the <a href="reference-rippled.html#tx"><code>tx</code> command</a>, <a href="reference-rippled.html#account-tx"><code>account_tx</code> command</a>, or other response from <code>rippled</code>. Look for <code>"validated": true</code> to indicate that this response uses a ledger version that has been validated by consensus.</p>
<table>
<thead>
<tr>
@@ -1439,10 +1644,6 @@
</thead>
<tbody>
<tr>
<td>telLOCAL_ERROR</td>
<td>Unspecified local error.</td>
</tr>
<tr>
<td>telBAD_DOMAIN</td>
<td>The transaction specified a domain value (for example, the <code>Domain</code> field of an <a href="#accountset">AccountSet transaction</a>) that cannot be used, probably because it is too long to store in the ledger.</td>
</tr>
@@ -1463,6 +1664,10 @@
<td>The <code>Fee</code> from the transaction is not high enough to meet the server's current <a href="concept-transaction-cost.html">transaction cost</a> requirement, which is derived from its load level.</td>
</tr>
<tr>
<td>telLOCAL_ERROR</td>
<td>Unspecified local error.</td>
</tr>
<tr>
<td>telNO_DST_PARTIAL</td>
<td>The transaction is an XRP payment that would fund a new account, but the <a href="#partial-payments">tfPartialPayment flag</a> was enabled. This is disallowed.</td>
</tr>
@@ -1479,10 +1684,6 @@
</thead>
<tbody>
<tr>
<td>temMALFORMED</td>
<td>Unspecified problem with the format of the transaction.</td>
</tr>
<tr>
<td>temBAD_AMOUNT</td>
<td>An amount specified by the transaction (for example the destination <code>Amount</code> or <code>SendMax</code> values of a <a href="#payment">Payment</a>) was invalid, possibly because it was a negative number.</td>
</tr>
@@ -1560,7 +1761,7 @@
</tr>
<tr>
<td>temDST_IS_SRC</td>
<td>The <a href="#trustset">TrustSet</a> transaction improperly specified the destination of the trustline (the <code>issuer</code> field of <code>LimitAmount</code>) as the <code>Account</code> sending the transaction. You cannot extend a trustline to yourself. (In the future, this code could also apply to other cases where the destination of a transaction is not allowed to be the account sending it.)</td>
<td>The <a href="#trustset">TrustSet</a> transaction improperly specified the destination of the trust line (the <code>issuer</code> field of <code>LimitAmount</code>) as the <code>Account</code> sending the transaction. You cannot extend a trust line to yourself. (In the future, this code could also apply to other cases where the destination of a transaction is not allowed to be the account sending it.)</td>
</tr>
<tr>
<td>temDST_NEEDED</td>
@@ -1575,6 +1776,10 @@
<td>The transaction includes a <a href="#flags">Flag</a> that does not exist, or includes a contradictory combination of flags.</td>
</tr>
<tr>
<td>temMALFORMED</td>
<td>Unspecified problem with the format of the transaction.</td>
</tr>
<tr>
<td>temREDUNDANT</td>
<td>The transaction would accomplish nothing; for example, it is sending a payment directly to the sending account, or creating an offer to buy and sell the same currency from the same issuer.</td>
</tr>
@@ -1586,6 +1791,30 @@
<td>temRIPPLE_EMPTY</td>
<td>The <a href="#payment">Payment</a> transaction includes an empty <code>Paths</code> field, but paths are necessary to complete this payment.</td>
</tr>
<tr>
<td>temBAD_WEIGHT</td>
<td>The <a href="#signerlistset">SignerListSet</a> transaction includes a <code>SignerWeight</code> that is invalid, for example a zero or negative value.</td>
</tr>
<tr>
<td>temBAD_SIGNER</td>
<td>The <a href="#signerlistset">SignerListSet</a> transaction includes a signer who is invalid. For example, there may be duplicate entries, or the owner of the SignerList may also be a member.</td>
</tr>
<tr>
<td>temBAD_QUORUM</td>
<td>The <a href="#signerlistset">SignerListSet</a> transaction has an invalid <code>SignerQuorum</code> value. Either the value is not greater than zero, or it is more than the sum of all signers in the list.</td>
</tr>
<tr>
<td>temUNCERTAIN</td>
<td>Used internally only. This code should never be returned.</td>
</tr>
<tr>
<td>temUNKNOWN</td>
<td>Used internally only. This code should never be returned.</td>
</tr>
<tr>
<td>temDISABLED</td>
<td>The transaction requires logic that is currently disabled. Typically this means you are trying to use an <a href="concept-amendments.html">amendment</a> that is not enabled for the current ledger.</td>
</tr>
</tbody>
</table>
<h3 id="tef-codes">tef Codes</h3>
@@ -1599,48 +1828,48 @@
</thead>
<tbody>
<tr>
<td>tefFAILURE</td>
<td>Unspecified failure in applying the transaction.</td>
</tr>
<tr>
<td>tefALREADY</td>
<td>The same exact transaction has already been applied.</td>
</tr>
<tr>
<td>tefBAD_ADD_AUTH</td>
<td>Deprecated. This code should never be returned.</td>
<td><strong>DEPRECATED.</strong></td>
</tr>
<tr>
<td>tefBAD_AUTH</td>
<td>The key used to sign this account is not authorized to modify this account. (It could be authorized if the account had the same key set as the <a href="#setregularkey">Regular Key</a>.)</td>
</tr>
<tr>
<td>tefBAD_AUTH_MASTER</td>
<td>The single signature provided to authorize this transaction does not match the master key, but no regular key is associated with this address.</td>
</tr>
<tr>
<td>tefBAD_LEDGER</td>
<td>While processing the transaction, the ledger was discovered in an unexpected state. If you can reproduce this error, please <a href="https://ripplelabs.atlassian.net/secure/CreateIssueDetails!init.jspa?pid=10800&amp;issuetype=1">file a bug</a> to get it fixed.</td>
<td>While processing the transaction, the ledger was discovered in an unexpected state. If you can reproduce this error, please <a href="https://github.com/ripple/rippled/issues">report an issue</a> to get it fixed.</td>
</tr>
<tr>
<td>tefBAD_QUORUM</td>
<td>The transaction was <a href="#multi-signing">multi-signed</a>, but the total weights of all included signatures did not meet the quorum.</td>
</tr>
<tr>
<td>tefBAD_SIGNATURE</td>
<td>The transaction was <a href="#multi-signing">multi-signed</a>, but contained a signature for an address not part of a SignerList associated with the sending account.</td>
</tr>
<tr>
<td>tefCREATED</td>
<td>Deprecated. This code should never be returned.</td>
<td><strong>DEPRECATED.</strong></td>
</tr>
<tr>
<td>tefEXCEPTION</td>
<td>While processing the transaction, the server entered an unexpected state. This may be caused by unexpected inputs, for example if the binary data for the transaction is grossly malformed. If you can reproduce this error, please <a href="https://ripplelabs.atlassian.net/secure/CreateIssueDetails!init.jspa?pid=10800&amp;issuetype=1">file a bug</a> to get it fixed.</td>
<td>While processing the transaction, the server entered an unexpected state. This may be caused by unexpected inputs, for example if the binary data for the transaction is grossly malformed. If you can reproduce this error, please <a href="https://github.com/ripple/rippled/issues">report an issue</a> to get it fixed.</td>
</tr>
<tr>
<td>tefFAILURE</td>
<td>Unspecified failure in applying the transaction.</td>
</tr>
<tr>
<td>tefINTERNAL</td>
<td>While attempting to apply the transaction, the server entered an unexpected state. If you can reproduce this error, please <a href="https://ripplelabs.atlassian.net/secure/CreateIssueDetails!init.jspa?pid=10800&amp;issuetype=1">file a bug</a> to get it fixed.</td>
</tr>
<tr>
<td>tefNO_AUTH_REQUIRED</td>
<td>The <a href="#trustset">TrustSet</a> transaction attempted to mark a trustline as authorized, but the <code>lsfRequireAuth</code> flag is not enabled for the corresponding account, so authorization is not necessary.</td>
</tr>
<tr>
<td>tefPAST_SEQ</td>
<td>The sequence number of the transaction is lower than the current sequence number of the account sending the transaction.</td>
</tr>
<tr>
<td>tefWRONG_PRIOR</td>
<td>The transaction contained an <code>AccountTxnID</code> field (or the deprecated <code>PreviousTxnID</code> field), but the transaction specified there does not match the account's previous transaction.</td>
<td>While attempting to apply the transaction, the server entered an unexpected state. If you can reproduce this error, please <a href="https://github.com/ripple/rippled/issues">report an issue</a> to get it fixed.</td>
</tr>
<tr>
<td>tefMASTER_DISABLED</td>
@@ -1650,6 +1879,22 @@
<td>tefMAX_LEDGER</td>
<td>The transaction included a <a href="#lastledgersequence"><code>LastLedgerSequence</code></a> parameter, but the current ledger's sequence number is already higher than the specified value.</td>
</tr>
<tr>
<td>tefNO_AUTH_REQUIRED</td>
<td>The <a href="#trustset">TrustSet</a> transaction attempted to mark a trustline as authorized, but the <code>lsfRequireAuth</code> flag is not enabled for the corresponding account, so authorization is not necessary.</td>
</tr>
<tr>
<td>tefNOT_MULTI_SIGNING</td>
<td>The transaction was <a href="#multi-signing">multi-signed</a>, but the sending account has no SignerList defined.</td>
</tr>
<tr>
<td>tefPAST_SEQ</td>
<td>The sequence number of the transaction is lower than the current sequence number of the account sending the transaction.</td>
</tr>
<tr>
<td>tefWRONG_PRIOR</td>
<td>The transaction contained an <code>AccountTxnID</code> field (or the deprecated <code>PreviousTxnID</code> field), but the transaction specified there does not match the account's previous transaction.</td>
</tr>
</tbody>
</table>
<h3 id="ter-codes">ter Codes</h3>
@@ -1663,30 +1908,34 @@
</thead>
<tbody>
<tr>
<td>terRETRY</td>
<td>Unspecified retriable error.</td>
</tr>
<tr>
<td>terFUNDS_SPENT</td>
<td>Deprecated. This code should never be returned.</td>
<td><strong>DEPRECATED.</strong></td>
</tr>
<tr>
<td>terINSUF_FEE_B</td>
<td>The account sending the transaction does not have enough XRP to pay the <code>Fee</code> specified in the transaction.</td>
</tr>
<tr>
<td>terLAST</td>
<td>Used internally only. This code should never be returned.</td>
</tr>
<tr>
<td>terNO_ACCOUNT</td>
<td>The account sending the transaction does not exist in the ledger (yet).</td>
<td>The address sending the transaction is not funded in the ledger (yet).</td>
</tr>
<tr>
<td>terNO_AUTH</td>
<td>The transaction would involve adding currency issued by an account with <code>lsfRequireAuth</code> enabled to a trustline that is not authorized. For example, you placed an offer to buy a currency you aren't authorized to hold.</td>
<td>The transaction would involve adding currency issued by an account with <code>lsfRequireAuth</code> enabled to a trust line that is not authorized. For example, you placed an offer to buy a currency you aren't authorized to hold.</td>
</tr>
<tr>
<td>terNO_LINE</td>
<td>Used internally only. This code should never be returned.</td>
</tr>
<tr>
<td>terNO_RIPPLE</td>
<td>Used internally only. This code should never be returned.</td>
</tr>
<tr>
<td>terOWNERS</td>
<td>The transaction requires that account sending it has a nonzero "owners count", so the transaction cannot succeed. For example, an account cannot enable the <a href="#accountset-flags"><code>lsfRequireAuth</code></a> flag if it has any trust lines or available offers.</td>
</tr>
@@ -1695,12 +1944,8 @@
<td>The <code>Sequence</code> number of the current transaction is higher than the current sequence number of the account sending the transaction.</td>
</tr>
<tr>
<td>terLAST</td>
<td>Used internally only. This code should never be returned.</td>
</tr>
<tr>
<td>terNO_RIPPLE</td>
<td>Used internally only. This code should never be returned.</td>
<td>terRETRY</td>
<td>Unspecified retriable error.</td>
</tr>
</tbody>
</table>
@@ -1737,24 +1982,14 @@
<td>Unspecified failure, with transaction cost destroyed.</td>
</tr>
<tr>
<td>tecPATH_PARTIAL</td>
<td>101</td>
<td>The transaction failed because the provided paths did not have enough liquidity to send the full amount.</td>
<td>tecDIR_FULL</td>
<td>121</td>
<td>The address sending the transaction cannot own any more objects in the ledger.</td>
</tr>
<tr>
<td>tecUNFUNDED_ADD</td>
<td>102</td>
<td><strong>DEPRECATED.</strong></td>
</tr>
<tr>
<td>tecUNFUNDED_OFFER</td>
<td>103</td>
<td>The <a href="#offercreate">OfferCreate transaction</a> failed because the account creating the offer does not have any of the <code>TakerGets</code> currency.</td>
</tr>
<tr>
<td>tecUNFUNDED_PAYMENT</td>
<td>104</td>
<td>The transaction failed because the sending account is trying to send more XRP than it holds, not counting the reserve. (See: <a href="concept-reserves.html">Reserves</a>)</td>
<td>tecDST_TAG_NEEDED</td>
<td>143</td>
<td>The <a href="#payment">Payment</a> transaction omitted a destination tag, but the destination account has the <code>lsfRequireDestTag</code> flag enabled. <em>(New in <a href="https://github.com/ripple/rippled/releases/tag/0.28.0-rc1">rippled 0.28.0</a>)</em></td>
</tr>
<tr>
<td>tecFAILED_PROCESSING</td>
@@ -1762,9 +1997,9 @@
<td>An unspecified error occurred when processing the transaction.</td>
</tr>
<tr>
<td>tecDIR_FULL</td>
<td>121</td>
<td>The "owners count" of the account sending the transaction is already maxed out.</td>
<td>tecFROZEN</td>
<td>137</td>
<td>The <a href="#offercreate">OfferCreate transaction</a> failed because one or both of the assets involved are subject to a <a href="concept-freeze.html">global freeze</a>.</td>
</tr>
<tr>
<td>tecINSUF_RESERVE_LINE</td>
@@ -1777,6 +2012,31 @@
<td>The transaction failed because the sending account does not have enough XRP to create a new Offer. (See: <a href="concept-reserves.html">Reserves</a>)</td>
</tr>
<tr>
<td>tecINSUFFICIENT_RESERVE</td>
<td>141</td>
<td>The <a href="#signerlistset">SignerListSet</a> or other transaction would increase the <a href="concept-reserves.html">reserve requirement</a> higher than the sending account's balance. See <a href="reference-ledger-format.html#signerlists-and-reserves">SignerLists and Reserves</a> for more information.</td>
</tr>
<tr>
<td>tecINTERNAL</td>
<td>144</td>
<td>Unspecified internal error, with transaction cost applied. This error code should not normally be returned.</td>
</tr>
<tr>
<td>tecNEED_MASTER_KEY</td>
<td>142</td>
<td>This transaction attempted to cause changes that require the master key, such as <a href="#accountset-flags">disabling the master key or giving up the ability to freeze balances</a>. <em>(New in <a href="https://github.com/ripple/rippled/releases/tag/0.28.0-rc1">rippled 0.28.0</a>)</em></td>
</tr>
<tr>
<td>tecNO_ALTERNATIVE_KEY</td>
<td>130</td>
<td>The transaction tried to remove the only available method of <a href="#authorizing-transactions">authorizing transactions</a>. This could be a <a href="#setregularkey">SetRegularKey transaction</a> to remove the regular key, a <a href="#signerlistset">SignerListSet transaction</a> to delete a SignerList, or an <a href="#accountset">AccountSet transaction</a> to disable the master key. (Prior to <a href="https://github.com/ripple/rippled/releases/tag/0.30.0">rippled 0.30.0</a>, this was called <code>tecMASTER_DISABLED</code>.)</td>
</tr>
<tr>
<td>tecNO_AUTH</td>
<td>134</td>
<td>The transaction failed because it needs to add a balance on a trust line to an account with the <code>lsfRequireAuth</code> flag enabled, and that trust line has not been authorized. If the trust line does not exist at all, tecNO_LINE occurs instead.</td>
</tr>
<tr>
<td>tecNO_DST</td>
<td>124</td>
<td>The account on the receiving end of the transaction does not exist. This includes Payment and TrustSet transaction types. (It could be created if it received sufficient XRP.)</td>
@@ -1787,6 +2047,21 @@
<td>The account on the receiving end of the transaction does not exist, and the transaction is not sending enough XRP to create it.</td>
</tr>
<tr>
<td>tecNO_ENTRY</td>
<td>140</td>
<td>Reserved for future use.</td>
</tr>
<tr>
<td>tecNO_ISSUER</td>
<td>133</td>
<td>The account specified in the <code>issuer</code> field of a currency amount does not exist.</td>
</tr>
<tr>
<td>tecNO_LINE</td>
<td>135</td>
<td>The <code>TakerPays</code> field of the <a href="#offercreate">OfferCreate transaction</a> specifies an asset whose issuer has <code>lsfRequireAuth</code> enabled, and the account making the offer does not have a trust line for that asset. (Normally, making an offer implicitly creates a trust line if necessary, but in this case it does not bother because you cannot hold the asset without authorization.) If the trust line exists, but is not authorized, <code>tecNO_AUTH</code> occurs instead.</td>
</tr>
<tr>
<td>tecNO_LINE_INSUF_RESERVE</td>
<td>126</td>
<td>The transaction failed because the sending account does not have enough XRP to create a new trust line. (See: <a href="concept-reserves.html">Reserves</a>) This error occurs when the counterparty does not have a trust line to this account for the same currency. (See tecINSUF_RESERVE_LINE for the other case.)</td>
@@ -1797,24 +2072,24 @@
<td>The transaction failed because it attempted to set a trust line to its default state, but the trust line did not exist.</td>
</tr>
<tr>
<td>tecPATH_DRY</td>
<td>128</td>
<td>The transaction failed because the provided paths did not have enough liquidity to send anything at all. This could mean that the source and destination accounts are not linked by trust lines.</td>
</tr>
<tr>
<td>tecUNFUNDED</td>
<td>129</td>
<td><strong>DEPRECATED.</strong> Replaced by tecUNFUNDED_OFFER and tecUNFUNDED_PAYMENT.</td>
</tr>
<tr>
<td>tecMASTER_DISABLED</td>
<td>130</td>
<td>The <a href="#setregularkey">SetRegularKey transaction</a> tried to unset the Regular Key, but the account has the <code>lsfDisableMaster</code> flag enabled. (Unsetting the Regular Key while also leaving the Master Key disabled would make the account unusable.)</td>
<td>tecNO_PERMISSION</td>
<td>139</td>
<td>Reserved for future use.</td>
</tr>
<tr>
<td>tecNO_REGULAR_KEY</td>
<td>131</td>
<td>The <a href="#accountset">AccountSet transaction</a> tried to disable the Master Key, but the account does not have a Regular Key set. (Disabling the Master Key without having a Regular Key configured would make the account unusable.)</td>
<td>The <a href="#accountset">AccountSet transaction</a> tried to disable the master key, but the account does not have another way to <a href="#authorizing-transactions">authorize transactions</a>. If <a href="#multi-signing">multi-signing</a> is enabled, this code is deprecated and <code>tecNO_ALTERNATIVE_KEY</code> is used instead.</td>
</tr>
<tr>
<td>tecNO_TARGET</td>
<td>138</td>
<td>Reserved for future use.</td>
</tr>
<tr>
<td>tecOVERSIZE</td>
<td>145</td>
<td>This transaction could not be processed, because attempted transaction processing created an excessively large amount of metadata. <em>(New in <a href="https://github.com/ripple/rippled/releases/tag/0.29.0-hf1">rippled 0.29.0-hf1</a> )</em></td>
</tr>
<tr>
<td>tecOWNERS</td>
@@ -1822,74 +2097,39 @@
<td>The transaction requires that account sending it has a nonzero "owners count", so the transaction cannot succeed. For example, an account cannot enable the <a href="#accountset-flags"><code>lsfRequireAuth</code></a> flag if it has any trust lines or available offers.</td>
</tr>
<tr>
<td>tecNO_ISSUER</td>
<td>133</td>
<td>The account specified in the <code>issuer</code> field of a currency amount does not exist.</td>
<td>tecPATH_DRY</td>
<td>128</td>
<td>The transaction failed because the provided paths did not have enough liquidity to send anything at all. This could mean that the source and destination accounts are not linked by trust lines.</td>
</tr>
<tr>
<td>tecNO_AUTH</td>
<td>134</td>
<td>The transaction failed because it needs to add a balance on a trust line to an account with the <code>lsfRequireAuth</code> flag enabled, and that trust line has not been authorized. If the trust line does not exist at all, tecNO_LINE occurs instead.</td>
<td>tecPATH_PARTIAL</td>
<td>101</td>
<td>The transaction failed because the provided paths did not have enough liquidity to send the full amount.</td>
</tr>
<tr>
<td>tecNO_LINE</td>
<td>135</td>
<td>The <code>TakerPays</code> field of the <a href="#offercreate">OfferCreate transaction</a> specifies an asset whose issuer has <code>lsfRequireAuth</code> enabled, and the account making the offer does not have a trust line for that asset. (Normally, making an offer implicitly creates a trust line if necessary, but in this case it does not bother because you cannot hold the asset without authorization.) If the trust line exists, but is not authorized, tecNO_AUTH occurs instead.</td>
<td>tecUNFUNDED</td>
<td>129</td>
<td><strong>DEPRECATED.</strong> Replaced by tecUNFUNDED_OFFER and tecUNFUNDED_PAYMENT.</td>
</tr>
<tr>
<td>tecINSUFF_FEE</td>
<td>136</td>
<td>The account sending the transaction does not possess enough XRP to pay the specified <code>Fee</code>. This error only occurs if the transaction has already been propagated through the network to achieve consensus,</td>
<td>tecUNFUNDED_ADD</td>
<td>102</td>
<td><strong>DEPRECATED.</strong></td>
</tr>
<tr>
<td>tecFROZEN</td>
<td>137</td>
<td>The <a href="#offercreate">OfferCreate transaction</a> failed because one or both of the assets involved are subject to a <a href="concept-freeze.html">global freeze</a>.</td>
<td>tecUNFUNDED_PAYMENT</td>
<td>104</td>
<td>The transaction failed because the sending account is trying to send more XRP than it holds, not counting the reserve. (See: <a href="concept-reserves.html">Reserves</a>)</td>
</tr>
<tr>
<td>tecNO_TARGET</td>
<td>138</td>
<td><strong>FORTHCOMING</strong> Part of multi-signature transactions.</td>
</tr>
<tr>
<td>tecNO_PERMISSION</td>
<td>139</td>
<td><strong>FORTHCOMING</strong> Part of multi-signature transactions.</td>
</tr>
<tr>
<td>tecNO_ENTRY</td>
<td>140</td>
<td><strong>FORTHCOMING</strong> Part of multi-signature transactions.</td>
</tr>
<tr>
<td>tecINSUFFICIENT_RESERVE</td>
<td>141</td>
<td><strong>FORTHCOMING</strong> Part of multi-signature transactions. (Code may change; see <a href="https://ripplelabs.atlassian.net/browse/RIPD-743">RIPD-743</a> for status.)</td>
</tr>
<tr>
<td>tecNEED_MASTER_KEY</td>
<td>142</td>
<td>This transaction attempted to cause changes that require the master key, such as <a href="#accountset-flags">disabling the master key or giving up the ability to freeze balances</a>. <em>(New in <a href="https://github.com/ripple/rippled/releases/tag/0.28.0-rc1">rippled 0.28.0</a>)</em></td>
</tr>
<tr>
<td>tecDST_TAG_NEEDED</td>
<td>143</td>
<td>The <a href="#payment">Payment</a> transaction omitted a destination tag, but the destination account has the <code>lsfRequireDestTag</code> flag enabled. <em>(New in <a href="https://github.com/ripple/rippled/releases/tag/0.28.0-rc1">rippled 0.28.0</a>)</em></td>
</tr>
<tr>
<td>tecINTERNAL</td>
<td>144</td>
<td>Unspecified internal error, with transaction cost applied. This error code should not normally be returned.</td>
</tr>
<tr>
<td>tecOVERSIZE</td>
<td>145</td>
<td>This transaction could not be processed, because attempted transaction processing created an excessively large amount of metadata. <em>(New in <a href="https://github.com/ripple/rippled/releases/tag/0.29.0-hf1">rippled 0.29.0-hf1</a> )</em></td>
<td>tecUNFUNDED_OFFER</td>
<td>103</td>
<td>The <a href="#offercreate">OfferCreate transaction</a> failed because the account creating the offer does not have any of the <code>TakerGets</code> currency.</td>
</tr>
</tbody>
</table>
<h3 id="tej-codes">tej Codes</h3>
<p>These codes are only ever returned by the <code>ripple-lib</code> client library, not by <code>rippled</code> itself. </p>
<p>These codes are only ever returned by the <code>ripple-lib</code> client library, not by <code>rippled</code> itself.</p>
<table>
<thead>
<tr>

View File

@@ -46,6 +46,7 @@
<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-reliable-transaction-submission.html">Reliable Transaction Submission</a></li>
<li><a href="tutorial-multisign.html">Multi-Signing Transactions</a></li>
</ul>
</li>
<li class="dropdown">
@@ -58,6 +59,8 @@
<li><a href="concept-fee-voting.html">Fee Voting</a></li>
<li><a href="concept-reserves.html">Reserves</a></li>
<li><a href="concept-freeze.html">Freeze</a></li>
<li><a href="concept-amendments.html">Amendments</a></li>
<li><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
</ul>
</li>
<li class="dropdown">

View File

@@ -46,6 +46,7 @@
<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-reliable-transaction-submission.html">Reliable Transaction Submission</a></li>
<li><a href="tutorial-multisign.html">Multi-Signing Transactions</a></li>
</ul>
</li>
<li class="dropdown">
@@ -58,6 +59,8 @@
<li><a href="concept-fee-voting.html">Fee Voting</a></li>
<li><a href="concept-reserves.html">Reserves</a></li>
<li><a href="concept-freeze.html">Freeze</a></li>
<li><a href="concept-amendments.html">Amendments</a></li>
<li><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
</ul>
</li>
<li class="dropdown">

View File

@@ -149,6 +149,13 @@ pages:
- local
- ripple.com
- name: Multi-Signing Transactions
category: Tutorials
html: tutorial-multisign.html
md: tutorial-multisign.md
ripple.com: https://wiki.ripple.com/Multisign
sidebar: true
# Concepts are introductions that explain a topic.
# In the Dev Portal, these are mostly summaries of RCL features.
- name: Paths
@@ -221,6 +228,20 @@ pages:
- local
- ripple.com
- name: Amendments
category: Concepts
html: concept-amendments.html
md: concept-amendments.md
ripple.com: https://wiki.ripple.com/Understanding:_Feature_adoption
sidebar: true
- name: Stand-Alone Mode
category: Concepts
html: concept-stand-alone-mode.html
md: concept-stand-alone-mode.md
ripple.com: https://wiki.ripple.com/Rippled#--standalone.2C_-a
sidebar: true
# "Best Practices" documents are mostly in the same category as tutorials
- name: Issuing and Operational Addresses
category: Best Practices

View File

@@ -1,162 +0,0 @@
[
{
"name": "Overview",
"template":"template-index.html",
"html": "index.html",
"targets": ["local", "ripple.com"],
"sidebar": false
},
{
"name": "Ripple Developer Resources",
"template":"template-pdf_intro.html",
"html": "pdf_intro.html",
"targets": ["pdf"]
},
{
"name": "Paths",
"md":"paths.md",
"html":"paths.html",
"ripple.com": "https://ripple.com/build/paths/",
"category": "Concepts",
"sidebar": "category-toc"
},
{
"name": "Fees (Disambiguation)",
"md": "fees.md",
"html": "fees.html",
"ripple.com": "https://ripple.com/knowledge_center/fees-disambiguation/",
"category": "Concepts",
"sidebar": "category-toc"
},
{
"name": "Transfer Fees",
"md":"transferrate.md",
"html":"transfer_fees.html",
"ripple.com": "https://ripple.com/knowledge_center/transfer-fees/",
"category": "Concepts",
"sidebar": "category-toc"
},
{
"name": "Transaction Cost",
"md": "tx-cost.md",
"html": "tx-cost.html",
"ripple.com": "https://ripple.com/build/transaction-cost/",
"category": "Concepts",
"sidebar": "category-toc"
},
{
"name": "Fee Voting",
"md": "fee-voting.md",
"html": "fee-voting.html",
"ripple.com": "https://ripple.com/build/fee-voting/",
"category": "Concepts",
"sidebar": "category-toc"
},
{
"name": "Reserves",
"md": "reserves.md",
"html": "reserves.html",
"ripple.com": "https://ripple.com/build/reserves/",
"category": "Concepts",
"sidebar": "category-toc"
},
{
"name": "Freeze",
"md": "freeze.md",
"html": "freeze.html",
"ripple.com": "https://ripple.com/build/freeze/",
"category": "Concepts",
"sidebar": "category-toc"
},
{
"name": "RippleAPI Quick Start Guide",
"md": "rippleapi_quickstart.md",
"html": "rippleapi_quickstart.html",
"category": "Tutorials",
"sidebar": "page-toc"
},
{
"name": "rippled",
"md":"rippled.md",
"html":"rippled-apis.html",
"ripple.com": "https://ripple.com/build/rippled-apis/",
"category": "References",
"sidebar": "page-toc"
},
{
"name": "rippled Setup",
"md":"rippled-setup.md",
"html":"rippled-setup.html",
"ripple.com": "https://ripple.com/build/rippled-setup/",
"category": "Tutorials",
"sidebar": "page-toc"
},
{
"name": "Transactions",
"md":"tx_format.md",
"html":"transactions.html",
"ripple.com": "https://ripple.com/build/transactions/",
"category": "References",
"sidebar": "page-toc"
},
{
"name": "Ledger Format",
"md":"ledger_format.md",
"html":"ripple-ledger.html",
"ripple.com": "https://ripple.com/build/ledger-format/",
"category": "References",
"sidebar": "page-toc"
},
{
"name": "Reliable Transaction Submission",
"md":"reliable_tx.md",
"html":"reliable_tx.html",
"ripple.com": "https://ripple.com/build/reliable-transaction-submission/",
"category": "Tutorials",
"sidebar": "page-toc"
},
{
"name": "Gateway Guide",
"md":"gateway_guide.md",
"html":"gateway_guide.html",
"ripple.com": "https://ripple.com/build/gateway-guide/",
"category": "Tutorials",
"sidebar": "page-toc"
},
{
"name": "Ripple Data API v2",
"md": "data_v2.md",
"html": "data_api_v2.html",
"ripple.com": "https://ripple.com/build/data-api-v2/",
"category": "References",
"sidebar": "page-toc"
},
{
"name": "RippleAPI",
"md": "https://raw.githubusercontent.com/ripple/ripple-lib/0.16.7/docs/index.md",
"html": "rippleapi.html",
"ripple.com": "https://ripple.com/build/rippleapi/",
"category": "References",
"sidebar": "page-toc"
},
{
"name": "WebSocket API Tool",
"template":"template-ripple-api-tool.html",
"category": "API Tools",
"ripple.com": "https://ripple.com/build/websocket-tool/",
"html": "ripple-api-tool.html",
"targets": ["local","ripple.com"],
"sidebar": "custom"
},
{
"name": "Data API v2 Tool",
"template":"template-rest-api-tool.html",
"methods_js": "js/apitool-methods-data_v2.js",
"category": "API Tools",
"rest_host": "https://data.ripple.com",
"html": "data-api-v2-tool.html",
"targets": ["local","ripple.com"],
"sidebar": "custom"
}
]

View File

@@ -60,6 +60,7 @@
<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-reliable-transaction-submission.html">Reliable Transaction Submission</a></li>
<li><a href="tutorial-multisign.html">Multi-Signing Transactions</a></li>
</ul>
</li>
<li class="dropdown">
@@ -72,6 +73,8 @@
<li><a href="concept-fee-voting.html">Fee Voting</a></li>
<li><a href="concept-reserves.html">Reserves</a></li>
<li><a href="concept-freeze.html">Freeze</a></li>
<li><a href="concept-amendments.html">Amendments</a></li>
<li><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
</ul>
</li>
<li class="dropdown">

715
tutorial-multisign.html Normal file
View File

@@ -0,0 +1,715 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible">
<meta content="width=device-width" name="viewport">
<title>Multi-Signing Transactions - Ripple Developer Portal</title>
<!-- favicon -->
<link href="favicon.ico" rel="icon" type="image/x-icon">
<link href="favicon.ico" rel="shortcut icon" 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 href="assets/vendor/docco.min.css" rel="stylesheet">
<script src="assets/vendor/highlight.min.js"></script>
<!-- syntax selection js -->
<script src="assets/js/multicodetab.js"></script>
<script>
$(document).ready(function() {
$().multicode_tabs();
hljs.initHighlighting();
make_code_expandable();
});
</script>
<script src="assets/js/expandcode.js"></script>
<script src="assets/js/fixsidebarscroll.js"></script>
</link></link></link></meta></meta></meta></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 class="banner navbar navbar-default navbar-fixed-top initial_header" role="banner">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="index.html"><img class="logo" src="assets/img/ripple-logo-color.png"/></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 class="menu" id="menu-dev-menu">
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">References <span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<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-rippleapi.html">RippleAPI</a></li>
<li><a href="reference-data-api.html">Ripple Data API v2</a></li>
</ul>
</li>
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">Tutorials <span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<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-reliable-transaction-submission.html">Reliable Transaction Submission</a></li>
<li><a href="tutorial-multisign.html">Multi-Signing Transactions</a></li>
</ul>
</li>
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">Concepts <span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<li><a href="concept-paths.html">Paths</a></li>
<li><a href="concept-fees.html">Fees (Disambiguation)</a></li>
<li><a href="concept-transfer-fees.html">Transfer Fees</a></li>
<li><a href="concept-transaction-cost.html">Transaction Cost</a></li>
<li><a href="concept-fee-voting.html">Fee Voting</a></li>
<li><a href="concept-reserves.html">Reserves</a></li>
<li><a href="concept-freeze.html">Freeze</a></li>
<li><a href="concept-amendments.html">Amendments</a></li>
<li><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
</ul>
</li>
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">Best Practices <span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<li><a href="concept-issuing-and-operational-addresses.html">Issuing and Operational Addresses</a></li>
<li><a href="tutorial-gateway-guide.html">Gateway Guide</a></li>
</ul>
</li>
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">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 class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">Resources <span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<li><a href="https://forum.ripple.com/viewforum.php?f=2">Forums</a></li>
<li><a href="https://www.bountysource.com/teams/ripple/bounties">Bounties</a></li>
<li><a href="https://ripplelabs.atlassian.net/">Bug Tracking</a></li>
<li><a href="https://ripple.com/category/dev-blog/">Dev Blog</a></li>
<li><a href="https://ripple.com/press-releases/">Press Center</a></li>
<li><a href="https://ripple.com/brand-guidelines/">Brand Guidelines</a></li>
</ul>
<li><a href="https://github.com/ripple/ripple-dev-portal" title="GitHub">Site Source</a></li>
</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">
<ul class="dev_nav_sidebar">
<li class="level-1"><a href="index.html">Category: Tutorials</a></li>
<li class="level-2"><a href="tutorial-rippleapi-beginners-guide.html">RippleAPI Beginners Guide</a></li>
<li class="level-2"><a href="tutorial-rippled-setup.html">rippled Setup</a></li>
<li class="level-2"><a href="tutorial-reliable-transaction-submission.html">Reliable Transaction Submission</a></li>
<li class="level-2"><a href="tutorial-multisign.html">Multi-Signing Transactions</a></li>
</ul>
<hr/>
<h5>In this page:</h5>
</div>
<script src="assets/js/jquery.gensidebar.js" type="text/javascript"></script>
</div>
</aside>
<main class="main" role="main">
<div class="content">
<h1 id="how-to-multi-sign">How to Multi-Sign</h1>
<p>Multi-signing is one of three ways to authorize transactions for the Ripple Consensus Ledger, alongside signing with <a href="reference-transaction-format.html#setregularkey">regular keys</a> and master keys. You can configure your address to allow any combination of the three methods to authorize transactions.</p>
<p>Benefits of multi-signing include:</p>
<ul>
<li>You can require keys from different devices, so that a malicious actor must compromise multiple machines to send transactions on your behalf.</li>
<li>You can share custody of an address between multiple people, each of whom only has one of several keys necessary to send transactions from that address.</li>
<li>You can delegate the power to send transactions from your address to a group of people, who can control your address if you are unavailable or unable to sign normally.</li>
<li>... and more.</li>
</ul>
<p>To use multi-signing:</p>
<ol>
<li><a href="#availability-of-multi-signing">The Ripple peer-to-peer network must have multi-signing enabled.</a></li>
<li><a href="#setting-up-multi-signing">Set up a list of signers on your account.</a></li>
<li><a href="#sending-a-multi-signed-transaction">Send transactions using multiple signatures.</a></li>
</ol>
<h2 id="availability-of-multi-signing">Availability of Multi-Signing</h2>
<p>Multi-signing is built into <code>rippled</code> starting with <a href="https://wiki.ripple.com/Rippled-0.31.0">version 0.31.0</a>. Because multi-signing is a change in transaction processing, the change is due to be enabled by an <strong>Amendment</strong> to the Ripple Consensus Protocol. This Amendment must be approved by a consensus of validators showing consistent support for the feature over a period of time. For more information, see <a href="concept-amendments.html">Amendments</a>.</p>
<p>If you want to test multi-signing before it becomes available in the production network, or without risking real money, you can do so by running <code>rippled</code> in <a href="concept-stand-alone-mode.html">stand-alone mode</a> with the MultiSign feature enabled. To enable multi-signing for testing, add the following stanza to your <code>rippled.cfg</code>:</p>
<pre><code>[features]
MultiSign
</code></pre>
<h2 id="setting-up-multi-signing">Setting up Multi-Signing</h2>
<p>Before you can set up multi-signing, first check that <a href="#availability-of-multi-signing">multi-signing is available</a>.</p>
<p>To multi-sign transactions from a particular address, you must create a list of addresses that can contribute to a multi-signature for your address. This list is stored in the Ripple Consensus Ledger as a <a href="reference-ledger-format.html#signerlist">SignerList node</a>. The following procedure demonstrates how to set up a SignerList for your address:</p>
<h3 id="1-prepare-a-funded-address">1. Prepare a funded address</h3>
<p>You need a Ripple address that can send transactions, and has enough XRP available. Multi-signing requires more than the usual amount of XRP for the <a href="concept-reserves.html">account reserve</a> and <a href="concept-transaction-cost.html">transaction cost</a>, increasing with the number of signers and signatures you use.</p>
<p>If you started <code>rippled</code> in <a href="concept-stand-alone-mode.html">stand-alone mode</a> with a new genesis ledger, you must:</p>
<ol>
<li>Generate keys for a new address, or reuse keys you already have.</li>
<li>Submit a Payment transaction to fund the new address from the genesis account. (Send at least 100,000,000 <a href="reference-rippled.html#specifying-currency-amounts">drops of XRP</a>.)</li>
<li>Manually close the ledger.</li>
</ol>
<h3 id="2-prepare-member-keys">2. Prepare member keys</h3>
<p>You need several sets of Ripple keys (address and secret) to include as members of your SignerList. These can be funded addresses that exist in the ledger, or you can generate new addresses using the <a href="reference-rippled.html#wallet-propose"><code>wallet_propose</code> command</a>. For example:</p>
<pre><code>$ rippled wallet_propose
Loading: "/home/mduo13/.config/ripple/rippled.cfg"
Connecting to 127.0.0.1:5005
{
"result" : {
"account_id" : "rnRJ4dpSBKDR2M1itf4Ah6tZZm5xuNZFPH",
"key_type" : "secp256k1",
"master_key" : "FLOG SEND GOES CUFF GAGE FAT ANTI DEL GUM TIRE ISLE BEAR",
"master_seed" : "snheH5UUjU4CWqiNVLny2k21TyKPC",
"master_seed_hex" : "A9F859765EB8614D26809836382AFB82",
"public_key" : "aBR4hxFXcDNHnGYvTiqb2KU8TTTV1cYV9wXTAuz2DjBm7S8TYEBU",
"public_key_hex" : "03C09A5D112B393D531E4F092E3A5769A5752129F0A9C55C61B3A226BB9B567B9B",
"status" : "success"
}
}
</code></pre>
<p>Take note of the <code>account_id</code> (Ripple Address) and <code>master_seed</code> (Ripple secret key) for each one you generate.</p>
<h3 id="3-send-signerlistset-transaction">3. Send SignerListSet transaction</h3>
<p><a href="reference-transaction-format.html#signing-and-submitting-transactions">Sign and submit</a> a <a href="reference-transaction-format.html#signerlistset">SignerListSet transaction</a> in the normal (single-signature) way. This associates a SignerList with your Ripple address, so that a combination of signatures from the members of that SignerList can multi-sign later transactions on your behalf.</p>
<p>In this example, the SignerList has 3 members, with the weights and quorum set up such that multi-signed transactions need a signature from rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW plus at least one signature from the other two members of the list.</p>
<p><strong>Caution:</strong> Never submit a secret key to a server you do not control. Do not transmit a secret key unencrypted over the network.</p>
<pre><code>$ rippled submit shqZZy2Rzs9ZqWTCQAdqc3bKgxnYq '{
&gt; "Flags": 0,
&gt; "TransactionType": "SignerListSet",
&gt; "Account": "rnBFvgZphmN39GWzUJeUitaP22Fr9be75H",
&gt; "Fee": "10000",
&gt; "SignerQuorum": 3,
&gt; "SignerEntries": [
&gt; {
&gt; "SignerEntry": {
&gt; "Account": "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW",
&gt; "SignerWeight": 2
&gt; }
&gt; },
&gt; {
&gt; "SignerEntry": {
&gt; "Account": "rUpy3eEg8rqjqfUoLeBnZkscbKbFsKXC3v",
&gt; "SignerWeight": 1
&gt; }
&gt; },
&gt; {
&gt; "SignerEntry": {
&gt; "Account": "raKEEVSGnKSD9Zyvxu4z6Pqpm4ABH8FS6n",
&gt; "SignerWeight": 1
&gt; }
&gt; }
&gt; ]
&gt; }'
Loading: "/home/mduo13/.config/ripple/rippled.cfg"
Connecting to 127.0.0.1:5005
{
"result" : {
"engine_result" : "tesSUCCESS",
"engine_result_code" : 0,
"engine_result_message" : "The transaction was applied. Only final in a validated ledger.",
"status" : "success",
"tx_blob" : "12000C2200000000240000000120230000000368400000000000271073210303E20EC6B4A39A629815AE02C0A1393B9225E3B890CAE45B59F42FA29BE9668D74473045022100BEDFA12502C66DDCB64521972E5356F4DB965F553853D53D4C69B4897F11B4780220595202D1E080345B65BAF8EBD6CA161C227F1B62C7E72EA5CA282B9434A6F04281142DECAB42CA805119A9BA2FF305C9AFA12F0B86A1F4EB1300028114204288D2E47F8EF6C99BCC457966320D12409711E1EB13000181147908A7F0EDD48EA896C3580A399F0EE78611C8E3E1EB13000181143A4C02EA95AD6AC3BED92FA036E0BBFB712C030CE1F1",
"tx_json" : {
"Account" : "rnBFvgZphmN39GWzUJeUitaP22Fr9be75H",
"Fee" : "10000",
"Flags" : 0,
"Sequence" : 1,
"SignerEntries" : [
{
"SignerEntry" : {
"Account" : "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW",
"SignerWeight" : 2
}
},
{
"SignerEntry" : {
"Account" : "rUpy3eEg8rqjqfUoLeBnZkscbKbFsKXC3v",
"SignerWeight" : 1
}
},
{
"SignerEntry" : {
"Account" : "raKEEVSGnKSD9Zyvxu4z6Pqpm4ABH8FS6n",
"SignerWeight" : 1
}
}
],
"SignerQuorum" : 3,
"SigningPubKey" : "0303E20EC6B4A39A629815AE02C0A1393B9225E3B890CAE45B59F42FA29BE9668D",
"TransactionType" : "SignerListSet",
"TxnSignature" : "3045022100BEDFA12502C66DDCB64521972E5356F4DB965F553853D53D4C69B4897F11B4780220595202D1E080345B65BAF8EBD6CA161C227F1B62C7E72EA5CA282B9434A6F042",
"hash" : "3950D98AD20DA52EBB1F3937EF32F382D74092A4C8DF9A0B1A06ED25200B5756"
}
}
}
</code></pre>
<p>Make sure that the <a href="reference-transaction-format.html#transaction-results">Transaction Result</a> is <a href="reference-transaction-format.html#tes-success"><strong>tesSUCCESS</strong></a>. Otherwise, the transaction failed.</p>
<p><strong>Note:</strong> The more members in the SignerList, the more XRP your address must have for purposes of the <a href="concept-reserves.html#owner-reserves">owner reserve</a>. If your address does not have enough XRP, the transaction fails with <a href="reference-transaction-format.html#tec-codes">tecINSUFFICIENT_RESERVE</a>. See also: <a href="reference-ledger-format.html#signerlists-and-reserves">SignerLists and Reserves</a>.</p>
<h3 id="4-close-the-ledger">4. Close the ledger</h3>
<p>On the live network, you can wait 4-7 seconds for the ledger to close automatically.</p>
<p>If you're running <code>rippled</code> in stand-alone mode, use the <a href="reference-rippled.html#ledger-accept"><code>ledger_accept</code> command</a> to manually close the ledger:</p>
<pre><code>$ rippled ledger_accept
Loading: "/home/mduo13/.config/ripple/rippled.cfg"
Connecting to 127.0.0.1:5005
{
"result" : {
"ledger_current_index" : 6,
"status" : "success"
}
}
</code></pre>
<h3 id="5-confirm-the-new-signer-list">5. Confirm the new signer list</h3>
<p>Use the <a href="reference-rippled.html#account-objects"><code>account_objects</code> command</a> to confirm that the SignerList is associated with the address in the latest validated ledger.</p>
<p>Normally, an account can own many objects of different types (such as trust lines and offers). If you funded a new address for this tutorial, the SignerList is the only object in the response.</p>
<pre><code>$ rippled account_objects rEuLyBCvcw4CFmzv8RepSiAoNgF8tTGJQC validated
Loading: "/home/mduo13/.config/ripple/rippled.cfg"
Connecting to 127.0.0.1:5005
{
"result" : {
"account" : "rEuLyBCvcw4CFmzv8RepSiAoNgF8tTGJQC",
"account_objects" : [
{
"Flags" : 0,
"LedgerEntryType" : "SignerList",
"OwnerNode" : "0000000000000000",
"PreviousTxnID" : "8FDC18960455C196A8C4DE0D24799209A21F4A17E32102B5162BD79466B90222",
"PreviousTxnLgrSeq" : 5,
"SignerEntries" : [
{
"SignerEntry" : {
"Account" : "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW",
"SignerWeight" : 2
}
},
{
"SignerEntry" : {
"Account" : "raKEEVSGnKSD9Zyvxu4z6Pqpm4ABH8FS6n",
"SignerWeight" : 1
}
},
{
"SignerEntry" : {
"Account" : "rUpy3eEg8rqjqfUoLeBnZkscbKbFsKXC3v",
"SignerWeight" : 1
}
}
],
"SignerListID" : 0,
"SignerQuorum" : 3,
"index" : "79FD203E4DDDF2EA78B798C963487120C048C78652A28682425E47C96D016F92"
}
],
"ledger_hash" : "56E81069F06492FB410A70218C08169BE3AB3CFD5AEA20E999662D81DC361D9F",
"ledger_index" : 5,
"status" : "success",
"validated" : true
}
}
</code></pre>
<p>If the SignerList is present with the expected contents, then your address is ready to multi-sign.</p>
<h3 id="6-further-steps">6. Further steps</h3>
<p>At this point, your address is ready to <a href="#sending-a-multi-signed-transaction">send a multi-signed transaction</a>. You may also want to:</p>
<ul>
<li>Disable the address's master key by sending an <a href="reference-transaction-format.html#accountset">AccountSet transaction</a> using the <code>asfDisableMaster</code> flag.</li>
<li>Remove the address's regular key (if you previously set one) by sending a <a href="reference-transaction-format.html#setregularkey">SetRegularKey transaction</a>.</li>
</ul>
<h2 id="sending-a-multi-signed-transaction">Sending a Multi-Signed Transaction</h2>
<p>Before you can multi-sign a transaction, first <a href="#setting-up-multi-signing">set up multi-signing</a> for your address. The following procedure demonstrates how to create, sign, and submit a multi-signed transaction.</p>
<h3 id="1-create-the-transaction">1. Create the transaction</h3>
<p>Create a JSON object that represents the transaction you want to submit. You have to specify <em>everything</em> about this transaction, including <code>Fee</code> and <code>Sequence</code>. Also include the field <code>SigningPubKey</code> as an empty string, to indicate that the transaction is multi-signed.</p>
<p>Keep in mind that the <code>Fee</code> for multi-signed transactions is significantly higher than for regularly-signed transactions. It should be (N+1) times the normal <a href="concept-transaction-cost.html">transaction cost</a>, where N is the number of signatures you plan to provide. Given that it sometimes takes a while to collect signatures from multiple sources, you may want to include additional buffer in case the <a href="concept-transaction-cost.html">transaction cost</a> increases in that time.</p>
<p>Here's an example transaction ready to be multi-signed:</p>
<pre><code>{
"TransactionType": "TrustSet",
"Account": "rEuLyBCvcw4CFmzv8RepSiAoNgF8tTGJQC",
"Flags": 262144,
"LimitAmount": {
"currency": "USD",
"issuer": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"value": "100"
},
"Sequence": 2,
"SigningPubKey": "",
"Fee": "30000"
}
</code></pre>
<p>(This transaction creates an accounting relationship from rEuLyBCvcw4CFmzv8RepSiAoNgF8tTGJQC to rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh with a maximum balance of 100 USD.)</p>
<h3 id="2-get-one-signature">2. Get one signature</h3>
<p>Use the <a href="reference-rippled.html#sign-for"><code>sign_for</code> command</a> with the secret key and address of one of the members of your SignerList to get a signature for that member.</p>
<p><strong>Caution:</strong> Never submit a secret key to a server you do not control. Do not transmit a secret key unencrypted over the network.</p>
<pre><code>$ rippled sign_for rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW &lt;rsA2L..'s secret&gt; '{
&gt; "TransactionType": "TrustSet",
&gt; "Account": "rEuLyBCvcw4CFmzv8RepSiAoNgF8tTGJQC",
&gt; "Flags": 262144,
&gt; "LimitAmount": {
&gt; "currency": "USD",
&gt; "issuer": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
&gt; "value": "100"
&gt; },
&gt; "Sequence": 2,
&gt; "SigningPubKey": "",
&gt; "Fee": "30000"
&gt; }'
Loading: "/home/mduo13/.config/ripple/rippled.cfg"
Connecting to 127.0.0.1:5005
{
"result" : {
"status" : "success",
"tx_blob" : "1200142200040000240000000263D5038D7EA4C680000000000000000000000000005553440000000000B5F762798A53D543A014CAF8B297CFF8F2F937E868400000000000753073008114A3780F5CB5A44D366520FC44055E8ED44D9A2270F3E010732102B3EC4E5DD96029A647CFA20DA07FE1F85296505552CCAC114087E66B46BD77DF744730450221009C195DBBF7967E223D8626CA19CF02073667F2B22E206727BFE848FF42BEAC8A022048C323B0BED19A988BDBEFA974B6DE8AA9DCAE250AA82BBD1221787032A864E58114204288D2E47F8EF6C99BCC457966320D12409711E1F1",
"tx_json" : {
"Account" : "rEuLyBCvcw4CFmzv8RepSiAoNgF8tTGJQC",
"Fee" : "30000",
"Flags" : 262144,
"LimitAmount" : {
"currency" : "USD",
"issuer" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"value" : "100"
},
"Sequence" : 2,
"Signers" : [
{
"Signer" : {
"Account" : "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW",
"SigningPubKey" : "02B3EC4E5DD96029A647CFA20DA07FE1F85296505552CCAC114087E66B46BD77DF",
"TxnSignature" : "30450221009C195DBBF7967E223D8626CA19CF02073667F2B22E206727BFE848FF42BEAC8A022048C323B0BED19A988BDBEFA974B6DE8AA9DCAE250AA82BBD1221787032A864E5"
}
}
],
"SigningPubKey" : "",
"TransactionType" : "TrustSet",
"hash" : "A94A6417D1A7AAB059822B894E13D322ED3712F7212CE9257801F96DE6C3F6AE"
}
}
}
</code></pre>
<p>Save the <code>tx_json</code> field of the response: it has the new signature in the <code>Signers</code> field. You can discard the value of the <code>tx_blob</code> field.</p>
<h3 id="3-get-additional-signatures">3. Get additional signatures</h3>
<p>You can collect additional signatures in parallel or in serial:</p>
<ul>
<li>In parallel: Use the <code>sign_for</code> command with the original JSON for the transaction. Each response has a single signature in the <code>Signers</code> array.</li>
<li>In serial: Use the <code>sign_for</code> command with the <code>tx_json</code> value from the previous <code>sign_for</code> response. Each response adds a new signature to the existing <code>Signers</code> array.</li>
</ul>
<p><strong>Caution:</strong> Never submit a secret key to a server you do not control. Do not transmit a secret key unencrypted over the network.</p>
<pre><code>$ rippled sign_for rUpy3eEg8rqjqfUoLeBnZkscbKbFsKXC3v &lt;rUpy..'s secret&gt; '{
&gt; "Account" : "rEuLyBCvcw4CFmzv8RepSiAoNgF8tTGJQC",
&gt; "Fee" : "30000",
&gt; "Flags" : 262144,
&gt; "LimitAmount" : {
&gt; "currency" : "USD",
&gt; "issuer" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
&gt; "value" : "100"
&gt; },
&gt; "Sequence" : 2,
&gt; "Signers" : [
&gt; {
&gt; "Signer" : {
&gt; "Account" : "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW",
&gt; "SigningPubKey" : "02B3EC4E5DD96029A647CFA20DA07FE1F85296505552CCAC114087E66B46BD77DF",
&gt; "TxnSignature" : "30450221009C195DBBF7967E223D8626CA19CF02073667F2B22E206727BFE848FF42BEAC8A022048C323B0BED19A988BDBEFA974B6DE8AA9DCAE250AA82BBD1221787032A864E5"
&gt; }
&gt; }
&gt; ],
&gt; "SigningPubKey" : "",
&gt; "TransactionType" : "TrustSet",
&gt; "hash" : "A94A6417D1A7AAB059822B894E13D322ED3712F7212CE9257801F96DE6C3F6AE"
&gt; }'
Loading: "/home/mduo13/.config/ripple/rippled.cfg"
Connecting to 127.0.0.1:5005
{
"result" : {
"status" : "success",
"tx_blob" : "1200142200040000240000000263D5038D7EA4C680000000000000000000000000005553440000000000B5F762798A53D543A014CAF8B297CFF8F2F937E868400000000000753073008114A3780F5CB5A44D366520FC44055E8ED44D9A2270F3E010732102B3EC4E5DD96029A647CFA20DA07FE1F85296505552CCAC114087E66B46BD77DF744730450221009C195DBBF7967E223D8626CA19CF02073667F2B22E206727BFE848FF42BEAC8A022048C323B0BED19A988BDBEFA974B6DE8AA9DCAE250AA82BBD1221787032A864E58114204288D2E47F8EF6C99BCC457966320D12409711E1E0107321028FFB276505F9AC3F57E8D5242B386A597EF6C40A7999F37F1948636FD484E25B744630440220680BBD745004E9CFB6B13A137F505FB92298AD309071D16C7B982825188FD1AE022004200B1F7E4A6A84BB0E4FC09E1E3BA2B66EBD32F0E6D121A34BA3B04AD99BC181147908A7F0EDD48EA896C3580A399F0EE78611C8E3E1F1",
"tx_json" : {
"Account" : "rEuLyBCvcw4CFmzv8RepSiAoNgF8tTGJQC",
"Fee" : "30000",
"Flags" : 262144,
"LimitAmount" : {
"currency" : "USD",
"issuer" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"value" : "100"
},
"Sequence" : 2,
"Signers" : [
{
"Signer" : {
"Account" : "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW",
"SigningPubKey" : "02B3EC4E5DD96029A647CFA20DA07FE1F85296505552CCAC114087E66B46BD77DF",
"TxnSignature" : "30450221009C195DBBF7967E223D8626CA19CF02073667F2B22E206727BFE848FF42BEAC8A022048C323B0BED19A988BDBEFA974B6DE8AA9DCAE250AA82BBD1221787032A864E5"
}
},
{
"Signer" : {
"Account" : "rUpy3eEg8rqjqfUoLeBnZkscbKbFsKXC3v",
"SigningPubKey" : "028FFB276505F9AC3F57E8D5242B386A597EF6C40A7999F37F1948636FD484E25B",
"TxnSignature" : "30440220680BBD745004E9CFB6B13A137F505FB92298AD309071D16C7B982825188FD1AE022004200B1F7E4A6A84BB0E4FC09E1E3BA2B66EBD32F0E6D121A34BA3B04AD99BC1"
}
}
],
"SigningPubKey" : "",
"TransactionType" : "TrustSet",
"hash" : "BD636194C48FD7A100DE4C972336534C8E710FD008C0F3CF7BC5BF34DAF3C3E6"
}
}
}
</code></pre>
<p>Depending on the SignerList you configured, you may need to repeat this step several times to get signatures from all the necessary parties.</p>
<h3 id="4-combine-signatures-and-submit">4. Combine signatures and submit</h3>
<p>If you collected the signatures in serial, the <code>tx_json</code> from the last <code>sign_for</code> response has all the signatures assembled, so you can use that as the argument to the <a href="reference-rippled.html#submit-multisigned"><code>submit_multisigned</code> command</a>.</p>
<p>If you collected the signatures in parallel, you must manually construct a <code>tx_json</code> object with all the signatures included. Take the <code>Signers</code> arrays from all the <code>sign_for</code> responses, and combine their contents into a single <code>Signers</code> array that has each signature. Add the combined <code>Signers</code> array to the original transaction JSON value, and use that as the argument to the <a href="reference-rippled.html#submit-multisigned"><code>submit_multisigned</code> command</a>.</p>
<pre><code>$ rippled submit_multisigned '{
&gt; "Account" : "rEuLyBCvcw4CFmzv8RepSiAoNgF8tTGJQC",
&gt; "Fee" : "30000",
&gt; "Flags" : 262144,
&gt; "LimitAmount" : {
&gt; "currency" : "USD",
&gt; "issuer" : "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
&gt; "value" : "100"
&gt; },
&gt; "Sequence" : 2,
&gt; "Signers" : [
&gt; {
&gt; "Signer" : {
&gt; "Account" : "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW",
&gt; "SigningPubKey" : "02B3EC4E5DD96029A647CFA20DA07FE1F85296505552CCAC114087E66B46BD77DF",
&gt; "TxnSignature" : "30450221009C195DBBF7967E223D8626CA19CF02073667F2B22E206727BFE848FF42BEAC8A022048C323B0BED19A988BDBEFA974B6DE8AA9DCAE250AA82BBD1221787032A864E5"
&gt; }
&gt; },
&gt; {
&gt; "Signer" : {
&gt; "Account" : "rUpy3eEg8rqjqfUoLeBnZkscbKbFsKXC3v",
&gt; "SigningPubKey" : "028FFB276505F9AC3F57E8D5242B386A597EF6C40A7999F37F1948636FD484E25B",
&gt; "TxnSignature" : "30440220680BBD745004E9CFB6B13A137F505FB92298AD309071D16C7B982825188FD1AE022004200B1F7E4A6A84BB0E4FC09E1E3BA2B66EBD32F0E6D121A34BA3B04AD99BC1"
&gt; }
&gt; }
&gt; ],
&gt; "SigningPubKey" : "",
&gt; "TransactionType" : "TrustSet",
&gt; "hash" : "BD636194C48FD7A100DE4C972336534C8E710FD008C0F3CF7BC5BF34DAF3C3E6"
&gt; }'
Loading: "/home/mduo13/.config/ripple/rippled.cfg"
Connecting to 127.0.0.1:5005
{
"result": {
"engine_result": "tesSUCCESS",
"engine_result_code": 0,
"engine_result_message": "The transaction was applied. Only final in a validated ledger.",
"status": "success",
"tx_blob": "1200142200040000240000000263D5038D7EA4C680000000000000000000000000005553440000000000B5F762798A53D543A014CAF8B297CFF8F2F937E868400000000000753073008114A3780F5CB5A44D366520FC44055E8ED44D9A2270F3E010732102B3EC4E5DD96029A647CFA20DA07FE1F85296505552CCAC114087E66B46BD77DF744730450221009C195DBBF7967E223D8626CA19CF02073667F2B22E206727BFE848FF42BEAC8A022048C323B0BED19A988BDBEFA974B6DE8AA9DCAE250AA82BBD1221787032A864E58114204288D2E47F8EF6C99BCC457966320D12409711E1E0107321028FFB276505F9AC3F57E8D5242B386A597EF6C40A7999F37F1948636FD484E25B744630440220680BBD745004E9CFB6B13A137F505FB92298AD309071D16C7B982825188FD1AE022004200B1F7E4A6A84BB0E4FC09E1E3BA2B66EBD32F0E6D121A34BA3B04AD99BC181147908A7F0EDD48EA896C3580A399F0EE78611C8E3E1F1",
"tx_json": {
"Account": "rEuLyBCvcw4CFmzv8RepSiAoNgF8tTGJQC",
"Fee": "30000",
"Flags": 262144,
"LimitAmount": {
"currency": "USD",
"issuer": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"value": "100"
},
"Sequence": 2,
"Signers": [{
"Signer": {
"Account": "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW",
"SigningPubKey": "02B3EC4E5DD96029A647CFA20DA07FE1F85296505552CCAC114087E66B46BD77DF",
"TxnSignature": "30450221009C195DBBF7967E223D8626CA19CF02073667F2B22E206727BFE848FF42BEAC8A022048C323B0BED19A988BDBEFA974B6DE8AA9DCAE250AA82BBD1221787032A864E5"
}
}, {
"Signer": {
"Account": "rUpy3eEg8rqjqfUoLeBnZkscbKbFsKXC3v",
"SigningPubKey": "028FFB276505F9AC3F57E8D5242B386A597EF6C40A7999F37F1948636FD484E25B",
"TxnSignature": "30440220680BBD745004E9CFB6B13A137F505FB92298AD309071D16C7B982825188FD1AE022004200B1F7E4A6A84BB0E4FC09E1E3BA2B66EBD32F0E6D121A34BA3B04AD99BC1"
}
}],
"SigningPubKey": "",
"TransactionType": "TrustSet",
"hash": "BD636194C48FD7A100DE4C972336534C8E710FD008C0F3CF7BC5BF34DAF3C3E6"
}
}
}
</code></pre>
<p>Take note of the <code>hash</code> value from the response so you can check the results of the transaction later. (In this case, the hash is <code>BD636194C48FD7A100DE4C972336534C8E710FD008C0F3CF7BC5BF34DAF3C3E6</code>.)</p>
<h3 id="5-close-the-ledger">5. Close the ledger</h3>
<p>If you are using the live network, you can wait 4-7 seconds for the ledger to close automatically.</p>
<p>If you're running <code>rippled</code> in stand-alone mode, use the <a href="reference-rippled.html#ledger-accept"><code>ledger_accept</code> command</a> to manually close the ledger:</p>
<pre><code>$ rippled ledger_accept
Loading: "/home/mduo13/.config/ripple/rippled.cfg"
Connecting to 127.0.0.1:5005
{
"result" : {
"ledger_current_index" : 7,
"status" : "success"
}
}
</code></pre>
<h3 id="6-confirm-transaction-results">6. Confirm transaction results</h3>
<p>Use the hash value from the response to the <code>submit_multisigned</code> command to look up the transaction using the <a href="reference-rippled.html#tx"><code>tx</code> command</a>. In particular, check that the <code>TransactionResult</code> is the string <code>tesSUCCESS</code>.</p>
<p>On the live network, you must also confirm that the <code>validated</code> field is set to the boolean <code>true</code>. If the field is not <code>true</code>, you might need to wait longer for the consensus process to finish; or your transaction may be unable to be included in a ledger for some reason.</p>
<p>In stand-alone mode, the server automatically considers a ledger to be <code>validated</code> if it has been manually closed.</p>
<pre><code>$ rippled tx BD636194C48FD7A100DE4C972336534C8E710FD008C0F3CF7BC5BF34DAF3C3E6
Loading: "/home/mduo13/.config/ripple/rippled.cfg"
Connecting to 127.0.0.1:5005
{
"result": {
"Account": "rEuLyBCvcw4CFmzv8RepSiAoNgF8tTGJQC",
"Fee": "30000",
"Flags": 262144,
"LimitAmount": {
"currency": "USD",
"issuer": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"value": "100"
},
"Sequence": 2,
"Signers": [{
"Signer": {
"Account": "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW",
"SigningPubKey": "02B3EC4E5DD96029A647CFA20DA07FE1F85296505552CCAC114087E66B46BD77DF",
"TxnSignature": "30450221009C195DBBF7967E223D8626CA19CF02073667F2B22E206727BFE848FF42BEAC8A022048C323B0BED19A988BDBEFA974B6DE8AA9DCAE250AA82BBD1221787032A864E5"
}
}, {
"Signer": {
"Account": "rUpy3eEg8rqjqfUoLeBnZkscbKbFsKXC3v",
"SigningPubKey": "028FFB276505F9AC3F57E8D5242B386A597EF6C40A7999F37F1948636FD484E25B",
"TxnSignature": "30440220680BBD745004E9CFB6B13A137F505FB92298AD309071D16C7B982825188FD1AE022004200B1F7E4A6A84BB0E4FC09E1E3BA2B66EBD32F0E6D121A34BA3B04AD99BC1"
}
}],
"SigningPubKey": "",
"TransactionType": "TrustSet",
"date": 512172510,
"hash": "BD636194C48FD7A100DE4C972336534C8E710FD008C0F3CF7BC5BF34DAF3C3E6",
"inLedger": 6,
"ledger_index": 6,
"meta": {
"AffectedNodes": [{
"ModifiedNode": {
"LedgerEntryType": "AccountRoot",
"LedgerIndex": "2B6AC232AA4C4BE41BF49D2459FA4A0347E1B543A4C92FCEE0821C0201E2E9A8",
"PreviousTxnID": "B7E1D33DB7DEA3BB65BFAB2C80E02125F47FCCF6C957A7FDECD915B3EBE0C1DD",
"PreviousTxnLgrSeq": 4
}
}, {
"CreatedNode": {
"LedgerEntryType": "RippleState",
"LedgerIndex": "93E317B32022977C77810A2C558FBB28E30E744C68E73720622B797F957EC5FA",
"NewFields": {
"Balance": {
"currency": "USD",
"issuer": "rrrrrrrrrrrrrrrrrrrrBZbvji",
"value": "0"
},
"Flags": 2162688,
"HighLimit": {
"currency": "USD",
"issuer": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"value": "0"
},
"LowLimit": {
"currency": "USD",
"issuer": "rEuLyBCvcw4CFmzv8RepSiAoNgF8tTGJQC",
"value": "100"
}
}
}
}, {
"ModifiedNode": {
"FinalFields": {
"Account": "rEuLyBCvcw4CFmzv8RepSiAoNgF8tTGJQC",
"Balance": "999960000",
"Flags": 0,
"OwnerCount": 6,
"Sequence": 3
},
"LedgerEntryType": "AccountRoot",
"LedgerIndex": "A6B1BA6F2D70813100908EA84ABB7783695050312735E2C3665259F388804EA0",
"PreviousFields": {
"Balance": "999990000",
"OwnerCount": 5,
"Sequence": 2
},
"PreviousTxnID": "8FDC18960455C196A8C4DE0D24799209A21F4A17E32102B5162BD79466B90222",
"PreviousTxnLgrSeq": 5
}
}, {
"ModifiedNode": {
"FinalFields": {
"Flags": 0,
"Owner": "rEuLyBCvcw4CFmzv8RepSiAoNgF8tTGJQC",
"RootIndex": "C2728175908D82FB1DE6676F203D8D3C056995A9FA9B369EF326523F1C65A1DE"
},
"LedgerEntryType": "DirectoryNode",
"LedgerIndex": "C2728175908D82FB1DE6676F203D8D3C056995A9FA9B369EF326523F1C65A1DE"
}
}, {
"CreatedNode": {
"LedgerEntryType": "DirectoryNode",
"LedgerIndex": "D8120FC732737A2CF2E9968FDF3797A43B457F2A81AA06D2653171A1EA635204",
"NewFields": {
"Owner": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"RootIndex": "D8120FC732737A2CF2E9968FDF3797A43B457F2A81AA06D2653171A1EA635204"
}
}
}],
"TransactionIndex": 0,
"TransactionResult": "tesSUCCESS"
},
"status": "success",
"validated": true
}
}
</code></pre>
</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 class="menu" id="menu-resources">
<li class="menu-insights"><a href="https://ripple.com/insights/">Insights</a></li>
<li class="menu-press-center"><a href="https://ripple.com/press-center/">Press Center</a></li>
<li class="menu-media-resources"><a href="https://ripple.com/media-resources/">Media Resources</a></li>
<li class="menu-videos"><a href="https://ripple.com/videos/">Videos</a></li>
<li class="menu-whitepapers-reports"><a href="https://ripple.com/whitepapers-reports/">Whitepapers &amp; Reports</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 class="menu" id="menu-compliance-regulatory-relations"><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 class="menu" id="menu-dev-footer-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 href="https://forum.ripple.com/" target="_blank">Ripple Forum</a></li>
</ul>
</section>
<section class="col-sm-3 widget nav_menu-2 widget_nav_menu">
<h4>About<hr/></h4>
<ul class="menu" id="menu-company-footer">
<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>© 2013-2015 Ripple Labs, Inc. All Rights Reserved.</span>
<span><a href="https://ripple.com/terms-of-use/">Terms</a></span>
<span><a href="https://ripple.com/privacy-policy/">Privacy</a></span>
</div>
</div><!-- /.absolute_bottom_footer -->
</div><!-- /.row -->
</div><!-- /.container -->
</footer>
</body>
</html>

View File

@@ -60,6 +60,7 @@
<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-reliable-transaction-submission.html">Reliable Transaction Submission</a></li>
<li><a href="tutorial-multisign.html">Multi-Signing Transactions</a></li>
</ul>
</li>
<li class="dropdown">
@@ -72,6 +73,8 @@
<li><a href="concept-fee-voting.html">Fee Voting</a></li>
<li><a href="concept-reserves.html">Reserves</a></li>
<li><a href="concept-freeze.html">Freeze</a></li>
<li><a href="concept-amendments.html">Amendments</a></li>
<li><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
</ul>
</li>
<li class="dropdown">
@@ -113,6 +116,7 @@
<li class="level-2"><a href="tutorial-rippleapi-beginners-guide.html">RippleAPI Beginners Guide</a></li>
<li class="level-2"><a href="tutorial-rippled-setup.html">rippled Setup</a></li>
<li class="level-2"><a href="tutorial-reliable-transaction-submission.html">Reliable Transaction Submission</a></li>
<li class="level-2"><a href="tutorial-multisign.html">Multi-Signing Transactions</a></li>
</ul>
<hr/>
<h5>In this page:</h5>

View File

@@ -60,6 +60,7 @@
<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-reliable-transaction-submission.html">Reliable Transaction Submission</a></li>
<li><a href="tutorial-multisign.html">Multi-Signing Transactions</a></li>
</ul>
</li>
<li class="dropdown">
@@ -72,6 +73,8 @@
<li><a href="concept-fee-voting.html">Fee Voting</a></li>
<li><a href="concept-reserves.html">Reserves</a></li>
<li><a href="concept-freeze.html">Freeze</a></li>
<li><a href="concept-amendments.html">Amendments</a></li>
<li><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
</ul>
</li>
<li class="dropdown">
@@ -113,6 +116,7 @@
<li class="level-2"><a href="tutorial-rippleapi-beginners-guide.html">RippleAPI Beginners Guide</a></li>
<li class="level-2"><a href="tutorial-rippled-setup.html">rippled Setup</a></li>
<li class="level-2"><a href="tutorial-reliable-transaction-submission.html">Reliable Transaction Submission</a></li>
<li class="level-2"><a href="tutorial-multisign.html">Multi-Signing Transactions</a></li>
</ul>
<hr/>
<h5>In this page:</h5>

View File

@@ -60,6 +60,7 @@
<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-reliable-transaction-submission.html">Reliable Transaction Submission</a></li>
<li><a href="tutorial-multisign.html">Multi-Signing Transactions</a></li>
</ul>
</li>
<li class="dropdown">
@@ -72,6 +73,8 @@
<li><a href="concept-fee-voting.html">Fee Voting</a></li>
<li><a href="concept-reserves.html">Reserves</a></li>
<li><a href="concept-freeze.html">Freeze</a></li>
<li><a href="concept-amendments.html">Amendments</a></li>
<li><a href="concept-stand-alone-mode.html">Stand-Alone Mode</a></li>
</ul>
</li>
<li class="dropdown">
@@ -113,6 +116,7 @@
<li class="level-2"><a href="tutorial-rippleapi-beginners-guide.html">RippleAPI Beginners Guide</a></li>
<li class="level-2"><a href="tutorial-rippled-setup.html">rippled Setup</a></li>
<li class="level-2"><a href="tutorial-reliable-transaction-submission.html">Reliable Transaction Submission</a></li>
<li class="level-2"><a href="tutorial-multisign.html">Multi-Signing Transactions</a></li>
</ul>
<hr/>
<h5>In this page:</h5>