Merge pull request #718 from mDuo13/ja_target

Add Japanese translation
This commit is contained in:
Rome Reginelli
2019-11-09 06:36:24 -08:00
committed by GitHub
296 changed files with 36177 additions and 305 deletions

View File

@@ -0,0 +1,329 @@
# RippleAPI入門ガイド
このチュートリアルでは、[Node.js](http://nodejs.org/)と[RippleAPI](rippleapi-reference.html)XRP LedgerにアクセスするためのJavaScript APIを使用して、XRP Ledgerに接続されるアプリケーションを開発するための基本事項を説明します。
このガイドで使用しているスクリプトと構成ファイルは、[Ripple開発者ポータルのGitHubリポジトリで入手できます](https://github.com/ripple/ripple-dev-portal/tree/master/content/_code-samples/rippleapi_quickstart)。
<!--#{ keep multiple H1s so that all steps are surfaced in sidebar. Do not change H1 titles unless they provide a clear improvement bc they are linked to on external sites. }# -->
# 環境の設置
RippleAPIを使用するための最初のステップは、開発環境の設置です。
## Node.jsとnpmのインストール
RippleAPIはNode.jsランタイム環境向けのアプリケーションとして構築されているため、最初のステップはNode.jsのインストールです。RippleAPIでは、Node.js v6以降が必要です。Node.js v10 LTSを使用することをお勧めします。
このステップは、オペレーティングシステムによって内容が異なります。使用しているオペレーティングシステムの[パッケージマネージャーを使用してNode.jsをインストールする場合の公式の手引き](https://nodejs.org/en/download/package-manager/)に準拠することをお勧めします。Node.jsとnpmNode Package Managerのパッケージが分かれている場合、両方をインストールしますこれに該当するのは、Arch Linux、CentOS、Fedora、RHELの場合です
Node.jsのインストール後、`node`バイナリーのバージョンはコマンドラインから確認できます。
```
node --version
```
プラットフォームによっては、バイナリーの名前が`nodejs`となっています。
```
nodejs --version
```
## Yarnのインストール
RippleAPIでは、Yarnを使用して依存関係を管理します。Yarn v1.13.0を使用することをお勧めします。
このステップは、オペレーティングシステムによって内容が異なります。使用しているオペレーティングシステムの[パッケージマネージャーを使用してYarnをインストールする場合の公式の手引き](https://yarnpkg.com/en/docs/install#mac-stable)に準拠することをお勧めします。
Yarnのインストール後、`yarn`バイナリーのバージョンはコマンドラインから確認できます。
```
yarn --version
```
## RippleAPIと依存関係のインストール
以下のステップに従い、Yarnを使用してRippleAPIと依存関係のインストールを完了します。
### 1. プロジェクトの新規ディレクトリーを作成
`my_ripple_experiment`といった名前でフォルダーを作成します。
```
mkdir my_ripple_experiment && cd my_ripple_experiment
```
コードに対する変更を追跡できるよう、このディレクトリーに[Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)リポジトリーを作成します(省略可)。
```
git init
```
作業内容のバージョン管理や共有を目的として、[GitHubにリポジトリーを作成](https://help.github.com/articles/create-a-repo/)してもかまいません。設置後、ローカルマシンに[リポジトリーのクローンを作成](https://help.github.com/articles/cloning-a-repository/)し、そのディレクトリーに`cd`します。
### 2. プロジェクトの新規`package.json`ファイルを作成
次の内容が含まれている、以下のテンプレートを使用します。
- RippleAPI自体`ripple-lib`
- (省略可)コード品質を確認するための[ESLint](http://eslint.org/)`eslint`
```
{% include '_code-samples/rippleapi_quickstart/package.json' %}
```
### 3. Yarnを使用してRippleAPIと依存関係をインストール
Yarnを使用して、プロジェクトで作成した`package.json`ファイルに定義されているRippleAPIと依存関係をインストールします。
```
yarn
```
これで、RippleAPIと依存関係がローカルフォルダー`node_modules/`にインストールされます。
インストールプロセスの終了時に、いくつかの警告が表示される場合があります。以下の警告は無視してかまいません。
```
warning eslint > file-entry-cache > flat-cache > circular-json@0.3.3: CircularJSON is in maintenance only, flatted is its successor.
npm WARN optional Skipping failed optional dependency /chokidar/fsevents:
npm WARN notsup Not compatible with your operating system or architecture: fsevents@1.0.6
```
# 最初のRippleAPIスクリプト
スクリプト`get-account-info.js`は、ハードコーディングされたアカウントに関する情報をフェッチします。このスクリプトを使用して、RippleAPIが動作することをテストします。
```
{% include '_code-samples/rippleapi_quickstart/get-account-info.js' %}
```
## スクリプトの実行
以下のコマンドを使用して、最初のRippleAPIスクリプトを実行します。
```
node get-account-info.js
```
出力:
```
getting account info for rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn
{ sequence: 359,
xrpBalance: '75.181663',
ownerCount: 4,
previousInitiatedTransactionID: 'E5C6DD25B2DCF534056D98A2EFE3B7CFAE4EBC624854DE3FA436F733A56D8BD9',
previousAffectingTransactionID: 'E5C6DD25B2DCF534056D98A2EFE3B7CFAE4EBC624854DE3FA436F733A56D8BD9',
previousAffectingTransactionLedgerVersion: 18489336 }
getAccountInfo done
done and disconnected.
```
## スクリプトの内容解説
このスクリプトでは、RippleAPI固有のコードに加え、JavaScriptにおける近年の開発成果である構文や規定も利用しています。今回のサンプルコードを小さめのチャンクに分割して、個別に説明していきます。
### スクリプトの冒頭
```
'use strict';
const RippleAPI = require('ripple-lib').RippleAPI;
```
先頭行では、[strictモード](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode)を有効にしています。このモードを使用するかどうかは任意に選択できますが、JavaScriptで陥りやすいいくつかの落とし穴を回避する上で役立ちます。
2行目では、Node.jsのrequire関数を使用して、RippleAPIを現在のスコープにインポートしています。RippleAPIは、[`ripple-lib`がエクスポートするモジュール](https://github.com/ripple/ripple-lib/blob/develop/src/index.ts)の1つです。
### APIのインスタンス化
```
const api = new RippleAPI({
server: 'wss://s1.ripple.com' // Public rippled server
});
```
このセクションでは、RippleAPIクラスの新規インスタンスを作成し、変数`api`に代入しています([`const`キーワード](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const)は、値`api`を何らかの別の値に再代入できないことを意味します。ただし、オブジェクトの内部状態は変化する可能性があります)。
コンストラクターへの引数の1つはoptionsオブジェクトであり、このオブジェクトには[さまざまなオプション](rippleapi-reference.html#parameters)が用意されています。`server`パラメーターでは、どの`rippled`サーバーに接続するのかを指定しています。
- この`server`設定例では、セキュアなWebSocket接続を使用して、Ripple社が運営している公開サーバーの1つに接続しています。
- `server`オプションを記述しない場合、RippleAPIは、ネットワーク接続の不要なメソッドのみが提供される[オフラインモード](rippleapi-reference.html#offline-functionality)で実行されます。
- 代わりに[Rippleテストネット](https://ripple.com/build/ripple-test-net/)サーバーを指定すると、本番環境のXRP Ledgerではなく、別空間のテストネットワークに接続できます。
- [独自の`rippled`を運用している](install-rippled.html)場合は、ローカルサーバーに接続するよう指示できます。例えば、代わりに`server: 'ws://localhost:5005'`と記述します。
### 接続とPromise
```
api.connect().then(() => {
```
[connect()メソッド](rippleapi-reference.html#connect)は、特殊なJavaScriptオブジェクトである[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)を返す多くのRippleAPIメソッドの1つです。Promiseは、XRP Ledgerを照会するなど、値を後ほど返す非同期操作の実行を目的としています。
何らかの式(`api.connect()`などからPromiseが返された場合、Promiseの`then`メソッドを呼び出して、コールバック関数を渡します。関数を引数として渡すことはJavaScriptでは常套的な手法であり、JavaScriptの関数が[第一級オブジェクト](https://en.wikipedia.org/wiki/First-class_function)であることを利用しています。
Promiseは、自身の非同期動作を完了すると、渡されたコールバック関数を実行します。`then`メソッドからの戻り値は別のPromiseオブジェクトであるため、別の`then`メソッドへの、または同様にコールバックを受け付けるPromiseの`catch`メソッドへの「チェーン」にすることができます。`catch`に渡すコールバックは、何らかの問題が生じた場合に呼び出されます。
この例では、非同期関数を手軽に定義できる手段である[arrow関数](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions)を使用しています。この方法は、1回限りの関数をコールバックとして大量に定義する場合に便利です。`()=> {...}`という構文は、 {...}/>`function() {...}`とほぼ等価です。パラメーターを1つ取る非同期関数が必要な場合は、代わりに`info => {...}`などの構文を使用できます。この構文は、 {...}/>`function(info) {...}`という構文とほぼ同一です。
### カスタムコード
```
/* begin custom code ------------------------------------ */
const myAddress = 'rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn';
console.log('getting account info for', myAddress);
return api.getAccountInfo(myAddress);
}).then(info => {
console.log(info);
console.log('getAccountInfo done');
/* end custom code -------------------------------------- */
```
ここが、スクリプトで実行する処理を記述するために変更を加える部分です。
このサンプルコードでは、XRP Ledgerアカウントのアドレスを使用してXRP Ledgerアカウントを参照しています。さまざまなアドレスを指定してコードを実行し、結果が変化することを確認してみてください。
`console.log()`関数はNode.jsとWebブラウザーの両方に組み込まれているもので、結果をコンソールに出力します。この例では大量のコンソール出力を得られるので、コードによって実行される処理の内容を簡単に理解できます。
このサンプルコードは、RippleAPIが接続を終了した時点で呼び出されるコールバック関数の中が始点となっています。その関数がRippleAPIの[`getAccountInfo`](rippleapi-reference.html#getaccountinfo)メソッドを呼び出すと、結果が返されます。
`getAccountInfo` APIメソッドは別のPromiseを返すものであるため、`}).then( info => {`の行で、このPromiseの非同期処理が完了した時点で実行される別の非同期コールバック関数を定義しています。前述の例とは異なり、このコールバック関数は、`getAccountInfo` APIメソッドからの非同期戻り値を保持する`info`という引数を1つ取ります。このコールバック関数の残りの部分は、その戻り値をコンソールに出力するものです。
### クリーンアップ
```
}).then(() => {
return api.disconnect();
}).then(() => {
console.log('done and disconnected.');
}).catch(console.error);
```
サンプルコードの残りの部分は、概ね[ボイラープレートコード](rippleapi-reference.html#boilerplate)としての性質を持ちます。1行目は前のコールバック関数を終了するもので、次に、終了時に実行される別のコールバックへのチェーンを作成しています。そのメソッドはXRP Ledgerからの明示的な切断を実行し、終了時にコンソールへの書き込みを実行する別のコールバックが記述されています。スクリプトで[RippleAPIイベント](rippleapi-reference.html#api-events)を待機する場合は、イベントの待機を終了するまで切断を実行しないでください。
`catch`メソッドで、このPromiseチェーンを終了します。ここに記述しているコールバックは、いずれかのPromiseまたはそのコールバック関数でエラーが発生した場合に実行されます。ここでは、カスタムのコールバックを定義するのではなく、コンソールへの書き込みを実行する標準の`console.error`関数を渡しています。より高機能のコールバック関数をここに定義して、特定のタイプのエラーをインテリジェントにキャッチすることもできます。
# 検証の待機
XRP Ledgerまたは任意の分散されたシステムを使用する上で最大の課題の1つとなるのが、最終的かつ不変のトランザクション結果を把握することです。[ベストプラクティスに従っている](reliable-transaction-submission.html)場合も、トランザクションが最終的に受け入れられるか拒否されるまで、[コンセンサスプロセス](https://ripple.com/build/ripple-ledger-consensus-process/)を待機しなければならないことに変わりはありません。以下のサンプルコードは、トランザクションの最終的な結果を待機する方法を示しています。
```
{% include '_code-samples/rippleapi_quickstart/submit-and-verify.js' %}
```
このコードは注文トランザクションを作成して送信するものですが、他のタイプのトランザクションにも同様の原則があてはまります。トランザクションを送信した後、setTimeoutを使用して所定の時間が経過するまで待機し、新しいPromiseでレジャーをもう一度照会して、トランザクションが検証済みとなっているかどうかを確認します。検証済みとなっていない場合は、検証済みレジャーの中にトランザクションが見つかるか、返されたレジャーがLastLedgerSequenceパラメーターの値よりも大きくなるまで、このプロセスを繰り返します。
まれなケースとして(特に、大きな遅延や電源喪失が発生した場合)、トランザクションを送信してから、`maxLedgerVersion`がネットワークから渡されたと判断するまでの間に、レジャーのいずれかのバージョンが`rippled`サーバーで欠落することがあります。この場合、トランザクションが失敗したのか、欠落したバージョンのレジャーに含まれているのかを最終的に確定することはできません。RippleAPIは、この場合、`MissingLedgerHistoryError`を返します。
`rippled`サーバーの管理者である場合は、[欠落しているレジャーを手動で要求できます](ledger_request.html)。管理者でない場合は、別のサーバーを使用してレジャー履歴を確認してみるという方法が考えられますRippleは、この目的で、すべての履歴が記録される公開サーバーを`s2.ripple.com`で運用しています)。
詳細は、[信頼できるトランザクションの送信](reliable-transaction-submission.html)を参照してください。
# WebブラウザーでのRippleAPI
RippleAPIは、ブラウザー互換のバージョンをコンパイルし、RippleAPIスクリプトよりも前に[lodash](https://www.npmjs.com/package/lodash)を依存関係として含めた場合、Webブラウザーでも使用できます。
## ブラウザー互換バージョンのRippleAPIのビルド
RippleAPIをブラウザーで使用するには、ブラウザー互換バージョンをビルドする必要があります。以下の手順では、RippleAPIをコンパイルして、Webページに含めることのできる単一のJavaScriptファイルを生成します。
### 1. RippleAPI gitリポジトリーのコピーをダウンロード
[Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)がインストールされている場合は、リポジトリーのクローンを作成して、**master**ブランチをチェックアウトできます。このブランチには、常に最新の公式リリースが収められています。
```
git clone https://github.com/ripple/ripple-lib.git
cd ripple-lib
git checkout master
```
または、特定のリリースのアーカイブ(.zipまたは.tar.gzを[RippleAPIリリースページ](https://github.com/ripple/ripple-lib/releases)からダウンロードし、抽出します。
### 2. Yarnのインストール
[Yarnのインストール](#yarnのインストール)に関する手順に従います。
### 3. Yarnを使用して依存関係をインストール
```
yarn
```
### 4. Gulpを使用して単一のJavaScript出力をビルド
RippleAPIには、[gulp](http://gulpjs.com/)パッケージを使用してすべてのソースコードをコンパイルし、ブラウザー互換バージョンのJavaScriptファイルを生成するためのコードが付属しています。Gulpは依存関係の1つとして自動的にインストールされるため、実行するだけで済みます。RippleAPIの構成上、これは容易に実行できるようになっています。
```
yarn run build
```
出力:
```
> ripple-lib@0.16.5 build /home/username/ripple-lib
> gulp
[14:11:02] Using gulpfile /home/username/ripple-lib/gulpfile.js
[14:11:02] Starting 'build'...
[14:11:03] Starting 'build-debug'...
[14:11:03] Starting 'build-min'...
[14:11:18] Finished 'build-debug' after 15 s
[14:11:18] Finished 'build' after 16 s
[14:11:18] Finished 'build-min' after 15 s
[14:11:18] Starting 'default'...
[14:11:18] Finished 'default' after 19 μs
```
完了までに、しばらく時間がかかる場合があります。最終的に、ビルドプロセスによって、目的のファイルが含まれた新しい`build/`フォルダーが作成されます。
`build/ripple-<VERSION NUMBER>.js`ファイルは、ブラウザーですぐに使用できるビルドしたバージョンのRippleAPIの直接エクスポートです。名前の末尾が`-min.js`のファイルも同じものですが、読み込みを高速化するため、内容が[縮小](https://en.wikipedia.org/wiki/Minification_%28programming%29)されています。
## ブラウザーでのRippleAPIのデモ
以下のHTMLファイルは、RippleAPIのブラウザーバージョンで公開`rippled`サーバーに接続し、そのサーバーに関する情報のレポートを生成するための基本的な使用方法を示しています。Node.jsの「require」構文を使用するのではなく、ブラウザーバージョンを使用して、`RippleAPI`クラスが含まれている`ripple`という名前のグローバル変数を作成します。
この例を使用するには、最初に[RippleAPIのブラウザー互換バージョンをビルド](#ブラウザー互換バージョンのrippleapiのビルド)した後、結果として生成される出力ファイルのいずれかを、このHTMLファイルと同一のフォルダーにコピーします縮小バージョンとフルサイズバージョンのどちらを使用してもかまいません。この例にある2番目の`<script>`タグを変更して、ビルドしたバージョンのRippleAPIに対応する適切なファイル名が使用されるようにします。
[**browser-demo.html:**](https://github.com/ripple/ripple-dev-portal/blob/master/content/_code-samples/rippleapi_quickstart/browser-demo.html "Source on GitHub")
```
{% include '_code-samples/rippleapi_quickstart/browser-demo.html' %}
```
このデモHTMLでは、Lodash v4.17.11をCloudflare上のCDNJSから読み込んだ後、ripple-lib v1.1.2を読み込んでいますが、Lodashのバリアントをローカルにダウンロードして読み込んでもかまいません。 <!--#{ no specific recommended or required version at this time. Update this once we have some guidance to provide here. }#-->

View File

@@ -0,0 +1,208 @@
# XRP Ledger APIの使用開始
`rippled`サーバーに対してコマンドを実行するには、接続先のサーバーをあらかじめ把握しておく必要があります。大多数のサーバーは、外部ネットワークからの直接のAPI要求を受け入れないよう設定されています。
別の方法として、[`rippled`の独自のローカルコピーを運用](install-rippled.html)することもできます。[管理用のメソッド](admin-rippled-methods.html)のいずれかにアクセスする場合、これは必須です。この場合、サーバーのバインド用として設定したIPアドレスとポートを使用する必要があります例えば`127.0.0.1:54321`。また、管理機能にアクセスするには、構成ファイルで管理用としてマークされているポートおよびIPアドレスから接続しなければなりません。
[構成ファイルの例](https://github.com/ripple/rippled/blob/8429dd67e60ba360da591bfa905b58a35638fda1/cfg/rippled-example.cfg#L1050-L1073)では、ローカルループバックネットワーク上127.0.0.1のポート5005でJSON-RPCHTTP、ポート6006でWebSocketWSの接続をリッスンし、接続されるすべてのクライアントを管理者として扱っています。
## WebSocket API
いくつかのメソッドをXRP Ledgerで試すことを予定している場合は、独自のWebSocketコードを記述することなく、[Ripple WebSocket APIツール](websocket-api-tool.html)でAPIをすぐに使用できます。後ほど、独自の`rippled`サーバーへの接続が必要となった時点で、[ブラウザー](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_client_applications)または[Node.jsで独自のクライアントをビルド](https://www.npmjs.com/package/ws)することが可能です。
### 要求フォーマット
`rippled`サーバーへのWebSocketを開いた後、以下の属性を使用して、コマンドを[JSON](https://en.wikipedia.org/wiki/JSON)オブジェクトとして送信できます。
* コマンド名を最上位の`"command"`フィールドに記述します。
* コマンドのすべての関連パラメーターも最上位に記述します。
* 任意の値を指定して`"id"`フィールドを記述します(省略可)。この要求への応答では、同一の`"id"`フィールドを使用します。そうすることで、応答が順不同で到達した場合も、どの要求によってどの応答を得られたのかがわかります。
応答はJSONオブジェクトとして返されます。
### 公開サーバー
現在、Ripple社は以下の一連の公開WebSocketサーバーを運用しています。
| `Domain` | ポート | 注記 |
|:----------------|:-----|:--------------------------------------|
| `s1.ripple.com` | 443 | `wss://`のみ。汎用サーバー |
| `s2.ripple.com` | 443 | `wss://`のみ。すべての履歴が記録されるサーバー |
これらの公開サーバーは継続的な使用やビジネスでの使用を想定したものではなく、いつでも使用不可となる可能性があります。日常的な使用については、独自の`rippled`サーバーを自社で運用するか、信頼できる事業者と運用委託契約を締結します。
## JSON-RPC
任意のHTTPクライアント[RESTED for Firefox](https://addons.mozilla.org/en-US/firefox/addon/rested/)や[Postman for Chrome](https://chrome.google.com/webstore/detail/postman/fhbjgbiflinjbdggehcddcbncdddomop?hl=en)などを使用して、JSON-RPCで`rippled`サーバーを呼び出すことができます。ほとんどのプログラミング言語には、HTTP要求を組み込むためのライブラリーが用意されています。
### 要求フォーマット
JSON-RPC要求を作成するには、`rippled`サーバーがJSON-RPC接続をリッスンしているポートおよびIPアドレス上で、HTTP **POST**要求をルートパス(`/`に送信します。HTTP/1.0またはHTTP/1.1を使用できます。HTTPSを使用する場合は、TLS v1.2を使用してください。セキュリティーの維持を理由として、`rippled` _は_ SSL v3以前をサポートしていません。
値を`application/json`として、`Content-Type`ヘッダーを常に記述してください。
複数の要求を作成することを予定している場合は、要求ごとに接続を閉じて再び開くことなく済むよう、[キープアライブ](http://tools.ietf.org/html/rfc7230#section-6.3)を使用します。
以下の属性を指定して、要求の本文を[JSON](https://en.wikipedia.org/wiki/JSON)オブジェクトとして送信します。
* コマンドを最上位の`"method"`フィールドに記述します。
* 最上位の`"params"`フィールドを記述します。このフィールドの内容は、コマンドのすべてのパラメーターが指定された1つの入れ子JSONオブジェクトのみを保持している**1要素配列**です。
応答もJSONオブジェクトになります。
### 公開サーバー
現在、Ripple社は以下の一連の公開JSON-RPCサーバーを運用しています。
| `Domain` | ポート | 注記 |
|:----------------|:------|:-----------------------|
| `s1.ripple.com` | 51234 | 汎用サーバー |
| `s2.ripple.com` | 51234 | すべての履歴が記録されるサーバー |
これらの公開サーバーは継続的な使用やビジネスでの使用を想定したものではなく、いつでも使用不可となる可能性があります。日常的な使用については、独自の`rippled`サーバーを自社で運用するか、信頼できる事業者と運用委託契約を締結します。
## コマンドライン
このコマンドラインインターフェイスは、JSON-RPCのものと同一のサービスに接続するため、公開サーバーおよびサーバー構成は同一です。コマンドラインクライアントとして、`rippled`がローカルインスタンスに接続します。例:
```
rippled --conf=/etc/rippled.cfg server_info
```
**注記:** コマンドラインインターフェイスは、管理の目的でのみ使用されることを想定しています。_サポートされるAPIではありません_。
### 要求フォーマット
コマンドラインでは、通常の(先頭にダッシュが付いた)コマンドラインオプションに続けてコマンドを記述した後、一連の限定的なパラメーターを空白文字で区切って記述します。空白文字などの特殊な文字が含まれている可能性があるパラメーター値は、一重引用符で囲みます。
## 要求の例
<!-- MULTICODE_BLOCK_START -->
*WebSocket*
```
{
"id": 2,
"command": "account_info",
"account": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
"strict": true,
"ledger_index": "validated"
}
```
*JSON-RPC*
```
POST http://s1.ripple.com:51234/
{
"method": "account_info",
"params": [
{
"account": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
"strict": true,
"ledger_index": "validated"
}
]
}
```
*コマンドライン*
```
rippled account_info r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59 validated true
```
<!-- MULTICODE_BLOCK_END -->
## 応答フォーマット
### 成功した場合の応答の例
<!-- MULTICODE_BLOCK_START -->
*WebSocket*
```
{
"id": 2,
"status": "success",
"type": "response",
"result": {
"account_data": {
"Account": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
"Balance": "27389517749",
"Flags": 0,
"LedgerEntryType": "AccountRoot",
"OwnerCount": 18,
"PreviousTxnID": "B6B410172C0B65575D89E464AF5B99937CC568822929ABF87DA75CBD11911932",
"PreviousTxnLgrSeq": 6592159,
"Sequence": 1400,
"index": "4F83A2CF7E70F77F79A307E6A472BFC2585B806A70833CCD1C26105BAE0D6E05"
},
"ledger_index": 6760970
}
}
```
*JSON-RPC*
```
HTTP Status: 200 OK
{
"result": {
"account_data": {
"Account": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
"Balance": "27389517749",
"Flags": 0,
"LedgerEntryType": "AccountRoot",
"OwnerCount": 18,
"PreviousTxnID": "B6B410172C0B65575D89E464AF5B99937CC568822929ABF87DA75CBD11911932",
"PreviousTxnLgrSeq": 6592159,
"Sequence": 1400,
"index": "4F83A2CF7E70F77F79A307E6A472BFC2585B806A70833CCD1C26105BAE0D6E05"
},
"ledger_index": 6761012,
"status": "success"
}
}
```
*コマンドライン*
```
{
"result": {
"account_data": {
"Account": "r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59",
"Balance": "27389517749",
"Flags": 0,
"LedgerEntryType": "AccountRoot",
"OwnerCount": 18,
"PreviousTxnID": "B6B410172C0B65575D89E464AF5B99937CC568822929ABF87DA75CBD11911932",
"PreviousTxnLgrSeq": 6592159,
"Sequence": 1400,
"index": "4F83A2CF7E70F77F79A307E6A472BFC2585B806A70833CCD1C26105BAE0D6E05"
},
"ledger_index": 6761012,
"status": "success"
}
}
```
<!-- MULTICODE_BLOCK_END -->
成功した場合の応答に含まれているフィールドは、以下のとおりです。
| `Field` | 型 | 説明 |
|:----------------|:---------|:------------------------------------------------|
| `id` | (場合により異なる) | WebSocketのみこの応答の要求元となった要求で提供されているID。 |
| `status` | 文字列 | WebSocketのみ値が`success`である場合、要求がサーバーによって正常に受信され、理解されたことを示します。 |
| `result.status` | 文字列 | JSON-RPCおよびコマンドライン値が`success`である場合、要求がサーバーによって正常に受信され、理解されたことを示します。 |
| `type` | 文字列 | WebSocketのみ値が`response`である場合、コマンドに対する正常な応答であることを示します。[非同期の通知](subscribe.html)では、`ledgerClosed``transaction`など、異なる値が使用されます。 |
| `result` | オブジェクト | クエリーの結果。内容はコマンドによって異なります。 |
### コマンドライン
コマンドラインのメソッドはJSON-RPCと同一のインターフェイスを使用しているため、応答フォーマットはJSON-RPCの応答と同一です。

View File

@@ -1,8 +1,30 @@
# Get Started with the rippled API
# Get Started with XRP Ledger APIs
Before you can run any commands against a `rippled` server, you must know which server you are connecting to. Most servers are configured not to accept API requests directly from the outside network.
The XRP Ledger's core server software is [`rippled`](the-rippled-server.html). You can jump straight into developing on the XRP Ledger by accessing the API of a `rippled` server.
Alternatively, you can [run your own local copy of `rippled`](install-rippled.html). This is required if you want to access any of the [Admin Methods](admin-rippled-methods.html). In this case, you should use whatever IP and port you configured the server to bind. (For example, `127.0.0.1:54321`) Additionally, to access admin functionality, you must connect from a port/IP address marked as admin in the config file.
The quickest way to dive into the API is with the [**WebSocket API Tool**](websocket-api-tool.html), or use the [XRP Ledger Explorer](https://livenet.xrpl.org/) to see watch the progress of the ledger live.
You can also [run your own instance of `rippled`](install-rippled.html) or use a [public server](#public-servers).
## Public Servers
Ripple provides several public servers for the benefit of the XRP Ledger community:
| Operator | [Network][] | JSON-RPC URL | WebSocket URL | Notes |
|:---------|:------------|:-------------|:--------------|:---------------------|
| Ripple | **Mainnet** | `https://s1.ripple.com:51234/` | `wss://s1.ripple.com/` | General purpose server cluster |
| Ripple | **Mainnet** | `https://s2.ripple.com:51234/` | `wss://s2.ripple.com/` | [Full-history server](ledger-history.html#full-history) cluster |
| Ripple | Testnet | `https://s.altnet.rippletest.net:51234/` | `wss://s.altnet.rippletest.net/` | Testnet public server |
| Ripple | Devnet | `https://s.devnet.rippletest.net:51234/` | `wss://s.devnet.rippletest.net/` | Devnet public server |
[Network]: parallel-networks.html
These public servers are not for sustained or business use, and they may become unavailable at any time. For regular use, you should run your own `rippled` server or contract someone you trust to do so.
## Admin Access
To use a `rippled` server's [Admin Methods](admin-rippled-methods.html). In this case, you should use whatever IP and port you configured the server to bind. (For example, `127.0.0.1:54321`) Additionally, to access admin functionality, you must connect from a port/IP address marked as admin in the config file.
The [example config file](https://github.com/ripple/rippled/blob/8429dd67e60ba360da591bfa905b58a35638fda1/cfg/rippled-example.cfg#L1050-L1073) listens for connections on the local loopback network (127.0.0.1), with JSON-RPC (HTTP) on port 5005 and WebSocket (WS) on port 6006, and treats all connected clients as admin.
@@ -21,22 +43,6 @@ After you open a WebSocket to the `rippled` server, you can send commands as a [
The response comes as a JSON object.
### Public Servers
Currently Ripple (the company) maintains a set of public WebSocket servers at:
| URL | [Network][] | Notes |
|:--------------------------------------|:------------|:-----------------------|
| `wss://s1.ripple.com/` | Mainnet | General purpose server cluster |
| `wss://s2.ripple.com/` | Mainnet | [Full-history server](ledger-history.html#full-history) cluster |
| `wss://s.altnet.rippletest.net` | Testnet | Testnet public server |
| `wss://s.devnet.rippletest.net` | Devnet | Devnet public server |
[Network]: parallel-networks.html
These public servers are not for sustained or business use, and they may become unavailable at any time. For regular use, you should run your own `rippled` server or contract someone you trust to do so.
## JSON-RPC
You can use any HTTP client (like [RESTED for Firefox](https://addons.mozilla.org/en-US/firefox/addon/rested/), [Postman for Chrome](https://chrome.google.com/webstore/detail/postman/fhbjgbiflinjbdggehcddcbncdddomop?hl=en) or [Online HTTP client ExtendsClass](https://extendsclass.com/rest-client-online.html)) to make JSON-RPC calls a `rippled` server. Most programming languages have a library for making HTTP requests built in.
@@ -56,19 +62,6 @@ Send request body as a [JSON](https://en.wikipedia.org/wiki/JSON) object with th
The response is also a JSON object.
### Public Servers
Currently, Ripple (the company) maintains a set of public JSON-RPC servers at:
| URL | [Network][] | Notes |
|:-----------------------------------------|:------------|:---------------------|
| `https://s1.ripple.com:51234/` | Mainnet | General purpose server cluster |
| `https://s2.ripple.com:51234/` | Mainnet | [Full-history server](ledger-history.html#full-history) cluster |
| `https://s.altnet.rippletest.net:51234/` | Testnet | Testnet public server |
| `https://s.devnet.rippletest.net:51234/` | Devnet | Devnet public server |
These public servers are not for sustained or business use, and they may become unavailable at any time. For regular use, you should run your own `rippled` server or contract someone you trust to do so.
## Commandline

View File

@@ -0,0 +1,22 @@
# トランザクションの結果の確認
トランザクションの最終結果を確認するには、[txメソッド][]または[account_txメソッド][]を使用するか、`rippled`の他の応答を使用します。コンセンサスにより検証されたレジャーバージョンがこの応答に使用されていることを示す`"validated": true`を検索します。
| フィールド | 値 | 説明 |
|:-----------------------|:--------|:------------------------------------------|
| meta.TransactionResult | 文字列 | 結果を以下のように分類するコード(`tecPATH_DRY`など) |
| validated | ブール値 | この結果が検証済みレジャーの結果であるかどうか。`false`の場合、結果は暫定的です。`true`の場合、結果は最終結果です。 |
```json
"hash": "E08D6E9754025BA2534A78707605E0601F03ACE063687A0CA1BDDACFCD1698C7",
"meta": {
...
"TransactionResult": "tesSUCCESS"
},
"validated": true
```
<!--{# common link defs #}-->
{% include '_snippets/rippled-api-links.md' %}
{% include '_snippets/tx-type-links.md' %}
{% include '_snippets/rippled_versions.md' %}

View File

@@ -208,7 +208,7 @@ A [Payment transaction][] can represent a direct XRP-to-XRP transaction, a [cros
XRP amounts are tracked in the `Balance` field of `AccountRoot` objects. (XRP can also exist in [Escrow objects](escrow-object.html) and [PayChannel objects](paychannel.html), but Payment transactions cannot affect those.)
You should always use [the delivered_amount field](partial-payments.html#the-delivered-amount-field) to see how much a payment delivered.
You should always use [the delivered_amount field](partial-payments.html#the-delivered_amount-field) to see how much a payment delivered.
If the payment contains a `CreatedNode` of LedgerEntryType `AccountRoot`, that means the payment [funded a new account](accounts.html#creating-accounts) in the ledger.

View File

@@ -0,0 +1,675 @@
# レギュラーキーペアの割り当て
XRP Ledgerでは、アカウントはその後のトランザクションには _レギュラーキーペア_ と呼ばれるセカンダリキーペアで署名することができます。レギュラーキーペアの秘密鍵が漏えいした場合は、秘密鍵を削除または交換できます。その際に、アカウントの秘密鍵以外の設定を変更したり、他のアカウントとの関係を再設定する必要はありません。レギュラーキーペアを積極的にローテーションすることも可能です。(アカウントのアドレスに固有に関連付けられているアカウントのマスターキーペアでは、このような操作は実行できません。)
マスターキーペアとレギュラーキーペアの詳細は、[暗号鍵](cryptographic-keys.html)を参照してください。
このチュートリアルでは、レギュラーキーペアをアカウントに割り当てるために必要な手順を説明します。
1. [キーペアの生成](#1-キーペアの生成)
2. [生成したキーペアをレギュラーキーペアとしてアカウントに割り当てる](#2-生成したキーペアをレギュラーキーペアとしてアカウントに割り当てる)
3. [レギュラーキーペアの検証](#3-レギュラーキーペアの検証)
4. [次のステップ](#4-次のステップ)
## 1. キーペアの生成
[wallet_proposeメソッド][]を使用して、アカウントにレギュラーキーペアとして割り当てるキーペアを生成します。
### 要求フォーマット
要求フォーマットの例:
<!-- MULTICODE_BLOCK_START -->
*WebSocket*
```
{
"command":"wallet_propose"
}
```
*JSON-RPC*
```
{
"method":"wallet_propose"
}
```
*コマンドライン*
```
#Syntax: wallet_propose
rippled wallet_propose
```
<!-- MULTICODE_BLOCK_END -->
### 応答フォーマット
処理が成功した応答の例:
<!-- MULTICODE_BLOCK_START -->
*WebSocket*
```
{
"result":{
"account_id":"rsprUqu6BHAffAeG4HpSdjBNvnA6gdnZV7",
"key_type":"secp256k1",
"master_key":"KNEW BENT LYNN LED GAD BEN KENT SHAM HOBO RINK WALT ALLY",
"master_seed":"sh8i92YRnEjJy3fpFkL8txQSCVo79",
"master_seed_hex":"966C0F68643EFBA50D58D191D4CA8AA7",
"public_key":"aBRNH5wUurfhZcoyR6nRwDSa95gMBkovBJ8V4cp1C1pM28H7EPL1",
"public_key_hex":"03AEEFE1E8ED4BBC009DE996AC03A8C6B5713B1554794056C66E5B8D1753C7DD0E"
},
"status":"success",
"type":"response"
}
```
*JSON-RPC*
```
{
"result":{
"account_id":"rsprUqu6BHAffAeG4HpSdjBNvnA6gdnZV7",
"key_type":"secp256k1",
"master_key":"KNEW BENT LYNN LED GAD BEN KENT SHAM HOBO RINK WALT ALLY",
"master_seed":"sh8i92YRnEjJy3fpFkL8txQSCVo79",
"master_seed_hex":"966C0F68643EFBA50D58D191D4CA8AA7",
"public_key":"aBRNH5wUurfhZcoyR6nRwDSa95gMBkovBJ8V4cp1C1pM28H7EPL1",
"public_key_hex":"03AEEFE1E8ED4BBC009DE996AC03A8C6B5713B1554794056C66E5B8D1753C7DD0E"
"status":"success"
}
}
```
*コマンドライン*
```
{
"result" :{
"account_id" :"rsprUqu6BHAffAeG4HpSdjBNvnA6gdnZV7",
"key_type" :"secp256k1",
"master_key" :"KNEW BENT LYNN LED GAD BEN KENT SHAM HOBO RINK WALT ALLY",
"master_seed" :"sh8i92YRnEjJy3fpFkL8txQSCVo79",
"master_seed_hex" :"966C0F68643EFBA50D58D191D4CA8AA7",
"public_key" :"aBRNH5wUurfhZcoyR6nRwDSa95gMBkovBJ8V4cp1C1pM28H7EPL1",
"public_key_hex" :"03AEEFE1E8ED4BBC009DE996AC03A8C6B5713B1554794056C66E5B8D1753C7DD0E",
"status" :"success"
}
}
```
<!-- MULTICODE_BLOCK_END -->
次のステップでは、この応答の`account_id`を使用してキーペアをレギュラーキーペアとしてアカウントに割り当てます。また、`master_seed`値を安全な場所に保管してください。(この値以外は特に覚えておく必要はありません。)
## 2. 生成したキーペアをレギュラーキーペアとしてアカウントに割り当てる
[SetRegularKeyトランザクション][]を使用して、ステップ1で生成したキーペアをレギュラーキーペアとしてアカウントに割り当てます。
SetRegularKeyトランザクションでレギュラーキーペアを初めてアカウントに割り当てる際には、アカウントのマスター秘密鍵シークレットによる署名が必要です。マスター秘密鍵の送信は危険であるため、トランザクションの署名とネットワークへのトランザクション送信を切り離した2段階方式でこのトランザクションを実行します。
それ以降のSetRegularKeyトランザクションの送信時には、既存のレギュラー秘密鍵で署名し、レギュラー秘密鍵自体を置換または[削除](change-or-remove-a-regular-key-pair.html)できます。ネットワーク上でレギュラー秘密鍵を送信してはならないことに注意してください。
### トランザクションの署名
{% include '_snippets/tutorial-sign-step.md' %}
<!--{#_ #}-->
要求フィールドに以下の値を指定します。
| 要求フィールド | 値 |
|:--------------|:-------------------------------------------------------------|
| `Account` | アカウントのアドレス。 |
| `RegularKey` | ステップ1で生成された`account_id`。 |
| `secret` | アカウントの`master_key``master_seed`、または`master_seed_hex`(マスター秘密鍵)。|
#### 要求フォーマット
要求フォーマットの例:
<!-- MULTICODE_BLOCK_START -->
*WebSocket*
```
{
"command":"sign",
"tx_json":{
"TransactionType":"SetRegularKey",
"Account":"rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93",
"RegularKey":"rsprUqu6BHAffAeG4HpSdjBNvnA6gdnZV7"
},
"secret":"ssCATR7CBvn4GLd1UuU2bqqQffHki"
}
```
*JSON-RPC*
```
{
"method":"sign",
"params":[
{
"tx_json":{
"TransactionType":"SetRegularKey",
"Account":"rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93",
"RegularKey":"rsprUqu6BHAffAeG4HpSdjBNvnA6gdnZV7"
},
"secret":"ssCATR7CBvn4GLd1UuU2bqqQffHki"
}
]
}
```
*コマンドライン*
```
#Syntax: sign secret tx_json
rippled sign ssCATR7CBvn4GLd1UuU2bqqQffHki '{"TransactionType":"SetRegularKey", "Account":"rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93", "RegularKey":"rsprUqu6BHAffAeG4HpSdjBNvnA6gdnZV7"}'
```
<!-- MULTICODE_BLOCK_END -->
#### 応答フォーマット
処理が成功した応答の例:
<!-- MULTICODE_BLOCK_START -->
*WebSocket*
```
{
"result":{
"tx_blob":"1200052280000000240000000468400000000000000A73210384CA3C528F10C75F26E0917F001338BD3C9AA1A39B9FBD583DFFFD96CF2E2D7A7446304402204BCD5663F3A2BA02D2CE374439096EC6D27273522CD6E6E0BDBFB518730EAAE402200ECD02D8D2525D6FA4642613E71E395ECCEA01C42C35A668BF092A00EB649C268114830923439D307E642CED308FD91EF701A7BAA74788141620D685FB08D81A70D0B668749CF2E130EA7540",
"tx_json":{
"Account":"rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93",
"Fee":"10",
"Flags":2147483648,
"RegularKey":"rsprUqu6BHAffAeG4HpSdjBNvnA6gdnZV7",
"Sequence":4,
"SigningPubKey":"0384CA3C528F10C75F26E0917F001338BD3C9AA1A39B9FBD583DFFFD96CF2E2D7A",
"TransactionType":"SetRegularKey",
"TxnSignature":"304402204BCD5663F3A2BA02D2CE374439096EC6D27273522CD6E6E0BDBFB518730EAAE402200ECD02D8D2525D6FA4642613E71E395ECCEA01C42C35A668BF092A00EB649C26",
"hash":"AB73BBF7C99061678B59FB48D72CA0F5FC6DD2815B6736C6E9EB94439EC236CE"
}
},
"status":"success",
"type":"response"
}
```
*JSON-RPC*
```
{
"result":{
"status":"success",
"tx_blob":"1200052280000000240000000768400000000000000A73210384CA3C528F10C75F26E0917F001338BD3C9AA1A39B9FBD583DFFFD96CF2E2D7A7446304402201453CA3D4D17F0EE3828B9E3D6ACF65327F5D4FC2BA30953CACF6CBCB4145E3502202F2154BED1D7462CAC1E3DBB31864E48C3BA0B3133ACA5E37EC54F0D0C339E2D8114830923439D307E642CED308FD91EF701A7BAA74788141620D685FB08D81A70D0B668749CF2E130EA7540",
"tx_json":{
"Account":"rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93",
"Fee":"10",
"Flags":2147483648,
"RegularKey":"rsprUqu6BHAffAeG4HpSdjBNvnA6gdnZV7",
"Sequence":4,
"SigningPubKey":"0384CA3C528F10C75F26E0917F001338BD3C9AA1A39B9FBD583DFFFD96CF2E2D7A",
"TransactionType":"SetRegularKey",
"TxnSignature":"304402201453CA3D4D17F0EE3828B9E3D6ACF65327F5D4FC2BA30953CACF6CBCB4145E3502202F2154BED1D7462CAC1E3DBB31864E48C3BA0B3133ACA5E37EC54F0D0C339E2D",
"hash":"AB73BBF7C99061678B59FB48D72CA0F5FC6DD2815B6736C6E9EB94439EC236CE"
}
}
}
```
*コマンドライン*
```
{
"result" :{
"status" :"success",
"tx_blob" :"1200052280000000240000000768400000000000000A73210384CA3C528F10C75F26E0917F001338BD3C9AA1A39B9FBD583DFFFD96CF2E2D7A7446304402201453CA3D4D17F0EE3828B9E3D6ACF65327F5D4FC2BA30953CACF6CBCB4145E3502202F2154BED1D7462CAC1E3DBB31864E48C3BA0B3133ACA5E37EC54F0D0C339E2D8114830923439D307E642CED308FD91EF701A7BAA74788141620D685FB08D81A70D0B668749CF2E130EA7540",
"tx_json" :{
"Account" :"rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93",
"Fee" :"10",
"Flags" :2147483648,
"RegularKey" :"rsprUqu6BHAffAeG4HpSdjBNvnA6gdnZV7",
"Sequence" :4,
"SigningPubKey" :"0384CA3C528F10C75F26E0917F001338BD3C9AA1A39B9FBD583DFFFD96CF2E2D7A",
"TransactionType" :"SetRegularKey",
"TxnSignature" :"304402201453CA3D4D17F0EE3828B9E3D6ACF65327F5D4FC2BA30953CACF6CBCB4145E3502202F2154BED1D7462CAC1E3DBB31864E48C3BA0B3133ACA5E37EC54F0D0C339E2D",
"hash" :"AB73BBF7C99061678B59FB48D72CA0F5FC6DD2815B6736C6E9EB94439EC236CE"
}
}
}
```
<!-- MULTICODE_BLOCK_END -->
`sign`コマンドの応答には上記のような`tx_blob`値が含まれています。オフライン署名応答には`signedTransaction`値が含まれています。いずれもトランザクションの署名済みバイナリ表現(ブロブ)です。
次に`submit`コマンドを使用して、トランザクションブロブ(`tx_blob`または`signedTransaction`)をネットワークに送信します。
### トランザクションの送信
オフライン署名応答の`signedTransaction`値、または`sign`コマンド応答の`tx_blob`値をとり、[submitメソッド][]を使用して`tx_blob`として値として送信します。
#### 要求フォーマット
要求フォーマットの例:
<!-- MULTICODE_BLOCK_START -->
*WebSocket*
```
{
"command":"submit",
"tx_blob":"1200052280000000240000000468400000000000000A73210384CA3C528F10C75F26E0917F001338BD3C9AA1A39B9FBD583DFFFD96CF2E2D7A7446304402204BCD5663F3A2BA02D2CE374439096EC6D27273522CD6E6E0BDBFB518730EAAE402200ECD02D8D2525D6FA4642613E71E395ECCEA01C42C35A668BF092A00EB649C268114830923439D307E642CED308FD91EF701A7BAA74788141620D685FB08D81A70D0B668749CF2E130EA7540"
}
```
*JSON-RPC*
```
{
"method":"submit",
"params":[
{
"tx_blob":"1200052280000000240000000468400000000000000A73210384CA3C528F10C75F26E0917F001338BD3C9AA1A39B9FBD583DFFFD96CF2E2D7A7446304402204BCD5663F3A2BA02D2CE374439096EC6D27273522CD6E6E0BDBFB518730EAAE402200ECD02D8D2525D6FA4642613E71E395ECCEA01C42C35A668BF092A00EB649C268114830923439D307E642CED308FD91EF701A7BAA74788141620D685FB08D81A70D0B668749CF2E130EA7540"
}
]
}
```
*コマンドライン*
```
#Syntax: submit tx_blob
rippled submit 1200052280000000240000000468400000000000000A73210384CA3C528F10C75F26E0917F001338BD3C9AA1A39B9FBD583DFFFD96CF2E2D7A7446304402204BCD5663F3A2BA02D2CE374439096EC6D27273522CD6E6E0BDBFB518730EAAE402200ECD02D8D2525D6FA4642613E71E395ECCEA01C42C35A668BF092A00EB649C268114830923439D307E642CED308FD91EF701A7BAA74788141620D685FB08D81A70D0B668749CF2E130EA7540
```
<!-- MULTICODE_BLOCK_END -->
#### 応答フォーマット
処理が成功した応答の例:
<!-- MULTICODE_BLOCK_START -->
*WebSocket*
```
{
"result":{
"engine_result":"tesSUCCESS",
"engine_result_code":0,
"engine_result_message":"The transaction was applied.Only final in a validated ledger.",
"tx_blob":"1200052280000000240000000468400000000000000A73210384CA3C528F10C75F26E0917F001338BD3C9AA1A39B9FBD583DFFFD96CF2E2D7A7446304402204BCD5663F3A2BA02D2CE374439096EC6D27273522CD6E6E0BDBFB518730EAAE402200ECD02D8D2525D6FA4642613E71E395ECCEA01C42C35A668BF092A00EB649C268114830923439D307E642CED308FD91EF701A7BAA74788141620D685FB08D81A70D0B668749CF2E130EA7540",
"tx_json":{
"Account":"rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93",
"Fee":"10",
"Flags":2147483648,
"RegularKey":"rsprUqu6BHAffAeG4HpSdjBNvnA6gdnZV7",
"Sequence":4,
"SigningPubKey":"0384CA3C528F10C75F26E0917F001338BD3C9AA1A39B9FBD583DFFFD96CF2E2D7A",
"TransactionType":"SetRegularKey",
"TxnSignature":"304402204BCD5663F3A2BA02D2CE374439096EC6D27273522CD6E6E0BDBFB518730EAAE402200ECD02D8D2525D6FA4642613E71E395ECCEA01C42C35A668BF092A00EB649C26",
"hash":"AB73BBF7C99061678B59FB48D72CA0F5FC6DD2815B6736C6E9EB94439EC236CE"
}
},
"status":"success",
"type":"response"
}
```
*JSON-RPC*
```
{
"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":"1200052280000000240000000468400000000000000A73210384CA3C528F10C75F26E0917F001338BD3C9AA1A39B9FBD583DFFFD96CF2E2D7A7446304402204BCD5663F3A2BA02D2CE374439096EC6D27273522CD6E6E0BDBFB518730EAAE402200ECD02D8D2525D6FA4642613E71E395ECCEA01C42C35A668BF092A00EB649C268114830923439D307E642CED308FD91EF701A7BAA74788141620D685FB08D81A70D0B668749CF2E130EA7540",
"tx_json":{
"Account":"rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93",
"Fee":"10",
"Flags":2147483648,
"RegularKey":"rsprUqu6BHAffAeG4HpSdjBNvnA6gdnZV7",
"Sequence":4,
"SigningPubKey":"0384CA3C528F10C75F26E0917F001338BD3C9AA1A39B9FBD583DFFFD96CF2E2D7A",
"TransactionType":"SetRegularKey",
"TxnSignature":"304402204BCD5663F3A2BA02D2CE374439096EC6D27273522CD6E6E0BDBFB518730EAAE402200ECD02D8D2525D6FA4642613E71E395ECCEA01C42C35A668BF092A00EB649C26",
"hash":"AB73BBF7C99061678B59FB48D72CA0F5FC6DD2815B6736C6E9EB94439EC236CE"
}
}
}
```
*コマンドライン*
```
{
"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" :"1200052280000000240000000468400000000000000A73210384CA3C528F10C75F26E0917F001338BD3C9AA1A39B9FBD583DFFFD96CF2E2D7A7446304402204BCD5663F3A2BA02D2CE374439096EC6D27273522CD6E6E0BDBFB518730EAAE402200ECD02D8D2525D6FA4642613E71E395ECCEA01C42C35A668BF092A00EB649C268114830923439D307E642CED308FD91EF701A7BAA74788141620D685FB08D81A70D0B668749CF2E130EA7540",
"tx_json" :{
"Account" :"rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93",
"Fee" :"10",
"Flags" :2147483648,
"RegularKey" :"rsprUqu6BHAffAeG4HpSdjBNvnA6gdnZV7",
"Sequence" :4,
"SigningPubKey" :"0384CA3C528F10C75F26E0917F001338BD3C9AA1A39B9FBD583DFFFD96CF2E2D7A",
"TransactionType" :"SetRegularKey",
"TxnSignature" :"304402204BCD5663F3A2BA02D2CE374439096EC6D27273522CD6E6E0BDBFB518730EAAE402200ECD02D8D2525D6FA4642613E71E395ECCEA01C42C35A668BF092A00EB649C26",
"hash" :"AB73BBF7C99061678B59FB48D72CA0F5FC6DD2815B6736C6E9EB94439EC236CE"
}
}
}
```
<!-- MULTICODE_BLOCK_END -->
応答に含まれるトランザクションの`hash`は、[トランザクションの最終結果を検索する](tx.html)ときに使用できることに注意してください。
## 3. レギュラーキーペアの検証
アカウントにレギュラーキーペアが正しく設定されていることを検証するため、ステップ2でアカウントに割り当てたレギュラー秘密鍵で[AccountSetトランザクション][]に署名し、アカウントからこのトランザクションを送信します。
ステップ2で説明したように、マスター秘密鍵の送信は危険です。レギュラー秘密鍵の送信も同様に危険です。そのため、トランザクションの署名とネットワークへのトランザクションの送信を切り離した2段階方式でこのトランザクションを実行します。
### トランザクションの署名
{% include '_snippets/tutorial-sign-step.md' %}
<!--{#_ #}-->
要求フィールドに以下の値を指定します。
| 要求フィールド | 値 |
|:--------------|:-------------------------------------------------------------|
| `Account` | アカウントのアドレス。 |
| `secret` | ステップ1で生成し、ステップ2でアカウントに割り当てた`master_key``master_seed`、または`master_seed_hex`(レギュラー秘密鍵)。 |
#### 要求フォーマット
要求フォーマットの例を示します。この要求には`AccountSet`オプションが含まれていないことに注意してください。つまり、トランザクションの成功による影響は、アカウントのレギュラーキーペアが正しく設定されていることを確認する(およびトランザクションコストを消却する)こと以外に何もありません。
<!-- MULTICODE_BLOCK_START -->
*WebSocket*
```
{
"command":"sign",
"tx_json":{
"TransactionType":"AccountSet",
"Account":"rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93"
},
"secret":"sh8i92YRnEjJy3fpFkL8txQSCVo79"
}
```
*JSON-RPC*
```
{
"method":"sign",
"params":[
{
"tx_json":{
"TransactionType":"AccountSet",
"Account":"rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93"
},
"secret":"sh8i92YRnEjJy3fpFkL8txQSCVo79"
}
]
}
```
*コマンドライン*
```
#Syntax: sign secret tx_json
rippled sign sh8i92YRnEjJy3fpFkL8txQSCVo79 '{"TransactionType":"AccountSet", "Account":"rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93"}'
```
<!-- MULTICODE_BLOCK_END -->
#### 応答フォーマット
処理が成功した応答の例:
<!-- MULTICODE_BLOCK_START -->
*WebSocket*
```
{
"result":{
"tx_blob":"1200032280000000240000000468400000000000000A73210330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD02074473045022100A50E867D3B1B5A39F23F1ABCA5C7C3EC755442FDAA357EFD897B865ACA7686DB02206077BF459BCE39BCCBFE1A128DA986D1E00CBEC5F0D6B0E11710F60BE2976FB88114623B8DA4A0BFB3B61AB423391A182DC693DC159E",
"tx_json":{
"Account":"rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93",
"Fee":"10",
"Flags":2147483648,
"Sequence":4,
"SigningPubKey":"0330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD020",
"TransactionType":"AccountSet",
"TxnSignature":"3045022100A50E867D3B1B5A39F23F1ABCA5C7C3EC755442FDAA357EFD897B865ACA7686DB02206077BF459BCE39BCCBFE1A128DA986D1E00CBEC5F0D6B0E11710F60BE2976FB8",
"hash":"D9B305CB6E861D0994A5CDD4726129D91AC4277111DC444DE4CEE44AD4674A9F"
}
},
"status":"success",
"type":"response"
}
```
*JSON-RPC*
```
{
"result":{
"status":"success",
"tx_blob":"1200032280000000240000000468400000000000000A73210330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD02074473045022100A50E867D3B1B5A39F23F1ABCA5C7C3EC755442FDAA357EFD897B865ACA7686DB02206077BF459BCE39BCCBFE1A128DA986D1E00CBEC5F0D6B0E11710F60BE2976FB88114623B8DA4A0BFB3B61AB423391A182DC693DC159E",
"tx_json":{
"Account":"rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93",
"Fee":"10",
"Flags":2147483648,
"Sequence":4,
"SigningPubKey":"0330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD020",
"TransactionType":"AccountSet",
"TxnSignature":"3045022100A50E867D3B1B5A39F23F1ABCA5C7C3EC755442FDAA357EFD897B865ACA7686DB02206077BF459BCE39BCCBFE1A128DA986D1E00CBEC5F0D6B0E11710F60BE2976FB8",
"hash":"D9B305CB6E861D0994A5CDD4726129D91AC4277111DC444DE4CEE44AD4674A9F"
}
}
}
```
*コマンドライン*
```
{
"result" :{
"status" :"success",
"tx_blob" :"1200032280000000240000000468400000000000000A73210330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD02074473045022100A50E867D3B1B5A39F23F1ABCA5C7C3EC755442FDAA357EFD897B865ACA7686DB02206077BF459BCE39BCCBFE1A128DA986D1E00CBEC5F0D6B0E11710F60BE2976FB88114623B8DA4A0BFB3B61AB423391A182DC693DC159E",
"tx_json" :{
"Account" :"rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93",
"Fee" :"10",
"Flags" :2147483648,
"Sequence" :4,
"SigningPubKey" :"0330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD020",
"TransactionType" :"AccountSet",
"TxnSignature" :"3045022100A50E867D3B1B5A39F23F1ABCA5C7C3EC755442FDAA357EFD897B865ACA7686DB02206077BF459BCE39BCCBFE1A128DA986D1E00CBEC5F0D6B0E11710F60BE2976FB8",
"hash" :"D9B305CB6E861D0994A5CDD4726129D91AC4277111DC444DE4CEE44AD4674A9F"
}
}
}
```
<!-- MULTICODE_BLOCK_END -->
`sign`コマンドの応答には上記のような`tx_blob`値が含まれています。オフライン署名応答には`signedTransaction`値が含まれています。いずれもトランザクションの署名済みバイナリ表現(ブロブ)です。
次に`submit`コマンドを使用して、トランザクションブロブ(`tx_blob`または`signedTransaction`)をネットワークに送信します。
### トランザクションの送信
オフライン署名応答の`signedTransaction`値、または`sign`コマンド応答の`tx_blob`値をとり、[submitメソッド][]を使用して`tx_blob`値として送信します。
#### 要求フォーマット
要求フォーマットの例:
<!-- MULTICODE_BLOCK_START -->
*WebSocket*
```
{
"command":"submit",
"tx_blob":"1200032280000000240000000468400000000000000A73210330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD02074473045022100A50E867D3B1B5A39F23F1ABCA5C7C3EC755442FDAA357EFD897B865ACA7686DB02206077BF459BCE39BCCBFE1A128DA986D1E00CBEC5F0D6B0E11710F60BE2976FB88114623B8DA4A0BFB3B61AB423391A182DC693DC159E"
}
```
*JSON-RPC*
```
{
"method":"submit",
"params":[
{
"tx_blob":"1200032280000000240000000468400000000000000A73210330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD02074473045022100A50E867D3B1B5A39F23F1ABCA5C7C3EC755442FDAA357EFD897B865ACA7686DB02206077BF459BCE39BCCBFE1A128DA986D1E00CBEC5F0D6B0E11710F60BE2976FB88114623B8DA4A0BFB3B61AB423391A182DC693DC159E"
}
]
}
```
*コマンドライン*
```
#Syntax: submit tx_blob
rippled submit 1200032280000000240000000468400000000000000A73210330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD02074473045022100A50E867D3B1B5A39F23F1ABCA5C7C3EC755442FDAA357EFD897B865ACA7686DB02206077BF459BCE39BCCBFE1A128DA986D1E00CBEC5F0D6B0E11710F60BE2976FB88114623B8DA4A0BFB3B61AB423391A182DC693DC159E
```
<!-- MULTICODE_BLOCK_END -->
#### 応答フォーマット
処理が成功した応答の例:
<!-- MULTICODE_BLOCK_START -->
*WebSocket*
```
{
"result":{
"engine_result":"tesSUCCESS",
"engine_result_code":0,
"engine_result_message":"The transaction was applied.Only final in a validated ledger.",
"tx_blob":"1200032280000000240000000468400000000000000A73210330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD02074473045022100A50E867D3B1B5A39F23F1ABCA5C7C3EC755442FDAA357EFD897B865ACA7686DB02206077BF459BCE39BCCBFE1A128DA986D1E00CBEC5F0D6B0E11710F60BE2976FB88114623B8DA4A0BFB3B61AB423391A182DC693DC159E",
"tx_json":{
"Account":"rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93",
"Fee":"10",
"Flags":2147483648,
"Sequence":4,
"SigningPubKey":"0330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD020",
"TransactionType":"AccountSet",
"TxnSignature":"3045022100A50E867D3B1B5A39F23F1ABCA5C7C3EC755442FDAA357EFD897B865ACA7686DB02206077BF459BCE39BCCBFE1A128DA986D1E00CBEC5F0D6B0E11710F60BE2976FB8",
"hash":"D9B305CB6E861D0994A5CDD4726129D91AC4277111DC444DE4CEE44AD4674A9F"
}
},
"status":"success",
"type":"response"
}
```
*JSON-RPC*
```
{
"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":"1200032280000000240000000468400000000000000A73210330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD02074473045022100A50E867D3B1B5A39F23F1ABCA5C7C3EC755442FDAA357EFD897B865ACA7686DB02206077BF459BCE39BCCBFE1A128DA986D1E00CBEC5F0D6B0E11710F60BE2976FB88114623B8DA4A0BFB3B61AB423391A182DC693DC159E",
"tx_json":{
"Account":"rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93",
"Fee":"10",
"Flags":2147483648,
"Sequence":4,
"SigningPubKey":"0330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD020",
"TransactionType":"AccountSet",
"TxnSignature":"3045022100A50E867D3B1B5A39F23F1ABCA5C7C3EC755442FDAA357EFD897B865ACA7686DB02206077BF459BCE39BCCBFE1A128DA986D1E00CBEC5F0D6B0E11710F60BE2976FB8",
"hash":"D9B305CB6E861D0994A5CDD4726129D91AC4277111DC444DE4CEE44AD4674A9F"
}
}
}
```
*コマンドライン*
```
{
"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" :"1200032280000000240000000468400000000000000A73210330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD02074473045022100A50E867D3B1B5A39F23F1ABCA5C7C3EC755442FDAA357EFD897B865ACA7686DB02206077BF459BCE39BCCBFE1A128DA986D1E00CBEC5F0D6B0E11710F60BE2976FB88114623B8DA4A0BFB3B61AB423391A182DC693DC159E",
"tx_json" :{
"Account" :"rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93",
"Fee" :"10",
"Flags" :2147483648,
"Sequence" :4,
"SigningPubKey" :"0330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD020",
"TransactionType" :"AccountSet",
"TxnSignature" :"3045022100A50E867D3B1B5A39F23F1ABCA5C7C3EC755442FDAA357EFD897B865ACA7686DB02206077BF459BCE39BCCBFE1A128DA986D1E00CBEC5F0D6B0E11710F60BE2976FB8",
"hash" :"D9B305CB6E861D0994A5CDD4726129D91AC4277111DC444DE4CEE44AD4674A9F"
}
}
}
```
<!-- MULTICODE_BLOCK_END -->
## 4. 次のステップ
これで、レギュラーキーペアをアカウントに割り当てるメリットについて理解しました。次に以下の関連トピックとチュートリアルを参照してください。
- [レギュラーキーペアの変更または削除](change-or-remove-a-regular-key-pair.html)
- [マルチ署名の設定](set-up-multi-signing.html)
- [発行アドレスと運用アドレス](issuing-and-operational-addresses.html)
- [取引所としてのXRPの上場](list-xrp-as-an-exchange.html)
<!--{# common link defs #}-->
{% include '_snippets/rippled-api-links.md' %}
{% include '_snippets/tx-type-links.md' %}
{% include '_snippets/rippled_versions.md' %}

View File

@@ -0,0 +1,361 @@
# レギュラーキーペアの変更または削除
XRP Ledgerでは、アカウントはその後のトランザクションには _レギュラーキーペア_ と呼ばれるセカンダリキーペアで署名することができます。アカウントのレギュラーキーペアが漏えいした場合、またはセキュリティ対策としてレギュラーキーペアを定期的に変更する必要がある場合は、[SetRegularKeyトランザクション][]を使用してアカウントレギュラーキーペアを削除または変更します。
マスターキーペアとレギュラーキーペアの詳細は、[暗号鍵](cryptographic-keys.html)を参照してください。
## レギュラーキーペアの変更
既存のレギュラーキーペアを変更する手順は、初めて[レギュラーキーを割り当てる](assign-a-regular-key-pair.html)手順とほぼ同じです。キーペアを生成し、レギュラーキーペアとしてアカウントに割り当てます。これにより既存のレギュラーキーペアが上書きされます。ただし大きく異なる点は、既存のレギュラーキーペアを変更するときには既存のレギュラー秘密鍵を使用して秘密鍵自体を置き換えることができますが、レギュラーキーペアをアカウントに初めて割り当てるときにはアカウントのマスター秘密鍵を使用する必要があることです。
マスターキーペアとレギュラーキーペアの詳細は、[暗号鍵](cryptographic-keys.html)を参照してください。
## レギュラーキーペアの削除
漏えいしたレギュラーキーペアを単にアカウントから削除する場合は、キーペアを最初に生成する必要はありません。`RegularKey`フィールドを省略した[SetRegularKeyトランザクション][]を使用します。アカウントの別の署名手段(マスターキーペアまたは[署名者リスト](multi-signing.html))が現在有効になっていない場合は、トランザクションが失敗することに注意してください。
アカウントのレギュラーキーペアを削除する場合、`SetRegularKey`トランザクションでは、アカウントのマスター秘密鍵シークレットまたは既存のレギュラーキーペアによる署名が必要です。マスター秘密鍵またはレギュラー秘密鍵の送信は危険であるため、トランザクションの署名とネットワークへのトランザクションの送信を切り離した2段階方式でこのトランザクションを実行します。
### トランザクションの署名
{% include '_snippets/tutorial-sign-step.md' %}
<!--{#_ #}-->
要求フィールドに以下の値を指定します。
| 要求フィールド | 値 |
|:--------------|:-------------------------------------------------------------|
| `Account` | アカウントのアドレス。 |
| `secret` | アカウントの`master_key``master_seed`、または`master_seed_hex`(マスター秘密鍵またはレギュラー秘密鍵) |
#### 要求フォーマット
要求フォーマットの例:
<!-- MULTICODE_BLOCK_START -->
*WebSocket*
```
{
"command":"sign",
"tx_json":{
"TransactionType":"SetRegularKey",
"Account":"r9xQZdFGwbwTB3g9ncKByWZ3du6Skm7gQ8"
},
"secret":"snoPBrXtMeMyMHUVTgbuqAfg1SUTb"
}
```
*JSON-RPC*
```
{
"method":"sign",
"params":[
{
"secret" :"snoPBrXtMeMyMHUVTgbuqAfg1SUTb",
"tx_json" :{
"TransactionType" :"SetRegularKey",
"Account" :"r9xQZdFGwbwTB3g9ncKByWZ3du6Skm7gQ8"
}
}
]
}
```
*コマンドライン*
```
#Syntax: sign secret tx_json
rippled sign snoPBrXtMeMyMHUVTgbuqAfg1SUTb '{"TransactionType":"SetRegularKey", "Account":"rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93"}'
```
<!-- MULTICODE_BLOCK_END -->
#### 応答フォーマット
処理が成功した応答の例:
<!-- MULTICODE_BLOCK_START -->
*WebSocket*
```
{
"result":{
"tx_blob":"1200052280000000240000000268400000000000000A73210330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD02074473045022100CAB9A6F84026D57B05760D5E2395FB7BE86BF39F10DC6E2E69DC91238EE0970B022058EC36A8EF9EE65F5D0D8CAC4E88C8C19FEF39E40F53D4CCECBB59701D6D1E838114623B8DA4A0BFB3B61AB423391A182DC693DC159E",
"tx_json":{
"Account":"r9xQZdFGwbwTB3g9ncKByWZ3du6Skm7gQ8",
"Fee":"10",
"Flags":2147483648,
"Sequence":2,
"SigningPubKey":"0330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD020",
"TransactionType":"SetRegularKey",
"TxnSignature":"3045022100CAB9A6F84026D57B05760D5E2395FB7BE86BF39F10DC6E2E69DC91238EE0970B022058EC36A8EF9EE65F5D0D8CAC4E88C8C19FEF39E40F53D4CCECBB59701D6D1E83",
"hash":"59BCAB8E5B9D4597D6A7BFF22F6C555D0F41420599A2E126035B6AF19261AD97"
}
},
"status":"success",
"type":"response"
}
```
*JSON-RPC*
```
{NEWWWWWWWWWWWW
"result":{
"status":"success",
"tx_blob":"1200052280000000240000000268400000000000000A73210330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD02074473045022100CAB9A6F84026D57B05760D5E2395FB7BE86BF39F10DC6E2E69DC91238EE0970B022058EC36A8EF9EE65F5D0D8CAC4E88C8C19FEF39E40F53D4CCECBB59701D6D1E838114623B8DA4A0BFB3B61AB423391A182DC693DC159E",
"tx_json":{
"Account":"r9xQZdFGwbwTB3g9ncKByWZ3du6Skm7gQ8",
"Fee":"10",
"Flags":2147483648,
"Sequence":2,
"SigningPubKey":"0330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD020",
"TransactionType":"SetRegularKey",
"TxnSignature":"3045022100CAB9A6F84026D57B05760D5E2395FB7BE86BF39F10DC6E2E69DC91238EE0970B022058EC36A8EF9EE65F5D0D8CAC4E88C8C19FEF39E40F53D4CCECBB59701D6D1E83",
"hash":"59BCAB8E5B9D4597D6A7BFF22F6C555D0F41420599A2E126035B6AF19261AD97"
}
}
}
```
*コマンドライン*
```
{
"result" :{
"status" :"success",
"tx_blob" :"1200052280000000240000000268400000000000000A73210330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD02074473045022100CAB9A6F84026D57B05760D5E2395FB7BE86BF39F10DC6E2E69DC91238EE0970B022058EC36A8EF9EE65F5D0D8CAC4E88C8C19FEF39E40F53D4CCECBB59701D6D1E838114623B8DA4A0BFB3B61AB423391A182DC693DC159E",
"tx_json" :{
"Account" :"r9xQZdFGwbwTB3g9ncKByWZ3du6Skm7gQ8",
"Fee" :"10",
"Flags" :2147483648,
"Sequence" :2,
"SigningPubKey" :"0330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD020",
"TransactionType" :"SetRegularKey",
"TxnSignature" :"3045022100CAB9A6F84026D57B05760D5E2395FB7BE86BF39F10DC6E2E69DC91238EE0970B022058EC36A8EF9EE65F5D0D8CAC4E88C8C19FEF39E40F53D4CCECBB59701D6D1E83",
"hash" :"59BCAB8E5B9D4597D6A7BFF22F6C555D0F41420599A2E126035B6AF19261AD97"
}
}
}
```
<!-- MULTICODE_BLOCK_END -->
`sign`コマンドの応答には上記のような`tx_blob`値が含まれています。オフライン署名応答には`signedTransaction`値が含まれています。いずれもトランザクションの署名済みバイナリ表現(ブロブ)です。
次に`submit`コマンドを使用して、トランザクションブロブ(`tx_blob`または`signedTransaction`)をネットワークに送信します。
### トランザクションの送信
オフライン署名応答の`signedTransaction`値、または`sign`コマンド応答の`tx_blob`値をとり、[submitメソッド][]を使用して`tx_blob`として送信します。
#### 要求フォーマット
要求フォーマットの例:
<!-- MULTICODE_BLOCK_START -->
*WebSocket*
```
{
"command":"submit",
"tx_blob":"1200052280000000240000000268400000000000000A73210330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD02074473045022100CAB9A6F84026D57B05760D5E2395FB7BE86BF39F10DC6E2E69DC91238EE0970B022058EC36A8EF9EE65F5D0D8CAC4E88C8C19FEF39E40F53D4CCECBB59701D6D1E838114623B8DA4A0BFB3B61AB423391A182DC693DC159E"
}
```
*JSON-RPC*
```
{
"method":"submit",
"params":[
{
"tx_blob":"1200052280000000240000000268400000000000000A73210330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD02074473045022100CAB9A6F84026D57B05760D5E2395FB7BE86BF39F10DC6E2E69DC91238EE0970B022058EC36A8EF9EE65F5D0D8CAC4E88C8C19FEF39E40F53D4CCECBB59701D6D1E838114623B8DA4A0BFB3B61AB423391A182DC693DC159E"
}
]
}
```
*コマンドライン*
```
#Syntax: submit tx_blob
rippled submit 1200052280000000240000000268400000000000000A73210330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD02074473045022100CAB9A6F84026D57B05760D5E2395FB7BE86BF39F10DC6E2E69DC91238EE0970B022058EC36A8EF9EE65F5D0D8CAC4E88C8C19FEF39E40F53D4CCECBB59701D6D1E838114623B8DA4A0BFB3B61AB423391A182DC693DC159E
```
<!-- MULTICODE_BLOCK_END -->
#### 応答フォーマット
処理が成功した応答の例:
<!-- MULTICODE_BLOCK_START -->
*WebSocket*
```
{
"result":{
"engine_result":"tesSUCCESS",
"engine_result_code":0,
"engine_result_message":"The transaction was applied.Only final in a validated ledger.",
"tx_blob":"1200052280000000240000000268400000000000000A73210330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD02074473045022100CAB9A6F84026D57B05760D5E2395FB7BE86BF39F10DC6E2E69DC91238EE0970B022058EC36A8EF9EE65F5D0D8CAC4E88C8C19FEF39E40F53D4CCECBB59701D6D1E838114623B8DA4A0BFB3B61AB423391A182DC693DC159E",
"tx_json":{
"Account":"r9xQZdFGwbwTB3g9ncKByWZ3du6Skm7gQ8",
"Fee":"10",
"Flags":2147483648,
"Sequence":2,
"SigningPubKey":"0330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD020",
"TransactionType":"SetRegularKey",
"TxnSignature":"3045022100CAB9A6F84026D57B05760D5E2395FB7BE86BF39F10DC6E2E69DC91238EE0970B022058EC36A8EF9EE65F5D0D8CAC4E88C8C19FEF39E40F53D4CCECBB59701D6D1E83",
"hash":"59BCAB8E5B9D4597D6A7BFF22F6C555D0F41420599A2E126035B6AF19261AD97"
}
},
"status":"success",
"type":"response"
}
```
*JSON-RPC*
```
{
"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":"1200052280000000240000000268400000000000000A73210330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD02074473045022100CAB9A6F84026D57B05760D5E2395FB7BE86BF39F10DC6E2E69DC91238EE0970B022058EC36A8EF9EE65F5D0D8CAC4E88C8C19FEF39E40F53D4CCECBB59701D6D1E838114623B8DA4A0BFB3B61AB423391A182DC693DC159E",
"tx_json":{
"Account":"r9xQZdFGwbwTB3g9ncKByWZ3du6Skm7gQ8",
"Fee":"10",
"Flags":2147483648,
"Sequence":2,
"SigningPubKey":"0330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD020",
"TransactionType":"SetRegularKey",
"TxnSignature":"3045022100CAB9A6F84026D57B05760D5E2395FB7BE86BF39F10DC6E2E69DC91238EE0970B022058EC36A8EF9EE65F5D0D8CAC4E88C8C19FEF39E40F53D4CCECBB59701D6D1E83",
"hash":"59BCAB8E5B9D4597D6A7BFF22F6C555D0F41420599A2E126035B6AF19261AD97"
}
}
}
```
*コマンドライン*
```
{
"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" :"1200052280000000240000000268400000000000000A73210330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD02074473045022100CAB9A6F84026D57B05760D5E2395FB7BE86BF39F10DC6E2E69DC91238EE0970B022058EC36A8EF9EE65F5D0D8CAC4E88C8C19FEF39E40F53D4CCECBB59701D6D1E838114623B8DA4A0BFB3B61AB423391A182DC693DC159E",
"tx_json" :{
"Account" :"r9xQZdFGwbwTB3g9ncKByWZ3du6Skm7gQ8",
"Fee" :"10",
"Flags" :2147483648,
"Sequence" :2,
"SigningPubKey" :"0330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD020",
"TransactionType" :"SetRegularKey",
"TxnSignature" :"3045022100CAB9A6F84026D57B05760D5E2395FB7BE86BF39F10DC6E2E69DC91238EE0970B022058EC36A8EF9EE65F5D0D8CAC4E88C8C19FEF39E40F53D4CCECBB59701D6D1E83",
"hash" :"59BCAB8E5B9D4597D6A7BFF22F6C555D0F41420599A2E126035B6AF19261AD97"
}
}
}
```
<!-- MULTICODE_BLOCK_END -->
レギュラーキーペアの削除が成功したかどうかを確認するには、削除したレギュラー秘密鍵を使用してトランザクションを送信できないことを確認します。
前述の`SetRegularKey`トランザクションにより削除されたレギュラー秘密鍵を使用して[AccountSetトランザクション][]に署名した際のエラー応答の例を以下に示します。
### 応答フォーマット
処理が成功した応答の例:
<!-- MULTICODE_BLOCK_START -->
*WebSocket*
```
{
"error":"badSecret",
"error_code":41,
"error_message":"Secret does not match account.",
"request":{
"command":"submit",
"secret":"snoPBrXtMeMyMHUVTgbuqAfg1SUTb",
"tx_json":{
"Account":"r9xQZdFGwbwTB3g9ncKByWZ3du6Skm7gQ8",
"TransactionType":"AccountSet"
}
},
"status":"error",
"type":"response"
}
```
*JSON-RPC*
```
{NEWWWWWWWWWWWW
"result":{
"error":"badSecret",
"error_code":41,
"error_message":"Secret does not match account.",
"request":{
"command":"submit",
"secret":"snoPBrXtMeMyMHUVTgbuqAfg1SUTb",
"tx_json":{
"Account":"r9xQZdFGwbwTB3g9ncKByWZ3du6Skm7gQ8",
"TransactionType":"AccountSet"
}
},
"status":"error"
}
}
```
*コマンドライン*
```
{
"result" :{
"error" :"badSecret",
"error_code" :41,
"error_message" :"Secret does not match account.",
"request" :{
"command" :"submit",
"secret" :"snoPBrXtMeMyMHUVTgbuqAfg1SUTb",
"tx_json" :{
"Account" :"r9xQZdFGwbwTB3g9ncKByWZ3du6Skm7gQ8",
"TransactionType" :"AccountSet"
}
},
"status" :"error"
}
}
```
<!-- MULTICODE_BLOCK_END -->
場合によっては、`SetRegularKey`トランザクションを使用して、[トランザクションコスト](transaction-cost.html)を支払わずに[Key Resetトランザクション](transaction-cost.html#key-resetトランザクション)を送信できます。FeeEscalation Amendmentを有効にすると、Key Resetトランザクションの名目トランザクションコストがゼロであっても、`rippled`は他のトランザクションよりもKey Resetトランザクションを優先します。
<!--{# common link defs #}-->
{% include '_snippets/rippled-api-links.md' %}
{% include '_snippets/tx-type-links.md' %}
{% include '_snippets/rippled_versions.md' %}

View File

@@ -0,0 +1,219 @@
# マルチ署名の設定
マルチ署名は、XRP Ledgerのトランザクションを承認する3種類の方法の1つです。マルチ署名の他に[レギュラーキーとマスターキー](cryptographic-keys.html)で署名する方法があります。3種類のトランザクション承認方法を自由に組み合わせて使用できるようにアドレスを設定できます。
このチュートリアルでは、アドレスのマルチ署名を有効にする方法を説明します。
## 前提条件
- 資金供給のあるXRP Ledgerアドレスが必要です。
- XRP Ledgerフォーマットでキーペアを生成するツールを利用できる必要があります。この処理に`rippled`サーバーを使用する場合は、[wallet_proposeメソッド][]が管理者専用であるため、管理者アクセス権限が必要です。
- マルチ署名は使用可能である必要があります。マルチ署名は、2016年6月27日以降、XRP Ledger Consensusプロトコルに対する[**Amendment**](amendments.html)により利用できるようになりました。
## 1. 資金供給のあるアドレスの準備
トランザクションを送信でき、利用可能なXRPを十分に保有するXRP Ledgerアドレスが必要です。
[MultiSignReserve Amendment][]が有効ではない場合、マルチ署名を使用するには[アカウント準備金](reserves.html)および[トランザクションコスト](transaction-cost.html)に通常よりも多くのXRPが必要となります。必要額は、使用する署名および署名者の数に応じて増加します。
[MultiSignReserve Amendment][]が有効な場合、マルチ署名を使用するには、使用する署名と署名者の数に関わらず、アカウントの準備金として5 XRPが必要です。マルチ署名済みトランザクションの[トランザクションコスト](transaction-cost.html)は、このAmendmentの影響を受けず、使用する署名と署名者の数に応じて増加します。
`rippled`を[スタンドアロンモード](rippled-server-modes.html#rippledサーバーをスタンドアロンモードで実行する理由)で新しいジェネシスレジャーで開始した場合は、以下の操作を行う必要があります:
1. 新しいアドレスのキーを生成するか、またはすでに所有するキーを再利用します。
2. ジェネシスアカウントから新しいアドレスに資金を供給するため、Paymentトランザクションを送信します。[XRPのdrop数][]で100,000,000以上を送信してください。
3. 手動でレジャーを閉鎖します。
## 2. メンバーキーの準備
複数のXRP LedgerキーセットアドレスとシークレットをSignerListのメンバーに追加する必要があります。SignerListには、レジャーに既存の資金供給のあるアドレス、または[wallet_proposeメソッド][]で生成した新しいアドレスを追加できます。例:
$ 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"
}
}
生成した各アドレスの`account_id`XRP Ledgerアドレス`master_seed`(シークレットキー)をメモします。
## 3. SignerListSetトランザクションの送信
通常の方法(シングルシグネチャー)で[SignerListSetトランザクション][]に[署名して送信](transaction-basics.html#トランザクションへの署名とトランザクションの送信)します。これによりSignerListがXRP Ledgerのアドレスに関連付けられるので、これ以降はSignerListの複数メンバーがあなたの代わりにトランザクションに署名するマルチ署名が可能となります。
この例ではSignerListに3人のメンバーが含まれています。また、マルチ署名済みトランザクションにはrsA2LpzuawewSBQXkiju3YQTMzW13pAAdWの署名と、リストの他の2人のメンバーからの少なくとも1つの署名を必要とするように、重みと定数が設定されています。
{% include '_snippets/secret-key-warning.md' %}
<!--{#_ #}-->
$ 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"
}
}
}
[トランザクションの結果](transaction-results.html)が[**tesSUCCESS**](tes-success.html)であることを確認します。それ以外の場合、トランザクションは失敗しています。スタンドアロンモードまたは本番環境以外のネットワークで問題が発生した場合は、[マルチ署名が有効であること](start-a-new-genesis-ledger-in-stand-alone-mode.html#新しいジェネシスレジャーの設定)を確認してください。
**注記:** [MultiSignReserve Amendment][]が有効ではない場合は、SignerListのメンバーの増加に応じて、アドレスの[所有者準備金](reserves.html#所有者準備金)のXRP額を増加する必要があります。アドレスに十分なXRPがないと、トランザクションは[tecINSUFFICIENT_RESERVE](tec-codes.html)で失敗します。[MultiSignReserve Amendment][]が有効な場合は、SignerListの署名者の数に関係なく[所有者準備金](reserves.html#所有者準備金)として必要なXRPは5 XRPです。関連項目: [SignerListと準備金](signerlist.html#signerlistと準備金)
## 4. レジャーの閉鎖
本番環境のネットワークでは、レジャーが自動的に閉鎖するまでに47秒かかる場合があります。
スタンドアロンモードで`rippled`を実行している場合は、[ledger_acceptメソッド][]を使用してレジャーを手動で閉鎖します。
$ 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. 新しい署名者リストの確認
[account_objectsメソッド][]を使用して、SignerListに最新の検証済みレジャーのアドレスが関連付けられていることを確認します。
通常、アカウントは異なるタイプのオブジェクトトラストラインやオファーなどを複数所有できます。このチュートリアルで新しいアドレスに資金を供給した場合、SignerListが応答の唯一のオブジェクトになります。
$ 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
}
}
SignerListが予期した内容で存在していれば、アドレスでマルチ署名ができるようになります。
## 6. その他のステップ
これで、アドレスから[マルチ署名済みトランザクションを送信](send-a-multi-signed-transaction.html)できます。次の操作も実行できます。
* `asfDisableMaster`フラグを使用して[AccountSetトランザクション][]を送信し、アドレスのマスターキーペアを無効化。
* [SetRegularKeyトランザクション][]を送信してアドレスのレギュラーキーペアを削除(レギュラーキーペアをすでに設定している場合)。
<!--{# common link defs #}-->
{% include '_snippets/rippled-api-links.md' %}
{% include '_snippets/tx-type-links.md' %}
{% include '_snippets/rippled_versions.md' %}

View File

@@ -0,0 +1,87 @@
# rippledサーバーのクラスター化
1つのデータセンターで複数の`rippled`サーバーを稼働している場合は、これらのサーバーを[クラスター](clustering.html)に構成して、効率を最大化できます。クラスター構成の設定は次のとおりです。
1. 各サーバーのIPアドレスをメモします。
2. [validation_createメソッド][]を使用して各サーバーの一意のシードを生成します。
コマンドラインインターフェイスを使用する場合の例を以下に示します。
$ rippled validation_create
Loading: "/etc/rippled.cfg"
Connecting to 127.0.0.1:5005
{
"result" : {
"status" : "success",
"validation_key" : "FAWN JAVA JADE HEAL VARY HER REEL SHAW GAIL ARCH BEN IRMA",
"validation_public_key" : "n9Mxf6qD4J55XeLSCEpqaePW4GjoCR5U1ZeGZGJUCNe3bQa4yQbG",
"validation_seed" : "ssZkdwURFMBXenJPbrpE14b6noJSu"
}
}
各応答の`validation_seed`パラメーターと`validation_public_key`パラメーターを安全な場所に保存します。
3. 各サーバーで[構成ファイル](https://github.com/ripple/rippled/blob/master/cfg/rippled-example.cfg)を編集し、以下のセクションを変更します。
1. `[ips_fixed]`セクションに、クラスターの _その他の_ 各メンバーのIPアドレスとポートを記入します。各サーバーのポート番号は、サーバーの `rippled.cfg`に指定されている`protocol = peer`ポート通常は51235と一致している必要があります。例:
[ips_fixed]
192.168.0.1 51235
192.168.0.2 51235
この例では、このサーバーがダイレクトピアツーピア接続の維持を常に試みる先のピアサーバーを特定しています。
2. `[node_seed]`セクションでは、サーバーのードシードを、ステップ2で[validation_createメソッド][]を使用して生成した`validation_seed`の値の1つに設定します。各サーバーは一意のードシードを使用する必要があります。例:
[node_seed]
ssZkdwURFMBXenJPbrpE14b6noJSu
この例では、ピアツーピア通信(検証メッセージを除く)の署名にサーバーが使用するキーペアを定義しています。
3. `[cluster_nodes]`セクションでは、サーバーのクラスターのメンバーを設定します。これらのメンバーは`validation_public_key`の値で識別されます。各サーバーのクラスターの _その他の_ すべてのメンバーをここに記入する必要があります。任意で、各サーバーのカスタム名を追加します。例:
[cluster_nodes]
n9McNsnzzXQPbg96PEUrrQ6z3wrvgtU4M7c97tncMpSoDzaQvPar keynes
n94UE1ukbq6pfZY9j54sv2A1UrEeHZXLbns3xK5CzU9NbNREytaa friedman
この例は、サーバーがクラスターのメンバーを認識するために使用するキーペアを定義しています。
4. 構成ファイルを保存した後、各サーバーで`rippled`を再起動します。
# systemctl restart rippled
5. 各サーバーがクラスターのメンバーになっていることを確認するには、[peersメソッド][]を使用します。`cluster`フィールドに、各サーバーの公開鍵とカスタム名(構成している場合)のリストが表示されます。
コマンドラインインターフェイスを使用する場合の例を以下に示します。
$ rippled peers
Loading: "/etc/rippled.cfg"
Connecting to 127.0.0.1:5005
{
"result" : {
"cluster" : {
"n9McNsnzzXQPbg96PEUrrQ6z3wrvgtU4M7c97tncMpSoDzaQvPar": {
"tag": "keynes",
"age": 1
},
"n94UE1ukbq6pfZY9j54sv2A1UrEeHZXLbns3xK5CzU9NbNREytaa": {
"tag": "friedman",
"age": 1
}
},
"peers" : [
...(omitted) ...
],
"status" : "success"
}
}
<!--{# common link defs #}-->
{% include '_snippets/rippled-api-links.md' %}
{% include '_snippets/tx-type-links.md' %}
{% include '_snippets/rippled_versions.md' %}

View File

@@ -0,0 +1,98 @@
# 指示による削除の設定
デフォルトの構成ファイルは、新しいレジャーバージョンが利用可能になると`rippled`が古いXRP Ledgerの履歴を自動的に削除するように設定されています。サーバーがピーク時にハードウェアリソースの大部分を使用する場合は、オフピーク時に実行するようスケジュールされたコマンドからの指示があった場合にのみ、レジャーを削除するようにサーバーを設定できます。これにより、オンライン削除がサーバーのパフォーマンスに及ぼす影響はほとんどなくなります。
## 前提条件
このチュートリアルでは、ご使用のサーバーが以下の条件を満たしていることを前提としています。
- サポートされているオペレーティングシステムを使用している。Ubuntu Linux、Red Hat Enterprise LinuxRHEL、CentOS
- `rippled`サーバーがすでに[インストール](install-rippled.html)されており、[オンライン削除](online-deletion.html)が有効になっている。
デフォルトの構成ファイルは、レジャーバージョンが2000個を超えるとオンライン削除を実行するよう設定されています。
- `cron`デーモンがインストールされており、実行されている。
Ubuntu Linuxではデフォルトで`cron`デーモンが実行されます。
RHELまたはCentOSでは、以下の`cronie`パッケージをインストールできます。
$ sudo yum install cronie
- 選択した量の履歴をレジャーストアーに保管するのに十分なディスク容量がサーバーにある。
各種設定で必要なストレージの容量についての詳細は、[容量計画](capacity-planning.html)を参照してください。指示による削除が有効な場合、削除が実行されるまでにサーバーに蓄積可能な履歴の最大数は、`online_delete`設定で設定したレジャーバージョン数と、オンライン削除の指示の間隔を**加算**したものに相当します。
- サーバーの使用率が最も低い時間帯を把握している。
## 設定手順
日次スケジュールで指示による削除は以下の手順で設定します。
1. `rippled`の構成ファイルの`[node_db]`スタンザで`advisory_delete`を有効にします。
[node_db]
# Other settings unchanged ...
online_delete=2000
advisory_delete=1
- 指示された場合にのみオンライン削除を実行するには、`advisory_delete``1`に設定します。(`0`に設定すると、新しいレジャーバージョンが使用可能になると自動的にオンライン削除が実行されます。)
- `online_delete`を、オンライン削除の実行後に維持するレジャーバージョンの最小数に設定します。オンライン削除が実行されるまでに蓄積される履歴は、この値よりも多くなります。
{% include '_snippets/conf-file-location.md' %}<!--_ -->
2. サーバーに対してオンライン削除を指示する[can_deleteメソッド][]の実行をテストします。
このコマンドの実行には[`rippled`コマンドラインインターフェイス](get-started-with-the-rippled-api.html#コマンドライン)を使用できます。例:
$ rippled --conf=/etc/opt/ripple/rippled.cfg can_delete now
応答は、サーバーがそのレジャーストアーから削除するレジャーインデックスの最大値を示します。たとえば、以下のメッセージはレジャーインデックス43633667以下のレジャーバージョンを削除できることを示します。
{
"result": {
"can_delete": 43633667,
"status": "success"
}
}
サーバー内の _新しい_ 検証済みレジャーバージョンの数が、`online_delete`の設定以上となった場合にのみ、レジャーバージョンが削除されます。
3. 前のステップでテストした`can_delete`メソッドを、予定した時刻に実行するように`cron`デーモンを設定します。
`cron` 設定を編集します。
$ crontab -e
以下の例では、サーバー時刻で毎日1:05 AMにサーバーが削除を実行するように設定されています。
5 1 * * * rippled --conf /etc/opt/ripple/rippled.cfg can_delete now
サーバーで設定されているタイムゾーンに基づいてコマンドが実行されるようにスケジュールしてください。
**ヒント:**`advisory_delete`を無効にしている場合は、`cron`ジョブをオンラインで実行するようにスケジュールする必要はありません。この場合、サーバーの最も古いレジャーバージョンと現行の検証済みレジャーバージョンの差が`online_delete`の値以上である場合に、`rippled`によりオンライン削除が実行されます。
4. `rippled`サービスを起動(または再起動)します。
$ sudo systemctl restart rippled
5. [server_infoメソッド][]を使用してサーバーの`complete_ledgers`範囲を定期的に調べ、レジャーがスケジュール通りに削除されていることを確認します。
オンライン削除の実行後には`complete_ledgers`の最小レジャーインデックスが増加します。
サーバーの使用率の状況と、一度に削除する履歴の量によっては、削除が完了するまでに数分間かかることがあります。
## トラブルシューティング
オンライン削除の設定後にオンライン削除が実行されていないようである場合は、以下を試してください。
- `cron`ジョブを設定したユーザーに、コマンドラインクライアントとして`rippled`サーバーを実行できる権限があることを確認します。
- cronジョブの構文とこのジョブの実行予定時刻を確認します。
- `rippled`実行可能ファイルが`cron`設定で指定したパスで使用可能であることを確認します。必要に応じて実行可能ファイルの絶対パス(`/opt/ripple/bin/rippled`など)を指定します。
- `rippled`ログで、`SHAMapStore::WRN`で始まるメッセージを調べます。このメッセージが出力されている場合、サーバーがネットワークと同期していない状態になったために[オンライン削除が中断されている](online-deletion.html#オンライン削除の中断)可能性があります。
<!--{# common link defs #}-->
{% include '_snippets/rippled-api-links.md' %}
{% include '_snippets/tx-type-links.md' %}
{% include '_snippets/rippled_versions.md' %}

View File

@@ -0,0 +1,92 @@
# 全履歴の設定
デフォルトの構成では、新しいレジャーバージョンが利用可能になると`rippled`サーバーが古いXRP Ledger状態とトランザクションの履歴を自動的に削除するように設定されています。ほとんどのサーバーでは現在の状態を把握してトランザクションを処理するのに古い履歴は不要なため、この設定で十分です。ただし、一部のサーバーが可能な限り多くのXRP Ledgerの履歴を提供する場合、これはネットワークにとって有用であることがあります。
## 警告
全履歴の保存にはコストがかかります。2018年12月11日の時点では、XRP Ledgerの全履歴が専有するディスク容量は約**9テラバイト**にのぼります。適切なサーバーパフォーマンスのためには、全履歴を高速なソリッドステートディスクドライブに保存する必要があります。このような大量のソリッドステートストレージは安価ではなく、また保管する必要のある履歴の合計量は毎日約12 GBずつ増加します。
ピアツーピアネットワークから全履歴を取得するには非常に長い時間がかかり(数か月)、また古い履歴を取得し、かつレジャーの新たな進展を常に把握するには、システムリソースとネットワークリソースを十分に備えたサーバーが必要となります。レジャー履歴の取得を迅速に開始するため、すでに大量の履歴をダウンロードしている別のサーバーオペレーターを探すこともできます。このようなオペレーターは、データベースダンプを提供できるか、または少なくとも、履歴の取得に十分な時間、あなたのサーバーをオペレーターのサーバーに明示的にピア接続することができます。サーバーはファイルからレジャー履歴を読み込み、インポートする履歴レジャーの整合性を検証できます。
ネットワークへの参加、トランザクションの検証、またはネットワークの現在の状態の確認には、全履歴を記録するサーバーは必要ありません。全履歴が有用となるのは、過去に発生したトランザクションの結果や、過去の特定の時点におけるレジャーの状態を確認する場合だけです。このような情報を取得するには、必要とする履歴を保持している他のサーバーを利用する必要があります。
全履歴は保管せずにXRP Ledgerネットワークの履歴の保管に参加したい場合には、[履歴シャーディングを構成](configure-history-sharding.html)すれば、レジャー履歴のグループをランダムに選択して保管できます。
## 構成手順
サーバーが全履歴を取得して保管するように構成するには、以下の手順を実行します。
1. `rippled`サーバーが稼働中の場合は停止します。
$ sudo systemctl stop rippled
0. サーバーの構成ファイルで`[node_db]`スタンザの`online_delete`設定と`advisory_delete`設定を削除(またはコメントアウト)し、タイプをまだ`NuDB`に変更していない場合は変更します。
[node_db]
type=NuDB
path=/var/lib/rippled/db/nudb
#online_delete=2000
#advisory_delete=0
全履歴が記録されるサーバーでは、レジャーストアーにNuDBを使用します。これは、データベースがこれほど大きいと、RocksDBでは非常に大量のRAMが必要になるためです。詳細は、[容量の計画](capacity-planning.html)を参照してください。パフォーマンス関連の構成オプション`open_files``filter_bits``cache_mb``file_size_mb`、および`file_size_mult`は、RocksDBのみに適用されるオプションであるため、デフォルトの`[node_db]`スタンザから削除できます。
**注意:** RocksDBで履歴をすでにダウンロードしている場合は、NuDBへ切り替えるときに構成ファイルでデータベースのパスを変更するか、またはそのデータを削除する必要があります。`[node_db]`スタンザの`path`設定**および**`[database_path]`SQLiteデータベース設定の両方を変更する必要があります。このようにしないと、サーバーの[起動が失敗する](server-wont-start.html#状態dbエラー)可能性があります。
{% include '_snippets/conf-file-location.md' %}<!--_ -->
0. サーバーの構成ファイルで`[ledger_history]`スタンザを`full`に設定します。
[ledger_history]
full
0. 全履歴が保管されている1台以上のサーバーと明示的にピア接続するように、サーバーの構成ファイルで`[ips_fixed]`スタンザを設定します。
[ips_fixed]
169.55.164.20
50.22.123.215
サーバーのダイレクトピアの1つが使用可能な履歴データを保持している場合に限り、サーバーはピアツーピアネットワークから履歴データをダウンロードできます。全履歴をダウンロードする最も容易な方法は、すでに全履歴を保管しているサーバーとピア接続することです。
**ヒント:** Rippleは、すべての履歴が記録されるサーバーのプールを公開しています。これらのサーバーのIPアドレスを取得するには、ドメイン`s2.ripple.com`を数回解決します。これらのサーバーは公開サービスとして提供されているため、他のサーバーとのピア接続での可用性は限られており、またこれらのサーバーを悪用するとブロックされる可能性があることに注意してください。
0. 全履歴が記録されている別のサーバーからのデータベースダンプがあり、このダンプをベースとして利用できる場合は、サーバーの構成ファイルで`[import_db]`スタンザがインポート対象データを指し示すように設定します。(それ以外の場合はこのステップをスキップします。)
[import_db]
type=NuDB
path=/tmp/full_history_dump/
0. 以前に稼働していた`rippled`からの既存のデータベースファイルがサーバーにある場合は、そのデータベースファイルを削除します。
オンライン削除を無効にすると、サーバーはオンライン削除が有効であった間にダウンロードしたデータをすべて無視するため、ディスク容量を空けることができます。次に例を示します。
rm -r /var/lib/rippled/db/*
**警告:** フォルダーを削除する前に、保持したいファイルがそのフォルダーに含まれていないことを確認してください。通常は安全に`rippled`サーバーのデータベースファイルをすべて削除できますが、この操作は、設定されているデータベースフォルダーが`rippled`のデータベース以外には使用されていない場合にのみ行ってください。
0. `rippled`サーバーを起動し、インポート可能なデータベースダンプがある場合にはインポートします。
`[Import_db]`で構成されている読み取り対象データベースダンプがある場合は、`--import` [コマンドラインオプション](commandline-usage.html#デーモンモードのオプション)を指定してサーバーを明示的に起動します。
$ /opt/ripple/bin/rippled --conf /etc/opt/ripple/rippled.cfg --import
大量のデータベースダンプのインポートには数分から数時間かかることがあります。インポート中はサーバーは完全には起動せず、ネットワークと同期しません。インポートの状況を確認するには、サーバーログを参照してください。
データベースダンプをインポートしない場合は、サーバーを通常の方法で起動します。
$ sudo systemctl start rippled
0. `[import_db]`スタンザをサーバーの構成ファイルに追加した場合は、インポートの完了後にそのスタンザを削除してください。
このようにしないと、次回の再起動時にサーバーが同じデータを再びインポートしようとします。
0. [server_infoメソッド][]を使用して、サーバーの利用可能な履歴を監視します。
`complete_ledgers`フィールドに表示される利用可能なレジャーの範囲は、時間の経過とともに増加します。
本番環境のXRP Ledgerの履歴で最も古い利用可能なレジャーバージョンは、レジャーインデックス**32570**です。レジャー履歴の最初の約2週間分は、当時のサーバーのバグが原因で失われています。Test Netやその他のチェーンでは通常、履歴の最初のバージョンはレジャーインデックス**1**です。
<!--{# common link defs #}-->
{% include '_snippets/rippled-api-links.md' %}
{% include '_snippets/tx-type-links.md' %}
{% include '_snippets/rippled_versions.md' %}

View File

@@ -0,0 +1,54 @@
# 履歴シャーディングの設定
[履歴シャーディング](history-sharding.html)では、各サーバーで完全な履歴を保管することなく、履歴XRP Ledgerデータを保存できます。デフォルトでは`rippled`サーバーは履歴シャードを保管しません。
**ヒント:** バリデータおよび`rippled`追跡(またはストック)サーバーの両方で履歴シャードを保管するように設定できます。ただし`rippled`バリデータサーバーの経費を抑えるために、バリデータサーバーでシャードを保管するように設定 _しない_ ことが推奨されます。バリデータを実行していて、XRP Ledger履歴を保管したい場合は、履歴シャーディングを有効にして別の`rippled`サーバーを実行することが推奨されます。
レジャー履歴のシャードを保管できるよう`rippled`を設定するには、以下の手順を実行します。
## 1. シャードストアーに割り当てる容量を決めます。
履歴シャードを保管できるように`rippled`サーバーを設定する前に、履歴シャードストアーに割り当てるディスク容量を決定する必要があります。これはまた、デフォルトのレジャーストアーに保持する履歴の量にも影響します。シャードストアーのサイズを設定する際には、以下の点を考慮してください。
- レジャーストアー(`[node_db]`スタンザにより定義される)は、履歴シャードストアーとは別のストアーです。レジャーストアーはすべてのサーバーに必要であり、そこには一定範囲の最近の履歴が保管されている _必要があります_ 。保管する範囲は、`online_delete`パラメーターに使用可能な状態で維持するレジャーの数によって定義されます。デフォルトの設定では、最新のレジャー2000個が保管されます。
- レジャーストアーに2^15個以上のレジャー32768が保持されている場合は、レジャーストアーからシャードストアーへ最近の履歴のグループを効率的にインポートできます。
- 履歴<sup></sup>シャードストアー(`[shard_db]`スタンザにより定義される)は、履歴シャードを保管する場合にのみ必要です。履歴シャードを保管しないサーバーではこの構成スタンザを省略する必要があります。履歴シャードストアーのサイズは`max_size_gb`パラメーターでギガバイト単位で定義されます。サーバーは完全なシャードを保管するため、この容量を最大限利用します。
- シャードには2^14個のレジャー16384が含まれており、シャードの経過期間に応じて約200 MB4 GBを専有します。古いシャードほどXRP Ledgerでのアクティビティが少ないため、サイズが小さくなります。
- 履歴シャードストアーとレジャーストアーはファイルパスを分けて保管する _必要があります_ 。必要に応じて、レジャーストアーと履歴ストアーをそれぞれ別のディスクやパーティションに配置するように設定できます。
- 完全なレジャー履歴をレジャーストアーと履歴シャードストアーの両方に保持できますが、冗長な処理となります。
- シャードの取得にかかる時間、`rippled`サーバーに必要なファイルハンドル数、およびメモリーキャッシュ使用率は、シャードのサイズの影響を直接受けます。
## 2. rippled.cfgの編集
`rippled.cfg`ファイルを編集し、`[shard_db]`スタンザを追加します。
{% include '_snippets/conf-file-location.md' %}<!--_ -->
以下のスニペットに、`[shard_db]` スタンザの例を示します。
```
[shard_db]
type=NuDB
path=/var/lib/rippled/db/shards/nudb
max_size_gb=50
```
**ヒント:** シャードストアーにはNuDB`type=NuDB`を使用することが推奨されます。NuDBはRocksDBに比べ、シャードあたりの使用ファイルハンドル数が少なくなります。RocksDBは、保管するデータのサイズに応じて拡張するメモリーを使用するため、大量のメモリーオーバーヘッドが必要になる可能性があります。ただし、NuDBはSSDドライブで使用するように設計されており、回転型ディスクでは機能しません。 <!-- NOTE: out of date; needs to be re-translated. NuDB is required as of v1.3.1. -->
**注意:** 履歴シャーディングを有効にした後にシャードストアーのデータベースタイプを変更する場合は、パスを変更するか、または設定されているパスから既存のデータを削除する必要があります。`rippled`がシャードストアーパスで不適切なデータを検出すると、[起動できない](server-wont-start.html)可能性があります。
詳細は、[rippled.cfgの設定例](https://github.com/ripple/rippled/blob/master/cfg/rippled-example.cfg)の`[shard_db]`の例を参照してください。
## 3. サーバーの再起動
```
systemctl restart rippled
```
## 4. シャードのダウンロードの待機
サーバーはネットワークと同期すると、履歴シャードのダウンロードを自動的に開始し、シャードストアーの空き容量を埋めます。ダウンロード対象のシャードを確認するには、シャードストアーを設定したフォルダー内に作成されるフォルダーを確認します。(これは`rippled.cfg`ファイルの`[shard_db]`スタンザの`path`フィールドによって定義されます。)
このフォルダーには、サーバーに保管されている各シャードのフォルダーが番号付きで保存されています。常に、最大で1つのフォルダーに、未完了であることを示す`control.txt`ファイルが保存されています。
<!-- TODO: add download_shard and crawl_shards commands when they get added. -->

View File

@@ -0,0 +1,75 @@
# オンライン削除の設定
`rippled`サーバーのデフォルトの構成では、最新2000個のレジャーバージョンよりも古い[履歴が削除され](online-deletion.html)、レジャー履歴は約15分間維持されます現行のレジャー毎の間隔に基づく。このページでは、削除までに`rippled`サーバーに保管される履歴の量を設定する方法を説明します。
## 前提条件
このチュートリアルでは、ご使用のサーバーが以下の条件を満たしていることを前提としています。
- サポートされているオペレーティングシステムを使用している。Ubuntu Linux、Red Hat Enterprise LinuxRHEL、CentOS
- `rippled`サーバーがすでに[インストール](install-rippled.html)されており、[オンライン削除](online-deletion.html)が有効になっている。
推奨されるプラットフォームのインストール手順に従えば、オンライン削除はデフォルトで有効となります。
- 選択した量の履歴をレジャーストアーに保管するのに[十分なディスク容量](capacity-planning.html)がサーバーにある。
## 構成手順
サーバーに保管する履歴の量を変更するには、以下の手順を実行します。
1. 保管する履歴に相当するレジャーバージョンの数を決定します。
新しいレジャーバージョンは通常34秒間隔で検証されます。このため、レジャーバージョンの数は、保管する期間におおむね対応しています。各種構成で必要なストレージの容量についての詳細は、[容量計画](capacity-planning.html)を参照してください。
オンライン削除は、履歴の削除 _後_ に維持するレジャーバージョンの数に基づいておこなわれるので、設定した維持するレジャー数の2倍を保管するのに十分なディスク容量が必要です。
0. `rippled`の構成ファイルで`[node_db]` スタンザの`online_delete`フィールドを編集します。
[node_db]
# Other settings unchanged ...
online_delete=2000
advisory_delete=0
`online_delete`を、オンライン削除の実行後に維持するレジャーバージョンの最小数に設定します。自動削除が設定されている場合デフォルト、サーバーは通常、この数の約2倍のレジャーバージョンが蓄積されると削除を実行します。
{% include '_snippets/conf-file-location.md' %}<!--_ -->
0. `rippled`サービスを起動(または再起動)します。
$ sudo systemctl restart rippled
0. サーバーがネットワークと同期するまで待ちます。
ネットワークとシステムの能力と、サーバーがオフラインになっていた期間に応じて、完全な同期が完了するまでには515分かかります。
サーバーとネットワークの同期が完了すると、[server_infoメソッド][]が再び開き、`server_state`の値として`"full"``"proposing"``"validating"`のいずれかが報告されます。
0. [server_infoメソッド][]を使用してサーバーの`complete_ledgers`範囲を定期的に調べ、レジャーが削除されていることを確認します。
オンライン削除実行後の`complete_ledgers`範囲には、古いレジャーが使用できなくなったことが反映されます。サーバーに履歴が蓄積されるにつれ、使用可能なレジャーの総数が徐々に増加します。この数が設定した`online_delete`値の2倍に達し、オンライン削除が実行されるとレジャーの総数は減少します。
0. `rippled`ログで、`SHAMapStore::WRN`で始まるメッセージを確認します。このメッセージが出力されている場合、サーバーがネットワークと同期していない状態になったために[オンライン削除が中断されている](online-deletion.html#オンライン削除の中断)可能性があります。
この状況が定期的に発生する場合は、サーバーのスペックが不十分で、オンライン削除の実行中にレジャーを最新状態に維持できていない可能性があります。同じハードウェア上の他のサービス(スケジュール済みバックアップやセキュリティスキャンなど)と`rippled`サーバーがリソースをめぐって競合していないことを確認してください。以下のいずれかの操作を実行できます。
- システムスペックを強化する。推奨事項については、[システム要件](system-requirements.html)を参照してください。
- 設定を変更し、保管する履歴の量を減らす。このチュートリアルのステップ2
- サーバーの[`node_size`パラメーター](capacity-planning.html)を変更する。
- レジャーストアーに[RocksDBの代わりにNuDB](capacity-planning.html)を使用する。
- [指示による削除を使用してオンライン削除をスケジュールする](configure-advisory-deletion.html)。
## 関連項目
- [オンライン削除](online-deletion.html)
- [指示による削除の設定](configure-advisory-deletion.html)
- [履歴シャーディングの設定](configure-history-sharding.html)
- [完全な履歴の設定](configure-full-history.html)
<!--{# common link defs #}-->
{% include '_snippets/rippled-api-links.md' %}
{% include '_snippets/tx-type-links.md' %}
{% include '_snippets/rippled_versions.md' %}

View File

@@ -0,0 +1,56 @@
# XRP Test Netへのrippledの接続
Rippleは、XRP Ledgerのテストプラットフォームを提供するため[XRP Test Network](https://ripple.com/build/xrp-test-net/)を開発しました。XRP Test Netの資金は実際の資金ではなく、テスト専用の資金です。本番環境のXRP Ledger Networkに接続する前に、`rippled`サーバーをXRP Test Netに接続して、`rippled`の機能をテストして理解できます。また、XRP Test Netを使用して、作成したコードが`rippled`と正しくやり取りすることを検証できます。
**注記:** XRP Test Netのレジャーと残高は定期的にリセットされます。
`rippled`サーバーをXRP Test Netに接続するには、以下の構成を設定します。
1. `rippled.cfg`ファイルで以下の手順に従います。
a. 以下のセクションのコメントを解除します。
[ips]
r.altnet.rippletest.net 51235
b. 以下のセクションを次のようにコメントアウトします。
# [ips]
# r.ripple.com 51235
2. `validators.txt`ファイルで以下の手順に従います。
a. 以下のセクションのコメントを解除します。
[validator_list_sites]
https://vl.altnet.rippletest.net
[validator_list_keys]
ED264807102805220DA0F312E71FC2C69E1552C9C5790F6C25E3729DEB573D5860
b. 以下のセクションを次のようにコメントアウトします。
# [validator_list_sites]
# https://vl.ripple.com
#
# [validator_list_keys]
# ED2677ABFFD1B33AC6FBC3062B71F1E8397C1505E1C42C64D11AD1B28FF73F4734
3. `rippled`を再起動します。
4. `rippled`がXRP Test Netに接続していることを確認するため、サーバーで[server_infoメソッド][]を使用して、その結果をTest Net のパブリックサーバーの結果と比較します。両方のサーバーで`validated_ledger`オブジェクトの`seq`フィールドが同一である必要があります確認中にこの数が変化した場合は、12の差が生じる可能性があります
以下のコマンドは、`s.altnet.rippletest.net` にあるTest Net サーバーの最新の検証済みレジャーをチェックします。
$ ./rippled --rpc_ip 34.210.87.206:51234 server_info | grep seq
以下のコマンドは、ローカルの `rippled` の最新検証済みレジャーシーケンスをチェックします。
$ ./rippled server_info | grep seq
<!--{# common link defs #}-->
{% include '_snippets/rippled-api-links.md' %}
{% include '_snippets/tx-type-links.md' %}
{% include '_snippets/rippled_versions.md' %}

View File

@@ -0,0 +1,36 @@
# パブリック署名の有効化
[新規: rippled 1.1.0][]デフォルトでは、`rippled`の署名メソッドは管理者接続に限定されています。v1.1.0以前のバージョンの`rippled`のように、署名メソッドをパブリックAPIメソッドとして使用できるようにするには、構成を変更することで、これを使用できるようにします。
これにより、サーバーが「パブリック」[JSON-RPC接続およびWebSocket接続](get-started-with-the-rippled-api.html)を受け入れる場合は、これらのパブリック接続で以下のメソッドが使用できるようになります。
- [sign][signメソッド]
- [sign_for][sign_forメソッド]
- [submit][submitメソッド](in "sign-and-submit" mode)
これらのメソッドを使用するにあたり、管理者接続からパブリック署名を有効にする必要は**ありません**。
**注意:** パブリック署名を有効にすることは推奨されません。[wallet_proposeメソッド][]と同様に、署名コマンドでは管理レベルの権限を必要とするアクションは実行されませんが、署名コマンドを管理者接続に制限することにより、ユーザーが安全ではない通信経由で、またはユーザーの管理下にないサーバーとの間でシークレットキーを無責任に送受信することを防止します。
パブリック署名を有効にするには、以下の手順を実行します。
1. `rippled`の構成ファイルを編集します。
vim /etc/opt/ripple/rippled.cfg
{% include '_snippets/conf-file-location.md' %}<!--_ -->
2. 以下のスタンザを構成ファイルに追加し、変更を保存します。
[signing_support]
true
3. `rippled`サーバーを再起動します。
systemctl restart rippled
<!--{# common link defs #}-->
{% include '_snippets/rippled-api-links.md' %}
{% include '_snippets/tx-type-links.md' %}
{% include '_snippets/rippled_versions.md' %}

View File

@@ -0,0 +1,270 @@
# バリデータとしてのrippledの実行
バリデータモードで実行されている`rippled`サーバーは、ストックサーバーが実行するあらゆる処理を実行します。
- ピアのネットワークへの接続
- 暗号署名されたトランザクションの中継
- 共有グローバル台帳全体のローカルコピーの維持
バリデータが _特異である_ のは、検証メッセージも発行するという点です。これらのメッセージは、[コンセンサスプロセス](consensus-principles-and-rules.html#コンセンサスの仕組み)の進行中、XRP Ledgerネットワークによる評価の対象となる候補のトランザクションです。
ただし、単に検証メッセージを発行するだけで、バリデータにコンセンサスプロセスでの発言権が自動的に付与されるわけではありません。他のサーバーがバリデータモードのサーバーを彼らのユニークードリストUNLに追加しない限り、彼らはバリデータモードのサーバーからの検証メッセージを無視します。バリデータがUNLに含まれている場合、 _信頼できる_ バリデータであり、その提案は、信頼する側のサーバーによってコンセンサスプロセスで検討されます。
バリデータが _信頼できる_ バリデータではない場合も、ネットワークの全体的な健全性に関して、重要な役割を果たすことに変わりはありません。これらのバリデータは、信頼できるバリデータを評価するための基準の確立を支援します。例えば、信頼できるバリデータが、UNLに含まれていない多数のバリデータに対して異議を唱えている場合、問題があることを示しているおそれがあります。
## 1. 優れたバリデータの特徴の理解
バリデータ(サーバー)が以下の特質を常に備えるよう努めます。優れたバリデータであることは、`rippled`サーバーの運用者や[https://vl.ripple.com](https://vl.ripple.com)などのバリデータリスト発行者が、バリデータを彼らのUNLに追加する際に、バリデータを信頼する上で後押しになります。
- **可用性**
優れたバリデータは、常に稼働し、提案されるあらゆるレジャーについて検証投票を送信します。100%のアップタイムを実現するよう努めてください。
- **合意**
優れたバリデータの投票は、可能な限り高い頻度で、コンセンサスプロセスの結果と合致します。これに該当しない場合は、バリデータのソフトウェアが最新のものではないか、不具合があるか、意図的な偏りがあることを示唆している可能性があります。常に[最新の`rippled`リリース](https://github.com/ripple/rippled/tree/master)を、修正を加えることなく実行します。新規リリースについて知るために、[`rippled`のリリースを確認](https://github.com/ripple/rippled/releases)してください。
- **適時の投票**
優れたバリデータの投票は、コンセンサスラウンドが終了する前に、素早く届きます。適時の投票を維持するには、バリデータが推奨される[システム要件](system-requirements.html)を満たしていることを確認してください。これには、高速のインターネット接続が含まれます。
- **身元の確さ**
優れたバリデータには、身元が明確な所有者が存在します。[ドメイン検証](#6-ドメイン検証の提供)を提供することは、その第一歩になります。XRP LedgerネットワークのUNLに、多くの法的な管轄域および地域のさまざまな所有者によって運営されているバリデータが含まれていると理想的です。結果として、信頼できるバリデータの公正な運用が地域特有の事象によって損なわれるおそれが低減されます。
Ripple社は、推奨される一連のバリデータを記載した[バリデータリスト](https://github.com/ripple/rippled/blob/develop/cfg/validators-example.txt)を公開しています。本番環境のサーバーでは、このリストを使用することを強くお勧めします。
## 2. `rippled`サーバーのインストール
詳細については、[`rippled`のインストール](install-rippled.html)を参照してください。
## 3. `rippled`サーバーで検証を有効化
`rippled`サーバーで検証を有効にすることは、サーバーの`rippled.cfg`ファイルにあるバリデータトークンを提供することを意味します。バリデータキーとトークンを安全に生成して管理するために、`validator-keys`ツール(`rippled` RPMに含まれるを使用することをお勧めします。
バリデータ(サーバー)**以外の** 場所で、以下の手順に従います。
1. `validator-keys`ツールを`rippled` RPMを通じてまだインストールしていない場合は、手動でビルドして実行します。
`validator-keys`ツールを手動でビルドして実行する方法については、[validator-keys-tool](https://github.com/ripple/validator-keys-tool)を参照してください。
2. `create_keys`コマンドを使用して、バリデータキーペアを生成します。
$ validator-keys create_keys
Ubuntuでの出力の例:
Validator keys stored in /home/my-user/.ripple/validator-keys.json
This file should be stored securely and not shared.
macOSでの出力の例:
Validator keys stored in /Users/my-user/.ripple/validator-keys.json
This file should be stored securely and not shared.
**警告:** 生成した`validator-keys.json`キーファイルは、暗号化されたUSBフラッシュドライブなど、安全かつ回復可能なオフラインの場所に保管してください。内容には修正を加えないでください。特に、キーの使用場所となるバリデータにキーファイルを保存しないようにします。バリデータの`secret_key`が悪用された場合は、ただちに[キーを破棄](https://github.com/ripple/validator-keys-tool/blob/master/doc/validator-keys-tool-guide.md#key-revocation)します。
`validator-keys`ツールおよびツールで生成されるキーペアの詳細は、[Validator Keys Tool Guide](https://github.com/ripple/validator-keys-tool/blob/master/doc/validator-keys-tool-guide.md)を参照してください。
3. `create_token`コマンドを使用して、バリデータトークンを生成します。
$ validator-keys create_token --keyfile /PATH/TO/YOUR/validator-keys.json
出力の例:
Update rippled.cfg file with these values:
# validator public key: nHUtNnLVx7odrz5dnfb2xpIgbEeJPbzJWfdicSkGyVw1eE5GpjQr
[validator_token]
eyJ2YWxpZGF0aW9uX3NlY3J|dF9rZXkiOiI5ZWQ0NWY4NjYyNDFjYzE4YTI3NDdiNT
QzODdjMDYyNTkwNzk3MmY0ZTcxOTAyMzFmYWE5Mzc0NTdmYT|kYWY2IiwibWFuaWZl
c3QiOiJKQUFBQUFGeEllMUZ0d21pbXZHdEgyaUNjTUpxQzlnVkZLaWxHZncxL3ZDeE
hYWExwbGMyR25NaEFrRTFhZ3FYeEJ3RHdEYklENk9NU1l1TTBGREFscEFnTms4U0tG
bjdNTzJmZGtjd1JRSWhBT25ndTlzQUtxWFlvdUorbDJWMFcrc0FPa1ZCK1pSUzZQU2
hsSkFmVXNYZkFpQnNWSkdlc2FhZE9KYy9hQVpva1MxdnltR21WcmxIUEtXWDNZeXd1
NmluOEhBU1FLUHVnQkQ2N2tNYVJGR3ZtcEFUSGxHS0pkdkRGbFdQWXk1QXFEZWRGdj
VUSmEydzBpMjFlcTNNWXl3TFZKWm5GT3I3QzBrdzJBaVR6U0NqSXpkaXRROD0ifQ==
バリデータ(サーバー)で、以下の手順に従います。
1. `[validator_token]`とその値を、バリデータの`rippled.cfg`ファイルに追加します。
以前に、`validator-keys`ツールを使用せずにバリデータを設定している場合は、`[validation_seed]`とその値を`rippled.cfg`ファイルから削除します。これにより、バリデータの公開鍵が変更されます。
2. `rippled`を再起動します。
$ sudo systemctl restart rippled.service
3. `server_info`コマンドを使用してバリデータの情報を取得し、バリデータとして実行されていることを確認します。
$ rippled server_info
- 応答に含まれている`pubkey_validator`の値は、バリデータで使用するために生成した`validator-keys.json`ファイルの`public_key`と一致している必要があります。
- `server_state`の値は、 _**proposing**_ にする必要があります。
## 4. ネットワークへの接続
バリデータのオペレーターが果たすべき重要な責任の1つは、信頼できる安全な接続によってバリデータがXRP Ledgerネットワークに接続されるようにすることです。ネットワーク上の潜在的に悪意のあるピアに無作為に接続するのではなく、以下のいずれかの方法でネットワークに接続するようにバリデータに指示できます。
- [公開ハブ](#公開ハブを使用した接続)
- [プロキシ](#プロキシを使用した接続)
これらのいずれかの構成を使用すると、[DDoS](https://en.wikipedia.org/wiki/Denial-of-service_attack)攻撃からバリデータを保護するとともに、ネットワークへの信頼できる接続をバリデータに提供する上で役立ちます。
### 公開ハブを使用した接続
この構成では、ネットワークに接続している1つ以上の公開ハブにバリデータを接続します。適切に運用されている公開ハブには、以下の特徴があります。
- 十分な帯域幅。
- 多数の信頼できるピアとの接続。
- メッセージを確実に中継する能力。
公開ハブに接続することの利点は、安全かつ信頼できる多くのネットワーク接続にアクセスしやすいことです。このような接続は、バリデータの健全性の維持に役立ちます。
公開ハブを使用してバリデータをネットワークに接続するには、バリデータの`rippled.cfg`ファイルで以下の構成を設定します。
1. 以下の`[ips_fixed]`スタンザを記述します。2つの値`r.ripple.com 51235``zaphod.alloy.ee 51235`が公開ハブです。このスタンザは、これらの公開ハブとのピア接続を常に維持するよう`rippled`に指示します。
[ips_fixed]
r.ripple.com 51235
zaphod.alloy.ee 51235
他の`rippled`サーバーのIPアドレスをここに記述することもできますが、それらのサーバーに対して以下の事項を期待できる場合に _**限ります**_
- メッセージを検閲することなく中継する。
- オンライン状態を常に維持する。
- サーバーに対するDDoS攻撃を実行しない。
- サーバーをクラッシュさせようとしない。
- 未知の相手にバリデータのIPアドレスを公開しない。
2. 以下の`[peer_private]`スタンザを記述し、`1`に設定します。この設定を有効にすると、バリデータのピアに対して、バリデータのIPアドレスをブロードキャストしないよう指示することになります。また、バリデータに対して、`[ips_fixed]`スタンザで設定されているピアにのみ接続するよう指示することになります。これにより、既知の信頼できるピア`rippled`サーバーに対してのみ、バリデータが接続を確立し、IPアドレスを共有することが保証されます。
**警告:** バリデータのIPアドレスを、その他の方法で公開していないことを確認してください。
[peer_private]
1
`[peer_private]`が有効になっている場合、`rippled`は、`[ips]`スタンザで指定されている接続をすべて無視します。現在`[ips]`スタンザにあるIPアドレスに接続する必要がある場合は、代わりに`[ips_fixed]`スタンザに記述します。ただし、それらのIPアドレスに対して、ステップ1で説明した挙動を期待できる場合に _**限ります**_
### プロキシを使用した接続
この構成では、バリデータと発着信ネットワークトラフィックの間でプロキシとして使用するストック`rippled`サーバーを実行します。
**注記:** これらのサーバーはプロキシとして動作しますが、HTTP(S)トラフィック用のWebプロキシではありません。
この設定の利点は、自社で運用するプロキシサーバーを通じて、安全かつ信頼できる多くのネットワークへの接続の冗長性やアクセス性が高まることです。このような接続は、バリデータの健全性の維持に役立ちます。
<!-- { TODO: Future: add a recommended network architecture diagram to represent the proxy, clustering, and firewall setup: https://ripplelabs.atlassian.net/browse/DOC-2046 }-->
1. `rippled`サーバーで[検証を有効に](#3-rippledサーバーで検証を有効化)します。
2. ストック`rippled`サーバーを設置します。詳細については、[rippledのインストール](install-rippled.html)を参照してください。
3. バリデータとストック`rippled`サーバーを設定して、[クラスター](cluster-rippled-servers.html)内で実行します。
4. バリデータの`rippled.cfg`ファイルで、`[peer_private]``1`に設定して、バリデータのIPアドレスが転送されないようにします。詳細については、[プライベートピア](peer-protocol.html#プライベートピア)を参照してください。
**警告:** バリデータのIPアドレスを、その他の方法で公開していないことを確認してください。
5. 以下のトラフィックのみを許可するように、バリデータのホストマシンのファイアウォールを構成します。
- 着信トラフィック: 構成したクラスター内にあるストック`rippled`サーバーのIPアドレスが発信元である場合のみ
- 発信トラフィック: 構成したクラスター内にあるストック`rippled`サーバーのIPアドレスおよびポート443経由の<https://vl.ripple.com>が送信先である場合のみ
6. `rippled`を再起動します。
$ sudo systemctl restart rippled.service
7. いずれかのストック`rippled`サーバーにある[ピアクローラー](peer-crawler.html)エンドポイントを使用します。応答には、バリデータが含まれていないはずです。これにより、バリデータの`[peer_private]`構成が機能していることが確認されます。バリデータの`[peer_private]`を有効にした場合の効果の1つは、バリデータのピアによって、ピアクローラーの結果にバリデータが含まれないことです。
## 5. ネットワーク接続の確認
ここでは、バリデータがXRP Ledgerネットワークへの健全な接続を保持していることを検証する方法をいくつか紹介します。
- [`peers`](peers.html)コマンドを使用して、バリデータに接続しているすべての`rippled`サーバーのリストを取得します。`peers`の配列が`null`である場合、ネットワークへの健全な接続が存在していません。このドキュメントの手順に従ってバリデータを設置した場合、`peers`の配列には、`[ips_fixed]`スタンザで定義されているピアの数と同数のオブジェクトが含まれています。
公開ハブを`[ips_fixed]`スタンザに記述した場合、そのハブがビジーになっているときは、バリデータの接続が拒否されることがあります。この場合、接続の数は、`[ips_fixed]`スタンザで設定した数よりも最終的に少なくなることがあります。初めて拒否された場合、バリデータは接続を再試行します。
ネットワークへの安全かつ信頼できる接続を維持することが困難であり、公開ハブまたはプロキシを使用して接続を設定していない場合、[4. ネットワークへの接続](#4-ネットワークへの接続)を参照してください。このセクションで説明されているいずれかの方法は、バリデータがネットワークへの健全な接続を維持する上で有用となる可能性があります。
- [`server_info`](server_info.html)コマンドを使用して、バリデータに関するいくつかの基本情報を取得します。`server_state`は、`proposing`に設定されているはずです。`full`または`validating`に設定されている場合もありますが、`proposing`に移行するまでの数分間に限られます。
`server_state``proposing`に設定されている時間が大部分を占めていない場合、XRP Ledgerネットワークにバリデータが完全に参加できていないことを示している可能性があります。サーバーの状態および`server_info`エンドポイントを使用してバリデータの問題を診断する方法の詳細は、[`rippled`サーバーの状態](rippled-server-states.html)および[`server_info`の取得](diagnosing-problems.html#server_infoの取得)を参照してください。
- [`validators`](validators.html)コマンドを使用して、バリデータによって使用される、公開済みかつ信頼できるバリデータの最新リストを取得します。`validator_list_expires`の値が、`never`(無期限)、期限が切れていない、または期限切れ間近のいずれかであることを確認してください。
## 6. ドメイン検証の提供
検証リスト発行者およびXRP Ledgerネットワーク内のその他の参加者がバリデータの運用元を把握しやすいようにするには、バリデータのドメイン検証を提供します。ドメイン検証とは、ハイレベルでは双方向リンクを指します。
- ドメインを使用して、バリデータキーの所有権を主張します。
- バリデータキーを使用して、ドメインの所有権を主張します。
このリンクを作成すると、バリデータキーとドメインの両方を所有しているという確固たる証拠が確立されます。この証拠を提供することは、[優れたバリデータであること](#1-優れたバリデータの特徴の理解)の側面の1つにすぎません。
ドメイン検証を提供するには、以下の手順に従います。
1. バリデータと公に関連付ける、所有しているドメインの名前を選択します。そのドメインのポート443で外部に公開されるHTTPSサーバーを実行中であり、そのサーバーのTLS証明書に関連付けられている秘密鍵ファイルへのアクセス権を持っている必要があります。注記: [TLSの旧称はSSLです](https://en.wikipedia.org/wiki/Transport_Layer_Security))。
2. バリデータの公開鍵を公開し、特に他の`rippled`オペレーターに知らせます。例えば、Webサイト、ソーシャルメディア、[XRPChatコミュニティーフォーラム](https://www.xrpchat.com/)、またはプレスリリースでバリデータの公開鍵を公表できます。
3. この[Googleフォーム](https://docs.google.com/forms/d/e/1FAIpQLScszfq7rRLAfArSZtvitCyl-VFA9cNcdnXLFjURsdCQ3gHW7w/viewform)を使用して、自身のバリデータをXRP Chartsの[バリデータレジストリー](https://xrpcharts.ripple.com/#/validators)に登録するための要求を送信します。バリデータをこのレジストリーに登録することは、そのバリデータとドメインを所有していることを示す、別の形での公的な証拠になります。フォームに漏れなく記入するには、以下の情報が必要です。
1. バリデータのサーバーで以下のコマンドを実行して、バリデータの公開鍵を検出します。
$ /opt/ripple/bin/rippled server_info | grep pubkey_validator
返された値を、Googleフォームの**Validator Public Key**フィールドに入力します。
2. WebドメインのTLS秘密鍵を使用して、バリデータの公開鍵に署名します。TLS秘密鍵ファイルをバリデータのサーバーに保存する必要はありません。
$ openssl dgst -sha256 -hex -sign /PATH/TO/YOUR/TLS.key <(echo YOUR_VALIDATOR_PUBLIC_KEY_HERE)
出力の例:
4a8b84ac264d18d116856efd2761a76f3f4544a1fbd82b9835bcd0aa67db91c53342a1ab197ab1ec4ae763d8476dd92fb9c24e6d9de37e3594c0af05d0f14fd2a00a7a5369723c019f122956bf3fc6c6b176ed0469c70c864aa07b4bf73042b1c7cf0b2c656aaf20ece5745f54ab0f78fab50ebd599e62401f4b57a4cccdf8b76d26f4490a1c51367e4a36faf860d48dd2f98a6134ebec1a6d92fadf9f89aae67e854f33e1acdcde12cfaf5f5dbf1b6a33833e768edbb9ff374cf4ae2be21dbc73186a5b54cc518f63d6081919e6125f7daf9a1d8e96e3fdbf3b94b089438221f8cfd78fd4fc85c646b288eb6d22771a3ee47fb597d28091e7aff38a1e636b4f
返された値を、Googleフォームの**SSL Signature**フィールドに入力します。
3. [`validator-keys`ツール](https://github.com/ripple/validator-keys-tool/blob/master/doc/validator-keys-tool-guide.md)`rippled`のRPMに収録を使用して、ドメイン名に署名します。
$ validator-keys --keyfile /PATH/TO/YOUR/validator-keys.json sign YOUR_DOMAIN_NAME
出力の例:
E852C2FE725B64F353E19DB463C40B1ABB85959A63B8D09F72C6B6C27F80B6C72ED9D5ED6DC4B8690D1F195E28FF1B00FB7119C3F9831459F3C3DE263B73AC04
返された値を、Googleフォームの**Domain Signature**フィールドに入力します。
4. 記入したGoogleフォームを送信すると、ドメイン検証の成否を通知するメールがXRP Chartsから送信されます。ドメイン検証が成功した場合は、XRP Chartsの[バリデータレジストリー](https://xrpcharts.ripple.com/#/validators)にバリデータとドメインが表示されます。
<!--{ ***TODO: For the future - add a new section or separate document: "Operating a Trusted Validator" -- things that you need to be aware of once your validator has been added to a UNL and is participating in consensus. We should tell the user what to expect once they are listed in a UNL. How to tell if your validator is participating in the consensus process? How to tell if something isn't right with your validator - warning signs that they should look out for? How to tell if your validator has fallen out of agreement - what is the acceptable vs unacceptable threshold? Maybe provide a script that will alert them when something is going wrong.*** }-->
## バリデータキーの破棄
バリデータのマスター秘密鍵が漏えいした場合は、ただちに永続的に破棄する必要があります。
`validator-keys`ツールでバリデータ用に生成したマスターキーペアを破棄する方法については、[Key Revocation](https://github.com/ripple/validator-keys-tool/blob/master/doc/validator-keys-tool-guide.md#key-revocation)を参照してください。

View File

@@ -264,7 +264,7 @@ Here are some methods you can use to verify that your validator has a healthy co
- Use the [`server_info`](server_info.html) command to return some basic information about your validator. The `server_state` should be set to `proposing`. It may also be set to `full` or `validating`, but only for a few minutes before moving into `proposing`.
If the `server_state` does not spend the majority of its time set to `proposing`, it may be a sign that your validator is unable to fully participate in the XRP Ledger network. For more information about server states and using the `server_info` endpoint to diagnose issues with your validator, see [`rippled` Server States](rippled-server-states.html) and [Get the `server_info`](diagnosing-problems.html#get-the-server-info).
If the `server_state` does not spend the majority of its time set to `proposing`, it may be a sign that your validator is unable to fully participate in the XRP Ledger network. For more information about server states and using the `server_info` endpoint to diagnose issues with your validator, see [`rippled` Server States](rippled-server-states.html) and [Get the `server_info`](diagnosing-problems.html#get-the-server_info).
- Use the [`validators`](validators.html) command to return the current list of published and trusted validators used by the validator. Ensure that the `validator_list_expires` value is either `never` or not expired or about to expire.

View File

@@ -0,0 +1,170 @@
# macOSでのrippledの構築と実行
現時点において、Rippleでは`rippled`の本番環境にmacOSの使用を推奨していません。本番環境には、最高レベルの品質管理とテストを経た、[Ubuntuプラットフォーム](install-rippled-on-ubuntu-with-alien.html)のご使用をご検討ください。
しかしながら、macOSは多くの開発やテストの作業に適しています。 `rippled` は、10.13 High SierraまでのmacOSでテスト済みです。
開発目的の場合は、`sudo`を使用するのではなく、自身のユーザーとして`rippled`を実行することをお勧めします。
1. [Xcode](https://developer.apple.com/download/)をインストールします。
0. Xcodeコマンドラインツールをインストールします。
$ xcode-select --install
0. [Homebrew](https://brew.sh/)をインストールします。
$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
0. Homebrewをアップデートします。
$ brew update
0. Homebrewを使用して依存関係をインストールします。
$ brew install git cmake pkg-config protobuf openssl ninja
0. Boost 1.70.0をインストールします。 `rippled` 1.3.1はBoost 1.70以上と互換性を持ちます。
1. [Boost 1.70.0](https://dl.bintray.com/boostorg/release/1.70.0/source/boost_1_70_0.tar.bz2)をダウンロードします。
2. フォルダに抽出します。場所をメモしておいてください。
3. ターミナルで以下を実行します。
cd /LOCATION/OF/YOUR/BOOST/DIRECTORY
./bootstrap.sh
./b2 cxxflags="-std=c++14"
0. `BOOST_ROOT`環境変数が、Boostのインストールで作成されたディレクトリーを指すようにします。Boostのインストールディレクトリーを見つけるには、`brew info boost`を使用します。この環境変数を`.bash_profile`ファイルに追加すると、ログイン時に自動的に設定されます。例えば、次のようにします。
export BOOST_ROOT=/Users/my_user/boost_1_70_0
0. 前のステップで`.bash_profile`ファイルをアップデートした場合には、それを読み込みます。例:
$ source .bash_profile
0. 希望の場所に`rippled`ソースコードをクローンし、`rippled`ディレクトリーにアクセスします。これを行うには、GitHomebrewを使用して前にインストール済みとGitHubを設定する必要があります。例えば、GitHubアカウントを作成し、SSHキーを設定します。詳細は、[Set up git](https://help.github.com/articles/set-up-git/)を参照してください。
$ git clone git@github.com:ripple/rippled.git
$ cd rippled
0. デフォルトでは、クローンを実行すると`develop`ブランチに移動します。開発作業をしていて、未テストの機能の最新セットを使用したい場合にはこのブランチを使用します。
最新の安定したリリースを使用したい場合には、`master`ブランチをチェックアウトします。
$ git checkout master
最新のリリース候補をテストしたい場合には、`release`ブランチをチェックアウトします。
$ git checkout release
または、[GitHub](https://github.com/ripple/rippled/releases)にリストされたタグ付きのリリースをチェックアウトすることもできます。
0. クローンしたばかりの`rippled`ディレクトリー内にビルドディレクトリーを作成し、そこにアクセスします。例:
$ mkdir my_build
$ cd my_build
0. `rippled`を構築します。ハードウェアの仕様にもよりますが、これには約5分ほどかかります。
$ cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug ..
`CMAKE_BUILD_TYPE``Debug`または`Release`ビルドタイプに設定できます。標準的な4つの[`CMAKE_BUILD_TYPE`](https://cmake.org/cmake/help/v3.0/variable/CMAKE_BUILD_TYPE.html)の値がすべてサポートされています。
0. CMakeを使用してビルドを実行します。ハードウェアの仕様にもよりますが、これには約10分ほどかかります。
$ cmake --build .-- -j 4
**ヒント:** この例では、`-j`パラメーターが`4`に設定されています。これにより、4つのプロセスを使用し、並行してビルドします。使用する最適なプロセス数は、お使いのハードウェアで使用可能なCPUコア数によって異なります。`sysctl -n hw.ncpu`を使用して、CPUのコア数を調べてください。
0. サーバー実行可能ファイルに組み込まれたユニットテストを実行します。ハードウェアの仕様にもよりますが、これには約5分ほどかかります。省略可能ですが、推奨します <!--{# ***TODO: We should provide info about what to do if you get failures. What should the user do? PM looking into this.*** #}-->
$ ./rippled --unittest
0. `rippled` は、`rippled.cfg`構成ファイルの実行を必要とします。`rippled/cfg`に、サンプル構成ファイルの`rippled-example.cfg`があります。このファイルをコピーし、`rippled`を非ルートユーザーとして実行できる場所に`rippled.cfg`という名前で保存します。`rippled`ディレクトリーにアクセスして、以下を実行します。
$ mkdir -p $HOME/.config/ripple
$ cp cfg/rippled-example.cfg $HOME/.config/ripple/rippled.cfg
0. `rippled.cfg`を編集し、必要なファイルパスを設定します。`rippled`を実行するユーザーは、ここで指定するすべてのパスへの書き込み権限を持っている必要があります。
* `[node_db]`パスを、台帳データベースを保存する場所に設定します。
* `[database_path]`パスを、その他のデータベースデータを保存する場所に設定します。この場所には、構成データを持つSQLiteデータベースも含まれ、通常、`[node_db]`パスフィールドの1つ上のレベルになります。
* `[debug_logfile]``rippled`がログ情報を書き込めるパスに設定します。
`rippled`を正常に起動するために必要な構成はこれだけです。その他の構成はすべて省略可能であり、作業サーバーをセットアップしてから調整することもできます。詳細については、[追加構成](#additional-configuration)を参照してください。
0. `rippled` は、`validators.txt`ファイルの実行を必要とします。`rippled/cfg/`に、サンプルバリデータファイルの`validators-example.txt`があります。このファイルをコピーし、`rippled.cfg`ファイルと同じフォルダーに`validators.txt`という名前で保存します。`rippled`ディレクトリーにアクセスして、以下を実行します。
$ cp cfg/validators-example.txt $HOME/.config/ripple/validators.txt
**警告:** Rippleは、安全を第一に考えて分散プランをデザインしました。特にRippleから勧められない限り、移行中に`validators.txt`ファイルを変更しないでください。小さな変更であっても、バリデータの設定に変更を加えると、サーバーがネットワークから分岐し、古い、不完全、または正しくないデータについて報告する原因となることがあります。そのようなデータを使用すると、経費の無駄になります。
0. ビルドディレクトリー(`my_build`など)にアクセスし、`rippled`サービスを開始します。
$ ./rippled
以下は、ターミナルに表示される内容の抜粋です。
```
2018-Oct-26 18:21:39.593738 JobQueue:NFO Auto-tuning to 6 validation/transaction/proposal threads.
2018-Oct-26 18:21:39.599634 Amendments:DBG Amendment 4C97EBA926031A7CF7D7B36FDE3ED66DDA5421192D63DE53FFB46E43B9DC8373 is supported.
2018-Oct-26 18:21:39.599874 Amendments:DBG Amendment 6781F8368C4771B83E8B821D88F580202BCB4228075297B19E4FDC5233F1EFDC is supported.
2018-Oct-26 18:21:39.599965 Amendments:DBG Amendment 42426C4D4F1009EE67080A9B7965B44656D7714D104A72F9B4369F97ABF044EE is supported.
2018-Oct-26 18:21:39.600024 Amendments:DBG Amendment 08DE7D96082187F6E6578530258C77FAABABE4C20474BDB82F04B021F1A68647 is supported.
...
2018-Oct-26 18:21:39.603201 OrderBookDB:DBG Advancing from 0 to 3
2018-Oct-26 18:21:39.603291 OrderBookDB:DBG OrderBookDB::update>
2018-Oct-26 18:21:39.603480 OrderBookDB:DBG OrderBookDB::update< 0 books found
2018-Oct-26 18:21:39.649617 ValidatorList:DBG Loading configured trusted validator list publisher keys
2018-Oct-26 18:21:39.649709 ValidatorList:DBG Loaded 0 keys
2018-Oct-26 18:21:39.649798 ValidatorList:DBG Loading configured validator keys
2018-Oct-26 18:21:39.650213 ValidatorList:DBG Loaded 5 entries
2018-Oct-26 18:21:39.650266 ValidatorSite:DBG Loading configured validator list sites
2018-Oct-26 18:21:39.650319 ValidatorSite:DBG Loaded 0 sites
2018-Oct-26 18:21:39.650829 NodeObject:DBG NodeStore.main target size set to 131072
2018-Oct-26 18:21:39.650876 NodeObject:DBG NodeStore.main target age set to 120000000000
2018-Oct-26 18:21:39.650931 TaggedCache:DBG LedgerCache target size set to 256
2018-Oct-26 18:21:39.650981 TaggedCache:DBG LedgerCache target age set to 180000000000
2018-Oct-26 18:21:39.654252 TaggedCache:DBG TreeNodeCache target size set to 512000
2018-Oct-26 18:21:39.654336 TaggedCache:DBG TreeNodeCache target age set to 90000000000
2018-Oct-26 18:21:39.674131 NetworkOPs:NFO Consensus time for #3 with LCL AF8D8984A226AE7099D8A9749B09CE1D84360D5AF9FB86CE2F37500FE1009F9D
2018-Oct-26 18:21:39.674271 ValidatorList:DBG 5 of 5 listed validators eligible for inclusion in the trusted set
2018-Oct-26 18:21:39.674334 ValidatorList:DBG Using quorum of 4 for new set of 5 trusted validators (5 added, 0 removed)
2018-Oct-26 18:21:39.674400 LedgerConsensus:NFO Entering consensus process, watching, synced=no
2018-Oct-26 18:21:39.674475 LedgerConsensus:NFO Consensus mode change before=observing, after=observing
2018-Oct-26 18:21:39.674539 NetworkOPs:DBG Initiating consensus engine
2018-Oct-26 18:21:39.751225 Server:NFO Opened 'port_rpc_admin_local' (ip=127.0.0.1:5005, admin IPs:127.0.0.1, http)
2018-Oct-26 18:21:39.751515 Server:NFO Opened 'port_peer' (ip=0.0.0.0:51235, peer)
2018-Oct-26 18:21:39.751689 Server:NFO Opened 'port_ws_admin_local' (ip=127.0.0.1:6006, admin IPs:127.0.0.1, ws)
2018-Oct-26 18:21:39.751915 Application:FTL Startup RPC:
{
"command" : "log_level",
"severity" : "warning"
}
2018-Oct-26 18:21:39.752079 Application:FTL Result: {}
2018-Oct-26 18:22:33.013409 NetworkOPs:WRN We are not running on the consensus ledger
2018-Oct-26 18:22:33.013875 LedgerConsensus:WRN Need consensus ledger 81804C95ADE119CC874572BAF24DB0C0D240AC58168597951B0CB64C4DA2C628
2018-Oct-26 18:22:33.883648 LedgerConsensus:WRN View of consensus changed during open status=open, mode=wrongLedger
2018-Oct-26 18:22:33.883815 LedgerConsensus:WRN 81804C95ADE119CC874572BAF24DB0C0D240AC58168597951B0CB64C4DA2C628 to 9250C6C8326A48C339E6F99167F4E6BFD0DB00C35518027724D7B376340D21A1
2018-Oct-26 18:22:33.884068 LedgerConsensus:WRN {"accepted":true,"account_hash":"BBA0E7273005D42E5548DD6456E5AD1F7C89B6EDCB01881E1EECD393E8545947","close_flags":0,"close_time":593893350,"close_time_human":"2018-Oct-26 18:22:30.000000","close_time_resolution":30,"closed":true,"hash":"9250C6C8326A48C339E6F99167F4E6BFD0DB00C35518027724D7B376340D21A1","ledger_hash":"9250C6C8326A48C339E6F99167F4E6BFD0DB00C35518027724D7B376340D21A1","ledger_index":"3","parent_close_time":593893290,"parent_hash":"AF8D8984A226AE7099D8A9749B09CE1D84360D5AF9FB86CE2F37500FE1009F9D","seqNum":"3","totalCoins":"100000000000000000","total_coins":"100000000000000000","transaction_hash":"0000000000000000000000000000000000000000000000000000000000000000"}
2018-Oct-26 18:23:03.034119 InboundLedger:WRN Want: D901E53926E68EFDA33172DDAC74E8C767D280B68EE68E3010AB0E3179D07B1C
2018-Oct-26 18:23:03.034334 InboundLedger:WRN Want: 1C01EE79083DE5CE76F3634519D6364C589C4D48631CB9CD10FC2408F87684E2
2018-Oct-26 18:23:03.034560 InboundLedger:WRN Want: 8CFE3912001BDC5B2C4B2691F3C7811B9F3F193E835D293459D80FBF1C4E684E
2018-Oct-26 18:23:03.034750 InboundLedger:WRN Want: 8DFAD21AD3090DE5D6F7592B3821C3DA77A72287705B4CF98DC0F84D5DD2BDF8
```
`rippled`ログメッセージの詳細については、[ログメッセージについて](understanding-log-messages.html)を参照してください。
## 次のステップ
{% include '_snippets/post-rippled-install.md' %}<!--_ -->
## 関連項目
- [Ubuntu Linuxでrippledをインストール](install-rippled-on-ubuntu-with-alien.html)本番環境用の、Ubuntu上の事前構築済みバイナリー
- [Ubuntuでの`rippled`の構築と実行](build-run-rippled-ubuntu.html)Ubuntuで`rippled`を自分でコンパイル)
- [その他のプラットフォーム用のコンパイル手順](https://github.com/ripple/rippled/tree/develop/Builds)

View File

@@ -0,0 +1,212 @@
# Ubuntuでのrippledの構築と実行
`rippled` は、XRP Ledgerを管理するコアのピアツーピアサーバーです。`rippled`サーバーは、ピアのネットワークに接続し、暗号で署名された取引を中継し、共有のグローバル台帳の完全なローカルコピーを維持します。
`rippled`の概要については、[Operating rippled Servers](install-rippled.html)を参照してください。
次の手順を使用し、16.04以降のUbuntu Linux上で、ソースバージョン1.2.0以上から、`rippled`実行可能ファイルを構築します。これらの手順は、Ubuntu 16.04 LTSでテスト済みです。
その他のプラットフォームでの`rippled`の構築については、`rippled` GitHubリポジトリの[Builds](https://github.com/ripple/rippled/tree/develop/Builds)を参照してください。
## 前提条件
`rippled`をコンパイルまたはインストールする前に、[システム要件](system-requirements.html)を満たす必要があります。
## 1. `rippled`の構築
次の手順では、UbuntuのAPTAdvanced Packaging Toolを使用し、`rippled`の構築と実行に必要なソフトウェアをインストールします。
1. `apt-get`でインストールまたはアップグレードできるパッケージのリストを更新します。
sudo apt-get update
2. 現在インストールされているパッケージをアップグレードします。
sudo apt-get -y upgrade
3. 依存関係をインストールします。
sudo apt-get -y install git pkg-config protobuf-compiler libprotobuf-dev libssl-dev wget
4. CMakeをインストールします。
`rippled`のバージョン1.3.1は、CMake 3.9.0以降を必要とします。このチュートリアルでは、執筆時の最新バージョンだったCMake 3.13.3を使用しました。
CMake 3.9.0以降をすでにインストールしてある場合には、このステップはスキップできます。
CMake 3.13.3をインストールするには、以下を実行します。
wget https://github.com/Kitware/CMake/releases/download/v3.13.3/cmake-3.13.3-Linux-x86_64.sh
sudo sh cmake-3.13.3-Linux-x86_64.sh --prefix=/usr/local --exclude-subdir
`cmake --version`を使用し、正常にインストールされたことを確認します。
5. Boostをコンパイルします。
`rippled` 1.3.1はBoost 1.70以上と互換性を持ちます。Ubuntu18.04も16.04ものソフトウェアリポジトリに、Boostバージョン1.70.0がないため、自分でコンパイルする必要があります。
以前に`rippled`用にBoost 1.70.0をインストールしていて、`BOOST_ROOT`環境変数を構成した場合には、このステップはスキップできます。
1. Boost 1.70.0をダウンロードします。
wget https://dl.bintray.com/boostorg/release/1.70.0/source/boost_1_70_0.tar.gz
2. `boost_1_70_0.tar.gz`を抽出します。
tar xvzf boost_1_70_0.tar.gz
3. 新しい`boost_1_70_0`ディレクトリーに移動します。
cd boost_1_70_0
4. 使用するBoost.Buildシステムを準備します。
./bootstrap.sh
5. 個別にコンパイルされたBoostライブラリを構築します。ハードウェアの仕様にもよりますが、これには約10分かかります。
./b2 -j 4
**ヒント:** この例では、4つのプロセスを並行して構築します。使用する最適なプロセス数は、お使いのハードウェアで使用可能なCPUコア数によって異なります。`cat /proc/cpuinfo`を使用して、ハードウェアプロセッサーに関する情報を取得できます。
6. `BOOST_ROOT`環境変数を、新しい`boost_1_70_0`ディレクトリーを参照するように設定します。ログイン時に自動的に設定されるようにするため、この環境変数を、シェル用の`.profile`またはそれに相当するファイルに入れることをお勧めします。ファイルに次の行を追加します。
export BOOST_ROOT=/home/my_user/boost_1_70_0
7. 更新した`.profile`ファイルを読み込みます。例:
source ~/.profile
6. 作業ディレクトリーから、`rippled`ソースコードを取得します。`master`ブランチに最新のリリースバージョンがあります。
git clone https://github.com/ripple/rippled.git
cd rippled
git checkout master
7. コミットログを調べ、正しいバージョンをコンパイルしていることを確認します。最新のコミットは、よく知られるRipple開発者によって署名され、バージョン番号が最新のリリースバージョンに設定されています。例:
$ git log -1
commit e1adbd7ddd5dfa9f2a9791aa3c0fcc1fdb4e8236
Author: Manoj doshi <mdoshi@ripple.com>
Date: Wed Jul 24 15:21:56 2019 -0700
Set version to 1.3.1
8. 以前に`rippled`を構築したことがある場合、または(そしてもっと重要なのは)構築しようとして失敗したことがある場合には、クリーンな状態から開始するために、次のステップに移る前に`my_build/`ディレクトリーまたはユーザーが付けた名前を削除する必要があります。このディレクトリーを削除しないと、セグメンテーションエラーsegfaultが原因で`rippled`実行可能ファイルがクラッシュするなど、予期しない動作が発生することがあります。
`rippled`1.0.0以上を構築するのが初めての場合には、`my_build/`ディレクトリーはないため、次のステップに進むことができます。
9. CMakeを使用して、ソースコードから`rippled`バイナリー実行可能ファイルを構築します。その結果、`my_build`ディレクトリーに`rippled`バイナリー実行可能ファイルが構築されます。
1. ビルドシステムを生成します。ビルドは、ソースツリールートとは別のディレクトリーで実行します。この例では、`rippled`のサブディレクトリーである`my_build`ディレクトリーを使用します。
mkdir my_build
cd my_build
cmake ..
**ヒント:** デフォルトのビルドには、本番環境では有用ではないものの、開発環境に便利なデバッグ記号が含まれています。`rippled`を本番環境用サーバーで使用するには、`cmake`コマンドの実行時に`-DCMAKE_BUILD_TYPE=Release`フラグを追加します。
2. `rippled`のバイナリー実行可能ファイルを構築します。ハードウェアの仕様にもよりますが、これには約30分かかります。
cmake --build .
10. _省略可能_`rippled`ユニットテストを実行します。テストエラーがない場合には、`rippled`実行可能ファイルがほぼ確実に正しくコンパイルされています。
./rippled -u
## 2. `rippled`の構成
`rippled`を正常に起動させるために必要な以下の構成を行います。その他の構成はすべて省略可能であり、作業サーバーをセットアップしてから調整することもできます。
1. `rippled`フォルダーに移動して、サンプル構成ファイルのコピーを作成します。構成ファイルをこの場所に保存すると、`rippled`を非ルートユーザーとして実行できます(推奨)。
mkdir -p ~/.config/ripple
cp cfg/rippled-example.cfg ~/.config/ripple/rippled.cfg
2. 構成ファイルを編集し、必要なファイルパスを設定します。`rippled`を実行するユーザーは、ここで指定するすべてのパスへの書き込み権限を持っている必要があります。
1. `[node_db]`のパスを、台帳データベースを保存する場所に設定します。
2. `[database_path]`を、その他のデータベースデータを保存する場所に設定します。この場所には、構成データを持つSQLiteデータベースも含まれ、通常、`[node_db]`パスフィールドの1つ上のレベルになります。
3. `[debug_logfile]``rippled`がロギング情報を書き込めるパスに設定します。
3. サンプルの`validators.txt`ファイルを`rippled.cfg`と同じフォルダーに保存します。
cp cfg/validators-example.txt ~/.config/ripple/validators.txt
**警告:** Rippleは、安全を第一に考えて[分散プラン](https://ripple.com/dev-blog/decentralization-strategy-update/)をデザインしました。特にRippleから勧められない限り、移行中に`validators.txt`ファイルを変更*しない*でください。小さな変更であっても、バリデータの設定に変更を加えると、サーバーがネットワークから分岐し、古い、不完全、または正しくないデータについて報告する原因となることがあります。そのようなデータを使用すると、経費の無駄になります。
## 3. `rippled`の実行
定義した構成を使用し、構築した実行可能ファイルからストック`rippled`サーバーを実行するには、以下を実行します。
```
cd my_build
./rippled
```
### ターミナルに表示される内容
`rippled`を実行するとターミナルに表示される内容の抜粋を以下に示します。
```
Loading: "/home/ubuntu/.config/ripple/rippled.cfg"
Watchdog: Launching child 1
2018-Jun-06 00:51:35.094331139 JobQueue:NFO Auto-tuning to 4 validation/transaction/proposal threads.
2018-Jun-06 00:51:35.100607625 Amendments:DBG Amendment 4C97EBA926031A7CF7D7B36FDE3ED66DDA5421192D63DE53FFB46E43B9DC8373 is supported.
2018-Jun-06 00:51:35.101226904 Amendments:DBG Amendment 6781F8368C4771B83E8B821D88F580202BCB4228075297B19E4FDC5233F1EFDC is supported.
2018-Jun-06 00:51:35.101354503 Amendments:DBG Amendment 42426C4D4F1009EE67080A9B7965B44656D7714D104A72F9B4369F97ABF044EE is supported.
2018-Jun-06 00:51:35.101503304 Amendments:DBG Amendment 08DE7D96082187F6E6578530258C77FAABABE4C20474BDB82F04B021F1A68647 is supported.
2018-Jun-06 00:51:35.101624717 Amendments:DBG Amendment 740352F2412A9909880C23A559FCECEDA3BE2126FED62FC7660D628A06927F11 is supported.
...
2018-Jun-06 00:51:35.106970906 OrderBookDB:DBG Advancing from 0 to 3
2018-Jun-06 00:51:35.107158071 OrderBookDB:DBG OrderBookDB::update>
2018-Jun-06 00:51:35.107380722 OrderBookDB:DBG OrderBookDB::update< 0 books found
2018-Jun-06 00:51:35.168875072 ManifestCache:NFO Manifest: AcceptedNew;Pk: nHBARBMi2MC3LJYuvs9Rhp94WcfbxoQD5BGhwN3jaHBsPkbNpoZq;Seq: 1;
2018-Jun-06 00:51:35.172099325 ManifestCache:NFO Manifest: AcceptedNew;Pk: nHB57Sey9QgaB8CubTPvMZLkLAzfJzNMWBCCiDRgazWJujRdnz13;Seq: 1;
2018-Jun-06 00:51:35.175302816 ManifestCache:NFO Manifest: AcceptedNew;Pk: nHDsPCxoBHZS9KNNfsd7iVaQXBSitNtbqXfB6BS1iEmJwwEKLhhQ;Seq: 1;
2018-Jun-06 00:51:35.178486951 ManifestCache:NFO Manifest: AcceptedNew;Pk: nHBQ3CT3EWYZ4uzbnL3k6TRf9bBPhWRFVcK1F5NjtwCBksMEt5yy;Seq: 2;
2018-Jun-06 00:51:35.181681868 ManifestCache:NFO Manifest: AcceptedNew;Pk: nHU5egMCYs1g7YRVKrKjEqVYFL12mFWwkqVFTiz2Zi4Z8jppPgxU;Seq: 2;
2018-Jun-06 00:51:35.184864291 ManifestCache:NFO Manifest: AcceptedNew;Pk: nHBbiP5ua5dUqCTz5i5vd3ia9jg3KJthohDjgKxnc7LxtmnauW7Z;Seq: 2;
...
2018-Jun-06 00:51:35.317972033 LedgerConsensus:NFO Entering consensus process, watching, synced=no
2018-Jun-06 00:51:35.318155351 LedgerConsensus:NFO Consensus mode change before=observing, after=observing
2018-Jun-06 00:51:35.318360468 NetworkOPs:DBG Initiating consensus engine
2018-Jun-06 00:51:35.358673488 Server:NFO Opened 'port_rpc_admin_local' (ip=127.0.0.1:5005, admin IPs:127.0.0.1, http)
2018-Jun-06 00:51:35.359296222 Server:NFO Opened 'port_peer' (ip=0.0.0.0:51235, peer)
2018-Jun-06 00:51:35.359778994 Server:NFO Opened 'port_ws_admin_local' (ip=127.0.0.1:6006, admin IPs:127.0.0.1, ws)
2018-Jun-06 00:51:35.360240190 Application:FTL Startup RPC:
{
"command" : "log_level",
"severity" : "warning"
}
...
2018-Jun-06 00:52:32.385295633 NetworkOPs:WRN We are not running on the consensus ledger
2018-Jun-06 00:52:32.388552023 LedgerConsensus:WRN Need consensus ledger 84726E8C5B346E28C21ADE6AAD703E65F802322EDAA5B76446A4D0C5206AB2DB
2018-Jun-06 00:52:33.379448561 LedgerConsensus:WRN View of consensus changed during open status=open, mode=wrongLedger
2018-Jun-06 00:52:33.379541915 LedgerConsensus:WRN 84726E8C5B346E28C21ADE6AAD703E65F802322EDAA5B76446A4D0C5206AB2DB to 1720162AE3BA8CD953BFB40EB746D7B78D13E1C97905E8C553E0B573F1B6A517
2018-Jun-06 00:52:33.379747629 LedgerConsensus:WRN {"accepted":true,"account_hash":"CC1F1EC08E76BC9FE843BBF9C6068C5B73192E6957B9CC1174DCB2B94DD2025A","close_flags":0,"close_time":581561550,"close_time_human":"2018-Jun-06 00:52:30.000000000","close_time_resolution":30,"closed":true,"hash":"94354A7FECAB638C29BBC79B18CFDBDC05E4FF72647AD62F072DB4D23A5E0317","ledger_hash":"94354A7FECAB638C29BBC79B18CFDBDC05E4FF72647AD62F072DB4D23A5E0317","ledger_index":"3","parent_close_time":581561490,"parent_hash":"80BF92A69F65F5C543E962DF4B41715546FDD97FC6988028E5ACBB46654756CA","seqNum":"3","totalCoins":"100000000000000000","total_coins":"100000000000000000","transaction_hash":"0000000000000000000000000000000000000000000000000000000000000000"}
...
2018-Jun-06 00:53:50.568965045 LedgerConsensus:WRN {"accepted":true,"account_hash":"A79E6754544F9C8FC74870C95A39CED1D45CC1206DDA4C113E51F9DB6DDB0E76","close_flags":0,"close_time":581561630,"close_time_human":"2018-Jun-06 00:53:50.000000000","close_time_resolution":10,"closed":true,"hash":"6294118F39F5F2B8349E7CC6D4D5931011622E78DD4E34D91372651E9F453E2F","ledger_hash":"6294118F39F5F2B8349E7CC6D4D5931011622E78DD4E34D91372651E9F453E2F","ledger_index":"29","parent_close_time":581561623,"parent_hash":"5F57870CE5160D6B53271955F26E3BE63696D1127B91BC7943F9A199B313CB85","seqNum":"29","totalCoins":"100000000000000000","total_coins":"100000000000000000","transaction_hash":"0000000000000000000000000000000000000000000000000000000000000000"}
2018-Jun-06 0:53:50.569776678 LedgerConsensus:WRN Need consensus ledger 6A0DE66550B6BA9636E3F8FDB71C2E924D182A1835E4143B2170DAA1D33CAE8D
2018-Jun-06 0:53:51.576778862 NetworkOPs:WRN We are not running on the consensus ledger
2018-Jun-06 00:53:53.576524564 LedgerConsensus:WRN View of consensus changed during establish status=establish, mode=wrongLedger
2018-Jun-06 0:53:53.576783663 LedgerConsensus:WRN 6A0DE66550B6BA9636E3F8FDB71C2E924D182A1835E4143B2170DAA1D33CAE8D to 1CB9C9A1C27403CBAB9DFCFA61E1F915059DFE4FA93524537B885CC190DB5C6B
2018-Jun-06 00:53:53.577079124 LedgerConsensus:WRN {"accepted":true,"account_hash":"5CAB3E4F5F2AC1A764106D7CC0729E6E7D1F7F93C65B7D8CB04C8DE2FC2C1305","close_flags":0,"close_time":581561631,"close_time_human":"2018-Jun-06 00:53:51.000000000","close_time_resolution":10,"closed":true,"hash":"201E147BD195CE3C56B0C0B8DF58386FC7BFF450E1E5B286A29AB856926D5F79","ledger_hash":"201E147BD195CE3C56B0C0B8DF58386FC7BFF450E1E5B286A29AB856926D5F79","ledger_index":"30","parent_close_time":581561630,"parent_hash":"6294118F39F5F2B8349E7CC6D4D5931011622E78DD4E34D91372651E9F453E2F","seqNum":"30","totalCoins":"100000000000000000","total_coins":"100000000000000000","transaction_hash":"0000000000000000000000000000000000000000000000000000000000000000"}
```
## 次のステップ
* これでストック`rippled`サーバーを実行できたので、次に検証サーバーとして実行してみましょう。検証サーバーの詳細について、そして検証サーバーを実行する理由については、[rippledのセットアップチュートリアル](install-rippled.html)を参照してください。
* `rippled` APIを使用して`rippled`サーバーと通信する方法については、[`rippled` API reference](rippled-api.html)を参照してください。
* 開発のベストプラクティスとして、`rippled` `.deb`ファイルを構築することをお勧めします。詳細は、_Ubuntu Packaging Guide_ の[Packaging New Software](http://packaging.ubuntu.com/html/packaging-new-software.html)を参照してください。
* また、`systemd`をインストールすることもできます。詳細については、[systemd for Upstart Users](https://wiki.ubuntu.com/SystemdForUpstartUsers)を参照してください。[公式の`rippled`システムユニットファイル](https://github.com/ripple/rippled-package-builder/blob/staging/rpm-builder/rippled.service)をそのまま使用するか、ニーズに合わせてファイルを編集して使用できます。

View File

@@ -0,0 +1,188 @@
# 容量の計画
このセクションでは、お使いの`rippled`サーバーのパフォーマンスを調整し、最適化するために使用できる、構成、ネットワーク、ハードウェアの推奨事項について説明します。これらの考慮事項を知っておくことにより、XRP Ledgerネットワークの現在および将来の容量を処理できるよう、お使いの`rippled`サーバーを準備するために役立ちます。
## 構成設定
Rippleでは、`rippled`サーバーのリソース利用およびパフォーマンスを最適化するために、これらの構成ガイドラインを使用することをお勧めします。
`rippled.cfg`ファイルで、`rippled`サーバーに使用する次のパラメーターを設定できます。サンプルの構成ファイル`rippled-example.cfg`は、`rippled` GitHubリポジトリの[`cfg`ディレクトリー](https://github.com/ripple/rippled/blob/develop/cfg/rippled-example.cfg)にあります。
### ノードサイズ
サーバーで予測される負荷と、`rippled`で使用できるメモリ量に基づいて`node_size`を設定します。
Rippleでは、お使いのRAMでサポートできる最大のードサイズを常に使用することをお勧めします。以下の表は推奨設定をまとめたものです。
#### 推奨事項
`node_size`には、それに対応する使用可能なRAMの要件があります。例えば、`node_size``huge`に設定すると、`rippled`がスムーズに稼働できるようにするため、最低でも32GBのRAMが必要です。
サーバーを調整するために、まず`tiny`から初め、ユースケースの要件に合わせてサイズを徐々に`small``medium`と増やしていくと便利です。
| `rippled`で使用できるRAM | `node_size` 値 | 注記 |
|:----------------------------|:------------------|:---------------------------|
| 8GB未満 | `tiny` | テストサーバーにも実稼働サーバーにも推奨できません。`rippled.cfg`で値を指定しないと、これがデフォルト値になります。 |
| 8GB | `small` | テストサーバーに推奨。 |
| 16GB | `medium` | `rippled-example.cfg`ファイルではこの値が使用されます。 |
| 32GB | `huge` | 実稼働サーバーに推奨。 |
`large``[node_size]`の値として有効ですが、実際に使用するとほとんどの環境で`huge`よりもパフォーマンスが悪くなります。Rippleでは、`large`の代わりに、常に`huge`を使用することを推奨します。
`node_size`パラメーターを無効な値に設定すると、[サーバーは起動しません](server-wont-start.html#node_sizeの値が正しくない)。
### ードDBタイプ
`rippled.cfg`ファイルの`[node_db]`スタンザの`type`フィールドでは、レジャーストアを保持するために`rippled`で使用されるkey-valueストアのタイプを設定します。
この設定は、直接RAM設定を構成するわけではありませんが、key-valueストアの選択はRAMの使用に大きな影響をもたらします。これは、テクロジーによって、高速検索のためにデータをキャッシュし、インデックス付けする方法が異なるためです。
この値は、`RocksDB`または`NuDB`に設定できます。
- サーバーがバリデーターの場合には、必要とされる履歴の量が少ないため、最良のパフォーマンスを得るために`RocksDB`を使用します。[詳細はこちらをご覧ください。](#rocksdbの使用の詳細)
- ほとんどのケースにおいて、ディスクのデータが膨大であってもパフォーマンスが一貫している`NuDB`を使用します。高速のSSDが必要です。[詳細はこちらをご覧ください。](#nudbの使用の詳細)
- 回転ディスク非推奨や、単に遅いSSDを使用している場合でも、`RocksDB`を使用してください。[詳細はこちらをご覧ください。](#rocksdbの使用の詳細)
サンプルの`rippled-example.cfg`ファイルでは、`[node_db]`スタンザの`type`フィールドが`RocksDB`に設定されています。
#### RocksDBの使用の詳細
[RocksDB](https://rocksdb.org/docs/getting-started.html)は、組み込み可能で永続的なkey-valueストアです。
RocksDBは、ソリッドステートディスクに最適です。回転式ディスクと共に使用した場合、RocksDBはパフォーマンスの点でNuDBよりも優れていますが、ソリッドステートディスクを使用しない限りパフォーマンス上の問題が発生する可能性があります。
RocksDBは、NuDBに比べて必要とする[ディスク容量](#ディスク容量)が約3分の1少なくてすみ、I/O待ち時間が削減されます。ただし、I/O待ち時間が短い半面、データインデックスを格納するために、RocksDBは大量のRAMを必要とします。
RocksDBを使用するようにバリデーターを構成し、レジャーストアに最大30万件約2週間分に相当する[履歴データ](#ディスク容量))までのレジャーを格納するように設定する必要があります。
最大のトランザクション処理スループットを達成するため、RocksDBには、`rippled.cfg`で設定できるパフォーマンス関連の構成オプションがあります。以下は、RocksDBを使用する`rippled`の推奨構成です。
```
[node_db]
type=RocksDB
path=/var/lib/rippled/db/rocksdb
open_files=512
filter_bits=12
cache_mb=512
file_size_mb=64
file_size_mult=2
online_delete=2000
advisory_delete=0
```
`path`を、ディスク上でレジャーを維持するディレクトリーに設定します。`online_delete``advisory_delete`をお使いの構成に合わせて調整します。)
#### NuDBの使用の詳細
[NuDB](https://github.com/vinniefalco/nudb#introduction)は、SSDドライブ用に最適化された追加専用のkey-valueストアです。
NuDBは、[格納されているデータ量に関係なく](#ディスク容量)、ほぼ一定したパフォーマンスとメモリーフットプリントを提供します。NuDBはソリッドステートドライブを _必要とします_ が、大容量のデータベースにアクセスするために使用するRAMがRocksDBよりも大幅に少なくなっています。
バリデーター以外の実稼働サーバーは、NuDBを使用してユースケースに必要な履歴データ量を格納するように構成する必要があります。
NuDBには、`rippled.cfg`にパフォーマンス関連の構成オプションがありません。以下は、NuDBを使用する`rippled`の推奨構成です。
```
[node_db]
type=NuDB
path=/var/lib/rippled/db/nudb
online_delete=2000
advisory_delete=0
```
`path`を、ディスク上でレジャーを維持するディレクトリーに設定します。`online_delete``advisory_delete`をお使いの構成に合わせて調整します。)
### ログレベル
サンプルの`rippled-example.cfg`ファイルの`[rpc_startup]`スタンザでは、ロギング詳細レベルが`warning`に設定されています。この設定を使用すると、より詳細なログ比べ、ディスク容量とI/O要件が大幅に緩和されます。ただし、より詳細なログレベルを設定すると、トラブルシューティングの際により細かな情報が得られます。
**注意:** `[rpc_startup]`スタンザで`log_level`コマンドを省略すると、`rippled``debug`レべルでディスクにログを書き込み、`warning`レベルのログをコンソールに出力します。 `debug` レベルのログは、`warning`レベルに比べ、トランザクション量とクライアントアクティビティーに基づいて、一日当たりに必要なディスク容量が数GB多くなります。
## ネットワークとハードウェア
XRP Ledgerネットワーク内の各`rippled`サーバーは、ネットワークのすべてのトランザクション処理を実行します。このため、実稼働用`rippled`サーバーのベースラインハードウェアはRippleの[パフォーマンステスト](https://ripple.com/dev-blog/demonstrably-scalable-blockchain/)で使用されるものと類似している必要があります。
`rippled`サーバーが、これらのネットワーク要件とハードウェア要件を満たすようにすることは、XRP Ledgerネットワーク全体で一貫した優れたパフォーマンスを実現するために役立ちます。
### 推奨事項
企業の本番環境で最良のパフォーマンスを実現するため、Rippleでは、以下の仕様のベアメタルで`rippled`を実行することを推奨しています。
- オペレーティングシステム: Ubuntu 16.04以上
- CPU: Intel Xeon 3以上、GHzプロセッサー、4コア、ハイパースレッディング有効
- ディスク速度: SSD7000回以上の書き込み/秒、10,000回以上の読み取り/秒)
- ディスク容量: 場合により異なる。最低50GBを推奨。
- RAM: 32GB
- ネットワーク: ホスト上にギガビットネットワークインターフェイスを備える企業データセンターネットワーク
#### CPU使用率および仮想化
ベアメタルを使用するとパフォーマンスが最大になりますが、ホストのハードウェアの仕様が十分であれば、仮想マシンでもほぼ同様のパフォーマンスが得られます。
#### ディスク速度
Rippleは、待ち時間の少ないランダム読み取りと高いスループットを備えた、グレードの高いソリッドステートディスクSSDの使用を _強くお勧めします。_ Rippleのエンジニアにより、以下の最大読み取り速度と書き込み速度が測定されています。
- 使用率が高いパブリックサーバークラスターで秒あたり10,000回の読み取り
- 専用のパフォーマンステストで秒あたり7,000回の書き込み
#### ディスク容量
`rippled`が必要とするディスク容量は、ローカルで維持する予定の[レジャー履歴](ledger-history.html)の量によって異なります。コンセンサスプロセスに従い、レジャー全体の状態を報告するには、`rippled`サーバーは最新の256のレジャーバージョンのみを格納する必要があります。ただし、サーバーで照会できる実行済みトランザクションは、ローカルで保存されたレジャーバージョンにあるものだけです。
保持するデータ量は、[オンライン削除](online-deletion.html)で管理できます。デフォルトの構成ファイルの設定では、サーバーは最新の2000のレジャーバージョンを保持します。オンライン削除を使用しないと、サーバーのディスク要件が際限なく増え続けます。
以下のテーブルは、本書の執筆時点2018年12月13日における、様々な履歴量の要件をまとめたものです。
| 実際の時間 | レジャーバージョンの数 | 必要なディスク容量RocksDB | 必要なディスク容量NuDB |
|:-----------------|:--------------------------|:------------------------------|:--|
| 2時間 | 2,000 | 250MB | 450MB |
| 1日 | 25,000 | 8GB | 12GB |
| 14日 | 350,000 | 112GB | 168GB |
| 30日 | 750,000 | 240GB | 360GB |
| 90日 | 2,250,000 | 720GB | 1TB |
| 1年 | 10,000,000 | 3TB | 4.5TB |
| 2年 | 20,000,000 | 6TB | 9TB |
| 完全な履歴2018まで | 43,000,000+ | (非推奨) | ~9TB |
これらの数値は概算です。様々な要因によって変わりますが、最も重要なのはネットワーク内のトランザクション量です。トランザクション量が増えるにつれ、各レジャーバージョンはより多くの固有データを格納します。今後の拡大に備え、予備のストレージ容量を準備しておくことをお勧めします。
`online_delete`設定は、古い履歴の削除後に保持するレジャーバージョンの数を指定するものです。オンライン削除が実行される直前レジャーの最大数の2倍を格納できるほどの十分な容量を計画する必要があります。
保持する履歴量の変更方法については、[オンライン削除の設定](configure-online-deletion.html)を参照してください。
レジャー履歴を格納したくても、全履歴を格納するための十分な容量がない場合には、[履歴シャーディング](history-sharding.html)機能を使用して個別の共有ストアにランダムな範囲のレジャーを格納できます。履歴シャーディングは、`[shard_db]`スタンザで構成されます。これは`[node_db]`スタンザでレジャーストアに定義したものとは別のタイプのkey-valueストアを使用できます。
##### Amazon Web Services
Amazon Web ServicesAWSは、人気のある仮想化ホスト環境です。AWSで`rippled`を実行することはできますが、RippleではElastic Block StorageEBSの使用はお勧めしません。Elastic Block Storageの最大IOPS数5,000は、非常に高額であるにもかかわらず、`rippled`の最大負荷には不十分です。
AWSインスタンスストア`ephemeral`ストレージにはこのような制約はありません。このため、Rippleでは、インスタンスストレージを備える`M3`などのホストタイプの`rippled`サーバーをデプロイすることをお勧めします。`database_path`パスと`node_db`パスの両方がインスタンスストレージに存在する必要があります。
**注意:** AWSインスタンスストレージは、ハードドライブが故障した場合に、必ずしもデータの保護を保証しません。また、インスタンスを停止、開始、またはリブートした場合にもデータが失われます。通常、個々のサーバーは失われたデータをピアサーバーから再取得できるため、後者のタイプのデータ損失は`rippled`サーバーでは容認できます。
#### RAM/メモリー
メモリー要件は、主に`node_size`構成設定の機能であり、履歴データを取得するクライアントトラフィック量です。メモリー要件についての詳細は、[ノードサイズ](#ノードサイズ)を参照してください。
#### ネットワーク
あらゆる企業または通信事業者クラスのデータセンターでは、`rippled`サーバーの実行をサポートするため、非常に大きなネットワーク帯域幅が必要です。
以下は、一般的な`rippled`タスクで使用されるネットワーク帯域幅の例です。
| タスク | 転送/受信 |
|:------------------------------------------------|:---------------------------|
| 現在のトランザクション量を処理する | 2Mbpsの転送、2Mbpsの受信 |
| 履歴レジャーとトランザクションレポートを提供する | 100Mbpsの転送 |
| `rippled`の起動 | 20Mbpsの受信 |

View File

@@ -32,7 +32,7 @@ To tune your server, it may be useful to start with `tiny` and increase the size
Although `large` is also a legal value for `[node_size]`, in practice it performs worse than `huge` in most circumstances. Ripple recommends always using `huge` instead of `large`.
If you set the `node_size` parameter to an invalid value, the [server fails to start](server-wont-start.html#bad-node-size-value).
If you set the `node_size` parameter to an invalid value, the [server fails to start](server-wont-start.html#bad-node_size-value).
### Node DB Type

View File

@@ -0,0 +1,41 @@
# yumを使用したCentOS/Red Hatへのインストール
このページでは、Rippleの[yum](https://en.wikipedia.org/wiki/Yellowdog_Updater,_Modified)リポジトリを使用して、**CentOS 7**または**Red Hat Enterprise Linux 7**に、`rippled`の安定した最新バージョンをインストールする場合の推奨手順を説明します。
以下の手順では、Rippleによってコンパイルされたバイナリーをインストールします。
## 前提条件
`rippled`をインストールする前に、[システム要件](system-requirements.html)を満たす必要があります。
## インストール手順
1. Ripple RPMリポジトリをインストールします。
$ sudo rpm -Uvh https://mirrors.ripple.com/ripple-repo-el7.rpm
2. `rippled`ソフトウェアパッケージをインストールします。
$ sudo yum install --enablerepo=ripple-stable rippled
3. システム起動時に開始するように、`rippled`サービスを設定します。
$ sudo systemctl enable rippled.service
4. `rippled`サービスを開始します。
$ sudo systemctl start rippled.service
## 次のステップ
{% include '_snippets/post-rippled-install.md' %}<!--_ -->
## 関連項目
- [CentOS/Red Hatでの自動更新](update-rippled-automatically-on-centos-rhel.html)
- [Ubuntu Linuxでrippledをインストール](install-rippled-on-ubuntu-with-alien.html)Ubuntu上の事前構築済みバイナリー
- [Ubuntuでの'rippled'の構築と実行](build-run-rippled-ubuntu.html)Ubuntuで`rippled`を自分でコンパイル)
- [その他のプラットフォーム用のコンパイル手順](https://github.com/ripple/rippled/tree/develop/Builds)

View File

@@ -1,6 +1,6 @@
# Install on Ubuntu or Debian Linux
This page describes the recommended instructions for installing the latest stable version of `rippled` on **Ubuntu Linux 16.04 or higher** or **Debian 9 (Stretch)**, using the [`apt`](https://help.ubuntu.com/lts/serverguide/apt.html) utility. [Updated in: rippled 1.3.1][New in: rippled 1.3.1]
This page describes the recommended instructions for installing the latest stable version of `rippled` on **Ubuntu Linux 16.04 or higher** or **Debian 9 (Stretch)**, using the [`apt`](https://help.ubuntu.com/lts/serverguide/apt.html) utility. [Updated in: rippled 1.3.1][]
These instructions install a binary that has been compiled by Ripple.

View File

@@ -0,0 +1,30 @@
# システム要件
## 最小仕様
ネットワークに参加するための費用を抑えるため、`rippled`サーバーは一般製品のハードウェア上で快適に実行できる必要があります。Rippleでは、現時点で以下の最小要件を推奨します。
- オペレーティングシステム:
- 本番環境: CentOSまたはRedHat Enterprise Linux最新リリース、またはUbuntu 16.04以降)をサポート
- 開発環境: Mac OS X、Windows64ビット、またはほとんどのLinuxディストリビューション
- CPU: 64ビットx86_64、2つ以上のコア
- ディスク: データベースパーティション用に最低50GB。SSDを強く推奨最低でも1000IOPS、それよりも多いことが望ましい
- RAM: 8GB以上
作業負荷によっては、Amazon EC2の`m3.large` VMサイズが適切な場合があります。高速のネットワーク接続が望ましいです。サーバーのクライアント処理負荷が増加すると、必要なリソースも増加します。
## 推奨される仕様
企業の本番環境で最良のパフォーマンスを実現するため、Rippleでは、以下の仕様のベアメタルで`rippled`を実行することを推奨しています。
- オペレーティングシステム: Ubuntu 16.04以上
- CPU: Intel Xeon 3以上、GHzプロセッサー、4コア、ハイパースレッディング有効
- ディスク: SSD7000回以上の書き込み/秒、10,000回以上の読み取り/秒)
- RAM:
- テスト用: 8GB以上
- 本番環境用: 32GB
- ネットワーク: ホスト上にギガビットネットワークインターフェイスを備える企業データセンターネットワーク
## 関連項目
実稼働向けの推奨仕様および計画について詳しくは、[容量の計画](capacity-planning.html)を参照してください。

View File

@@ -0,0 +1,17 @@
# スタンドアロンモードでレジャーを進める
スタンドアロンモードでは`rippled`はピアツーピアネットワークの他のメンバーと通信せず、またコンセンサスプロセスに参加しません。このため、[ledger_acceptメソッド][]を使用してレジャーインデックスを手動で進める必要があります。
```
rippled ledger_accept --conf=/path/to/rippled.cfg
```
スタンドアロンモードでは`rippled`は「閉鎖済み」レジャーバージョンと「検証済み」レジャーバージョンは区別されません。(これらのバージョンの違いについての詳細は、[XRP Ledgerコンセンサスプロセス](consensus.html)を参照してください。)
`rippled`は、レジャーを閉鎖するたびに、確定的だが操作困難なアルゴリズムに基づいてトランザクションを並べ替えます。(トランザクションはネットワークの異なるパスに異なる順序で着信することがあるため、これはコンセンサスの重要な部分です。)スタンドアロンモードで`rippled`を使用するときには、別のアドレスからのトランザクションの結果に依存するトランザクションは、それを送信する前に、レジャーを手動で進める必要があります。このようにしないと、レジャーの閉鎖時に2つのトランザクションが逆の順序で実行される可能性があります。**注記:** 複数のトランザクションを1つのアドレスから1つのレジャーへ安全に送信できます。これは、同じアドレスからのトランザクションは`rippled`により[`Sequence`番号](transaction-common-fields.html)の昇順でソートされるためです。
<!--{# common link defs #}-->
{% include '_snippets/rippled-api-links.md' %}
{% include '_snippets/tx-type-links.md' %}
{% include '_snippets/rippled_versions.md' %}

View File

@@ -0,0 +1,66 @@
# スタンドアロンモードでの保存済みレジャーの読み込み
`rippled`サーバーが以前にXRP Ledgerピアツーピアネットワーク本番環境ネットワークまたは[Test Net](parallel-networks.html))と同期されている場合は、ディスクに保存されたレジャーバージョンから開始できます。
## 1.`rippled`を通常の方法で起動します。
既存のレジャーを読み込むには、最初にネットワークから当該のレジャーを取得する必要があります。`rippled`をオンラインモードで通常の方法で起動します。
```
rippled --conf=/path/to/rippled.cfg
```
## 2.`rippled`が同期されるまで待ちます。
[server_infoメソッド][]を使用して、ネットワークに対するサーバーの状態を確認します。`server_state`に以下のいずれかの値が示される場合は、サーバーは同期しています。
* `full`
* `proposing`
* `validating`
詳細は、[考えられるサーバーの状態](rippled-server-states.html)を参照してください。
## 3.(省略可)特定のレジャーバージョンを取得します。
最新レジャーのみを必要とする場合は、このステップをスキップできます。
特定の履歴レジャーバージョンを読み込むには、[ledger_requestメソッド][]を実行して`rippled`にそのレジャーバージョンを取得させます。`rippled`にまだレジャーバージョンがない場合は、レジャーの取得が完了するまで`ledger_request`コマンドを複数回実行する必要があります。
特定の履歴レジャーバージョンをリプレイする場合は、リプレイするレジャーバージョンとその直前のレジャーバージョンの両方を取得する必要があります。(前のレジャーバージョンにより、リプレイするレジャーバージョンに記述されている変更を適用する初期状態が設定されます。)
## 4.`rippled`をシャットダウンします。
[stopメソッド][]を使用します。
```
rippled stop --conf=/path/to/rippled.cfg
```
## 5.スタンドアロンモードで`rippled`を起動します。
最新のレジャーバージョンを読み込むには、`-a`オプションと`--load`オプションを指定してサーバーを起動します。
```
rippled -a --load --conf=/path/to/rippled.cfg
```
特定の履歴レジャーを読み込むには、`--load`パラメーターと`--ledger`パラメーターを使用し、読み込むレジャーバージョンのレジャーインデックスまたは識別用ハッシュを指定してサーバーを起動します。
```
rippled -a --load --ledger 19860944 --conf=/path/to/rippled.cfg
```
スタンドアロンモードで`rippled`を起動するときに使用できるオプションについての詳細は、[コマンドラインの使用リファレンスの「スタンドアロンモードのオプション」](commandline-usage.html#スタンドアロンモードのオプション)を参照してください。
## 6.レジャーを手動で進めます。
スタンドアロンモードで`--ledger`を使用してレジャーを読み込むと、読み込まれたレジャーが現行のオープンレジャーになるので、[レジャーを手動で進める](advance-the-ledger-in-stand-alone-mode.html)必要があります。
```
rippled ledger_accept --conf=/path/to/rippled.cfg
```
<!--{# common link defs #}-->
{% include '_snippets/rippled-api-links.md' %}
{% include '_snippets/tx-type-links.md' %}
{% include '_snippets/rippled_versions.md' %}

View File

@@ -0,0 +1,28 @@
# スタンドアロンモードでの新しいジェネシスレジャーの開始
スタンドアロンモードでは`rippled`に新しいジェネシスレジャーを作成させることができます。これにより既知の状態が実現され、本番環境のXRP Ledgerのレジャー履歴は使用されません。これは単体テストなどに特に便利です。
* スタンドアロンモードで新しいジェネシスレジャーを使用して`rippled`を起動するには、`-a`オプションと`--start`オプションを使用します。
```
rippled -a --start --conf=/path/to/rippled.cfg
```
スタンドアロンモードで`rippled`を起動時に使用できるオプションについての詳細は、[コマンドラインの使用リファレンスのスタンドアロンモードのオプション](commandline-usage.html#スタンドアロンモードのオプション)を参照してください。
ジェネシスレジャーの[ジェネシスアドレス](accounts.html#特別なアドレス)は1,000億XRPすべてを保有しています。ジェネシスアドレスのキーは以下のように[ハードコーディング](https://github.com/ripple/rippled/blob/94ed5b3a53077d815ad0dd65d490c8d37a147361/src/ripple/app/ledger/Ledger.cpp#L184)されています。
**アドレス:** `rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh`
**シークレット:** `snoPBrXtMeMyMHUVTgbuqAfg1SUTb`"masterpassphrase"
## 新しいジェネシスレジャーの設定
新しいジェネシスレジャーでは、デフォルトでハードコーディングされる[準備金](reserves.html)は**200 XRP**です。この額は、新規アドレスに支給される最低額で、レジャーの1オブジェクトにつき**50 XRP**ずつ増加します。これらは本番環境ネットワークの現在の必要準備金よりも大きな値です。(関連項目: [手数料投票](fee-voting.html)
デフォルトでは、新しいジェネシスレジャーでは[Amendment](amendments.html)が有効になっていません。`--start`を使用して新しいジェネシスレジャーを開始する場合、ジェネシスレジャーには、構成ファイルで明示的に無効にされたAmendmentを除き、`rippled`サーバーでネイティブにサポートされているすべてのAmendmentを有効にする[EnableAmendment疑似トランザクション](enableamendment.html)が含まれています。これらのAmendmentの効果は、直後のレジャーバージョンから反映されます。留意事項: スタンドアロンモードでは[レジャーを手動で進める](advance-the-ledger-in-stand-alone-mode.html)必要があります。)[新規: rippled 0.50.0][]
<!--{# common link defs #}-->
{% include '_snippets/rippled-api-links.md' %}
{% include '_snippets/tx-type-links.md' %}
{% include '_snippets/rippled_versions.md' %}

View File

@@ -0,0 +1,76 @@
# rippledの問題の診断
`rippled`で問題が発生した場合はまず、問題の特徴を正確に明らかにするため、詳細な情報を収集します。これにより、根本原因を洗い出して修正策を編み出すことが容易になります。
サーバーが起動しない場合(クラッシュが発生した場合や自動的にシャットダウンした場合など)は、[rippledサーバーが起動しない](server-wont-start.html)で考えられる原因と修正策のリストを確認してください。
このドキュメントでは、サーバーが稼働している場合(プロセスがアクティブだがネットワークと同期できない場合を含む)に発生する可能性がある問題の診断手順を説明します。
## server_infoの取得
コマンドラインを使用して、ローカル`rippled`インスタンスからサーバーステータス情報を取得できます。例:
```
rippled server_info
```
このコマンドに対する応答には大量の情報が含まれています。これについては、[server_infoメソッド][]で説明します。
トラブルシューティングで最も重要なフィールドは以下のとおりです(最も一般的に使われるものから順に説明します)。
- **`server_state`** - ほとんどの場合、このフィールドには`proposing`[バリデータとして設定されている](run-rippled-as-a-validator.html)サーバーの場合)または `full`(バリデータではないサーバーの場合)が表示されます。値が`connected`の場合は、サーバーはピアツーピアネットワークの他の部分と通信できますが、共有レジャーの状態を追跡するのに十分なデータがありません。通常、レジャーの残りの部分の状態を同期するには起動後515分かかります。
- サーバーが数時間にわたり`connected`状態である場合、または`full`あるいは`proposing`状態になってから`connected`状態に戻る場合は通常、サーバーがネットワークの他の部分よりも遅れています。最も一般的なボトルネックはディスクI/O、ネットワーク帯域幅、RAMです。
- **`complete_ledgers`** - このフィールドは、サーバーに完全なレジャーデータが保管されている[レジャーインデックス](basic-data-types.html#レジャーインデックス)を示します。通常、正常なサーバーには連続した最新のレジャーのセット(`"12133424-12133858"`など)があります。
- 連続していない完全なレジャーのセット(`"11845721-12133420,12133424-12133858"`などがある場合、サーバーで断続的な障害が発生したか、またはネットワークの他の部分との同期が一時的にできなかった可能性があります。このようなケースの最も一般的な原因は、ディスクI/Oまたはネットワーク帯域幅の不足です。
- 通常、`rippled`サーバーはピアから最新のレジャー履歴をダウンロードします。レジャー履歴のギャップが数時間以上続く場合は、欠落データを所有しているピアに接続されていない可能性があります。この状況が発生した場合は、構成ファイルに次のスタンザを追加して再起動すれば、完全な履歴が保管されているRippleのパブリックサーバーの1つにサーバーを強制的にピア接続できます。
[ips_fixed]
s2.ripple.com 51235
- **`amendment_blocked`** - このフィールドは通常`server_info`応答では省略されます。このフィールドの値が`true`の場合は、ネットワークにより承認された[Amendment](amendments.html)がサーバーに導入されていません。ほとんどの場合は、最新バージョンに[rippledを更新する](install-rippled.html)ことで修正できます。また[featureメソッド][]を使用して、現在有効なAmendment ID、サーバーでサポートされているAmendment ID、サーバーでサポートされていないAmendment IDを確認することもできます。
- **`peers`** - このフィールドは、サーバーが接続しているXRP Ledgerピアツーピアネットワーク内のその他のサーバーの数を示します。特定のピアのみに接続するように明示的に構成されているサーバーを除き、正常なサーバーでは通常550ピアと表示されます。
- ピアの数が0の場合、サーバーがネットワークに接続できないか、またはシステムクロックが正しくない可能性があります。サーバーのクロックを同期するため、すべてのサーバーで[NTP](http://www.ntp.org/)デーモンを実行することが推奨されます。)
- ピアの数が10の場合、`rippled`が[NAT](https://en.wikipedia.org/wiki/Network_address_translation)を使用したルーター経由での着信接続を受信できていない可能性があります。接続を改善するには、ルーターのファイアウォールがピアツーピア接続に使用するポート([デフォルトでは](https://github.com/ripple/rippled/blob/8429dd67e60ba360da591bfa905b58a35638fda1/cfg/rippled-example.cfg#L1065)ポート51235を転送するように設定します。
### サーバーから応答がない場合
`rippled`実行可能ファイルがクライアントとして`rippled`サーバーに接続できなかった場合、以下のメッセージが返されます。
```json
{
"error" : "internal",
"error_code" : 71,
"error_message" : "Internal error.",
"error_what" : "no response from server"
}
```
通常これはさまざまな問題の1つを示します。
- `rippled`サーバーが起動したばかりであるか、または完全に稼働していません。サービスのステータスを確認してください。稼働している場合は数秒間待ってから再試行してください。
- サーバーに接続するために異なる[パラメーターを`rippled`コマンドラインクライアントに](commandline-usage.html#クライアントモードのオプション)渡す必要があります。
- `rippled`サーバーがJSON-RPC接続を受け入れるように構成されていない可能性があります。
## サーバーログの確認
[デフォルトでは](https://github.com/ripple/rippled/blob/master/cfg/rippled-example.cfg#L1139-L1142)`rippled`はサーバーのデバッグログを`/var/log/rippled/debug.log`ファイルに書き込みます。このデバッグログの位置は、サーバーの構成ファイルにより異なる可能性があります。`rippled`サービスを(`systemctl`または`service`を使用して開始するのではなく)直接開始した場合、デフォルトではログメッセージはコンソールにも出力されます。
デフォルトの構成ファイルでは、起動時に[log_levelメソッド][]を内部で使用して、すべてのログメッセージカテゴリーでログレベルの重大度は「警告」に設定されています。デバッグログの詳細レベルを制御するには、[起動時に`--silent`コマンドラインオプションを使用し](commandline-usage.html#詳細レベルのオプション)、サーバーの稼働中に[log_levelメソッド][]を使用します。(設定については構成ファイルの`[rpc_startup]`スタンザを参照してください。)
`rippled`サーバーが起動中に多数の警告レベルの(`WRN`メッセージを出力し、その後はときどきいくつかの警告レベルメッセージを出力することは正常です。サーバー起動時の最初の515分間に出力されるほとんどの警告は、**安全に無視**できます。
さまざまな種類のログメッセージに関する詳しい説明については、[ログメッセージについて](understanding-log-messages.html)を参照してください。
<!--{# common link defs #}-->
{% include '_snippets/rippled-api-links.md' %}
{% include '_snippets/tx-type-links.md' %}
{% include '_snippets/rippled_versions.md' %}

View File

@@ -0,0 +1,173 @@
# SQLiteトランザクションデータベースのページサイズの問題の解決
全トランザクション履歴(または極めて大量のトランザクション履歴)が記録されている`rippled`サーバーと、0.40.02017年1月リリースよりも古いバージョンの`rippled`で最初に作成されたデータベースでは、SQLiteデータベースのページサイズが原因でサーバーが適切に稼働しなくなる問題が発生する可能性があります。最近のトランザクション履歴のみが保管されているサーバーデフォルト構成と、バージョン0.40.0以降の`rippled`でデータベースファイルが作成されているサーバーでは、この問題が発生する可能性はそれほどありません。
このドキュメントでは、この問題の発生時に問題を検出し解決する手順を説明します。
## 背景
`rippled` サーバーではトランザクション履歴のコピーがSQLiteデータベースに保管されます。バージョン0.40.0より古い`rippled`では、このデータベースの容量は約2TBに設定されました。ほとんどの場合はこの容量で十分です。ただし、レジャー32570本番環境XRP Ledgerの履歴で利用可能な最も古いレジャーバージョン以降の全トランザクション履歴は、このSQLiteデータベースの容量を超える可能性があります。`rippled`サーバーバージョン0.40.0以降では、これよりも大きな容量でSQLiteデータベースファイルが作成されているため、この問題が発生する可能性は低くなります。
SQLiteデータベースの容量は、データベースの_ページサイズ_パラメーターによって決まります。この容量は、データベース作成後は容易に変更できません。SQLiteの内部についての詳細は、[SQLite公式ドキュメント](https://www.sqlite.org/fileformat.html)を参照してください。)データベースが保管されているディスクとファイルシステムに空き容量がある場合でも、データベースが容量いっぱいになることがあります。以下の「[解決策](#解決策)」で説明するように、この問題を回避するためにページサイズを再構成するには、時間のかかる移行プロセスが必要です。
**ヒント:** ほとんどの場合、`rippled`サーバーの稼働に全履歴が必要となることはありません。サーバーにトランザクションの全履歴が記録されていれば、長期分析やアーカイブ、または災害に対する事前対策に役立ちます。リソースを大量に消費せずにトランザクション履歴を保管する方法については、[履歴シャーディング](history-sharding.html)を参照してください。
## 検出
サーバーがこの問題に対して脆弱である場合は、次の2種類の方法でこの問題を検出できます。
- ご使用の`rippled`サーバーが[バージョン1.1.0][新規: rippled 1.1.0]以降の場合、(問題が発生する前に)[事前に](#事前の検出)問題を検出できます。
- (サーバーがクラッシュした場合)どの`rippled`バージョンでも、問題を[事後に](#事後の検出)特定できます。
いずれの場合でも、問題を検出するには`rippled`のサーバーログへのアクセスが必要です。
**ヒント:** このデバッグログの位置は、`rippled`サーバーの構成ファイルの設定に応じて異なる可能性があります。[デフォルトの構成](https://github.com/ripple/rippled/blob/master/cfg/rippled-example.cfg#L1139-L1142)では、サーバーのデバッグログは`/var/log/rippled/debug.log`ファイルに書き込まれます。
### 事前の検出
SQLiteのページサイズの問題を事前に検出するには、 **[rippled 1.1.0][新規: rippled 1.1.0]以上**を実行している必要があります。`rippled`サーバーは、以下のようなメッセージをデバッグログに定期的に少なくとも2分間隔で書き込みます。ログエントリーの正確な数値とトランザクションデータベースへのパスは、ご使用の環境に応じて異なります。
```text
Transaction DB pathname:/opt/rippled/transaction.db; SQLite page size:1024
bytes; Free pages:247483646; Free space:253423253504 bytes; Note that this
does not take into account available disk space.
```
`SQLite page size: 1024 bytes`という値は、トランザクションデータベースが小さいページサイズで構成されており、全トランザクション履歴に対応できる容量がないことを示しています。この値がすでに4096バイト以上の場合、SQLiteデータベースにはすでに全トランザクション履歴を保管できる十分な容量があり、このドキュメントで説明する移行を行う必要はありません。
`rippled`サーバーは、このログメッセージに示されている`Free space`が524288000バイト500MB未満になると停止します。空き容量がこのしきい値に近づいている場合は、予期しない停止を回避するために[この問題を解決](#解決策)してください。
### 事後の検出
サーバーのSQLiteデータベース容量をすでに超えている場合には、`rippled`サービスがこの問題を示すログメッセージを書き込み、停止します。
#### rippled 1.1.0以降
`rippled`バージョン1.1.0以降では、サーバーは以下のようなメッセージをサーバーのデバッグログに書き込み、通常の方法でシャットダウンします。
```text
Free SQLite space for transaction db is less than 512MB.To fix this, rippled
must be executed with the vacuum <sqlitetmpdir> parameter before restarting.
Note that this activity can take multiple days, depending on database size.
```
#### rippled 1.1.0より前
バージョン1.1.0より前の`rippled`では、サーバーが繰り返しクラッシュし、以下のようなメッセージがサーバーのデバッグログに書き込まれます。
```text
Terminating thread doJob:AcquisitionDone: unhandled
N4soci18sqlite3_soci_errorE 'sqlite3_statement_backend::loadOne: database or
disk is full while executing "INSERT INTO [...]
```
## 解決策
この問題を解決するには、このドキュメントで説明する手順に従い、サポートされているLinuxシステムで`rippled`を使用します。[推奨されるハードウェア構成](capacity-planning.html#推奨事項-1)とおおよそ一致するシステムスペックで全履歴を記録するサーバーの場合、このプロセスにかかる日数は2日を超える可能性があります。
### 前提条件
- **[rippledバージョン1.1.0][新規: rippled 1.1.0]以上**を実行している必要があります。
- このプロセスを開始する前に、安定した最新バージョンに[rippledをアップグレード](install-rippled.html)します。
- 以下のコマンドを実行して、ローカルにインストールした`rippled`のバージョンを確認できます。
rippled --version
- `rippled`ユーザーが書き込めるディレクトリーに、トランザクションデータベースの2つめのコピーを一時的に保管するのに十分な空き容量が必要です。この空き容量は、既存のトランザクションデータベースと同じファイルシステムに設ける必要はありません。
トランザクションデータベースは、構成の`[database_path]`設定で指定されるフォルダーの`transaction.db`ファイルに保管されます。このファイルのサイズを調べ、必要な空き容量を確認できます。次に例を示します。
ls -l /var/lib/rippled/db/transaction.db
### 移行プロセス
トランザクションデータベースを大きなページサイズに移行するには、以下の手順を実行します。
1. すべての[前提条件](#前提条件)を満たしていることを確認します。
2. 移行プロセスの実行中に一時ファイルを保管するフォルダーを作成します。
mkdir /tmp/rippled_txdb_migration
3. `rippled`ユーザーに、一時フォルダーの所有権を付与します。これにより、ユーザーは一時フォルダー内のファイルに書き込みできるようになります。(`rippled`ユーザーがすでにアクセス権限を持つ場所に一時フォルダーがある場合は、この操作は不要です。)
chown rippled /tmp/rippled_txdb_migration
4. 一時フォルダーに、トランザクションデータベースのコピーを保管するのに十分な空き容量があることを確認します。
たとえば、`df`コマンドの`Avail`出力と、[`transaction.db`ファイルのサイズ](#前提条件)を比較します。
df -h /tmp/rippled_txdb_migration
Filesystem Size Used Avail Use% Mounted on
/dev/sda2 5.4T 2.6T 2.6T 50% /tmp
5. `rippled`がまだ稼働している場合は停止します。
sudo systemctl stop rippled
6. `screen`セッション(または類似のツール)を開き、ログアウトしてもプロセスが停止しないようにします。
screen
7. `rippled`ユーザーになります。
sudo su - rippled
8. 一時ディレクトリへのパスを指定した`--vacuum`コマンドで、`rippled`実行可能ファイルを直接実行できます。
/opt/ripple/bin/rippled -q --vacuum /tmp/rippled_txdb_migration
`rippled`実行可能ファイルにより次のメッセージが即時に表示されます。
VACUUM beginning. page_size:1024
9. プロセスが完了するまで待ちます。これには丸2日以上かかることがあります。
プロセスが完了したら、`rippled`実行可能ファイルは以下のメッセージを表示して終了します。
VACUUM finished. page_size:4096
待機している間に`screen`セッションを切り離すには、**CTRL-A**を押してから**D**を押します。その後、以下のようなコマンドでスクリーンセッションを再接続します。
screen -x -r
プロセスが完了したら、スクリーンセッションを終了します。
exit
`screen`コマンドについての詳細は、[公式Screenユーザーマニュアル](https://www.gnu.org/software/screen/manual/screen.html)またはオンラインで使用可能なその他の多数のリソースを参照してください。
10. `rippled`サービスを再起動します。
sudo systemctl start rippled
11. `rippled`サービスが正常に起動したかどうかを確認します。
[コマンドラインインターフェイス](get-started-with-the-rippled-api.html#コマンドライン)を使用してサーバーの状況を確認できますサーバーがJSON-RPC要求を受け入れないように設定している場合を除く。次に例を示します。
/opt/ripple/bin/rippled server_info
このコマンドの予期される応答の説明については、[server_infoメソッド][]ドキュメントを参照してください。
12. サーバーのデバッグログを参照し、`SQLite page size`が現在4096であることを確認します。
tail -F /var/log/rippled/debug.log
また[定期的なログメッセージ](#事前の検出)には、移行前に比べて非常に多くのフリーページとフリースペースが示されているはずです。
13. 必要に応じて、移行プロセスのために作成した一時フォルダーをこの時点で削除できます。
rm -r /tmp/rippled_txdb_migration
トランザクションデータベースの一時コピーを保持するために追加のストレージをマウントした場合は、この時点でそのストレージをアンマウントして取り外すことができます。
<!--{# common link defs #}-->
{% include '_snippets/rippled-api-links.md' %}
{% include '_snippets/tx-type-links.md' %}
{% include '_snippets/rippled_versions.md' %}

View File

@@ -0,0 +1,195 @@
# rippledサーバーが起動しない
このページでは、`rippled`サーバーが起動しない際に考えられる原因とその修正方法を説明します。
以下の手順では、サポートされているプラットフォームに[`rippled`がインストール](install-rippled.html)されていることを前提としています。
## ファイル記述子の制限
一部のLinuxバリアントでは、`rippled`を実行しようとすると以下のようなエラーメッセージが出力されることがあります。
```テキスト
WARNING: There are only 1024 file descriptors (soft limit) available, which
limit the number of simultaneous connections.
```
これは、セキュリティの点からシステムで1つのプロセスが開くことができるファイルの数に制限があるが、その制限が`rippled`にとっては少なすぎる場合に発生します。この問題を修正するには、**ルートアクセス権限が必要です**。以下の手順に従い、`rippled`が開くことができるファイルの数を増やします。
1. 次の行を`/etc/security/limits.conf` ファイルの終わりに追加します。
* soft nofile 65536
* hard nofile 65536
2. [開くことができるファイルの数のハード制限](https://ss64.com/bash/ulimit.html)が現在`65536`であることを確認します。
ulimit -Hn
このコマンドの出力は`65536`になるはずです。
3. `rippled`をもう一度起動します。
systemctl start rippled
4. それでも`rippled`が起動しない場合は、`/etc/sysctl.conf`を開き、以下のカーネルレベル設定を付加します。
fs.file-max = 65536
## /etc/opt/ripple/rippled.cfgを開くことができない
`rippled` が起動時にクラッシュし、以下のようなエラーが出力される場合は、`rippled`が構成ファイルを読み取ることができません。
```テキスト
Loading: "/etc/opt/ripple/rippled.cfg"
Failed to open '"/etc/opt/ripple/rippled.cfg"'.
Terminating thread rippled: main: unhandled St13runtime_error 'Can not create "/var/opt/ripple"'
Aborted (core dumped)
```
考えられる解決策:
- 構成ファイル(デフォルトのロケーションは`/etc/opt/ripple/rippled.cfg`)が存在しており、`rippled`プロセスを実行するユーザー(通常は`rippled`)にこのファイルの読み取り権限があることを確認します。
- `rippled`ユーザーが読み取ることができる構成ファイルを`$HOME/.config/ripple/rippled.cfg`に作成します(`$HOME``rippled`ユーザーのホームディレクトリを指しています)。
**ヒント:**`rippled`リポジトリには、RPMのインストール時にデフォルトの構成として提供される[`rippled.cfg`サンプルファイル](https://github.com/ripple/rippled/blob/master/cfg/rippled-example.cfg)が含まれています。このファイルがない場合は、上記のリンク先からコピーできます。
- `--conf` [コマンドラインオプション](commandline-usage.html)を使用して、使用する構成ファイルのパスを指定します。
## バリデータファイルを開くことができない
`rippled`が起動時にクラッシュし、以下のようなエラーが出力される場合は、`rippled`はプライマリ構成ファイルを読み取ることはできても、この構成ファイルに指定されている別のバリデータ構成ファイル(通常は`validators.txt`)を読み取ることができません。
```テキスト
Loading: "/home/rippled/.config/ripple/rippled.cfg"
Terminating thread rippled: main: unhandled St13runtime_error 'The file specified in [validators_file] does not exist: /home/rippled/.config/ripple/validators.txt'
Aborted (core dumped)
```
考えられる解決策:
- `[validators.txt]`ファイルが存在し、`rippled`ユーザーにこのファイルの読み取り権限があることを確認します。
**ヒント:**`rippled`リポジトリには、RPMのインストール時にデフォルトの構成として提供される[`validators.txt`サンプルファイル](https://github.com/ripple/rippled/blob/master/cfg/validators-example.txt)が含まれています。このファイルがない場合は、上記のリンク先からコピーできます。
- `rippled.cfg`ファイルを編集し、`[validators_file]`設定を変更して、`validators.txt`ファイル(またはこれに相当するファイル)の正しいパスを指定します。ファイル名の前後に余分な空白があるかどうかを確認します。
- `rippled.cfg`ファイルを編集し、`[validators_file]`設定を削除します。バリデータ設定を`rippled.cfg`ファイルに直接追加します。例:
[validator_list_sites]
https://vl.ripple.com
[validator_list_keys]
ED2677ABFFD1B33AC6FBC3062B71F1E8397C1505E1C42C64D11AD1B28FF73F4734
## データベースパスを作成できない
`rippled`が起動時にクラッシュし、以下のようなエラーが出力される場合は、その構成ファイルの`[database_path]`への書き込み権限がサーバーにありません。
```text
Loading: "/home/rippled/.config/ripple/rippled.cfg"
Terminating thread rippled: main: unhandled St13runtime_error 'Can not create "/var/lib/rippled/db"'
Aborted (core dumped)
```
構成ファイルのパス(`/home/rippled/.config/ripple/rippled.cfg`)とデータベースのパス(`/var/lib/rippled/db`)は、システムによっては異なる可能性があります。
考えられる解決策:
- エラーメッセージに出力されているデータベースパスへの書き込み権限を持つ別のユーザーとして`rippled`を実行します。
- `rippled.cfg`ファイルを編集し、`[database_path]`設定を変更して、`rippled`ユーザーに書き込み権限があるパスを使用します。
- `rippled`ユーザーに対し、設定されているデータベースパスへの書き込み権限を付与します。
## 状態DBエラー
`rippled`サーバーの状態データベースが破損している場合に、以下のエラーが発生する可能性があります。これは、予期しないシャットダウンが行われた場合、またはデータベースのタイプをRocksDBからNuDBに変更したが構成ファイルの`path`設定と`[database_path]`設定を変更しなかった場合に発生する可能性があります。
```text
2018-Aug-21 23:06:38.675117810 SHAMapStore:ERR state db error:
writableDbExists false archiveDbExists false
writableDb '/var/lib/rippled/db/rocksdb/rippledb.11a9' archiveDb '/var/lib/rippled/db/rocksdb/rippledb.2d73'
To resume operation, make backups of and remove the files matching /var/lib/rippled/db/state* and contents of the directory /var/lib/rippled/db/rocksdb
Terminating thread rippled: main: unhandled St13runtime_error 'state db error'
```
この問題を修正する最も簡単な方法は、データベース全体を削除することです。あるいは、データベースを任意の場所にバックアップすることもできます。例:
```sh
mv /var/lib/rippled/db /var/lib/rippled/db-bak
```
あるいは、データベースが必要ではないことが判明している場合は以下のようにします。
```sh
rm -r /var/lib/rippled/db
```
**ヒント:** 一般に`rippled`データベースは安全に削除できます。これは、個々のサーバーはXRP Ledgerネットワーク内の他のサーバーからレジャー履歴を再ダウンロードできるためです。
あるいは、構成ファイルでデータベースのパスを変更できます。例:
```
[node_db]
type=NuDB
path=/var/lib/rippled/custom_nudb_path
[database_path]
/var/lib/rippled/custom_sqlite_db_path
```
## オンライン削除の値がレジャー履歴の値よりも少ない
以下のようなエラーメッセージが出力される場合、`rippled.cfg`ファイルの`[ledger_history]``online_delete`に矛盾する値が指定されています。
```テキスト
Terminating thread rippled: main: unhandled St13runtime_error 'online_delete must not be less than ledger_history (currently 3000)
```
`[ledger_history]`設定は、サーバーが埋め戻す履歴のレジャー数を表します。`online_delete`フィールド(`[node_db]`スタンザ)は、古い履歴を削除するときに維持する履歴のレジャー数を示します。サーバーがダウンロードしようとしている履歴レジャーを削除しないようにするため、`online_delete`の値は`[ledger_history]`以上でなければなりません。
この問題を修正するには、`rippled.cfg`ファイルを編集し、`[ledger_history]`オプションまたは`online_delete`オプションのいずれかを変更または削除します。(`[ledger_history]`を省略すると、デフォルトの256レジャーバージョンに設定されるので、`online_delete`を残して指定する場合は256よりも大きな値にする必要があります。`online_delete`を省略すると、古いレジャーバージョンの自動削除が無効になります。)
## node_sizeの値が正しくない
以下のようなエラーが出力される場合は、`rippled.cfg`ファイルの`node_size`設定の値が誤っています。
```テキスト
Terminating thread rippled: main: unhandled N5beast14BadLexicalCastE 'std::bad_cast'
```
`node_size`フィールドの有効なパラメーターは`tiny``small``medium``large``huge`です。詳細は、[ノードサイズ](capacity-planning.html#ノードサイズ)を参照してください。
## シャードパスが欠落している
以下のようなエラーが出力される場合は、`rippled.cfg`の[履歴シャーディング](history-sharding.html)の設定が不完全です。
```テキスト
Terminating thread rippled: main: unhandled St13runtime_error 'shard path missing'
```
設定に`[shard_db]`スタンザが含まれている場合、このスタンザには`path`フィールドが指定されている必要があります。このフィールドは、`rippled`がシャードストアーのデータを書き込むことができるディレクトリを指しています。このエラーが発生する場合は、`path`フィールドが欠落しているか、誤った位置に指定されています。構成ファイルで余分な空白やスペルミスがないかどうかを確認し、[シャード設定の例](configure-history-sharding.html#2-rippledcfgの編集)と比較してください。
## ShardStoreがRocksDBを開くかまたは作成することができない
[履歴シャーディング](history-sharding.html)を有効にし、その後設定を変更してNuDBではなくRocksDBを使用するように設定した場合、サーバーは既存のNuDBデータをRocksDBデータとして読み取ろうとし、起動に失敗します。この場合、サーバーは以下のようなエラーを書き込みます。
```テキスト
ShardStore:ERR shard 504 error: Unable to open/create RocksDB: Invalid argument: /var/lib/rippled/db/shards/504: does not exist (create_if_missing is false)
```
この問題を修正するには、以下のいずれかを行います。
- 設定されているフォルダーから既存のシャードデータを移動する。
- ディスク上のシャードストアーの位置を変更するため、`rippled.cfg`ファイルの`[shard_db]`スタンザの`path`を変更する。
- NuDBを使用するようにシャードストアーを変更する。

View File

@@ -0,0 +1,178 @@
# ログメッセージについて
以下のセクションでは、`rippled`サーバーのデバッグログに出力される最も一般的なログメッセージタイプとその解釈を説明します。
これは、`rippled`の[問題を診断する](diagnosing-problems.html)上で重要なステップです。
## クラッシュ
ログに記録されたランタイムエラーのメッセージは、サーバーがクラッシュしたことを示している可能性があります。このようなメッセージは通常、以下の例に示すいずれかのメッセージで始まります。
```
Throw<std::runtime_error>
```
```
Terminating thread rippled: main: unhandled St13runtime_error
```
サーバーが起動時に常にクラッシュする場合は、[サーバーが起動しない](server-wont-start.html)で考えられる原因を参照してください。
サーバーが稼働中にランダムにクラッシュする場合、または特定のコマンドを実行するとクラッシュする場合は、`rippled`が最新バージョンに[更新](install-rippled.html)されていることを確認してください。最新バージョンに更新済で、サーバーがクラッシュする場合は、以下の点を確認してください。
- サーバーのメモリーが不足していませんか。一部のシステムでは、OOMOut Of MemoryKillerやその他の監視プロセスによって`rippled`が終了されることがあります。
- サーバーが共有環境で稼働している場合、他のユーザーや管理者によってマシンまたはサービスが再起動されますか。たとえば、一部のホステッドプロバイダーは、長期にわたって共有マシンのリソースを大量に消費するサービスを自動的に終了します。
- サーバーは`rippled`を実行するための[最小要件](system-requirements.html)を満たしていますか。[本番環境サーバーに関する推奨事項](system-requirements.html#推奨される仕様)を適用していますか。
上記のいずれにも該当しない場合は、その問題をセキュリティ上重要なバグとしてRippleに報告してください。Rippleでクラッシュを再現できる場合は、報奨を受領できる可能性があります。詳細は<https://ripple.com/bug-bounty/>を参照してください。
## Connection reset by peer
以下のメッセージは、ピア`rippled`サーバーによって接続が閉じられたことを示します。
```テキスト
2018-Aug-28 22:55:41.738765510 Peer:WRN [012] onReadMessage: Connection reset by peer
```
ピアツーピアネットワークで接続が時折失われることは、特に異常な動作ではありません。**この種類のメッセージが時折発生しても問題ではありません。**
このようなメッセージが同時に大量に出力される場合は、以下のような問題がある可能性があります。
- 1つ以上の特定のピアへのインターネット接続が切断されている。
- サーバーからの要求でピアに過剰な負担がかかり、ピアがサーバーをドロップした。
## No hash for fetch pack
以下のようなメッセージは、[履歴シャーディング](history-sharding.html)のために履歴レジャーをダウンロードする際に、`rippled` v1.1.0以前のバグが原因で発生します。
```テキスト
2018-Aug-28 22:56:21.397076850 LedgerMaster:ERR No hash for fetch pack.Missing Index 7159808
```
これらは安全に無視できます。
## LoadMonitor:WRN Job
以下のようなメッセージは、機能の実行に時間がかかっている場合この例では11秒以上に出力されます。
```テキスト
2018-Aug-28 22:56:36.180827973 LoadMonitor:WRN Job: gotFetchPack run: 11566ms wait: 0ms
```
以下のようなメッセージは、ジョブの実行待機に時間がかかっている場合この例でも11秒以上に出力されます。
```テキスト
2018-Aug-28 22:56:36.180970431 LoadMonitor:WRN Job: processLedgerData run: 0ms wait: 11566ms
2018-Aug-28 22:56:36.181053831 LoadMonitor:WRN Job: AcquisitionDone run: 0ms wait: 11566ms
2018-Aug-28 22:56:36.181110594 LoadMonitor:WRN Job: processLedgerData run: 0ms wait: 11566ms
2018-Aug-28 22:56:36.181169931 LoadMonitor:WRN Job: AcquisitionDone run: 0ms wait: 11566ms
```
ジョブの実行に時間がかかり、そのジョブの完了を他のジョブが待っている場合に、この2種類のメッセージが同時に出力されることがよくあります。
サーバー起動後の**最初の数分間**にこの種類のメッセージがいくつか発生することは**特に異常な動作ではありません**。
サーバーの起動後5分以上にわたってこれらのメッセージが継続する場合、特に`run`時間が1000msを大きく上回る場合は、**サーバーに十分なリソースディスクI/O、RAM、CPUなどがない**可能性があります。この原因として、使用しているハードウェアの性能が不十分であること、または同じハードウェアで実行されている他のプロセスがリソースをめぐって`rippled`と競合していることが考えられます。(`rippled`とリソースをめぐって競合する可能性のある他のプロセスの例としては、スケジュール済みバックアップ、ウィルススキャナー、定期的なデータベースクリーナーなどがあります。)
考えられるもう1つの原因として、回転型ハードディスクでNuDBの使用を試みていることが挙げられます。NuDBはソリッドステートドライブSSDでのみ使用してください。`rippled`のデータベースには常にSSDストレージの使用が推奨されますが、RocksDBを使用する回転型ディスクで`rippled`を正常に稼働できる _可能性があります_ 。回転型ディスクを使用している場合は、`[node_db]``[shard_db]`使用している場合の両方がRocksDBを使用するように設定されていることを確認してください。例:
```
[node_db]
type=RocksDB
# ... more config omitted
[shard_db]
type=RocksDB
```
## View of consensus changed during open
以下のようなログメッセージが出力される場合は、サーバーがネットワークの他の部分と同期していません。
```テキスト
2018-Aug-28 22:56:22.368460130 LedgerConsensus:WRN View of consensus changed during open status=open, mode=proposing
2018-Aug-28 22:56:22.368468202 LedgerConsensus:WRN 96A8DF9ECF5E9D087BAE9DDDE38C197D3C1C6FB842C7BB770F8929E56CC71661 to 00B1E512EF558F2FD9A0A6C263B3D922297F26A55AEB56A009341A22895B516E
2018-Aug-28 22:56:22.368499966 LedgerConsensus:WRN {"accepted":true,"account_hash":"89A821400087101F1BF2D2B912C6A9F2788CC715590E8FA5710F2D10BF5E3C03","close_flags":0,"close_time":588812130,"close_time_human":"2018-Aug-28 22:55:30.000000000","close_time_resolution":30,"closed":true,"hash":"96A8DF9ECF5E9D087BAE9DDDE38C197D3C1C6FB842C7BB770F8929E56CC71661","ledger_hash":"96A8DF9ECF5E9D087BAE9DDDE38C197D3C1C6FB842C7BB770F8929E56CC71661","ledger_index":"3","parent_close_time":588812070,"parent_hash":"5F5CB224644F080BC8E1CC10E126D62E9D7F9BE1C64AD0565881E99E3F64688A","seqNum":"3","totalCoins":"100000000000000000","total_coins":"100000000000000000","transaction_hash":"0000000000000000000000000000000000000000000000000000000000000000"}
```
サーバー起動後の最初の515分間に、サーバーがネットワークの他の部分と同期せず、このようなメッセージが出力されることは特に異常な動作ではありません。サーバー起動後かなり経過してからこれらのメッセージが書き込まれる場合は、問題が発生している可能性があります。一般的な原因としては、信頼性の低いネットワーク接続や不十分なハードウェアスペックなどが考えられます。また、同じハードウェアで実行されている他のプロセスがリソースをめぐって`rippled`と競合している場合にも発生する可能性があります。(`rippled`とリソースをめぐって競合する可能性のある他のプロセスの例としては、スケジュール済みバックアップ、ウィルススキャナー、定期的なデータベースクリーナーなどがあります。)
## Already validated sequence at or past
以下のようなログメッセージが出力される場合は、サーバーが異なるレジャーシーケンスの検証を順不同で受信しています。
```テキスト
2018-Aug-28 22:55:58.316094260 Validations:WRN Val for 2137ACEFC0D137EFA1D84C2524A39032802E4B74F93C130A289CD87C9C565011 trusted/full from nHUeUNSn3zce2xQZWNghQvd9WRH6FWEnCBKYVJu2vAizMxnXegfJ signing key n9KcRZYHLU9rhGVwB9e4wEMYsxXvUfgFxtmX25pc1QPNgweqzQf5 already validated sequence at or past 12133663 src=1
```
この種類のメッセージが時折発生しても通常は問題ありません。この種類のメッセージが同じ送信バリデータで頻繁に発生する場合は、以下のような問題がある可能性があります(可能性の高いものから順に示しています)。
- メッセージを書き込むサーバーにネットワークの問題がある。
- メッセージに表示されているバリデータにネットワークの問題がある。
- メッセージに表示されているバリデータが悪意のある振る舞いをしている。
## Unable to determine hash of ancestor
以下のようなログメッセージは、サーバーがピアからの検証メッセージを認識するけれども、サーバーが基盤としている親レジャーバージョンを認識しない場合に発生します。これは、サーバーがネットワークと同期している場合には正常です。
```テキスト
2018-Aug-28 22:56:22.256065549 Validations:WRN Unable to determine hash of ancestor seq=3 from ledger hash=00B1E512EF558F2FD9A0A6C263B3D922297F26A55AEB56A009341A22895B516E seq=12133675
```
サーバー起動後の515分以外の時点でこのメッセージが頻繁に発生する場合は、問題が発生している可能性があります。
## InboundLedger Want hash
以下のようなログメッセージは、サーバーが他のサーバーにレジャーデータを要求していることを示しています。
```テキスト
InboundLedger:WRN Want: 5AE53B5E39E6388DBACD0959E5F5A0FCAF0E0DCBA45D9AB15120E8CDD21E019B
```
これは、サーバーの同期中、埋め戻し中、[履歴シャード](history-sharding.html)のダウンロード中は正常です。
## InboundLedger 11 timeouts for ledger
```テキスト
InboundLedger:WRN 11 timeouts for ledger 8265938
```
これは、サーバーがそのピアに対して特定のレジャーデータを要求する際に問題が発生していることを示しています。[レジャーインデックス](basic-data-types.html#レジャーインデックス)が、[server_infoメソッド][]により報告される最新の検証済みレジャーのインデックスよりもかなり小さい場合は、サーバーが[履歴シャード](history-sharding.html)のダウンロード中である可能性があります。
これは厳密には問題ではありませんが、レジャー履歴を迅速に取得したい場合は、`[ips_fixed]`構成スタンザを追加または編集してからサーバーを再起動することで、すべての履歴が記録されたピアに接続するように`rippled`を構成できます。たとえば、すべての履歴が記録されたRippleのサーバーに常に接続するには、以下のようにします。
```
[ips_fixed]
s2.ripple.com 51235
```
## Potential Censorship
XRP Ledgerが取引検閲の可能性を検出すると、以下のようなログメッセージが出力されます。ログメッセージと取引検閲検出機能の詳細については、[取引検閲の検知](transaction-censorship-detection.html)を参照してください。
**警告メッセージ**
```テキスト
LedgerConsensus:WRN Potential Censorship: Eligible tx E08D6E9754025BA2534A78707605E0601F03ACE063687A0CA1BDDACFCD1698C7, which we are tracking since ledger 18851530 has not been included as of ledger 18851545.
```
**エラーメッセージ**
```テキスト
LedgerConsensus:ERR Potential Censorship: Eligible tx E08D6E9754025BA2534A78707605E0601F03ACE063687A0CA1BDDACFCD1698C7, which we are tracking since ledger 18851530 has not been included as of ledger 18851605.Additional warnings suppressed.
```
<!--{# common link defs #}-->
{% include '_snippets/rippled-api-links.md' %}
{% include '_snippets/tx-type-links.md' %}
{% include '_snippets/rippled_versions.md' %}

View File

@@ -0,0 +1,197 @@
# Checkの取消し
_[Checks Amendment][]が必要です。_
このチュートリアルでは、[Check](checks.html)を取り消す手順を説明します。この手順を実行すると、送金を行わずに[レジャーのCheckオブジェクト](check.html)が削除されます。
着信したCheckが不要な場合、取り消すことができます。送信時に内容を誤って入力した場合や状況が変化した場合に、送信したCheckを取り消すこともできます。有効期限切れのCheckはレジャーから削除する必要があります。これにより、送金元に[所有者準備金](reserves.html#所有者準備金)が戻ります。
{% set cancel_n = cycler(* range(1,99)) %}
## 前提条件
このチュートリアルでCheckを取り消すには、以下が必要です。
- 現在レジャーに記録されているCheckオブジェクトのIDが必要です。
- たとえばこのチュートリアルの例では、IDが`49647F0D748DC3FE26BDACBC57F251AADEFFF391403EC9BF87C97F67E9977FB0`のCheckを取り消しますが、この手順を自身で実行する場合は異なるIDを使用する必要があります。
- CheckCancelトランザクションを送信する資金供給のあるアカウントの**アドレス**と**シークレットキー**。Checkが有効期限切れでない限り、このアドレスは、Checkの送金元または受取人のいずれかでなければなりません。
- トランザクションに安全に署名できる手段([RippleAPI][]や各自の[`rippled`サーバー](install-rippled.html)など)。
- `rippled`サーバーに接続できるクライアントライブラリ([RippleAPI][]、HTTPライブラリ、またはWebSocketライブラリなど
- 詳細は、[`rippled` APIの使用開始](get-started-with-the-rippled-api.html)を参照してください。
## {{cancel_n.next()}}.CheckCancelトランザクションの準備
[CheckCancelトランザクション][]のフィールドの値を決定します。以下のフィールドは必要最小限のフィールドです。その他のフィールドはオプションまたは署名時に[自動入力](transaction-common-fields.html#自動入力可能なフィールド)可能なフィールドです。
| フィールド | 値 | 説明 |
|:------------------|:-----------------|:--------------------------------------|
| `TransactionType` | 文字列 | Checkを取り消す場合は文字列`CheckCancel`を使用します。 |
| `Account` | 文字列(アドレス) | Checkを取り消す送信元のアドレス。あなたのアドレスです。 |
| `CheckID` | 文字列 | レジャーで取り消すCheckオブジェクトのID。この情報を確認するには、[txメソッド][]を使用してCheckCreateトランザクションのメタデータを調べるか、または[account_objectsメソッド][]を使用してCheckを探します。 |
[RippleAPI](rippleapi-reference.html)を使用している場合は、`prepareCheckCancel()`ヘルパーメソッドを使用できます。
**注記:** CheckはRippleAPIバージョン0.19.0以降でサポートされています。
### CheckCancelトランザクションの準備の例
Checkを取り消す例を以下に示します。
<!-- MULTICODE_BLOCK_START -->
*JSON-RPC、WebSocket、またはコマンドライン*
```
{
"TransactionType": "CheckCancel",
"Account": "rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo",
"CheckID": "49647F0D748DC3FE26BDACBC57F251AADEFFF391403EC9BF87C97F67E9977FB0",
"Fee": "12"
}
```
*RippleAPI*
```js
{% include '_code-samples/checks/js/prepareCancel.js' %}
```
<!-- MULTICODE_BLOCK_END -->
## {{cancel_n.next()}}.CheckCancelトランザクションの署名
{% include '_snippets/tutorial-sign-step.md' %} <!--#{ fix md highlighting_ #}-->
### 要求の例
<!-- MULTICODE_BLOCK_START -->
*RippleAPI*
```js
{% include '_code-samples/checks/js/signCancel.js' %}
```
*コマンドライン*
```bash
{% include '_code-samples/checks/cli/sign-cancel-req.sh' %}
```
<!-- MULTICODE_BLOCK_END -->
### 応答の例
<!-- MULTICODE_BLOCK_START -->
*RippleAPI*
```
{% include '_code-samples/checks/js/sign-cancel-resp.txt' %}
```
*コマンドライン*
```json
{% include '_code-samples/checks/cli/sign-cancel-resp.txt' %}
```
<!-- MULTICODE_BLOCK_END -->
## {{cancel_n.next()}}.署名済みCheckCancelトランザクションの送信
{% set step_1_link = "#1checkcancelトランザクションの準備" %}
{% include '_snippets/tutorial-submit-step.md' %} <!--#{ fix md highlighting_ #}-->
### 要求の例
<!-- MULTICODE_BLOCK_START -->
*RippleAPI*
```js
{% include '_code-samples/checks/js/submitCancel.js' %}
```
*コマンドライン*
```bash
{% include '_code-samples/checks/cli/submit-cancel-req.sh' %}
```
<!-- MULTICODE_BLOCK_END -->
### 応答の例
<!-- MULTICODE_BLOCK_START -->
*RippleAPI*
```js
{% include '_code-samples/checks/js/submit-cancel-resp.txt' %}
```
*コマンドライン*
```json
{% include '_code-samples/checks/cli/submit-cancel-resp.txt' %}
```
<!-- MULTICODE_BLOCK_END -->
## {{cancel_n.next()}}.検証の待機
{% include '_snippets/wait-for-validation.md' %} <!--#{ fix md highlighting_ #}-->
## {{cancel_n.next()}}.最終結果の確認
トランザクションのステータスを確認するには、CheckCancelトランザクションの識別用ハッシュを指定した[txメソッド][]を使用します。トランザクションが成功したことを示す`"TransactionResult": "tesSUCCESS"`フィールドをトランザクションメタデータから検索し、またこの結果が最終結果であることを示す`"validated": true`フィールドを結果から検索します。
トランザクションによって[Checkレジャーオブジェクト](check.html)が削除されたことを示す`"LedgerEntryType": "Check"`を含む`DeletedNode`オブジェクトを、トランザクションメタデータから検索します。このオブジェクトの`LedgerIndex`はCheckのIDに一致している必要があります。
### 要求の例
<!-- MULTICODE_BLOCK_START -->
*RippleAPI*
```js
{% include '_code-samples/checks/js/getCancelTx.js' %}
```
*コマンドライン*
```bash
{% include '_code-samples/checks/cli/tx-cancel-req.sh' %}
```
<!-- MULTICODE_BLOCK_END -->
### 応答の例
<!-- MULTICODE_BLOCK_START -->
*RippleAPI*
```json
{% include '_code-samples/checks/js/get-cancel-tx-resp.txt' %}
```
*コマンドライン*
```json
{% include '_code-samples/checks/cli/tx-cancel-resp.txt' %}
```
<!-- MULTICODE_BLOCK_END -->
<!--{# common link defs #}-->
[RippleAPI]: rippleapi-reference.html
{% include '_snippets/rippled-api-links.md' %}
{% include '_snippets/tx-type-links.md' %}
{% include '_snippets/rippled_versions.md' %}

View File

@@ -0,0 +1,209 @@
# Checkの変動金額での換金
_[Checks Amendment][]が必要です。_
Checkがレジャーに記録されており有効期限切れではない場合は、指定受取人は`DeliverMin`フィールドを指定した[CheckCashトランザクション][]を送信することで、Checkを変動金額で換金して受領できます。この方法でCheckを換金すると、受取人は送金を最大限受領でき、Checkの送金元からは、Checkの`SendMax`の全額が引き落とされるか、または可能な限りの額が引き落とされます。Checkの受取人に`DeliverMin`以上の額を送金できない場合は換金が失敗します。
Checkから可能な限りの額を受領したい場合には、変動金額でCheckを換金できます。
指定受取人は、[Checkを正確な金額で換金する](cash-a-check-for-a-flexible-amount.html)こともできます。
{% set cash_flex_n = cycler(* range(1,99)) %}
## 前提条件
{% include '_snippets/checkcash-prereqs.md' %}<!--#{ fix md highlighting_ #}-->
## {{cash_flex_n.next()}}.CheckCashトランザクションの準備
[CheckCashトランザクション][]のフィールドの値を決定します。Checkを変動金額で換金する場合、以下のフィールドは必要最小限です。それ以外のフィールドはオプションまたは署名時に[自動入力](transaction-common-fields.html#自動入力可能なフィールド)可能なフィールドです。
| フィールド | 値 | 説明 |
|:------------------|:--------------------------|:-----------------------------|
| `TransactionType` | 文字列 | 値が`CheckCash`の場合、これはCheckCashトランザクションです。 |
| `Account` | 文字列(アドレス) | Checkを換金する送信者のアドレス。あなたのアドレスです。 |
| `CheckID` | 文字列 | レジャーで換金するCheckオブジェクトのID。この情報を確認するには、[txメソッド][]を使用してCheckCreateトランザクションのメタデータを調べるか、または[account_objectsメソッド][]を使用してCheckを探します。 |
| `DeliverMin` | 文字列またはオブジェクト(額) | Checkから受領する最小額。この額を受領できない場合はCheckの換金が失敗し、Checkがレジャーに残るので、後で換金を再試行できます。XRPの場合、XRPのdrop数を示す文字列でなければなりません。発行済み通貨の場合、これは`currency``issuer`、および`value` フィールドを持つオブジェクトです。`currency`フィールドと`issuer`フィールドは、Checkオブジェクトの対応するフィールドに一致しており、`value`はCheckオブジェクトの額以下でなければなりません。詳細は、[通貨額の指定][]を参照してください。 |
### 変動金額で換金するCheckCashトランザクションの準備の例
Checkを変動金額で換金するためのトランザクションを準備する手順を以下の例に示します。
<!-- MULTICODE_BLOCK_START -->
*JSON-RPC、WebSocket、またはコマンドライン*
```
{
"Account": "rGPnRH1EBpHeTF2QG8DCAgM7z5pb75LAis",
"TransactionType": "CheckCash",
"DeliverMin": "95000000",
"CheckID": "2E0AD0740B79BE0AAE5EDD1D5FC79E3C5C221D23C6A7F771D85569B5B91195C2"
}
```
*RippleAPI*
```js
{% include '_code-samples/checks/js/prepareCashFlex.js' %}
```
<!-- MULTICODE_BLOCK_END -->
## {{cash_flex_n.next()}}.CheckCashトランザクションの署名
{% include '_snippets/tutorial-sign-step.md' %} <!--#{ fix md highlighting_ #}-->
### 要求の例
<!-- MULTICODE_BLOCK_START -->
*コマンドライン*
```bash
{% include '_code-samples/checks/cli/sign-cash-flex-req.sh' %}
```
<!-- MULTICODE_BLOCK_END -->
### 応答の例
<!-- MULTICODE_BLOCK_START -->
*コマンドライン*
```json
{% include '_code-samples/checks/cli/sign-cash-flex-resp.txt' %}
```
<!-- MULTICODE_BLOCK_END -->
## {{cash_flex_n.next()}}.署名済みCheckCashトランザクションの送信
{% set step_1_link = "#1checkcashトランザクションの準備" %}
{% include '_snippets/tutorial-submit-step.md' %} <!--#{ fix md highlighting_ #}-->
### 要求の例
<!-- MULTICODE_BLOCK_START -->
*コマンドライン*
```bash
{% include '_code-samples/checks/cli/submit-cash-flex-req.sh' %}
```
<!-- MULTICODE_BLOCK_END -->
### 応答の例
<!-- MULTICODE_BLOCK_START -->
*コマンドライン*
```json
{% include '_code-samples/checks/cli/submit-cash-flex-resp.txt' %}
```
<!-- MULTICODE_BLOCK_END -->
## {{cash_flex_n.next()}}.検証の待機
{% include '_snippets/wait-for-validation.md' %} <!--#{ fix md highlighting_ #}-->
## {{cash_flex_n.next()}}.最終結果の確認
トランザクションのステータスを確認するには、CheckCashトランザクションの識別用ハッシュを指定した[txメソッド][]を使用します。トランザクションが成功したことを示す`"TransactionResult": "tesSUCCESS"`フィールドをトランザクションメタデータから検索し、またこの結果が最終結果であることを示す`"validated": true`フィールドを結果から検索します。
### 要求の例
<!-- MULTICODE_BLOCK_START -->
*コマンドライン*
```bash
{% include '_code-samples/checks/cli/tx-cash-flex-req.sh' %}
```
<!-- MULTICODE_BLOCK_END -->
### 応答の例
<!-- MULTICODE_BLOCK_START -->
*コマンドライン*
```json
{% include '_code-samples/checks/cli/tx-cash-flex-resp.txt' %}
```
<!-- MULTICODE_BLOCK_END -->
### エラー処理
[](transaction-results.html)Checkの換金が`tec`クラスコードで失敗した場合は、[すべてのトランザクション応答のリスト](transaction-results.html)でコードを確認し、適切に対処してください。CheckCashトランザクションでよく返される結果コードの一部を次に示します。
| 結果コード | 意味 | 対処 |
|-------------|---------|----------------|
| `tecEXPIRED` | Checkが有効期限切れです。 | Checkを取り消して、以前より長い有効期限を設定して新しいCheckを作成するように送金元に依頼します。 |
| `tecNO_ENTRY` | Check IDが存在していません。 | CheckCashトランザクションの`CheckID`が正しいことを確認してください。Checkがまだ取り消されていないこと、または正常に換金されていないことを確認してください。 |
| `tecNO_LINE` | 受取人がCheckの通貨のトラストラインを所有していません。 | このイシュアーからのこの通貨を保有するには、指定された通貨とイシュアーのトラストラインを作成し、[TrustSetトランザクション][]を使用してこのトラストラインに適切な限度額を設定してから、Checkの換金を再試行します。 |
| `tecNO_PERMISSION` | CheckCashトランザクションの送信者はCheckの`Destination`ではありません。 | Checkの`Destination`を再度確認します。 |
| `tecNO_AUTH` | このCheckの通貨のイシュアーは[Authorized Trust Line](authorized-trust-lines.html)を使用していますが、受取人からイシュアーへのトラストラインが承認されていません。 | このトラストラインを承認するようイシュアーに依頼し、承認されたらCheckの換金を再試行します。 |
| `tecPATH_PARTIAL` | トラストラインの限度額、または送金元に送金通貨の残高(イシュアーの[送金手数料](transfer-fees.html)がある場合はこの手数料を含むが十分になかったことが原因で、Checkでは十分な発行済み通貨を送金できませんでした。 | 原因がトラストラインの限度額である場合は、(希望する場合には)限度額を引き上げる[TrustSetトランザクション][]を送信するか、または通貨の一部を消費して残高を減らしてから、Checkの換金を再試行します。原因が送金元の残高である場合は、送金元にCheckの通貨が積み増しされるまで待つか、または以前よりも低い額でCheckの換金を再試行します。 |
| `tecUNFUNDED_PAYMENT` | Checkで十分なXRPを送金できませんでした。 | 送金元にXRPが積み増しされるまで待つか、または以前よりも低い額でCheckの換金を再試行します。 |
## {{cash_flex_n.next()}}.送金された額の確認
Checkが変動する`DeliverMin`の額で換金された場合は、Checkは少なくとも`DeliverMin`の額で換金されたと想定できます。送金された額を正確に得るには、トランザクションメタデータを調べます。<!--{# TODO: Update if RIPD-1623 adds a delivered_amount field. #}-->メタデータの`AffectedNodes`配列には、通貨のタイプに応じて、Checkの換金による残高の変更を反映した12つのオブジェクトが含まれています。
- XRPの場合、Checkの送金元の`AccountRoot`オブジェクトのXRP `Balance` フィールドから引き落しが行われます。Checkの受取人CheckCashトランザクションを送信したユーザー`AccountRoot`オブジェクトでは、最低でもCheckCashトランザクションの`DeliverMin`から、トランザクションの送信にかかる[トランザクションコスト](transaction-cost.html)を差し引いた額が、XRP `Balance`に入金されます。
たとえば以下の`ModifiedNode`は、アカウントrGPnRH1EBpHeTF2QG8DCAgM7z5pb75LAisCheckの受取人でありこのCheckCashトランザクションの送信者のXRP残高が`9999999970` dropから`10099999960` dropに変更されています。つまり、このトランザクションを処理した結果として、受取人に対し _正味_ 99.99999 XRPが入金されています。
{
"ModifiedNode": {
"FinalFields": {
"Account": "rGPnRH1EBpHeTF2QG8DCAgM7z5pb75LAis",
"Balance": "10099999960",
"Flags": 0,
"OwnerCount": 2,
"Sequence": 5
},
"LedgerEntryType": "AccountRoot",
"LedgerIndex": "7939126A732EBBDEC715FD3CCB056EB31E65228CA17E3B2901E7D30B90FD03D3",
"PreviousFields": {
"Balance": "9999999970",
"Sequence": 4
},
"PreviousTxnID": "0283465F0D21BE6B1E91ABDE17266C24C1B4915BAAA9A88CC098A98D5ECD3E9E",
"PreviousTxnLgrSeq": 8005334
}
}
正味金額99.99999 XRPは、このCheckCashトランザクションを送信するにあたり、トランザクションコストを支払うために消却された額を差し引いた後の金額です。以下のトランザクション指示抜粋は、トランザクションコスト`Fee`フィールドがXRPの10 dropであることを示しています。これを正味残高の変更に追加することで、このCheckの換金のために受取人rGPnRH1EBpHeTF2QG8DCAgM7z5pb75LAisに _総額_ 100 XRPが入金されます。
"Account" : "rGPnRH1EBpHeTF2QG8DCAgM7z5pb75LAis",
"TransactionType" : "CheckCash",
"DeliverMin" : "95000000",
"Fee" : "10",
- Checkの送金元または受取人がイシュアーである発行済み通貨の場合、これらのアカウント間のトラストラインを表す`RippleState`オブジェクトでは、`Balance`がCheckの受取人に有利な方法で調整されています。
<!-- {# TODO: example of single-RippleState balance changes #}-->
- イシュアーが第三者である発行済み通貨の場合、2つの`RippleState`送金元からイシュアーへのトラストラインとイシュアーから受取人へのトラストラインに対する変更があります。Checkの送金元とイシュアーの関係を表す`RippleState`オブジェクトではその`Balance`がイシュアーに有利に変更され、イシュアーと受取人の間の関係を表す`RippleState`オブジェクトではその`Balance`が受取人に有利に変更されます。
<!--{# TODO: example of double-RippleState balance changes #}-->
- 発行済み通貨に[送金手数料](transfer-fees.html)がある場合、受取人への入金額を上回る額がCheckの送金元から引き落とされます。この差額が送金手数料であり、これがイシュアーに戻されることによりイシュアーの正味の債務は減少します。
<!--{# common links #}-->
[RippleAPI]: rippleapi-reference.html
{% include '_snippets/tx-type-links.md' %}
{% include '_snippets/rippled-api-links.md' %}

View File

@@ -0,0 +1,153 @@
# Checkの正確な金額での換金
_[Checks Amendment][]が必要です。_
Checkがレジャーに含まれており有効期限切れではない場合は、指定の受取人は`Amount`フィールドを指定した[CheckCashトランザクション][]を送信することで、Checkを換金し、Checkに指定されている額までの正確な額を受領できます。請求書の額面通りの金額を回収したい場合など、特定の金額の受領を希望する際には、この方法でCheckを換金できます。
指定の受取人は、[Checkを変動金額で換金する](cash-a-check-for-a-flexible-amount.html)こともできます。
{% set cash_exact_n = cycler(* range(1,99)) %}
## 前提条件
{% include '_snippets/checkcash-prereqs.md' %} <!--#{ fix md highlighting_ #}-->
## {{cash_exact_n.next()}}.CheckCashトランザクションの準備
[CheckCashトランザクション][]のフィールドの値を決定します。Checkを正確な金額で換金する場合、以下のフィールドが最低限必要です。それ以外のフィールドはオプションまたは署名時に[自動入力](transaction-common-fields.html#自動入力可能なフィールド)可能なフィールドです。
| フィールド | 値 | 説明 |
|:------------------|:--------------------------|:-----------------------------|
| `TransactionType` | 文字列 | 値が`CheckCash`の場合、これはCheckCashトランザクションです。 |
| `Account` | 文字列(アドレス) | Checkを換金する送信者のアドレス。あなたのアドレスです。 |
| `CheckID` | 文字列 | レジャーで換金するCheckオブジェクトのID。この情報を確認するには、[txメソッド][]を使用してCheckCreateトランザクションのメタデータを調べるか、または[account_objectsメソッド][]を使用してCheckを探します。 |
| `Amount` | 文字列またはオブジェクト(額) | Checkから精算する額。XRPの場合、XRPのdrop数を示す文字列でなければなりません。発行済み通貨の場合、これは`currency``issuer`、および`value` フィールドを持つオブジェクトです。`currency`フィールドと`issuer`フィールドは、Checkオブジェクトの対応するフィールドに一致しており、`value`はCheckオブジェクトの額以下でなければなりません。送金手数料のかかる通貨の場合、`SendMax`で送金手数料を支払えるように、`SendMax`よりも低い額を換金する必要があります。この額を受領できない場合はCheckの換金が失敗し、Checkがレジャーに残るので、後で換金を再試行できます。詳細は、[通貨額の指定][]を参照してください。 |
### 正確な金額で換金するCheckCashトランザクションの準備の例
Checkを正確な金額で換金するためのトランザクションを準備する手順を以下の例に示します。
<!-- MULTICODE_BLOCK_START -->
*JSON-RPC、WebSocket、またはコマンドライン*
```
{
"Account": "rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy",
"TransactionType": "CheckCash",
"Amount": "100000000",
"CheckID": "838766BA2B995C00744175F69A1B11E32C3DBC40E64801A4056FCBD657F57334",
"Fee": "12"
}
```
*RippleAPI*
```js
{% include '_code-samples/checks/js/prepareCashExact.js' %}
```
<!-- MULTICODE_BLOCK_END -->
## {{cash_exact_n.next()}}.CheckCashトランザクションの署名
{% include '_snippets/tutorial-sign-step.md' %} <!--#{ fix md highlighting_ #}-->
### 要求の例
<!-- MULTICODE_BLOCK_START -->
*コマンドライン*
```bash
{% include '_code-samples/checks/cli/sign-cash-exact-req.sh' %}
```
<!-- MULTICODE_BLOCK_END -->
### 応答の例
<!-- MULTICODE_BLOCK_START -->
*コマンドライン*
```json
{% include '_code-samples/checks/cli/sign-cash-exact-resp.txt' %}
```
<!-- MULTICODE_BLOCK_END -->
## {{cash_exact_n.next()}}.署名済みCheckCashトランザクションの送信
{% set step_1_link = "#1checkcashトランザクションの準備" %}
{% include '_snippets/tutorial-submit-step.md' %} <!--#{ fix md highlighting_ #}-->
### 要求の例
<!-- MULTICODE_BLOCK_START -->
*コマンドライン*
```bash
{% include '_code-samples/checks/cli/submit-cash-exact-req.sh' %}
```
<!-- MULTICODE_BLOCK_END -->
### 応答の例
<!-- MULTICODE_BLOCK_START -->
*コマンドライン*
```json
{% include '_code-samples/checks/cli/submit-cash-exact-resp.txt' %}
```
<!-- MULTICODE_BLOCK_END -->
## {{cash_exact_n.next()}}.検証の待機
{% include '_snippets/wait-for-validation.md' %} <!--#{ fix md highlighting_ #}-->
## {{cash_exact_n.next()}}.最終結果の確認
トランザクションのステータスを確認するには、CheckCashトランザクションの識別用ハッシュを指定した[txメソッド][]を使用します。トランザクションが成功したことを示す`"TransactionResult": "tesSUCCESS"`フィールドをトランザクションメタデータから検索し、またこの結果が最終結果であることを示す`"validated": true`フィールドを結果から検索します。
Checkが正確な`Amount`で換金された場合は、受取人に対し正確な額が入金されたと想定できます(発行済み通貨の金額が極めて大きい場合や小さい場合は、金額が丸められることがあります)。
Checkを換金できない場合、Checkはレジャーに残るため、後日換金を再試行できます。代わりに[Checkを変動金額で換金する](cash-a-check-for-a-flexible-amount.html)ことができます。
### 要求の例
<!-- MULTICODE_BLOCK_START -->
*コマンドライン*
```bash
{% include '_code-samples/checks/cli/tx-cash-exact-req.sh' %}
```
<!-- MULTICODE_BLOCK_END -->
### 応答の例
<!-- MULTICODE_BLOCK_START -->
*コマンドライン*
```json
{% include '_code-samples/checks/cli/tx-cash-exact-resp.txt' %}
```
<!-- MULTICODE_BLOCK_END -->
<!--{# common links #}-->
[RippleAPI]: rippleapi-reference.html
{% include '_snippets/tx-type-links.md' %}
{% include '_snippets/rippled-api-links.md' %}

View File

@@ -0,0 +1,79 @@
# 受取人に基づくCheckの検索
_[Checks Amendment][]が必要です。_
このチュートリアルでは、[Check](checks.html)をその受取人で検索する方法を説明します。[Checkを送金元で検索する](look-up-checks-by-sender.html)こともできます。
## 1. 特定のアドレスのすべてのCheckの検索
特定のアドレスで受信および送信されるすべてのCheckのリストを取得するには、受取人アカウントのアドレスを指定した`account_objects`コマンドを実行し、要求の`type` フィールドを`checks`に設定します。
**注記:**`account_objects`コマンドのコマンドラインインターフェイスでは`type`フィールドは受け入れられません。代わりに[jsonメソッド][]を使用してコマンドラインからJSON-RPCフォーマットの要求を送信できます。
**注記:** RippleAPIには、`account_objects`メソッドの組み込みサポートはありません。`api.connection.request(websocket_request_json)`メソッドを使用して、Webフォーマットで未加工の要求を作成できます。
### 要求の例
<!-- MULTICODE_BLOCK_START -->
*RippleAPI*
```js
{% include '_code-samples/checks/js/getChecks.js' %}
```
*JSON-RPC*
```json
{% include '_code-samples/checks/json-rpc/account_objects-req.json' %}
```
<!-- MULTICODE_BLOCK_END -->
### 応答の例
<!-- MULTICODE_BLOCK_START -->
*RippleAPI*
```
{% include '_code-samples/checks/js/get-checks-resp.txt' %}
```
*JSON-RPC*
```json
200 OK
{% include '_code-samples/checks/json-rpc/account_objects-resp.json' %}
```
<!-- MULTICODE_BLOCK_END -->
## 2. 受取人に基づく応答の絞り込み
応答には、要求のアカウントが送金元であるCheckと、アカウントが受取人であるCheckが含まれていることがあります。応答の`account_objects`配列の各メンバーは1つのCheckを表します。これらの各Checkオブジェクトでは、`Destination`のアドレスはそのCheckの受取人のアドレスです。
以下の疑似コードに、受取人で応答を絞り込む方法を示します。
```js
recipient_address = "rBXsgNkPcDN2runsvWmwxk3Lh97zdgo9za"
account_objects_response = get_account_objects({
account: recipient_address,
ledger_index: "validated",
type: "check"
})
for (i=0; i < account_objects_response.account_objects.length; i++) {
check_object = account_objects_response.account_objects[i]
if (check_object.Destination == recipient_address) {
log("Check to recipient:", check_object)
}
}
```
<!--{# common links #}-->
[RippleAPI]: rippleapi-reference.html
{% include '_snippets/tx-type-links.md' %}
{% include '_snippets/rippled-api-links.md' %}

View File

@@ -0,0 +1,80 @@
# 送金元に基づくCheckの検索
_[Checks Amendment][]が必要です。_
このチュートリアルでは、[Check](checks.html)をその送金元で検索する方法を説明します。[Checkを受取人で検索する](look-up-checks-by-recipient.html)こともできます。
## 1. 特定のアドレスのすべてのCheckの検索
<!--{# TODO: Update if https://github.com/ripple/rippled/issues/2443 gets done #}-->
特定のアドレスで受信および送信されるすべてのCheckのリストを取得するには、送金元アカウントのアドレスを指定した`account_objects`コマンドを実行し、要求の`type` フィールドを`checks`に設定します。
**注記:**`account_objects`コマンドのコマンドラインインターフェイスでは`type`フィールドは受け入れられません。代わりに[jsonメソッド][]を使用してコマンドラインからJSON-RPCフォーマットの要求を送信できます。
**注意:** RippleAPIには、`account_objects`メソッドの組み込みサポートはありません。`api.connection.request(websocket_request_json)`メソッドを使用して、Webフォーマットで未加工の要求を作成できます。このメソッドに対する応答のフォーマットは`rippled` APIフォーマットです。たとえばXRPは小数ではなく整数の「drop数」で指定します。
### 要求の例
<!-- MULTICODE_BLOCK_START -->
*RippleAPI*
```js
{% include '_code-samples/checks/js/getChecks.js' %}
```
*JSON-RPC*
```json
{% include '_code-samples/checks/json-rpc/account_objects-req.json' %}
```
<!-- MULTICODE_BLOCK_END -->
### 応答の例
<!-- MULTICODE_BLOCK_START -->
*RippleAPI*
```
{% include '_code-samples/checks/js/get-checks-resp.txt' %}
```
*JSON-RPC*
```json
200 OK
{% include '_code-samples/checks/json-rpc/account_objects-resp.json' %}
```
<!-- MULTICODE_BLOCK_END -->
## 2. 送金元に基づく応答の絞り込み
応答には、要求のアカウントが送金元であるCheckと、アカウントが受取人であるCheckが含まれていることがあります。応答の`account_objects`配列の各メンバーは1つのCheckを表します。これらの各Checkオブジェクトでは、`Account`のアドレスはそのCheckの送金元のアドレスです。
以下の疑似コードに、送金元で応答を絞り込む方法を示します。
```js
sender_address = "rBXsgNkPcDN2runsvWmwxk3Lh97zdgo9za"
account_objects_response = get_account_objects({
account: sender_address,
ledger_index: "validated",
type: "check"
})
for (i=0; i < account_objects_response.account_objects.length; i++) {
check_object = account_objects_response.account_objects[i]
if (check_object.Account == sender_address) {
log("Check from sender:", check_object)
}
}
```
<!--{# common links #}-->
[RippleAPI]: rippleapi-reference.html
{% include '_snippets/tx-type-links.md' %}
{% include '_snippets/rippled-api-links.md' %}

View File

@@ -0,0 +1,240 @@
# Checkの送信
_[Checks Amendment][]が必要です。_
Checkの送信は、指定受取人にあなたからの支払いを引き出す許可を与えることに似ています。このプロセスの結果、受取人が後で現金化できる[レジャーのCheckオブジェクト](check.html)が作成されます。
多くの場合、Checkではなく[Payment][]が送信されます。これは、Paymentでは1つのステップで受取人に直接送金できるためです。ただし、指定受取人が[DepositAuth](depositauth.html)を使用している場合はPaymentを直接送信できないため、代替手段としてCheckが適切です。
このチュートリアルでは、架空の会社BoxSend SGXRP LedgerアドレスはrBXsgNkPcDN2runsvWmwxk3Lh97zdgo9zaが架空の暗号資産コンサルタント会社Grand PaymentsXRP LedgerアドレスはrGPnRH1EBpHeTF2QG8DCAgM7z5pb75LAisに、コンサルティング料を支払う例を取り上げます。Grand PaymentsはXRPでの支払いを望んでいますが、税務処理と規制対応を簡素化するため、明示的に承認した支払いのみを受け入れます。
XRP Ledgerの外部でGrand PaymentsはBoxSend SGに請求書IDは`46060241FABCF692D4D934BA2A6C4427CD4279083E38C77CBE642243E43BE291`を送り、Grand PaymentsのXRP LedgerアドレスrGPnRH1EBpHeTF2QG8DCAgM7z5pb75LAis宛てに100 XRPのCheckを送信するよう要求します。
{% set send_n = cycler(* range(1,99)) %}
## 前提条件
このチュートリアルでCheckを送信するには、以下が必要です。
- Checkの送信元である資金供給のあるアカウントの**アドレス**と**シークレットキー**。
- [XRP Ledger Test Net Faucet](xrp-test-net-faucet.html)を使用して、10,000 Test Net XRPを保有する資金供給のあるアドレスおよびシークレットを取得できます。
- Checkを受領する資金供給のあるアカウントの**アドレス**。
- トランザクションに安全に署名できる手段([RippleAPI][]や各自の[`rippled`サーバー](install-rippled.html)など)。
- `rippled`サーバーに接続できるクライアントライブラリ([RippleAPI][]、HTTPライブラリ、またはWebSocketライブラリなど
- 詳細は、[`rippled` APIの使用開始](get-started-with-the-rippled-api.html)を参照してください。
## {{send_n.next()}}.CheckCreateトランザクションの準備
Checkの額と、Checkを現金化できる当事者を決定します。[CheckCreateトランザクション][]のフィールドの値を決定します。以下のフィールドは必要最小限のフィールドです。その他のフィールドはオプションまたは署名時に[自動入力](transaction-common-fields.html#自動入力可能なフィールド)できるフィールドです。
| フィールド | 値 | 説明 |
|:------------------|:--------------------------|:-----------------------------|
| `TransactionType` | 文字列 | このフィールドには文字列`CheckCreate`を使用します。 |
| `Account` | 文字列(アドレス) | Checkを作成する送金元のアドレス。あなたのアドレスです。 |
| `Destination` | 文字列(アドレス) | Checkを換金できる指定受取人のアドレス。 |
| `SendMax` | 文字列またはオブジェクト(額) | Checkが現金化されるときに送金元から引き出される最大額。XRPの場合、XRPのdrop数を示す文字列を使用します。発行済み通貨の場合、`currency``issuer`、および`value` フィールドを含むオブジェクトを使用します。詳細は、[通貨額の指定][]を参照してください。受取人がXRP以外の通貨で正確な額のCheckを換金できるようにし、かつ[送金手数料](transfer-fees.html)を含めるには、送金手数料分の追加パーセンテージを必ず指定してください。たとえば受取人が送金手数料2%でCheckをイシュアーからの100 CADに現金化できるようにするには、`SendMax`をイシュアーからの102 CADに設定する必要があります。 |
[RippleAPI](rippleapi-reference.html)を使用している場合は、`prepareCheckCreate()`ヘルパーメソッドを使用できます。
**注記:** ChecksはRippleAPIバージョン0.19.0以上でサポートされています。
### CheckCreateトランザクションの準備の例
以下の例は、BoxSend SGrBXsgNkPcDN2runsvWmwxk3Lh97zdgo9zaがGrand PaymentsrGPnRH1EBpHeTF2QG8DCAgM7z5pb75LAis宛てに作成した100 XRPのCheckです。追加オプションのメタデータとして、BoxSend SGはGrand Paymentsの請求書のIDを追加しています。これによりGrand PaymentsはこのCheckがどの請求書に対する支払いかを確認できます。
<!-- MULTICODE_BLOCK_START -->
*JSON-RPC、WebSocket、またはコマンドライン*
```
{
"TransactionType":"CheckCreate",
"Account":"rBXsgNkPcDN2runsvWmwxk3Lh97zdgo9za",
"Destination":"rGPnRH1EBpHeTF2QG8DCAgM7z5pb75LAis",
"SendMax":"100000000",
"InvoiceID":"46060241FABCF692D4D934BA2A6C4427CD4279083E38C77CBE642243E43BE291"
}
```
*RippleAPI*
```js
{% include '_code-samples/checks/js/prepareCreate.js' %}
```
<!-- MULTICODE_BLOCK_END -->
## {{send_n.next()}}.CheckCreateトランザクションへの署名
{% include '_snippets/tutorial-sign-step.md' %}
<!--{#_ #}-->
### 要求の例
<!-- MULTICODE_BLOCK_START -->
*RippleAPI*
```js
{% include '_code-samples/checks/js/signCreate.js' %}
```
*WebSocket*
```json
{% include '_code-samples/checks/websocket/sign-create-req.json' %}
```
*コマンドライン*
```bash
{% include '_code-samples/checks/cli/sign-create-req.sh' %}
```
<!-- MULTICODE_BLOCK_END -->
#### 応答の例
<!-- MULTICODE_BLOCK_START -->
*RippleAPI*
```js
{% include '_code-samples/checks/js/sign-create-resp.txt' %}
```
*WebSocket*
```json
{% include '_code-samples/checks/websocket/sign-create-resp.json' %}
```
*コマンドライン*
```json
{% include '_code-samples/checks/cli/sign-create-resp.txt' %}
```
<!-- MULTICODE_BLOCK_END -->
## {{send_n.next()}}.署名済みトランザクションの送信
{% set step_1_link = "#1checkcreateトランザクションの準備" %}
{% include '_snippets/tutorial-submit-step.md' %}
<!--{#_ #}-->
### 要求の例
<!-- MULTICODE_BLOCK_START -->
*RippleAPI*
```js
{% include '_code-samples/checks/js/submitCreate.js' %}
```
*WebSocket*
```json
{% include '_code-samples/checks/websocket/submit-create-req.json' %}
```
*コマンドライン*
```bash
{% include '_code-samples/checks/cli/submit-create-req.sh' %}
```
<!-- MULTICODE_BLOCK_END -->
### 応答の例
<!-- MULTICODE_BLOCK_START -->
*RippleAPI*
```js
{% include '_code-samples/checks/js/submit-create-resp.txt' %}
```
*WebSocket*
```json
{% include '_code-samples/checks/websocket/submit-create-resp.json' %}
```
*コマンドライン*
```json
{% include '_code-samples/checks/cli/submit-create-resp.txt' %}
```
<!-- MULTICODE_BLOCK_END -->
## {{send_n.next()}}.検証の待機
{% include '_snippets/wait-for-validation.md' %}
<!--{#_ #}-->
## {{send_n.next()}}.最終結果の確認
トランザクションのステータスを確認するには、CheckCreateトランザクションの識別用ハッシュを指定した[txメソッド][]を使用します。トランザクションメタデータで、トランザクションが成功したことを示す`"TransactionResult": "tesSUCCESS"`フィールドを探し、またこの結果が最終結果であることを示す`"validated": true`フィールドを結果で探します。
トランザクションのメタデータで、`LedgerEntryType``"Check"``CreatedNode`オブジェクトを探します。これは、トランザクションにより[Checkレジャーオブジェクト](check.html)が作成されたことを示します。このオブジェクトの`LedgerIndex` がCheckのIDです。以下の例ではCheckのIDは`84C61BE9B39B2C4A2267F67504404F1EC76678806C1B901EA781D1E3B4CE0CD9`です。
**注記:** RippleAPIでは、CheckCreateトランザクションの検索時にCheckのIDが報告されません。この回避策として、以下のRippleAPIコードの例に示すように[Check IDフォーマット](check.html#check-idのフォーマット)からCheckのIDを計算することができます。 <!--{# TODO: Remove this and update the code samples if ripple-lib #876 gets fixed. #}-->
### 要求の例
<!-- MULTICODE_BLOCK_START -->
*RippleAPI*
```
{% include '_code-samples/checks/js/getCreateTx.js' %}
```
*WebSocket*
```json
{% include '_code-samples/checks/websocket/tx-create-req.json' %}
```
*コマンドライン*
```bash
{% include '_code-samples/checks/cli/tx-create-req.sh' %}
```
<!-- MULTICODE_BLOCK_END -->
### 応答の例
<!-- MULTICODE_BLOCK_START -->
*RippleAPI*
```
{% include '_code-samples/checks/js/get-create-tx-resp.txt' %}
```
*WebSocket*
```json
{% include '_code-samples/checks/websocket/tx-create-resp.json' %}
```
*コマンドライン*
```json
{% include '_code-samples/checks/cli/tx-create-resp.txt' %}
```
<!-- MULTICODE_BLOCK_END -->
<!--{# common link defs #}-->
[RippleAPI]: rippleapi-reference.html
{% include '_snippets/rippled-api-links.md' %}
{% include '_snippets/tx-type-links.md' %}
{% include '_snippets/rippled_versions.md' %}

View File

@@ -0,0 +1,10 @@
# Checksの使用
XRP LedgerのChecksでは、別のアカウントが後で支払いを請求することが認められていており、個人用の紙の小切手の仕組みと似ています。
**注意:** 2018年10月11日の時点では、[Checks Amendment][]は本番環境のXRP Ledgerで有効になっていません。Checksは[XRP Test Net](xrp-test-net-faucet.html)でのみ使用できます。
<!--{# common link defs #}-->
{% include '_snippets/rippled-api-links.md' %}
{% include '_snippets/tx-type-links.md' %}
{% include '_snippets/rippled_versions.md' %}

View File

@@ -0,0 +1,130 @@
# 有効期限切れEscrowの取消し
## 1.有効期限切れEscrowの確認
XRP LedgerのEscrowが有効期限切れとなるのは、その`CancelAfter`の時刻が検証済みレジャーの`close_time`よりも前である場合です。Escrowに`CancelAfter`時刻が指定されていない場合は、Escrowが有効期限切れになることはありません。最新の検証済みレジャーの閉鎖時刻は、[ledgerメソッド][]を使用して検索できます。
要求:
<!-- MULTICODE_BLOCK_START -->
_Websocket_
```json
{% include '_code-samples/escrow/websocket/ledger-request-expiration.json' %}
```
<!-- MULTICODE_BLOCK_END -->
応答:
<!-- MULTICODE_BLOCK_START -->
_Websocket_
```json
{% include '_code-samples/escrow/websocket/ledger-response-expiration.json' %}
```
<!-- MULTICODE_BLOCK_END -->
[account_objectsメソッド][]を使用してEscrowを検索し、`CancelAfter`の時刻と比較できます。
要求:
<!-- MULTICODE_BLOCK_START -->
_Websocket_
```json
{% include '_code-samples/escrow/websocket/account_objects-request-expiration.json' %}
```
<!-- MULTICODE_BLOCK_END -->
応答:
<!-- MULTICODE_BLOCK_START -->
_Websocket_
```json
{% include '_code-samples/escrow/websocket/account_objects-response-expiration.json' %}
```
<!-- MULTICODE_BLOCK_END -->
## 2.EscrowCancelトランザクションの送信
XRP Ledgerでは、[EscrowCancelトランザクション][]に[署名して送信する](transaction-basics.html#トランザクションへの署名とトランザクションの送信)ことで、***誰でも***有効期限切れのEscrowを取り消すことができます。トランザクションの`Owner`フィールドを、そのEscrowを作成した`EscrowCreate`トランザクションの`Account`に設定します。`OfferSequence`フィールドを、`EscrowCreate`トランザクションの`Sequence`に設定します。
{% include '_snippets/secret-key-warning.md' %} <!--#{ fix md highlighting_ #}-->
要求:
<!-- MULTICODE_BLOCK_START -->
_Websocket_
```json
{% include '_code-samples/escrow/websocket/submit-request-escrowcancel.json' %}
```
<!-- MULTICODE_BLOCK_END -->
応答:
<!-- MULTICODE_BLOCK_START -->
_Websocket_
```json
{% include '_code-samples/escrow/websocket/submit-response-escrowcancel.json' %}
```
<!-- MULTICODE_BLOCK_END -->
トランザクションの識別用`hash`値をメモしておきます。これにより、検証済みレジャーバージョンに記録されるときにその最終ステータスを確認できます。
## 3.検証の待機
{% include '_snippets/wait-for-validation.md' %} <!--#{ fix md highlighting_ #}-->
## 4.最終結果の確認
EscrowCancelトランザクションの識別用ハッシュを指定した[txメソッド][]を使用してトランザクションの最終ステータスを確認します。トランザクションのメタデータで`LedgerEntryType``Escrow`である`DeletedNode`を探します。また、エスクローに預託された支払いの送金元の`ModifiedNode`(タイプが`AccountRoot`)も探します。オブジェクトの`FinalFields`に、`Balance`フィールドのXRP返金額の増分が表示されている必要があります。
要求:
<!-- MULTICODE_BLOCK_START -->
_Websocket_
```json
{% include '_code-samples/escrow/websocket/tx-request-escrowcancel.json' %}
```
<!-- MULTICODE_BLOCK_END -->
応答:
<!-- MULTICODE_BLOCK_START -->
_Websocket_
```json
{% include '_code-samples/escrow/websocket/tx-response-escrowcancel.json' %}
```
<!-- MULTICODE_BLOCK_END -->
上記の例では、`r3wN3v2vTUkr5qd6daqDc2xE4LSysdVjkT`がEscrowの送金元であり、`Balance`が99999**8**9990 dropから99999**9**9990 dropに増加していることから、エスクローに預託されていた10,000 XRP dropが返金されたことがわかりますdrop = 0.01XRP
**ヒント:** Escrowを実行する[EscrowFinishトランザクション][]で使用する`OfferSequence`が不明な場合は、Escrowの`PreviousTxnID`フィールドのトランザクションの識別用ハッシュを指定した[txメソッド][]を使用して、そのEscrowを作成したトランザクションを検索します。Escrowを終了するときには、そのトランザクションの`Sequence`の値を`OfferSequence`の値として使用します。
{% include '_snippets/tx-type-links.md' %}
{% include '_snippets/rippled_versions.md' %}
{% include '_snippets/rippled-api-links.md' %}

View File

@@ -0,0 +1,82 @@
# Escrowの検索
保留中のEscrowはすべて[Escrowオブジェクト](escrow.html)としてレジャーに保管されます。
Escrowオブジェクトを検索するには、[account_objectsメソッド][]で[送金元のアドレス](#送金元のアドレスによるescrowの検索)または[送金先のアドレス](#送金先のアドレスによるescrowの検索)を使用して検索します。
## 送金元のアドレスによるEscrowの検索
[account_objectsメソッド][]を使用して、送金元アドレスからEscrowオブジェクトを検索できます。
たとえば、送金元アドレスが`rfztBskAVszuS3s5Kq7zDS74QtHrw893fm`である保留中のEscrowオブジェクトをすべて検索するとします。以下の要求の例に従ってこの検索を実行できます。この例では送金元アドレスは`account`の値です。
要求:
<!-- MULTICODE_BLOCK_START -->
_Websocket_
```json
{% include '_code-samples/escrow/websocket/account_objects-request.json' %}
```
<!-- MULTICODE_BLOCK_END -->
応答は以下の例のようになります。この応答には、送金元アドレスまたは送金先アドレスが`rfztBskAVszuS3s5Kq7zDS74QtHrw893fm`である保留中のEscrowオブジェクトがすべて含まれています。送金元アドレスは`Account`の値であり、送金先アドレスは`Destination`の値です。
この例では、2番目と4番目のEscrowオブジェクトが検索条件に一致しています。これは、これらのオブジェクトの`Account`(送金元のアドレス)の値が`rfztBskAVszuS3s5Kq7zDS74QtHrw893fm`に設定されているためです。
応答:
<!-- MULTICODE_BLOCK_START -->
_Websocket_
```json
{% include '_code-samples/escrow/websocket/account_objects-response.json' %}
```
<!-- MULTICODE_BLOCK_END -->
## 送金先のアドレスによるEscrowの検索
[account_objectsメソッド][]を使用して、送金先アドレスからEscrowオブジェクトを検索できます。
**注記:** 送金先のアドレスによる保留中のEscrowオブジェクトの検索は、[fix1523 Amendment][]が2017/11/14に有効化された後に作成されたEscrowについてのみ行うことができます。
たとえば、送金先アドレスが`rfztBskAVszuS3s5Kq7zDS74QtHrw893fm`である保留中のEscrowオブジェクトをすべて検索するとします。以下の要求の例に従ってこの検索を実行できます。この例では送金先アドレスは`account`の値です。
要求:
<!-- MULTICODE_BLOCK_START -->
_Websocket_
```json
{% include '_code-samples/escrow/websocket/account_objects-request.json' %}
```
<!-- MULTICODE_BLOCK_END -->
応答は以下の例のようになります。応答には送金先アドレスまたは送金元アドレスが`rfztBskAVszuS3s5Kq7zDS74QtHrw893fm`である保留中のEscrowオブジェクトがすべて含まれています。送金先アドレスは`Destination`の値であり、送金元アドレスは`Account`の値です。
この例では、1番目と3番目のEscrowオブジェクトが検索条件に一致しています。これは、これらのオブジェクトの`Destination`(送金先のアドレス)の値が`rfztBskAVszuS3s5Kq7zDS74QtHrw893fm`に設定されているためです。
応答:
<!-- MULTICODE_BLOCK_START -->
_Websocket_
```json
{% include '_code-samples/escrow/websocket/account_objects-response.json' %}
```
<!-- MULTICODE_BLOCK_END -->
{% include '_snippets/tx-type-links.md' %}
{% include '_snippets/rippled_versions.md' %}
{% include '_snippets/rippled-api-links.md' %}

View File

@@ -0,0 +1,187 @@
# 条件に基づくEscrowの送信
## 1.条件とフルフィルメントの生成
XRP Ledger EscrowにはPREIMAGE-SHA-256 [Crypto-Conditions](https://tools.ietf.org/html/draft-thomas-crypto-conditions-03)が必要です。条件とフルフィルメントを適切なフォーマットで計算するには、[five-bells-condition](https://github.com/interledgerjs/five-bells-condition)などのCrypto-conditionsライブラリを使用する必要があります。フルフィルメントについては、以下のフルフィルメントを生成するためのメソッドのいずれかを使用することが推奨されます。
- 暗号論的に安全な乱数ソースを使用して、32バイト以上のランダムバイトを生成します。
- Interledger Protocolの[PSK仕様](https://github.com/interledger/rfcs/blob/master/deprecated/0016-pre-shared-key/0016-pre-shared-key.md)に従い、ILPパケットのHMAC-SHA-256をフルフィルメントとして使用します。
ランダムなフルフィルメントと条件のJavaScriptコードの例:
```js
const cc = require('five-bells-condition')
const crypto = require('crypto')
const preimageData = crypto.randomBytes(32)
const myFulfillment = new cc.PreimageSha256()
myFulfillment.setPreimage(preimageData)
const condition = myFulfillment.getConditionBinary().toString('hex').toUpperCase()
console.log('Condition:', condition)
// (Random hexadecimal, 72 chars in length)
// keep secret until you want to finish executing the held payment:
const fulfillment = myFulfillment.serializeBinary().toString('hex').toUpperCase()
console.log('Fulfillment:', fulfillment)
// (Random hexadecimal, 78 chars in length)
```
後で使用できるように条件とフルフィルメントを保存します。保留中の支払いの実行が完了するまでは、フルフィルメントを公開しないでください。フルフィルメントを知っていれば誰でもEscrowを終了でき、保留中の資金を指定された送金先にリリースできます。
## 2.リリース時刻または取消し時刻の計算
条件付き`Escrow`トランザクションには、`CancelAfter`フィールドと`FinishAfter`フィールドのいずれか、または両方が含まれている必要があります。`CancelAfter`フィールドを使用すると、指定の時刻までに条件を満たすことができなかった場合に送金元へXRPを返金できます。`FinishAfter`フィールドに指定される時刻より前の時間は、正しいフルフィルメントが送信されてもEscrowを実行できません。いずれのフィールドでも、将来の時刻を指定する必要があります。
`CancelAfter`の時刻を24時間先に設定する例:
<!-- MULTICODE_BLOCK_START -->
_JavaScript_
```js
const rippleOffset = 946684800
const CancelAfter = Math.floor(Date.now() / 1000) + (24*60*60) - rippleOffset
console.log(CancelAfter)
// Example:556927412
```
<!--{# Striking Python example for now since we don't have full examples
_Python 2/3_
```python
from time import time
ripple_offset = 946684800
cancel_after = int(time()) + (24*60*60) - 946684800
print(cancel_after)
# Example: 556927412
```
#}-->
<!-- MULTICODE_BLOCK_END -->
**警告:** XRP Ledgerでは、時刻を**Rippleエポック2000-01-01T00:00:00Z以降の経過秒数**として指定する必要があります。`CancelAfter`または`FinishAfter`フィールドで、UNIX時刻を同等のRipple時刻に変換せずに使用すると、ロック解除時刻が**30年**先に設定されることになります。
## 3.EscrowCreateトランザクションの送信
[EscrowCreateトランザクション][]に[署名して送信](transaction-basics.html#トランザクションへの署名とトランザクションの送信)します。トランザクションの`Condition`フィールドを、保留中の支払いがリリースされる時刻に設定します。`Destination`を受取人に設定します。受取人と送金元のアドレスは同じでもかまいません。前の手順で算出した`CancelAfter`または`FinishAfter`の時刻も指定します。`Amount`を、Escrowする[XRP、drop単位][]の合計額に設定します。
{% include '_snippets/secret-key-warning.md' %} <!--#{ fix md highlighting_ #}-->
要求:
<!-- MULTICODE_BLOCK_START -->
*Websocket*
```json
{% include '_code-samples/escrow/websocket/submit-request-escrowcreate-condition.json' %}
```
<!-- MULTICODE_BLOCK_END -->
応答:
<!-- MULTICODE_BLOCK_START -->
*Websocket*
```json
{% include '_code-samples/escrow/websocket/submit-response-escrowcreate-condition.json' %}
```
<!-- MULTICODE_BLOCK_END -->
## 4.検証の待機
{% include '_snippets/wait-for-validation.md' %} <!--#{ fix md highlighting_ #}-->
## 5.Escrowが作成されたことの確認
トランザクションの識別用ハッシュを指定した[txメソッド][]を使用して、トランザクションの最終ステータスを確認します。特に、[Escrowレジャーオブジェクト](escrow.html)が作成されたことを示す`CreatedNode`をトランザクションメタデータで探します。
要求:
<!-- MULTICODE_BLOCK_START -->
*Websocket*
```json
{% include '_code-samples/escrow/websocket/tx-request-escrowcreate-condition.json' %}
```
<!-- MULTICODE_BLOCK_END -->
応答:
<!-- MULTICODE_BLOCK_START -->
*Websocket*
```json
{% include '_code-samples/escrow/websocket/tx-response-escrowcreate-condition.json' %}
```
<!-- MULTICODE_BLOCK_END -->
## 6.EscrowFinishトランザクションの送信
`FinishAfter`の時刻が経過した後で資金のリリースを実行する[EscrowFinishトランザクション][]に[署名して送信](transaction-basics.html#トランザクションへの署名とトランザクションの送信)します。トランザクションの`Owner`フィールドにEscrowCreateトランザクションの`Account`アドレスを設定し、`OfferSequence` にEscrowCreateトランザクションの`Sequence`番号を設定します。`Condition`フィールドと`Fulfillment`フィールドに、ステップ1で生成した条件値とフルフィルメント値をそれぞれ16進数で設定します。フルフィルメントのサイズバイト数に基づいて`Fee`[トランザクションコスト](transaction-cost.html)の値を設定します。条件付きEscrowFinishでは、少なくとも330 dropXRPと、フルフィルメントのサイズで16バイトごとに10 dropが必要です。
**注記:** EscrowCreateトランザクションに`FinishAfter`フィールドが含まれている場合、Escrowの条件として正しいフルフィルメントを指定しても、この時刻よりも前の時点ではこのトランザクションを実行できません。前に閉鎖されたレジャーの閉鎖時刻が`FinishAfter`の時刻よりも前である場合、EscrowFinishトランザクションは[結果コード](transaction-results.html)`tecNO_PERMISSION`で失敗します。
Escrowが有効期限切れの場合は、[Escrowの取消し](cancel-an-expired-escrow.html)だけが可能です。
{% include '_snippets/secret-key-warning.md' %} <!--#{ fix md highlighting_ #}-->
<!-- MULTICODE_BLOCK_START -->
_Websocket_
```json
{% include '_code-samples/escrow/websocket/submit-request-escrowfinish-condition.json' %}
```
<!-- MULTICODE_BLOCK_END -->
応答:
<!-- MULTICODE_BLOCK_START -->
_Websocket_
```json
{% include '_code-samples/escrow/websocket/submit-response-escrowfinish-condition.json' %}
```
<!-- MULTICODE_BLOCK_END -->
トランザクションの識別用`hash`値をメモしておきます。これにより、検証済みレジャーバージョンに記録されるときにその最終ステータスを確認できます。
## 7.検証の待機
{% include '_snippets/wait-for-validation.md' %} <!--#{ fix md highlighting_ #}-->
## 8.最終結果の確認
EscrowFinishトランザクションの識別用ハッシュを指定した[txメソッド][]を使用して、トランザクションの最終ステータスを確認します。特にトランザクションメタデータ内で、エスクローに預託された支払いの送金先の`ModifiedNode`(タイプが`AccountRoot`)を確認します。オブジェクトの`FinalFields`に、`Balance`フィールドのXRP返金額の増分が表示されている必要があります。
要求:
```json
{% include '_code-samples/escrow/websocket/tx-request-escrowfinish-condition.json' %}
```
応答:
```json
{% include '_code-samples/escrow/websocket/tx-response-escrowfinish-condition.json' %}
```
<!--{# common link defs #}-->
{% include '_snippets/rippled-api-links.md' %}
{% include '_snippets/tx-type-links.md' %}
{% include '_snippets/rippled_versions.md' %}

View File

@@ -0,0 +1,207 @@
# 時間に基づくEscrowの送信
[EscrowCreateトランザクション][]タイプでは、リリースの唯一の条件が特定時刻を経過することであるEscrowを作成できます。このためには、`FinishAfter`フィールドを使用し、`Condition`フィールドを省略します。
## 1.リリース時刻の計算
時刻を **[Rippleエポック以降の経過秒数][]** として指定する必要があります。Rippleエポックは、UNIXエポックの946684800秒後です。たとえば、2017年11月13日の午前0時UTCに資金をリリースする場合、以下のようになります。
<!-- MULTICODE_BLOCK_START -->
*JavaScript*
```js
// JavaScript Date() is natively expressed in milliseconds; convert to seconds
const release_date_unix = Math.floor( new Date("2017-11-13T00:00:00Z") / 1000 );
const release_date_ripple = release_date_unix - 946684800;
console.log(release_date_ripple);
// 563846400
```
<!--{# //Python code works OK but we don't have full examples, so hiding it
*Python 3*
```python
import datetime
release_date_utc = datetime.datetime(2017,11,13,0,0,0,tzinfo=datetime.timezone.utc)
release_date_ripple = int(release_date_utc.timestamp()) - 946684800
print(release_date_ripple)
# 563846400
```
#}-->
<!-- MULTICODE_BLOCK_END -->
**警告:** `FinishAfter`フィールドで、UNIX時刻を同等のRipple時刻に変換せずに使用すると、ロック解除時刻が30年先に設定されることになります。
## 2.EscrowCreateトランザクションの送信
[EscrowCreateトランザクション][]に[署名して送信](transaction-basics.html#トランザクションへの署名とトランザクションの送信)します。トランザクションの`FinishAfter`フィールドを、保留中の支払いがリリースされる時刻に設定します。`Condition`フィールドを省略して、時刻を保留中の支払いをリリースする唯一の条件とします。`Destination`を受取人に設定します。受取人と送金元のアドレスは同じでもかまいません。`Amount`を、Escrowする[XRP、drop単位][]の合計額に設定します。
{% include '_snippets/secret-key-warning.md' %} <!--#{ fix md highlighting_ #}-->
要求:
<!-- MULTICODE_BLOCK_START -->
*Websocket*
```json
{% include '_code-samples/escrow/websocket/submit-request-escrowcreate-time.json' %}
```
<!-- MULTICODE_BLOCK_END -->
応答:
<!-- MULTICODE_BLOCK_START -->
*Websocket*
```json
{% include '_code-samples/escrow/websocket/submit-response-escrowcreate-time.json' %}
```
<!-- MULTICODE_BLOCK_END -->
トランザクションの識別用`hash`値をメモしておきます。これにより、検証済みレジャーバージョンに記録されるときにその最終ステータスを確認できます。
## 3.検証の待機
{% include '_snippets/wait-for-validation.md' %} <!--#{ fix md highlighting_ #}-->
## 4.Escrowが作成されたことの確認
トランザクションの識別用ハッシュを指定した[txメソッド][]を使用して、トランザクションの最終ステータスを確認します。[Escrowレジャーオブジェクト](escrow.html)が作成されたことを示す`CreatedNode`をトランザクションメタデータで探します。
要求:
<!-- MULTICODE_BLOCK_START -->
*Websocket*
```json
{% include '_code-samples/escrow/websocket/tx-request-escrowcreate-time.json' %}
```
<!-- MULTICODE_BLOCK_END -->
応答:
<!-- MULTICODE_BLOCK_START -->
*Websocket*
```json
{% include '_code-samples/escrow/websocket/tx-response-escrowcreate-time.json' %}
```
<!-- MULTICODE_BLOCK_END -->
## 5.リリース時刻までの待機
`FinishAfter`時刻が指定されている保留中の支払いは、Escrowードの`FinishAfter`時刻よりも後の[`close_time`ヘッダーフィールド](ledger-header.html)の時刻でレジャーが閉鎖するまでは完了できません。
最新の検証済みレジャーの閉鎖時刻は、[ledgerメソッド][]を使用して検索できます。
要求:
<!-- MULTICODE_BLOCK_START -->
*Websocket*
```json
{% include '_code-samples/escrow/websocket/ledger-request.json' %}
```
<!-- MULTICODE_BLOCK_END -->
応答:
<!-- MULTICODE_BLOCK_START -->
*Websocket*
```json
{% include '_code-samples/escrow/websocket/ledger-response.json' %}
```
<!-- MULTICODE_BLOCK_END -->
## 6.EscrowFinishトランザクションの送信
`FinishAfter`の時刻が経過した後で資金のリリースを実行する[EscrowFinishトランザクション][]に[署名して送信](transaction-basics.html#トランザクションへの署名とトランザクションの送信)します。トランザクションの`Owner`フィールドにEscrowCreateトランザクションの`Account`アドレスを設定し、`OfferSequence` にEscrowCreateトランザクションの`Sequence`番号を設定します。時刻のみに基づいて保留されているEscrowの場合は、`Condition`フィールドと`Fulfillment`フィールドを省略します。
**ヒント:** XRP Ledgerの状態はトランザクションでしか変更できないため、EscrowFinishトランザクションが必要です。このトランザクションの送信者は、Escrowの受取人、Escrowの元としての送金人、またはその他のXRP Ledgerアドレスのいずれかです。
Escrowが有効期限切れの場合は、[Escrowの取消し](cancel-an-expired-escrow.html)だけが可能です。
{% include '_snippets/secret-key-warning.md' %} <!--#{ fix md highlighting_ #}-->
要求:
<!-- MULTICODE_BLOCK_START -->
*Websocket*
```json
{% include '_code-samples/escrow/websocket/submit-request-escrowfinish-time.json' %}
```
<!-- MULTICODE_BLOCK_END -->
応答:
<!-- MULTICODE_BLOCK_START -->
*Websocket*
```json
{% include '_code-samples/escrow/websocket/submit-response-escrowfinish-time.json' %}
```
<!-- MULTICODE_BLOCK_END -->
トランザクションの識別用`hash`値をメモしておきます。これにより、検証済みレジャーバージョンに記録されるときにその最終ステータスを確認できます。
## 7.検証の待機
{% include '_snippets/wait-for-validation.md' %} <!--#{ fix md highlighting_ #}-->
## 8.最終結果の確認
EscrowFinishトランザクションの識別用ハッシュを指定した[txメソッド][]を使用して、トランザクションの最終ステータスを確認します。特にトランザクションメタデータ内で、エスクローに預託された支払いの送金先の`ModifiedNode`(タイプが`AccountRoot`)を確認します。オブジェクトの`FinalFields`に、`Balance`フィールドのXRP返金額の増分が表示されている必要があります。
要求:
<!-- MULTICODE_BLOCK_START -->
*Websocket*
```json
{% include '_code-samples/escrow/websocket/tx-request-escrowfinish-time.json' %}
```
<!-- MULTICODE_BLOCK_END -->
応答:
<!-- MULTICODE_BLOCK_START -->
*Websocket*
```json
{% include '_code-samples/escrow/websocket/tx-response-escrowfinish-time.json' %}
```
<!-- MULTICODE_BLOCK_END -->
<!--{# common link defs #}-->
{% include '_snippets/rippled-api-links.md' %}
{% include '_snippets/tx-type-links.md' %}
{% include '_snippets/rippled_versions.md' %}

View File

@@ -0,0 +1,607 @@
# Payment Channelの使用
Payment Channelは、少額の単位に分割可能な「非同期」のXRPペイメントを送信し、後日決済する高度な機能です。このチュートリアルでは、全体的な[Payment Channel](payment-channels.html)の使用方法を、ローカル`rippled`サーバーの[JSON-RPC API](rippled-api.html)を使用する例を使って説明します。
このチュートリアルを進めるにあたって[資金供給されているXRP Ledgerアカウント](accounts.html)を所有するユーザーが2名いれば理想的です。ただし、2つのXRP Ledgerアドレスを管理する1名のユーザーとしてこのチュートリアルを進めることもできます。
## サンプルの値
このチュートリアルでは、例として以下のアドレスを使用します。
| | |
|--|--|
| **支払人のアドレス** | rN7n7otQDd6FczFgLdSqtcsAUxDkw6fzRH |
| **Channelに使用する公開鍵XRP Ledgerの[base58][]エンコード文字列フォーマット)** | aB44YfzW24VDEJQ2UuLPV2PvqcPCSoLnL7y5M1EzhdW4LnK5xMS3
| **Channelに使用する公開鍵16進数** | 023693F15967AE357D0327974AD46FE3C127113B1110D6044FD41E723689F81CC6 |
| **受取人のアドレス** | rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn |
**ヒント:** この例では、Channelの公開鍵は支払人のマスターキーペアの公開鍵です。これは完全に安全であり有効です。また、支払人のみが異なるキーペアの公開鍵と秘密鍵を把握している場合に限り、そのキーペアを使用することも完全に安全であり有効です。 <!-- Editor's note: We don't have a good page to link to explain key pairs as of time of this writing. -->
また、トランザクションの送信先`rippled`サーバーも必要です。このチュートリアルの例では、`rippled`サーバーがテストマシン(`localhost`)で稼働しており、このテストマシンはポート**5005**で非暗号化JSON-RPC APIエンドポイントに接続しています。
実際のXRPを送金せずにテストを実施するには、Test Net XRPを保有する[XRP Ledger Testnet](xrp-testnet-faucet.html)のアドレスを使用できます。XRP Ledger Test Netを使用する場合、`http://localhost:5005/`ではなく`https://api.altnet.rippletest.net:51234`に接続することで、Test NetサーバーのJSON-RPC APIを使用できます。
Payment Channelに使用できるXRPの額に制限はありません。このチュートリアルで使用されているサンプルの値では、Payment Channelで100 XRP`100000000` dropが少なくとも1日間は確保されます。
## フローチャート
[フローチャート]: #フローチャート
次の図は、Payment Channelのライフサイクルの概要を示します。
[![Payment Channelフローチャート](img/paychan-flow.ja.png)](img/paychan-flow.ja.png)
この図のステップの番号は、このチュートリアルのステップの番号に対応しています。
1. [支払人: Channelの作成](#1-支払人が特定の受取人へのpayment-channelを作成します)
2. [受取人: Channelの確認](#2-受取人がpayment-channelの特性を確認します)
3. [支払人: クレームへの署名](#3-支払人がchannelのxrpに対して1つ以上の署名付き-クレーム-を作成します)
4. [支払人: 受取人へのクレームの送信](#4-支払人が商品またはサービスに対する支払いとしてクレームを受取人に送信します)
5. [受取人: クレームの検証](#5-受取人がクレームを検証します)
6. [受取人: 商品またはサービスの提供](#6-受取人が商品またはサービスを提供します)
7. [必要に応じてステップ36を繰り返す](#7-必要に応じてステップ36を繰り返します)
8. [受取人: クレームの清算](#8-準備が完了すれば受取人は承認された額のクレームを清算します)
9. [支払人: Channel閉鎖の要求](#9-支払人と受取人の取引完了後支払人はchannelの閉鎖を要求します)
10. [支払人(またはその他の担当者): 有効期限切れChannelの閉鎖](#10-有効期限切れのchannelは誰でも閉鎖できます)
## 1. 支払人が特定の受取人へのPayment Channelを作成します。
これは[PaymentChannelCreateトランザクション][]です。このプロセスでは、支払人がChannelの特定の特性有効期限、決済遅延など、Channelのクレームに関する保証に影響する特性を設定します。支払人は、Channelに対するクレームの検証に使用する公開鍵も設定します。 <!-- STYLE_OVERRIDE: will -->
**ヒント:** 「決済遅延」の設定だけが決済を遅延するわけでわありません。レジャーバージョンが閉鎖すると即時に決済が遅延されます35秒。「決済遅延」とは、Channel閉鎖の強制的な遅延です。これにより、受取人が決済を完了できるようになります。
以下の例は、JSON-RPC APIを使用してローカル`rippled`サーバーへ[送信](submit.html#署名と送信モード)することでPayment Channelを作成する方法を示しています。Payment Channelは、決済を1日遅らせて[サンプルの支払人](#サンプルの値)rN7n7...)から[サンプルの受取人](#サンプルの値)rf1Bi...に100 XRPを割り当てます。公開鍵はサンプルの支払人のマスター公開鍵16進数です。
**注記:** Payment Channelは1つのオブジェクトとして支払人の[所有者準備金](reserves.html#所有者準備金)に反映されます。所有者は少なくとも、Payment Channelに割り当てられたXRPを差引き後に、準備金を維持するのに十分なXRPを保有している必要があります。
要求:
POST http://localhost:5005/
Content-Type: application/json
{
"method": "submit",
"params": [{
"secret": "s████████████████████████████",
"tx_json": {
"Account": "rN7n7otQDd6FczFgLdSqtcsAUxDkw6fzRH",
"TransactionType": "PaymentChannelCreate",
"Amount": "100000000",
"Destination": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
"SettleDelay": 86400,
"PublicKey": "023693F15967AE357D0327974AD46FE3C127113B1110D6044FD41E723689F81CC6",
"DestinationTag": 20170428
},
"fee_mult_max": 1000
}]
}
応答:
200 OK
{
"result": {
"engine_result": "tesSUCCESS",
"engine_result_code": 0,
"engine_result_message": "The transaction was applied.Only final in a validated ledger.",
...
"tx_json": {
...
"TransactionType": "PaymentChannelCreate",
"hash": "3F93C482C0BC2A1387D9E67DF60BECBB76CC2160AE98522C77AF0074D548F67D"
}
}
}
`submit`要求に対する直接の応答には、トランザクションを識別する`hash`値を含む _暫定的な_ 結果が含まれています。支払人は、検証済みレジャーでトランザクションの _最終_ 結果を確認し、メタデータからChannel IDを取得する必要があります。この処理は`tx`コマンドを使用して実行できます。
要求:
POST http://localhost:5005/
Content-Type: application/json
{
"method": "tx",
"params": [{
"transaction": "3F93C482C0BC2A1387D9E67DF60BECBB76CC2160AE98522C77AF0074D548F67D"
}]
}
応答:
200 OK
{
"result": {
"Account": "rN7n7otQDd6FczFgLdSqtcsAUxDkw6fzRH",
"Amount": "100000000",
"Destination": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
...
"TransactionType": "PaymentChannelCreate",
...
"hash": "3F93C482C0BC2A1387D9E67DF60BECBB76CC2160AE98522C77AF0074D548F67D",
"inLedger": 29380080,
"ledger_index": 29380080,
"meta": {
"AffectedNodes": [
...
{
"CreatedNode": {
"LedgerEntryType": "PayChannel",
"LedgerIndex": "5DB01B7FFED6B67E6B0414DED11E051D2EE2B7619CE0EAA6286D67A3A4D5BDB3",
"NewFields": {
"Account": "rN7n7otQDd6FczFgLdSqtcsAUxDkw6fzRH",
"Amount": "100000000",
"Destination": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
"DestinationTag": 20170428,
"PublicKey": "023693F15967AE357D0327974AD46FE3C127113B1110D6044FD41E723689F81CC6",
"SettleDelay": 86400
}
}
},
...
],
"TransactionIndex": 16,
"TransactionResult": "tesSUCCESS"
},
"status": "success",
"validated": true
}
}
支払人はJSON-RPCからの応答で以下を確認する必要があります。
- トランザクションの`meta`フィールドで、`TransactionResult``tesSUCCESS`であることを確認します。
- データが検証済みレジャーのデータであることを示す`"validated":true`が応答に含まれていることを確認します。(結果`tesSUCCESS`は、検証済みレジャーバージョンに記録されている場合にのみ[最終的な](finality-of-results.html)結果です。)
- トランザクションの`meta`フィールドの`AffectedNodes`配列で、`LedgerEntryType``PayChannel`である`CreatedNode`オブジェクトを検索します。`CreatedNode`オブジェクトの`LedgerIndex`フィールドはChannel IDを示します。上記の例では、これは「5DB0...」で始まる16進文字列です。Channel IDは、後でクレームに署名する際に必要です。
PayChannelレジャーオブジェクトタイプの詳細については、[PayChannelレジャーオブジェクト](paychannel.html)を参照してください。
## 2. 受取人がPayment Channelの特性を確認します。
Payment Channelを見つけるには、以下の例JSON-RPC APIを使用に示すようにChannelの支払人を指定した[account_channelsメソッド][]を使用します。
要求:
POST http://localhost:5005/
Content-Type: application/json
{
"method": "account_channels",
"params": [{
"account": "rN7n7otQDd6FczFgLdSqtcsAUxDkw6fzRH",
"destination_account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
"ledger_index": "validated"
}]
}
応答:
200 OK
{
"result": {
"account": "rN7n7otQDd6FczFgLdSqtcsAUxDkw6fzRH",
"channels": [{
"account": "rN7n7otQDd6FczFgLdSqtcsAUxDkw6fzRH",
"amount": "100000000",
"balance": "0",
"channel_id": "5DB01B7FFED6B67E6B0414DED11E051D2EE2B7619CE0EAA6286D67A3A4D5BDB3",
"destination_account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
"destination_tag": 20170428,
"public_key": "aB44YfzW24VDEJQ2UuLPV2PvqcPCSoLnL7y5M1EzhdW4LnK5xMS3",
"public_key_hex": "023693F15967AE357D0327974AD46FE3C127113B1110D6044FD41E723689F81CC6",
"settle_delay": 86400
}],
"status": "success"
}
}
受取人は、以下のすべての点を含め、Payment Channelのパラメーターが特定のユースケースに適していることを確認します。
- `destination_account`フィールドに受取人の正しいアドレスが指定されていることを確認します。
- `settle_delay`フィールドに、受取人が未処理のクレームを清算するのに十分な決済遅延期間が秒単位で指定されていることを確認します。
- `cancel_after`(変更できない有効期限)フィールドと`expiration`(変更できる有効期限)フィールドが含まれている場合は、これらのフィールドの値が早過ぎないことを確認します。受取人はこれらの時刻をメモして、それらの時刻より前にクレームを清算できるようにします。
- `public_key`フィールドと`channel_id`フィールドをメモします。これらのフィールドは、後でクレームを検証、清算する際に必要です。
- _省略可_`destination_tag`フィールドが存在しており、必要な宛先タグが指定されていることを確認します。
2名の当事者間に複数のChannelが存在している可能性があるため、受取人が正しいChannelのクオリティを確認することが重要です。混乱する場合は、使用するChannelのChannel ID`channel_id`)を支払人が明確にする必要があります。
## 3. 支払人がChannelのXRPに対して1つ以上の署名付き _クレーム_ を作成します。
これらのクレームの額は、支払人が購入する具体的な商品またはサービスに応じて異なります。
各クレームの額は累計額でなければなりません。つまり、2つのアイテムをそれぞれ10 XRPで購入する場合、1番目のクレームの額は10 XRPで、2番目のクレームの額は20 XRPである必要があります。クレームは、Channelに割り当てられているXRPの合計額を超えることはありません。[PaymentChannelFund][]トランザクションでは、Channelに割り当てられるXRPの合計額を増加できます。
[channel_authorizeメソッド][]を使用してクレームを作成できます。以下の例では、Channelから1 XRPが承認されます。
要求:
POST http://localhost:5005/
Content-Type: application/json
{
"method": "channel_authorize",
"params": [{
"channel_id": "5DB01B7FFED6B67E6B0414DED11E051D2EE2B7619CE0EAA6286D67A3A4D5BDB3",
"secret": "s████████████████████████████",
"amount": "1000000"
}]
}
応答:
{
"result": {
"signature": "304402204EF0AFB78AC23ED1C472E74F4299C0C21F1B21D07EFC0A3838A420F76D783A400220154FB11B6F54320666E4C36CA7F686C16A3A0456800BBC43746F34AF50290064",
"status": "success"
}
}
## 4. 支払人が、商品またはサービスに対する支払いとしてクレームを受取人に送信します。
この通信は、支払人と受取人が合意できる通信システムで「レジャー外」で行われます。これには安全な通信を使用する必要がありますが、必須ではありません。Channelの支払人または受取人がそのChannelに対するクレームを清算できます。
クレームで以下の情報が伝達される限り、クレームの厳密なフォーマットは重要ではありません。
| フィールド | 例 |
|:------------------------|:---------------------------------------------------|
| Channel ID | `5DB01B7FFED6B67E6B0414DED11E051D2EE2B7619CE0EAA6286D67A3A4D5BDB3` |
| XRPの額drop単位 | `1000000` |
| 署名 | `304402204EF0AFB78AC23ED1C472E74F4299C0C21F1B21D07EFC0A3838A420F76D783A` <br/> `400220154FB11B6F54320666E4C36CA7F686C16A3A0456800BBC43746F34AF50290064` _注記: この長い文字列は1行に収まるように改行されています_ |
受取人は、Channelに関連付けられている公開鍵も把握する必要があります。この鍵は、Channelの存続期間中変更されることはありません。
## 5. 受取人がクレームを検証します。
[channel_verifyメソッド][]を使用してクレームを検証できます。受取人は、クレームの額が提供した商品およびサービスの合計価格以上であることを確認する必要があります。(金額は累計額であるため、これまでに購入されたすべての商品およびサービスの合計価格です。)
JSON-RPC APIで`channel_verify`を使用する例:
要求:
POST http://localhost:5005/
Content-Type: application/json
{
"method": "channel_verify",
"params": [{
"channel_id": "5DB01B7FFED6B67E6B0414DED11E051D2EE2B7619CE0EAA6286D67A3A4D5BDB3",
"signature": "304402204EF0AFB78AC23ED1C472E74F4299C0C21F1B21D07EFC0A3838A420F76D783A400220154FB11B6F54320666E4C36CA7F686C16A3A0456800BBC43746F34AF50290064",
"public_key": "aB44YfzW24VDEJQ2UuLPV2PvqcPCSoLnL7y5M1EzhdW4LnK5xMS3",
"amount": "1000000"
}]
}
応答:
200 OK
{
"result": {
"signature_verified":true,
"status":"success"
}
}
応答に`"signature_verified": true`が含まれている場合、クレームの署名は真正です。受取人は、クレームを換金できる十分なXRPがChannelにあること**も**確認する必要があります。このためには、受取人は[account_channelsメソッド][]を使用して、Payment Channelの最新の検証済み状態を確認します。
要求:
POST http://localhost:5005/
Content-Type: application/json
{
"method": "account_channels",
"params": [{
"account": "rN7n7otQDd6FczFgLdSqtcsAUxDkw6fzRH",
"destination_account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
"ledger_index": "validated"
}]
}
応答:
200 OK
{
"result": {
"account": "rN7n7otQDd6FczFgLdSqtcsAUxDkw6fzRH",
"channels": [{
"account": "rN7n7otQDd6FczFgLdSqtcsAUxDkw6fzRH",
"amount": "100000000",
"balance": "0",
"channel_id": "5DB01B7FFED6B67E6B0414DED11E051D2EE2B7619CE0EAA6286D67A3A4D5BDB3",
"destination_account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
"destination_tag": 20170428,
"public_key": "aB44YfzW24VDEJQ2UuLPV2PvqcPCSoLnL7y5M1EzhdW4LnK5xMS3",
"public_key_hex": "023693F15967AE357D0327974AD46FE3C127113B1110D6044FD41E723689F81CC6",
"settle_delay": 86400
}],
"status": "success"
}
}
受取人は以下の点を確認する必要があります:
- `channel_id`がクレームのChannel IDと一致する`channels`配列のオブジェクトを見つけます。同一の当事者間であっても複数のPayment Channelが存在していることがありますが、クレームはIDが一致するChannelでのみ清算できます。
- Channelの`expiration`(変更可能な有効期限)がある場合は、この期限が早過ぎないことを確認します。受取人はこの期限の前にクレームを清算する必要があります。
- クレームの`amount`がChannelの`amount`以下であることを確認します。クレームの`amount`の方が大きい場合、支払人が[PaymentChannelFundトランザクション][]を使用してChannelで使用可能なXRPの合計額を増加しない限り、クレームを清算できません。
- Channelの`balance`が、受取人がすでにChannelから受領していると予測している額と一致していることを確認します。これらの金額が一致しない場合、受取人はChannelのトランザクション履歴を再度確認する必要があります。不一致の原因として以下のものが考えられます。
- 支払人が[PaymentChannelClaim][]トランザクションを使用してChannelから受取人にXRPを送金したところ、受取人がこれに気付かず、着信トランザクションを記録していなかった。
- 受取人のレコードに、「処理中」のトランザクションや、最新の検証済みレジャーバージョンにはまだ記録されていないトランザクションが含まれていた。受取人は[txメソッド][]を使用して個々のトランザクションの状態を調べ、この点を確認できます。
- `account_channels`要求に正しいレジャーバージョンが指定されていなかった。(最新の検証済みバージョンを確認するには、`"ledger_index":"validated”`を使用します)
- 受取人は以前にXRPを清算したものの、記録し忘れていた。
- 受取人がXRPの清算を試行し、暫定的な結果を記録したが、トランザクションの最終的な検証済みの結果がこれとは異なり、受取人はこの最終検証済み結果を記録し忘れていた。
- 受取人が照会した`rippled`サーバーが、ネットワークの他の部分と同期していない状態であったか、または不明なバグが発生した。サーバーの状態を確認するには、[server_infoメソッド][]を使用します。(この状況を再現できる場合は、[問題を報告してください](https://github.com/ripple/rippled/issues/)。)
受取人がPayment Channelの署名と現行状態の両方を確認した後で、XRPをまだ受領していない場合、XRPを清算するトランザクションがChannelの有効期限より前に処理される限り、XRPを確実に清算 _できます_
## 6. 受取人が商品またはサービスを提供します。
この時点で受取人は支払がすでに保証されていることを把握しているので、商品またはサービスを支払人に提供できます。
このチュートリアルに関して、受取人は支払人に「商品およびサービス」としてハイタッチまたは同等のオンラインメッセージを送信できます。
## 7. 必要に応じてステップ36を繰り返します。
支払人と受取人はXRP Ledger自体を待つことなく、ステップ36商品およびサービスと交換するクレームの作成、送信、検証を必要な回数と間隔で繰り返すことができます。この処理に関する2つの主な制限を以下に示します。
- Payment ChannelのXRPの額。支払人は必要に応じて[PaymentChannelFundトランザクション][]を送信し、Channelで使用可能なXRPの合計額を増加できます。
- Payment Channelの変更可能な有効期限設定されている場合これは[account_channelsメソッド][]に対する応答の`cancel_after`フィールドに表示されます。)
## 8. 準備が完了すれば、受取人は承認された額のクレームを清算します。
この時点で受取人は最終的にChannelからXRPを受領します。
これは、`Balance``Amount``Signature`、および`PublicKey`フィールドが指定された[PaymentChannelClaimトランザクション][]です。クレームの値は累計額であるため、受取人は最も高額な(最新の)クレームを清算するだけで全額を受領できます。受取人は、承認済みの額全額をクレームで清算する必要はありません。
受取人は必要に応じて、取引継続中にこの手順を繰り返し実行して、一部の額を決済することができます。
ChannelからXRPを清算する例:
要求:
POST http://localhost:5005/
Content-Type: application/json
{
"method": "submit",
"params": [{
"secret": "s████████████████████████████",
"tx_json": {
"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
"TransactionType": "PaymentChannelClaim",
"Amount": "1000000",
"Balance": "1000000",
"Channel": "5DB01B7FFED6B67E6B0414DED11E051D2EE2B7619CE0EAA6286D67A3A4D5BDB3",
"PublicKey": "023693F15967AE357D0327974AD46FE3C127113B1110D6044FD41E723689F81CC6",
"Signature": "304402204EF0AFB78AC23ED1C472E74F4299C0C21F1B21D07EFC0A3838A420F76D783A400220154FB11B6F54320666E4C36CA7F686C16A3A0456800BBC43746F34AF50290064"
},
"fee_mult_max": 1000
}]
}
応答:
200 OK
{
"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": "12000F2280000000240000017450165DB01B7FFED6B67E6B0414DED11E051D2EE2B7619CE0EAA6286D67A3A4D5BDB36140000000000F42406240000000000F424068400000000000000A7121023693F15967AE357D0327974AD46FE3C127113B1110D6044FD41E723689F81CC6732103AB40A0490F9B7ED8DF29D246BF2D6269820A0EE7742ACDD457BEA7C7D0931EDB7447304502210096B933BC24DA77D8C4057B4780B282BA66C668DFE1ACF4EEC063AD6661725797022037C8823669CE91AACA8CC754C9F041359F85B0B32384AEA141EBC3603798A24C7646304402204EF0AFB78AC23ED1C472E74F4299C0C21F1B21D07EFC0A3838A420F76D783A400220154FB11B6F54320666E4C36CA7F686C16A3A0456800BBC43746F34AF5029006481144B4E9C06F24296074F7BC48F92A97916C6DC5EA9",
"tx_json": {
"Account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
"Amount": "1000000",
"Balance": "1000000",
"Channel": "5DB01B7FFED6B67E6B0414DED11E051D2EE2B7619CE0EAA6286D67A3A4D5BDB3",
"Fee": "10",
"Flags": 2147483648,
"PublicKey": "023693F15967AE357D0327974AD46FE3C127113B1110D6044FD41E723689F81CC6",
"Sequence": 372,
"Signature": "304402204EF0AFB78AC23ED1C472E74F4299C0C21F1B21D07EFC0A3838A420F76D783A400220154FB11B6F54320666E4C36CA7F686C16A3A0456800BBC43746F34AF50290064",
"SigningPubKey": "03AB40A0490F9B7ED8DF29D246BF2D6269820A0EE7742ACDD457BEA7C7D0931EDB",
"TransactionType": "PaymentChannelClaim",
"TxnSignature": "304502210096B933BC24DA77D8C4057B4780B282BA66C668DFE1ACF4EEC063AD6661725797022037C8823669CE91AACA8CC754C9F041359F85B0B32384AEA141EBC3603798A24C",
"hash": "C9FE08FC88CF76C3B06622ADAA47AE99CABB3380E4D195E7751274CFD87910EB"
}
}
}
受取人は検証済みレジャーでこのトランザクションが正常に処理されたことを確認します。詳細は、[確実なトランザクションの送信](reliable-transaction-submission.html)を参照してください。
## 9. 支払人と受取人の取引完了後、支払人はChannelの閉鎖を要求します。
これは、`tfClose`フラグを設定した[PaymentChannelClaimトランザクション][]、または`Expiration`フィールドを設定した[PaymentChannelFundトランザクション][]です。_[フローチャート][]の9a_。
支払人がChannelの閉鎖を要求した時点でChannelにXRPが残っていない場合は、Channelは即時に閉鎖されます。
ChannelにXRPが _残っている_ 場合は、このChannelの閉鎖要求は、受取人に対し未処理のクレームを速やかに清算することを求める最終警告となります。Channelの閉鎖までに、少なくとも決済遅延期間相当の時間が受取人に残されています。正確な秒数は、レジャーの閉鎖時刻に応じて多少異なります。
また、受取人はクレームの処理完了直後にPayment Channelを閉鎖できます _[フローチャート][]の9b_
Channelの閉鎖を要求する[トランザクションを送信する](submit.html#署名と送信モード)例:
{
"method": "submit",
"params": [{
"secret": "s████████████████████████████",
"tx_json": {
"Account": "rN7n7otQDd6FczFgLdSqtcsAUxDkw6fzRH",
"TransactionType": "PaymentChannelClaim",
"Channel": "5DB01B7FFED6B67E6B0414DED11E051D2EE2B7619CE0EAA6286D67A3A4D5BDB3",
"Flags": 2147614720
},
"fee_mult_max": 1000
}]
}
トランザクションが検証済みレジャーに記録されたら、いずれの当事者も[account_channelsメソッド][]を使用して現在スケジュールされているChannelの有効期限を確認できます。最新の検証済みレジャーバージョンからデータを取得するには、`"ledger_index": "validated"`を必ず指定してください。
`account_channels`応答の例:
{
"result": {
"account": "rN7n7otQDd6FczFgLdSqtcsAUxDkw6fzRH",
"channels": [
{
"account": "rN7n7otQDd6FczFgLdSqtcsAUxDkw6fzRH",
"amount": "100000000",
"balance": "1000000",
"channel_id": "5DB01B7FFED6B67E6B0414DED11E051D2EE2B7619CE0EAA6286D67A3A4D5BDB3",
"destination_account": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
"destination_tag": 20170428,
"expiration": 547073182,
"public_key": "aB44YfzW24VDEJQ2UuLPV2PvqcPCSoLnL7y5M1EzhdW4LnK5xMS3",
"public_key_hex": "023693F15967AE357D0327974AD46FE3C127113B1110D6044FD41E723689F81CC6",
"settle_delay": 86400
}
],
"status": "success"
}
}
この例に示されている`expiration`の値547073182[Rippleエポック以降の経過秒数][] は2017-05-02T20:46:22Zに対応しています。このため、この時刻までに決済されなかったクレームはすべて無効になります。
## 10. 有効期限切れのChannelは誰でも閉鎖できます。
決済遅延が経過するか、またはChannelが予定されている有効期限に達したら、Channelは有効期限切れになります。それ以降に行われるこのChannelに影響するトランザクションはすべて、Channelを閉鎖するだけであり、未請求のXRPは支払人に返金されます。
Channelは期限切れ状態で永久にレジャーに残ることがあります。これは、レジャーはトランザクションの結果によってのみ変わるので、_誰かが_ 有効期限切れのChannelを閉鎖するトランザクションを送信する必要があるためです。Channelがレジャーに残っている限り、そのChannelは[所有者準備金](reserves.html#所有者準備金)の点から支払人が所有するオブジェクトと見なされます。
このため、支払人には`tfClose`フラグを指定した2番目の[PaymentChannelClaimトランザクション][]を送信することが推奨されます。ただしその他のアカウントPayment Channelに関与するアカウントを含むは有効期限切れのChannelを閉鎖できません。
このトランザクションを送信するコマンドは、Channelの有効期限切れを要求する前述の例と同じです。ただしコマンドの実行結果である[自動入力](transaction-common-fields.html#自動入力可能なフィールド) `Sequence`番号、署名、識別用ハッシュは一意です。)
有効期限切れのChannelを閉鎖するトランザクションを[送信する](submit.html#署名と送信モード)例:
{
"method": "submit",
"params": [{
"secret": "s████████████████████████████",
"tx_json": {
"Account": "rN7n7otQDd6FczFgLdSqtcsAUxDkw6fzRH",
"TransactionType": "PaymentChannelClaim",
"Channel": "5DB01B7FFED6B67E6B0414DED11E051D2EE2B7619CE0EAA6286D67A3A4D5BDB3",
"Flags": 2147614720
},
"fee_mult_max": 1000
}]
}
トランザクションが検証済みレジャーに記録されたら、そのトランザクションのメタデータを調べて、Channelが削除され、XRPが送金元に返金されたことを確認できます。
このステップのトランザクションを検索する[txメソッド][]を使用した場合の応答の例:
{
"result": {
"Account": "rN7n7otQDd6FczFgLdSqtcsAUxDkw6fzRH",
"Channel": "5DB01B7FFED6B67E6B0414DED11E051D2EE2B7619CE0EAA6286D67A3A4D5BDB3",
"Fee": "5606",
"Flags": 2147614720,
"Sequence": 41,
"SigningPubKey": "023693F15967AE357D0327974AD46FE3C127113B1110D6044FD41E723689F81CC6",
"TransactionType": "PaymentChannelClaim",
"TxnSignature": "3044022008922FEB6F7D35D42006685BCBB007103D2A40AFAA69A7CFC10DF529F94BB6A402205D67816F50BBAEE0A2709AA3A93707304EC21133550FD2FF7436AD0C3CA6CE27",
"date": 547091262,
"hash": "9C0CAAC3DD1A74461132DA4451F9E53BDF4C93DFDBEFCE1B10021EC569013B33",
"inLedger": 29480670,
"ledger_index": 29480670,
"meta": {
"AffectedNodes": [
{
"ModifiedNode": {
"LedgerEntryType": "AccountRoot",
"LedgerIndex": "13F1A95D7AAB7108D5CE7EEAF504B2894B8C674E6D68499076441C4837282BF8",
"PreviousTxnID": "C9FE08FC88CF76C3B06622ADAA47AE99CABB3380E4D195E7751274CFD87910EB",
"PreviousTxnLgrSeq": 29385089
}
},
{
"DeletedNode": {
"FinalFields": {
"Account": "rN7n7otQDd6FczFgLdSqtcsAUxDkw6fzRH",
"Amount": "100000000",
"Balance": "1000000",
"Destination": "rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn",
"DestinationTag": 20170428,
"Expiration": 547073182,
"Flags": 0,
"OwnerNode": "0000000000000000",
"PreviousTxnID": "C5C70B2BCC515165B7F62ACC8126F8F8B655EB6E1D949A49B2358262BDA986B4",
"PreviousTxnLgrSeq": 29451256,
"PublicKey": "023693F15967AE357D0327974AD46FE3C127113B1110D6044FD41E723689F81CC6",
"SettleDelay": 86400
},
"LedgerEntryType": "PayChannel",
"LedgerIndex": "5DB01B7FFED6B67E6B0414DED11E051D2EE2B7619CE0EAA6286D67A3A4D5BDB3"
}
},
{
"ModifiedNode": {
"FinalFields": {
"Account": "rN7n7otQDd6FczFgLdSqtcsAUxDkw6fzRH",
"Balance": "1041862844",
"Flags": 0,
"OwnerCount": 2,
"Sequence": 42
},
"LedgerEntryType": "AccountRoot",
"LedgerIndex": "B1CB040A17F9469BC00376EC8719535655824AD16CB5F539DD5765FEA88FDBE3",
"PreviousFields": {
"Balance": "942868450",
"OwnerCount": 3,
"Sequence": 41
},
"PreviousTxnID": "C5C70B2BCC515165B7F62ACC8126F8F8B655EB6E1D949A49B2358262BDA986B4",
"PreviousTxnLgrSeq": 29451256
}
},
{
"ModifiedNode": {
"FinalFields": {
"Flags": 0,
"Owner": "rN7n7otQDd6FczFgLdSqtcsAUxDkw6fzRH",
"RootIndex": "E590FC40B4F24D18341569BD3702A2D4E07E7BC04D11CE63608B67979E67030C"
},
"LedgerEntryType": "DirectoryNode",
"LedgerIndex": "E590FC40B4F24D18341569BD3702A2D4E07E7BC04D11CE63608B67979E67030C"
}
}
],
"TransactionIndex": 7,
"TransactionResult": "tesSUCCESS"
},
"status": "success",
"validated": true
}
}
トランザクションメタデータで以下のエントリを検索します。
- `"LedgerEntryType": "PayChannel"`が指定された`DeletedNode``LedgerIndex`フィールドはChannel IDと一致している必要があります。これはChannelが削除されたことを示します。
- `"LedgerEntryType": "AccountRoot"`が指定された`ModifiedNode``PreviousFields``FinalFields``Balance`フィールドの変化は、支払人に返金される未使用のXRPを反映しています。
これらのフィールドは、Payment Channelが閉鎖したことを示しています。
## 結論
これでPayment Channelの使用法のチュートリアルを終了します。ユーザーが、Payment Channelのスピードと利便性を最大限に活用できる独特で興味深い用途を考えることが推奨されます。
<!--{# common link defs #}-->
{% include '_snippets/rippled-api-links.md' %}
{% include '_snippets/tx-type-links.md' %}
{% include '_snippets/rippled_versions.md' %}

View File

@@ -0,0 +1,522 @@
# 信頼できるトランザクションの送信
XRP Ledgerを使用する金融機関やその他のサービスは、ここで説明するベストプラクティスを使用し、迅速で確認可能な方法で、トランザクションが検証または拒否されるようにする必要があります。 信頼できる(ローカルで運営されている)`rippled`サーバーにトランザクションを送信してください。
本書で説明されているベストプラクティスを使用すると、アプリケーションはアーカイブ中にトランザクションをXRP Ledgerに送信できます。
1. [べき等性](https://en.wikipedia.org/wiki/Idempotence) - トランザクションは、一度のみ処理するか、またはまったく処理しないようにします。
2. 検証可能性 - アプリケーションはトランザクションの最終結果を判断できます。
ベストプラクティスを導入しないと、アプリケーションに以下のエラーが発生する可能性があります。
1. 誤って実行されなかったトランザクションを送信する。
2. 暫定的なトランザクションを、最終的で不変の結果として誤判断する。
3. レジャーに以前に適用されたトランザクションの正式な結果を検出できない。
こういったタイプのエラーは、深刻な問題に繋がる可能性があります。 例えば、以前のPaymentトランザクションを検出できないアプリケーションは、誤ってトランザクションを再送信してしまい、元の支払いが重複してしまう可能性があります。 したがって、本書で説明するテクニックを使用し、アプリケーションが正式なトランザクション結果に基づいてアクションをとることが非常に重要です。
## 背景
XRP Ledgerプロトコルは、ネットワークのすべてのサーバーで共有されるレジャー台帳を提供します。 [コンセンサスと検証のプロセス](https://ripple.com/build/ripple-ledger-consensus-process/)を通じ、ネットワークはトランザクションがレジャーに適用される(または除外される)順序に同意します。
正しい形式のトランザクションを信頼できるXRP Ledgerサーバーに送信すると、数秒で検証または拒否されます。 ただし、正しい形式のトランザクションであっても迅速に検証も拒否もされないことがあります。このような特殊なケースは、アプリケーションがトランザクションを送信した後にグルーバル[トランザクションコスト](transaction-cost.html)が増加すると発生することがあります。 トランザクションに指定された額よりもトランザクションコストが増加すると、そのトランザクションは次回の検証済みレジャーに含まれません。後日、グローバルトランザクションコストが下がった場合には、そのトランザクションは後のレジャーに含まれます。トランザクションに有効期限が指定されていない場合には、レジャーへの追加はいつになるか分かりません。
電源やネットワークに障害が発生した場合には、送信済みトランザクションのステータスの検出時にさらに多くの問題に直面します。アプリケーションは、トランザクションの適切な送信と、その後の正式結果の適切な受信の両方に十分な注意を払う必要があります。
### トランザクションのタイムライン
XRP Ledgerには、[`rippled` API](rippled-api.html)や[RippleAPI](rippleapi-reference.html)など、トランザクションを送信するためのAPIがいくつかあります。 使用するAPIにかかわらず、トランザクションは以下のようにレジャーに適用されます。
1. アカウント所有者は、トランザクションを作成して署名します。
2. 所有者は、トランザクション候補として、そのトランザクションをネットワークに送信します。
- 形式が正しくないトランザクションや無意味なトランザクションはただちに拒否されます。
- 形式が正しいトランザクションは、暫定的に成功し、後で失敗することもあります。
- 形式が正しいトランザクションは、暫定的に失敗し、後で成功することもあります。
- 形式が正しいトランザクションは、暫定的に成功し、後で少々異なった形で成功することもあります。(例えば、別のオファーが使用され、暫定的な結果よりも良い(または悪い)為替レートになることがあります。)
3. コンセンサスと検証を通じ、トランザクションがレジャーに適用されます。ネットワークの伝達のコストを適用するために、一部の失敗したトランザクションも適用されることがあります。
4. 検証されたレジャーにはそのトランザクションが含まれ、その結果がレジャーの状態に反映されます。
- トランザクション結果は暫定的なものではなくなり、成功または失敗の結果は最終的かつ不変のものとなります。
**注記:** `rippled`を介してトランザクションを送信すると、送信コマンドから返される成功ステータスコードによって、`rippled`サーバーがトランザクション候補を受信したことが示されます。このトランザクションは、検証されたレジャーに適用される場合とされない場合があります。
APIは、現在の進行中のレジャーにトランザクション候補を適用した結果に基づいて、暫定的な結果を返すことがあります。アプリケーションでは、この結果を、トランザクションの最終的な*不変の*結果と混同してはなりません。 不変の結果は、検証済みのレジャーだけにあります。 アプリケーションは、トランザクション結果を含むレジャーが検証されるまで、トランザクションのステータスを繰り返し照会する必要があります。
トランザクションの適用時に、`rippled`サーバーは、*最後に検証されたレジャー*を使用します。これは、すでにネットワーク全体によって検証されたトランザクションに基づくレジャーの状態のスナップショットです。 コンセンサスと検証のプロセスは、新しいトランザクションのセットを、最後に検証されたレジャーに正規の順序で適用します。その結果、新しい検証済みレジャーが出来上がります。 この新しい検証済みレジャーインスタンスとその前のインスタンスがレジャー履歴を形成します。
検証済みの各レジャーインスタンスにはシーケンス番号が付けられます。これは、前のインスタンスのシーケンス番号よりも1つ大きい番号です。また、各レジャーには識別用のハッシュ値があります。これは、レジャーの内容から決定される固有の値です。進行中のレジャーには多数のバージョンが存在することがあります。その場合、シーケンス番号は同じですが、ハッシュ値が異なります。検証できるのは、1つのバージョンのみです。
各検証済みレジャーには、トランザクションが適用される正規の順序があります。この順序は、レジャーの最終的なトランザクションセットに基づいて決定されます。これと異なり、各`rippled`サーバーの進行中のレジャーでは、トランザクションの受信時に増分計算されます。トランザクションを暫定的に実行する順序は、新しい検証済みレジャーを構築するためにトランザクションを実行する順序とは通常異なります。これが、トランザクションの暫定的な結果が最終結果とは異なる可能性がある理由の1つです。例えば、ある支払いが、同じオファーを使用する別の支払いの前と後のどちらで実行されるかによって、最終的な為替レートが異なることがあります。
### LastLedgerSequence
`LastLedgerSequence`は、省略可能な[全トランザクションに適用されるパラメーター](transaction-common-fields.html)です。 このパラメーターは、XRP Ledgerに、トランザクションを特定のレジャーインスタンスで検証する必要があること、またはトランザクションを特定のレジャーインスタンスの前に検証する必要があることを指示します。 XRP Ledgerは、シーケンス番号がトランザクションの`LastLedgerSequence`パラメーターよりも大きいトランザクションをレジャーインスタンスに含めることは決してありません。
`LastLedgerSequence`パラメーターを使用すれば、トランザクションが迅速に確認されず、将来のレジャーに含まれるような好ましくないケースを防止できます。 `LastLedgerSequence`パラメーターは、各トランザクションに指定する必要があります。 自動プロセスでは、最後に検証されたレジャーインデックスよりも4つ大きい数値を使用して、トランザクションが予測可能な方法で、かつ迅速に検証または拒否されるようにします。
`rippled` APIを使用するアプリケーションは、トランザクションの送信時に、`LastLedgerSequence`を明示的に指定する必要があります。
RippleAPIでは、[Transaction Instructions](rippleapi-reference.html#transaction-instructions)で説明されている`maxLedgerVersion`フィールドを使用して`LastLedgerSequence`を指定します。 RippleAPIは、デフォルトで自動的に適切な値を提供します。 期限なしで実行される可能性のあるトランザクションを実行する場合には、`maxLedgerVersion``null`に指定して故意に`LastLedgerSequence`を省略できますが、これはお勧めできません。
## ベストプラクティス
### 信頼性の高いトランザクション送信
トランザクションを送信するアプリケーションでは、以下のベストプラクティスを使用し、プロセス終了やその他の問題が発生した場合でも信頼性が高い方法でトランザクションを送信する必要があります。 アプリケーションが最終的で検証済みの結果に基づいて処理できるように、アプリケーションのトランザクション結果を確認する必要があります。
送信と確認は別々の異なる手続きであり、本書の説明に基づいてこれを実装することができます。
1. 送信 - トランザクションがネットワークに送信され、暫定的な結果が戻されます。
2. 確認 - 検証済みレジャーを確認し、正式な結果が判断されます。
### 送信
送信が完了する前に電源障害やネットワーク障害が発生する可能性に備え、送信前にトランザクションの詳細を[保持](https://en.wikipedia.org/wiki/Persistence_%28computer_science%29)しておきます。 再起動時に、保持された値により、トランザクションのステータスを確認することが可能になります。
送信プロセスは次のとおりです。
1. トランザクションを生成して署名します
- `LastLedgerSequence`パラメーターを指定します
2. 以下を保存して、トランザクション詳細を保持しておきます
- トランザクションハッシュ
- LastLedgerSequence
- 送信者のアドレスとシーケンス番号
- 送信時における最新の検証済みレジャーインデックス
- 必要に応じて、アプリケーション固有のデータ
3. トランザクションを送信します
### 確認
通常の操作中に、アプリケーションは、送信されたトランザクションのステータスをハッシュによって確認できます。または、使用するAPIによっては、トランザクションが確認または拒否されたときにその通知を受信できます。 この通常操作は、ネットワーク障害や電源障害などによって中断されることがあります。 そのような中断が発生した場合には、アプリケーションは信頼性の高い方法で、中断前にネットワークに送信された(または送信されなかった)可能性のあるトランザクションのステータスを確認する必要があります。
再起動時、または最新の検証済みレジャーの確認時の例を示します(擬似コード):
```
For each persisted transaction without validated result:
Query transaction by hash
If (result appears in validated ledger)
# Outcome is final
Persist the final result
If (result code is tesSUCCESS)
Application may act based on successful transaction
Else
The transaction failed (1)
If appropriate for the application and failure type, submit with
new LastLedgerSequence and Fee
Else if (LastLedgerSequence > newest validated ledger)
# Outcome is not yet final
Wait for more ledgers to be validated
Else
If (server has continuous ledger history from the ledger when the
transaction was submitted up to and including the ledger
identified by LastLedgerSequence)
The transaction failed (2)
If appropriate for the application, submit with
new LastLedgerSequence and Fee
Else
# Outcome is final, but not known due to a ledger gap
Wait to acquire continuous ledger history
```
#### 失敗のケース
2つのトランザクション失敗のケース疑似コードの12の間の違いは、トランザクションが検証されたレジャーに含まれていたかどうかです。いずれのケースにおいても、失敗の処理には十分な注意が必要です。
- 失敗のケース1では、トランザクションはレジャーに含まれ、[XRPトランザクションコスト](transaction-cost.html)は消却されましたが、それ以外には何も起こりませんでした。この原因としては、流動性の欠如、適切でない[パス](paths.html)、またはその他の状況が考えられます。多くの場合、このような失敗の場合には、同様のトランザクションをすぐに試すと同じ結果が出ることが多いです。状況が変わるのを待ってから送信すると、別の結果が得られることがあります。
- 失敗のケース2では、トランザクションは検証済みレジャーには含まれないため、何も起こらず、トランザクションコストも消却されませんでした。これは、XRP Ledgerの現在の負荷に対してトランザクションコストが低すぎる、`LastLedgerSequence`が早すぎる、または不安定なネットワーク接続などの状況が原因である可能性があります。
- 失敗のケース1と異なり、このケースでは`LastLedgerSequence`のみを変更(または`Fee`も変更)するだけで、新しいトランザクションが成功する可能性があります。
- また、トランザクションが成功しないのはレジャーのステータスが原因である可能性もあります。例えば、トランザクションに署名するために使用されたキーペアが送信アドレスで無効になっている場合などです。トランザクションの暫定的な結果が[`tef`-class code](tef-codes.html)の場合には、修正をしない限りそのトランザクションが成功する可能性は低くなります。
#### レジャーのギャップ
サーバーに、トランザクションが最初に送信されてから、レジャーが`LastLedgerSequence`によって識別された時点までを含む、継続したレジャー履歴がない場合には、トランザクションの最終結果を得られない可能性があります。(サーバーにないレジャーバージョンに結果が含まれている場合、成功したか失敗したかが分かりません。)
`rippled`サーバーにリソースCPU/RAM/ディスクIOの余裕がある場合には、不足しているレジャーバージョンを自動的に取得します。ただし、取得しようとするレジャーが[保管する履歴の設定量](https://github.com/ripple/rippled/blob/develop/cfg/rippled-example.cfg#L581)よりも古い場合には取得されません。ギャップのサイズや、サーバーのリソース使用率に基づき、不足しているレジャーバージョンの取得には数分かかります。[ledger_requestメソッド][]を使用して履歴となっているレジャーバージョンを手動で要求することもできます。
あるいは、`s2.ripple.com`にあるRippleの完全履歴サーバーなど、必要なレジャー履歴を含む別の`rippled`サーバーを使用して、トランザクションのステータスを検索することもできます。この目的には、信頼できるサーバーのみを使用してください。不正なサーバーは、トランザクションのステータスや結果について偽の情報を提供するようにプログラムされている可能性があります。
## 技術的応用
トランザクションの送信および確認のベストプラクティスを実施するには、アプリケーションで以下を実行する必要があります。
1. 署名するアカウントの次のシーケンス番号を判断します
* 各トランザクションにはアカウント固有のシーケンス番号があります。 これにより、アカウントによって署名されたトランザクションの実行順序が保証され、再送信しても同じトランザクションがレジャーに二重に適用されることがなくなります。
3. `LastLedgerSequence`を決定します
* トランザクションの`LastLedgerSequence`は、最後の検証済みレジャーのシーケンス番号から計算されます。
3. トランザクションを生成して署名します
* 送信前に、署名されたトランザクションの詳細を保持します。
4. トランザクションを送信します
* 初期の結果は暫定的なものであり、変化する可能性があります。
5. トランザクションの最終結果を判断します
* 最終結果は、レジャー履歴における不変部分です。
アプリケーションでのこれらのアクションの実行方法は、アプリケーションが使用するAPIによって異なります。 アプリケーションでは、以下のインターフェイスを使用できます。
1. [`rippled` API](rippled-api.html)
2. [RippleAPI](rippleapi-reference.html)
3. `rippled`上にレイヤーされた、任意の数の他のソフトウェアAPI
### rippled - トランザクションの送信と確認
#### アカウントシーケンスの判断
`rippled`には、最後に検証されたレジャーでのアカウントのシーケンス番号を知るための[account_infoメソッド][]があります。
JSON-RPC要求:
```
{
"method": "account_info",
"params": [
{
"account": "rG5Ro9e3uGEZVCh3zu5gB9ydKUskCs221W",
"ledger": "validated"
}
]
}
```
応答の本文:
```
{
"result": {
"validated": true,
"status": "success",
"ledger_index": 10266396,
"account_data": {
"index": "96AB97A1BBC37F4F8A22CE28109E0D39D709689BDF412FE8EDAFB57A55E37F38",
"Sequence": 4,
"PreviousTxnLgrSeq": 9905632,
"PreviousTxnID": "CAEE0E34B3DB50A7A0CA486E3A236513531DE9E52EAC47CE4C26332CC847DE26",
"OwnerCount": 2,
"LedgerEntryType": "AccountRoot",
"Flags": 0,
"Balance": "49975988",
"Account": "rG5Ro9e3uGEZVCh3zu5gB9ydKUskCs221W"
}
}
}
```
この例では、最後に検証されたレジャーの時点において(要求の`"ledger": "validated"`と、応答の`"validated": "true"`を参照)、アカウントのシーケンスは**4**です(`"account_data"``"Sequence": 4`を参照)。
アプリケーションが、このアカウントで署名された3つのトランザクションを送信する場合には、4、5、6のシーケンス番号を使用します。 各トランザクションの検証を待たずに複数のトランザクションを送信するには、アプリケーションで継続的なアカウントシーケンス番号を使用します。
#### 最後に検証されたレジャーの判断
[server_stateメソッド][]は、最後に検証されたレジャーのレジャーインデックスを返します。
要求:
```
{
"id": "client id 1",
"method": "server_state"
}
```
応答:
```
{
"result": {
"status": "success",
"state": {
"validation_quorum": 3,
"validated_ledger": {
"seq": 10268596,
"reserve_inc": 5000000,
"reserve_base": 20000000,
"hash": "0E0901DA980251B8A4CCA17AB4CA6C3168FE83FA1D3F781AFC5B9B097FD209EF",
"close_time": 470798600,
"base_fee": 10
},
"server_state": "full",
"published_ledger": 10268596,
"pubkey_node": "n9LGg37Ya2SS9TdJ4XEuictrJmHaicdgTKiPJYi8QRSdvQd3xMnK",
"peers": 58,
"load_factor": 256000,
"load_base": 256,
"last_close": {
"proposers": 5,
"converge_time": 3004
},
"io_latency_ms": 2,
"fetch_pack": 10121,
"complete_ledgers": "10256331-10256382,10256412-10268596",
"build_version": "0.26.4-sp3-private"
}
}
}
```
この例では、最後に検証されたレジャーのシーケンス番号は10268596応答の`result.state.validated_ledger`)です。 この例では、レジャー履歴にギャップがあることも示されています。 ここで使用されたサーバーは、ギャップの間レジャー10256383から10256411に適用されたトランザクションに関する情報を提供することはできません。 その部分のレジャー履歴を取得するよう設定されていれば、最終的にサーバーで取得できます。
#### トランザクションの生成
`rippled`には、トランザクション送信に備えて準備するための[signメソッド][]があります。 このメソッドは信頼できる<rippled/>インスタンスにのみに渡すことができるアカウントの機密情報を必要とします。信頼できる`rippled`インスタンスにのみ渡 この例では、10 FOO架空の通貨を別のXRP Ledgerアドレスに発行します。
要求:
```
{
"method": "sign",
"params": [
{
"offline": true,
"secret": "sssssssssssssssssssssssssssss",
"tx_json": {
"Account": "rG5Ro9e3uGEZVCh3zu5gB9ydKUskCs221W",
"Sequence": 4,
"LastLedgerSequence": 10268600,
"Fee": 10000,
"Amount": {
"currency": "FOO",
"issuer": "rG5Ro9e3uGEZVCh3zu5gB9ydKUskCs221W",
"value": "10"
},
"Destination": "rawz2WQ8i9FdTHp4KSNpBdyxgFqNpKe8fM",
"TransactionType": "Payment"
}
}
]
}
```
アプリケーションは、`tefPAST_SEQ`エラーを防ぐため、`account_info`への以前の呼び出しで判明した`"Sequence": 4`を使用しています。
また、アプリケーションが`server_state`から取得した最後の検証済みレジャーに基づく`LastLedgerSequence`にも注意してください。 バックエンドアプリケーションでは、 *「最後の検証済みレジャーシーケンス + 4」* を使用することをお勧めします。または、 *「現行のレジャー + 3」* の値を使用します。 `LastLedgerSequence`の計算が誤りで、最後の検証済みレジャーの番号よりも小さい場合には、そのトランザクションは`tefMAX_LEDGER`エラーで失敗します。
応答:
```
{
"result": {
"tx_json": {
"hash": "395C313F6F11F70FEBAF3785529A6D6DE3F44C7AF679515A7EAE22B30146DE57",
"TxnSignature": "304402202646962A21EC0516FCE62DC9280F79E7265778C571E9410D795E67BB72A2D8E402202FF4AF7B2E2160F5BCA93011CB548014626CAC7FCBEBDB81FE8193CEFF69C753",
"TransactionType": "Payment",
"SigningPubKey": "0267268EE0DDDEE6A862C9FF9DDAF898CF17060A673AF771B565AA2F4AE24E3FC5",
"Sequence": 4,
"LastLedgerSequence": 10268600,
"Flags": 2147483648,
"Fee": "10000",
"Destination": "rawz2WQ8i9FdTHp4KSNpBdyxgFqNpKe8fM",
"Amount": {
"value": "10",
"issuer": "rG5Ro9e3uGEZVCh3zu5gB9ydKUskCs221W",
"currency": "FOO"
},
"Account": "rG5Ro9e3uGEZVCh3zu5gB9ydKUskCs221W"
},
"tx_blob": "12000022800000002400000004201B009CAFB861D4C38D7EA4C68000000000000000000000000000464F4F0000000000AC5FA3BB28A09BD2EC1AE0EED2315060E83D796A68400000000000271073210267268EE0DDDEE6A862C9FF9DDAF898CF17060A673AF771B565AA2F4AE24E3FC57446304402202646962A21EC0516FCE62DC9280F79E7265778C571E9410D795E67BB72A2D8E402202FF4AF7B2E2160F5BCA93011CB548014626CAC7FCBEBDB81FE8193CEFF69C7538114AC5FA3BB28A09BD2EC1AE0EED2315060E83D796A831438BC6F9F5A6F6C4E474DB0D59892E90C2C7CED5C",
"status": "success"
}
}
```
トランザクションを送信する前に、アプリケーションでトランザクションのハッシュを保持しておきます。 `sign`メソッドの結果の`tx_json`の下にハッシュが含まれます。
#### トランザクションの送信
`rippled`には、署名されたトランザクションの送信を可能にする、[submitメソッド][]があります。 これは、`sign`メソッドで返された`tx_blob`パラメーターを使用します。
要求:
```
{
"method": "submit",
"params": [
{
"tx_blob": "12000022800000002400000004201B009CAFB861D4C38D7EA4C68000000000000000000000000000464F4F0000000000AC5FA3BB28A09BD2EC1AE0EED2315060E83D796A68400000000000271073210267268EE0DDDEE6A862C9FF9DDAF898CF17060A673AF771B565AA2F4AE24E3FC57446304402202646962A21EC0516FCE62DC9280F79E7265778C571E9410D795E67BB72A2D8E402202FF4AF7B2E2160F5BCA93011CB548014626CAC7FCBEBDB81FE8193CEFF69C7538114AC5FA3BB28A09BD2EC1AE0EED2315060E83D796A831438BC6F9F5A6F6C4E474DB0D59892E90C2C7CED5C"
}
]
}
```
応答:
```
{
"result": {
"tx_json": {
"hash": "395C313F6F11F70FEBAF3785529A6D6DE3F44C7AF679515A7EAE22B30146DE57",
"TxnSignature": "304402202646962A21EC0516FCE62DC9280F79E7265778C571E9410D795E67BB72A2D8E402202FF4AF7B2E2160F5BCA93011CB548014626CAC7FCBEBDB81FE8193CEFF69C753",
"TransactionType": "Payment",
"SigningPubKey": "0267268EE0DDDEE6A862C9FF9DDAF898CF17060A673AF771B565AA2F4AE24E3FC5",
"Sequence": 4,
"LastLedgerSequence": 10268600,
"Flags": 2147483648,
"Fee": "10000",
"Destination": "rawz2WQ8i9FdTHp4KSNpBdyxgFqNpKe8fM",
"Amount": {
"value": "10",
"issuer": "rG5Ro9e3uGEZVCh3zu5gB9ydKUskCs221W",
"currency": "FOO"
},
"Account": "rG5Ro9e3uGEZVCh3zu5gB9ydKUskCs221W"
},
"tx_blob": "12000022800000002400000004201B009CAFB861D4C38D7EA4C68000000000000000000000000000464F4F0000000000AC5FA3BB28A09BD2EC1AE0EED2315060E83D796A68400000000000271073210267268EE0DDDEE6A862C9FF9DDAF898CF17060A673AF771B565AA2F4AE24E3FC57446304402202646962A21EC0516FCE62DC9280F79E7265778C571E9410D795E67BB72A2D8E402202FF4AF7B2E2160F5BCA93011CB548014626CAC7FCBEBDB81FE8193CEFF69C7538114AC5FA3BB28A09BD2EC1AE0EED2315060E83D796A831438BC6F9F5A6F6C4E474DB0D59892E90C2C7CED5C",
"status": "success",
"engine_result_message": "The transaction was applied.",
"engine_result_code": 0,
"engine_result": "tesSUCCESS"
}
}
```
これは**初期**結果です。 最終結果は検証済みのレジャーのみにあります。 `"validated": true`フィールドがないことが、これが**不変の結果ではない**ことを示しています。
#### トランザクションの確認
トランザクションの結果を取得するために、トランザクションが署名された時に生成されるトランザクションハッシュが[txメソッド][]に渡されます。
要求:
```
{
"method": "tx",
"params": [
{
"transaction": "395C313F6F11F70FEBAF3785529A6D6DE3F44C7AF679515A7EAE22B30146DE57",
"binary": false
}
]
}
```
応答:
```
{
"result": {
"validated": true,
"status": "success",
"meta": {
"TransactionResult": "tesSUCCESS",
"TransactionIndex": 2,
"AffectedNodes": [...]
},
"ledger_index": 10268599[d],
"inLedger": 10268599,
"hash": "395C313F6F11F70FEBAF3785529A6D6DE3F44C7AF679515A7EAE22B30146DE57",
"date": 470798270,
"TxnSignature": "304402202646962A21EC0516FCE62DC9280F79E7265778C571E9410D795E67BB72A2D8E402202FF4AF7B2E2160F5BCA93011CB548014626CAC7FCBEBDB81FE8193CEFF69C753",
"TransactionType": "Payment",
"SigningPubKey": "0267268EE0DDDEE6A862C9FF9DDAF898CF17060A673AF771B565AA2F4AE24E3FC5",
"Sequence": 4,
"LastLedgerSequence": 10268600,
"Flags": 2147483648,
"Fee": "10000",
"Destination": "rawz2WQ8i9FdTHp4KSNpBdyxgFqNpKe8fM",
"Amount": {
"value": "10",
"issuer": "rG5Ro9e3uGEZVCh3zu5gB9ydKUskCs221W",
"currency": "FOO"
},
"Account": "rG5Ro9e3uGEZVCh3zu5gB9ydKUskCs221W"
}
}
```
この応答例には、`"validated": true`があります。これは、トランザクションが検証済みレジャーに含まれていること、つまりトランザクション結果が不変であることを示しています。 さらに、メタデータには、トランザクションがレジャーに適用されたことを示す`"TransactionResult": "tesSUCCESS"`が含まれています。
応答に`"validated": true`が含まれていない場合には、結果は暫定的であり変化する可能性があります。 最終結果を取得するには、アプリケーションで`tx`メソッドを再度呼び出し、ネットワークでさらに多くのレジャーインスタンスを検証できるよう十分な時間をかけます。 `LastLedgerSequence`で指定されたレジャーが検証されるまで待たなければならない場合もありますが、そのトランザクションが以前の検証済みレジャーに含まれている場合には、その結果はその時点で不変です。
#### 不明のトランザクションの確認
[txメソッド][]への呼び出しに`txnNotFound`エラーが返された場合には、アプリケーションで対処する必要があります。
```
{
"result": {
"status": "error",
"request": {
"transaction": "395C313F6F11F70FEBAF3785529A6D6DE3F44C7AF679515A7EAE22B30146DE56",
"command": "tx",
"binary": false
},
"error_message": "Transaction not found.",
"error_code": 24,
"error": "txnNotFound"
}
}
```
`txnNotFound`結果コードは、トランザクションがどのレジャーにも含まれていない場合に発生します。 ただし、`rippled`インスタンスに完全なレジャー履歴がない場合や、そのトランザクションが`rippled`インスタンスにまだ伝達されていない場合にも発生します。 これにどのように対処すべきかを判断するため、アプリケーションはさらに照会を行う必要があります。
[server_stateメソッド][](最後の検証済みレジャーを判断するために先に使用する)は、`result.state.complete_ledgers`のもとにレジャー履歴が完全かどうかを示します。
```
{
"result": {
"status": "success",
"state": {
"validation_quorum": 3,
"validated_ledger": {
"seq": 10269447,
"reserve_inc": 5000000,
"reserve_base": 20000000,
"hash": "D05C7ECC66DD6F4FEA3A6394F209EB5D6824A76C16438F562A1749CCCE7EAFC2",
"close_time": 470802340,
"base_fee": 10
},
"server_state": "full",
"pubkey_node": "n9LJ5eCNjeUXQpNXHCcLv9PQ8LMFYy4W8R1BdVNcpjc1oDwe6XZF",
"peers": 84,
"load_factor": 256000,
"load_base": 256,
"last_close": {
"proposers": 5,
"converge_time": 2002
},
"io_latency_ms": 1,
"complete_ledgers": "10256331-10256382,10256412-10269447",
"build_version": "0.26.4-sp3-private"
}
}
}
```
このトランザクションの例では、その時点の最後の検証済みレジャーに基づいて`LastLedgerSequence` 10268600を指定し、4を足します。 不明のトランザクションが完全に失敗したかどうかを判断するには、`rippled`サーバーに、10268597から10268600のレジャーが必要です。 サーバーの履歴にそれらの検証済みレジャーが存在し、**かつ**`tx``txnNotFound`が返される場合には、そのトランザクションは失敗であり、今後のレジャーに含めることはできません。 この場合、アプリケーションのロジックで、同じアカウントシーケンスと更新された`LastLedgerSequence`を使用して代わりのトランザクションを作成して送信することが可能です。
サーバーは、指定された`LastLedgerSequence`よりも小さい検証済みレジャーシーケンス番号をレポートする場合があります。 その場合、`txnNotFound`に、a送信されたトランザクションがまだネットワークに配布されていないこと、またはbトランザクションがネットワークに配布されたものの、まだ処理されていないことを示します。 最初のケースに対処するために、アプリケーションは再度同じ署名済みのトランザクションを送信できます。 トランザクションには固有のアカウントシーケンス番号がつけられているため、処理されるのは一度のみです。
最後に、サーバーにトランザクション履歴のギャップが1つ以上存在する場合があります。上記の応答に示される`completed_ledgers`フィールドは、このrippledインスタンスの10256383から10256411のレジャーが不足していることを示しています。 このトランザクションの例では、(トランザクションの送信時点と`LastLedgerSequence`に基づいてトランザクションは10268597から10268600のレジャーのみに含まれるため、このギャップはここでは関係ありません。 ただし、必要範囲のレジャーが不足している場合には、`txnNotFound`の結果が不変の結果であるかどうかを判断するために、アプリケーションは別のrippledサーバーに照会するまたはこのサーバーによって不足しているレジャーが取得されるまで待つ必要があります。
## その他のリソース
- [トランザクションのフォーマット](transaction-formats.html)
- [トランザクションコスト](transaction-cost.html)
- [XRP Ledger コンセンサスプロセスの概要](consensus.html)
- [コンセンサスの原理とルール](consensus-principles-and-rules.html)
<!--{# common link defs #}-->
{% include '_snippets/rippled-api-links.md' %}
{% include '_snippets/tx-type-links.md' %}
{% include '_snippets/rippled_versions.md' %}

View File

@@ -0,0 +1,386 @@
# マルチ署名済みトランザクションの送信
マルチ署名済みトランザクションを作成、署名、送信する方法を以下で説明します。
## 前提条件
- 事前にアドレスの[マルチ署名の設定](set-up-multi-signing.html)をする必要があります。
- マルチ署名は使用可能である必要があります。マルチ署名は、XRP Ledgerコンセンサスプロトコルに対する[**Amendment**](amendments.html)により2016/06/27以降利用可能になりました。
## 1.トランザクションの作成
送信するトランザクションを表すJSONオブジェクトを作成します。`Fee``Sequence`をはじめ、このトランザクションに関する _すべての_ 情報を指定する必要があります。また、トランザクションがマルチ署名済みトランザクションであることを示すため、`SigningPubKey`を空の文字列として指定します。
マルチ署名済みトランザクションの`Fee`は、標準の署名済みトランザクションよりもかなり高額ですので、ご注意ください。手数料は通常の[トランザクションコスト](transaction-cost.html)のN+1倍以上となりますNは付与する予定の署名数です。複数のソースから署名を収集するのに時間がかかることがあるため、その間に[トランザクションコスト](transaction-cost.html)の増加に備えて現行の最小値よりも大きな値を指定できます。
マルチ署名が可能なトランザクションの例を以下に示します。
{
"TransactionType":"TrustSet",
"Account":"rEuLyBCvcw4CFmzv8RepSiAoNgF8tTGJQC",
"Flags":262144,
"LimitAmount":{
"currency":"USD",
"issuer":"rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
"value":"100"
},
"Sequence":2,
"SigningPubKey":"",
"Fee":"30000"
}
このトランザクションは、残高上限額が100 USDのrEuLyBCvcw4CFmzv8RepSiAoNgF8tTGJQCから rHb9CJAWyB4rj91VRWn96DkukG4bwdtyThへの会計上の関係を作成します。
## 2.1つの署名の取得
SlignerListのメンバーの1人のシークレットキーとアドレスを指定した[sign_forメソッド][]を使用して、そのメンバーの署名を取得します。
{% include '_snippets/secret-key-warning.md' %}
<!--{#_ #}-->
$ 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"
}
}
}
応答の`tx_json`フィールドを保存します。このフィールドの`Signers`フィールドに新しい署名が入力されています。`tx_blob`フィールドの値は無視できます。
スタンドアロンモードまたは本番環境以外のネットワークで問題が発生した場合は、[マルチ署名が有効であること](start-a-new-genesis-ledger-in-stand-alone-mode.html#新しいジェネシスレジャーの設定)を確認してください。
## 3.追加の署名の取得
追加の署名は平行して取得するか、または順次取得することができます。 
* 並行して取得する場合: トランザクションの元のJSONを指定した`sign_for`コマンドを使用します。各応答の`Signers`配列に1つの署名が含まれています。
* 順次取得する場合: 前の`sign_for`応答の`tx_json`値を指定した`sign_for`コマンドを使用します。各応答の既存の`Signers`配列に新しい署名が追加されます。
{% include '_snippets/secret-key-warning.md' %}
<!--{#_ #}-->
$ 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"
}
}
}
構成したSignerListによっては、必要なすべての当事者からの署名を取得するためにこのステップを複数回繰り返す必要があります。
## 4.署名の結合と送信
署名を順次収集した場合、最後の`sign_for`応答の`tx_json`ではすべての署名が結合されているので、これを[submit_multisignedメソッド][]の引数として使用できます。
署名を並行して収集した場合、すべての署名を含む`tx_json`オブジェクトを手動で作成する必要があります。すべての`sign_for`応答の`Signers`配列の内容を1つの`Signers`配列に結合します。この配列には各署名が含まれます。結合された`Signers`配列を元のトランザクションのJSON値に追加し、これを[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"
}
}
}
応答の`hash`値をメモしておきます。これにより、後でトランザクションの結果を確認できます。(この例ではハッシュは`BD636194C48FD7A100DE4C972336534C8E710FD008C0F3CF7BC5BF34DAF3C3E6`です。)
## 5.レジャーの閉鎖
本番環境のネットワークを使用している場合は、レジャーが自動的に閉鎖するまで47秒待つことがあります。
スタンドアロンモードで`rippled`を実行している場合は、[ledger_acceptメソッド][]を使用してレジャーを手動で閉鎖します。
$ 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.トランザクション結果の確認
`submit_multisigned`コマンドの応答のハッシュ値を使用して、[txメソッド][]でトランザクションを検索します。特に`TransactionResult`が文字列`tesSUCCESS`であることを確認してください。
本番環境のネットワークでは、`validated`フィールドがブール値`true`に設定されていることも確認する必要があります。このフィールドが`true`ではない場合は、コンセンサスプロセスの完了までしばらく待機する必要があるか、または何らかの理由でトランザクションをレジャーに記録できない可能性があります。
スタンドアロンモードでは、サーバーは手動で閉鎖されたレジャーを自動的に`validated`とみなします。
$ 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
}
}
<!--{# common link defs #}-->
{% include '_snippets/rippled-api-links.md' %}
{% include '_snippets/tx-type-links.md' %}
{% include '_snippets/rippled_versions.md' %}

View File

@@ -0,0 +1,605 @@
# 取引所としてのXRPの上場
本書では、取引所がXRPを上場するために必要なステップを説明します。
## Alpha Exchange
本書での説明目的で、架空の企業である _Alpha Exchange_ を使用して、XRPを上場するために必要な手順の概要を説明します。本書では、Alpha Exchangeは以下のような取引所です。
* 現在BTC/USDの上場を専門としています
* BTC/XRPとXRP/USDの取引ペアの追加を希望しています
* すべての顧客の残高を保持しています
* サポートしている各通貨の残高を保持しています
### ユーザーの利益
Alpha Exchangeは、BTC/XRPおよびXRP/USDの取引ペアを上場することを希望しています。理由の1つとして、これらのペアがユーザーにとって有用なものであることが挙げられます。特に、このサポートによりユーザーは以下ができるようになります。
* XRP Ledger _から_ Alpha Exchange _に_ XRPを入金できます
* Alpha Exchange _から_ XRP Ledger _に_ XRPを送金できます
* XRPをBTCやUSDなどの他の通貨と交換できます
## XRPをサポートするための前提条件
XRPをサポートするために、Alpha Exchangeでは以下を行う必要があります。
* 新しい[アカウント](#アカウント)を作成して維持します
* [バランスシート](#バランスシート)を作成して維持します
関連項目:
* [ゲートウェイコンプライアンス](become-an-xrp-ledger-gateway.html#gateway-compliance) — ゲートウェイと取引所は異なりますが、取引所は地域の規制に準拠し、適切な当局の監督下になければなりません。
* [Requirements for Sending to XRP Ledger](become-an-xrp-ledger-gateway.html#requirements-for-sending-to-xrp-ledger)
* [Requirements for Receiving from XRP Ledger](become-an-xrp-ledger-gateway.html#requirements-for-receiving-from-xrp-ledger)
* [ゲートウェイの注意事項](become-an-xrp-ledger-gateway.html#precautions)
### Partial Payments
追加の前に、取引所は[Partial Payments](partial-payments.html)機能について知っておく必要があります。この機能を使用すると、XRP Ledgerのユーザーは、`SendMax`を増やさずに、受取金額を減額して、支払いを正常に送信できます。この機能は、送信者側に追加費用が発生せず、[支払いの返金](become-an-xrp-ledger-gateway.html#bouncing-payments)に便利です。
#### Partial Paymentsに関する警告
[tfPartialPaymentフラグ](payment.html#paymentのフラグ)が有効にされると、`Amount`フィールド **_は受取り金額とは同じでなくなることがあります_** 。支払いのメタデータにある`delivered_amount`フィールドは、宛先アカウントが実際に受け取る通貨の金額を示しています。支払いを受信するときに、Amountフィールドの代わりに、`delivered_amount`を使用してアカウントで受信した金額を判断します。
**警告:** この機能が悪用されることがあります。詳細については、[Partial Payments](partial-payments.html)を参照してください。
### アカウント
XRPは、XRP Ledgerの _アカウント_ _ウォレット__アドレス_ とも呼ばれるで保持されます。XRP Ledgerのアカウントは、例えばBitcoinのような、アカウントに経費がほとんどまたは一切かからない他のブロックチェーンの台帳とは異なります。XRP Ledgerでは、アカウントは[決して削除できず](accounts.html#アカウントの永続性)、各アカウントは個別の、他の人に送信することのできない、[XRPの準備金](reserves.html)を保持する必要があります。このような理由から、Rippleでは利用機関に対し、必要のない過剰なアカウントを作成しないように勧めています。
<!-- STYLE_OVERRIDE: hot wallet, warm wallet, cold wallet, wallet -->
Rippleが推奨するベストプラクティスに従い、Alpha Exchangeは、XRP Ledgerに最低2つのアカウントを作成する必要があります。シークレットキーが悪用された場合の危険を最小限にとどめるため、Rippleでは、[ _コールドアカウント_ 、 _ホットアカウント_ 、 _ウォームアカウント_ ](https://ripple.com/build/issuing-operational-addresses/)(それぞれコールドウォレット、ホットウォレット、ウォームウォレットとも呼ばれる)の作成をお勧めしています。コールド/ホット/ウォームのモデルは、セキュリティと利便性のバランスをとるためのものです。XRPを上場する取引所は、以下のアカウントを作成する必要があります。
* 大部分のXRPと顧客の資金を維持する[ _コールドウォレット_ ](issuing-and-operational-addresses.html#発行アドレス)。取引所にとって、これはユーザーが[預入れ](#取引所へのxrpの入金)をするアドレスです。 セキュリティを最適化するため、このアカウントのシークレットキーはオフラインにする必要があります。
取引所のコールドウォレットが悪用されると、以下のような結果が生じるおそれがあります。
* 不正使用者が、コールドウォレットの全XRPにアクセスできます。
* マスターキーが悪用されると、不正使用者はマスターキーを無効にし、新しいレギュラーキーや署名者リストを設定することによりそのコールドウォレットを恒久的に制御できます。これにより、その不正使用者は今後そのコールドウォレットで受信するすべてのXRPも制御できるようになります。
* このような事態が発生した場合には、取引所は新しいコールドウォレットアドレスを作成し、顧客にその新しいアドレスを伝える必要があります。
* レギュラーキーや署名者リストが悪用された場合には、取引所はコールドウォレットの制御を取り戻すことができます。ただし、不正使用者の行為の中には、以下のように簡単に元に戻せないものもあります。 <!-- STYLE_OVERRIDE: easily -->
* 不正使用者が、コールドウォレットを使用してXRP Ledgerで通貨を発行しても、その通貨の価値はだれにも認められません。取引所が明示的にゲートウェイでもあると示した場合を除きます
* 不正使用者が、アカウントにasfRequireAuthフラグを設定した場合。この設定は解除できません。ただし、これは通貨の発行のみに関係し、ゲートウェイではない取引所には影響しません。不正使用者がマスターキーで設定または設定解除したその他の設定は、元に戻すことができます。
* 顧客のXRP出金や入金を管理する、日常業務を遂行するための1つ以上の[ _ホットウォレット_ ](issuing-and-operational-addresses.html#運用アドレス)。例えば、ホットウォレットがあれば、取引所はこの種のXRPの自動送金を安全にサポートできます。出金要求にただちに応じるため、ホットウォレットはオンラインである必要があります。
不正使用されたホットウォレットによって発生するおそれのある結果についての詳細は、[Operational Account Compromise](issuing-and-operational-addresses.html#運用アドレスの漏えい)を参照してください。
* オプションとして、コールドウォレットとホットウォレットの間で追加のセキュリティ層を提供する、1つ以上のウォームウォレット。ホットウォレットとは異なり、ウォームウォレットのシークレットキーはオンラインである必要はありません。さらに、ウォームウォレットのシークレットキーを複数の人に分散し、[マルチ署名](multi-signing.html)を導入してセキュリティを強化することもできます。
不正使用されたウォームウォレットによって発生するおそれのある結果についての詳細は、[スタンバイアドレスの漏えい](issuing-and-operational-addresses.html#スタンバイアドレスの漏えい)を参照してください。
関連項目:
* ["Suggested Business Practices" in the _Gateway Guide_](become-an-xrp-ledger-gateway.html#suggested-business-practices)
* [発行アドレスと運用アドレス](issuing-and-operational-addresses.html)
* [アカウントの作成](accounts.html#アカウントの作成)
* [準備金](reserves.html)
### バランスシート
顧客のXRPを管理するため、Alpha Exchangeは各顧客のXRP残高と自身の保有残高を追跡する必要があります。このためには、Alpha Exchangeは別のバランスシートまたは会計システムを作成し、維持する必要があります。以下の表は、このバランスシートを説明するものです。
新しいXRP Ledgerアカウント _Alpha Hot__Alpha Warm__Alpha Cold_ )が、「*XRP LedgerのXRP残高*」表の*ユーザー*列に示されています。
「*Alpha ExchangeのXRP残高*」表は、新しい追加のバランスシートを表します。Alpha Exchangeのソフトウェアは、この会計システムでユーザーのXRP残高を管理します。
<table>
<tr>
<td><b><i>XRP Ledgerの
XRP残高</i></b></td>
<td></td>
<td></td>
<td><b><i>Alpha Exchange
のXRP残高</i></b></td>
<td></td>
<td></td>
</tr>
<tr>
<td><b>ユーザー</b></td>
<td><b>残高</b></td>
<td></td>
<td><b>アカウント番号</b></td>
<td><b>ユーザー</b></td>
<td><b>残高</b></td>
</tr>
<tr>
<td>Dave</td>
<td>25,000</td>
<td></td>
<td>123</td>
<td>Alice</td>
<td>0</td>
</tr>
<tr>
<td>Edward</td>
<td>45,000</td>
<td></td>
<td>456</td>
<td>Bob</td>
<td>0</td>
</tr>
<tr>
<td>Charlie</td>
<td>50,000</td>
<td></td>
<td>789</td>
<td>Charlie</td>
<td>0</td>
</tr>
<tr>
<td><i>Alpha Hot</i></td>
<td>0</td>
<td></td>
<td>...</td>
<td></td>
<td></td>
</tr>
<tr>
<td><i>Alpha Warm</i></td>
<td>0</td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td><i>Alpha Cold</i></td>
<td>0</td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>...</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</table>
#### XRPの額
XRPの額は、XRP Ledgerで、符号なし整数の _drop_ として示されます。1XRPは1,000,000 dropです。Rippleでは、ソフトウェアでXRP残高をdropの整数値として格納し、これらの数値に整数演算を実行することをお勧めしています。ただし、ユーザーインターフェイスでは残高をXRPの単位で表示すべきです。
1drop.000001XRPはこれ以上分割できません。XRPと他の資産の間でFXレートを計算して表示するときには、この点にご注意ください。
詳細は、[通貨額の指定][]を参照してください。
#### 台帳上と台帳外
_Alpha Exchange_ のような取引所では、XRPは「台帳上」または「台帳外」に存在します。
* **台帳上のXRP**: XRP保有者のパブリック[アドレス](accounts.html#アドレス)を指定し、パブリックのXRP Ledgerを通じて照会できるXRP。これらの残高の取引相手はXRP Ledgerです。詳細については、[XRP](xrp.html)を参照してください。
* **台帳外のXRP**: 取引所の会計システムに保持されている、取引所のインターフェイスで照会できるXRP。台帳外のXRP残高はクレジットペースです。取引相手は、XRPを保有している取引所です。
台帳外のXRP残高は、取引所の参加者の間で取引されます。このような取引をサポートするため、取引所は取引で使用可能な、 _台帳外_ のXRP合計金額に等しい _台帳上_ のXRP残高を保持する必要があります。
## 資金の流れ
残りのセクションでは、ユーザーによる入金、取引、XRP残高の換金の過程で、Alpha Exchangeが管理するアカウントを通じて資金がどのように流れるのかを説明します。資金の流れを解説するため、本書では、[「バランスシート」セクション](#バランスシート)で使用した表を使用します。
取引所の一般的な資金の流れには、主要な4つステップが伴います。
1. [取引所へのXRPの入金](#取引所へのxrpの入金)
2. [XRPの保有高のリバランス](#xrpの保有高のリバランス)
3. [取引所からのXRPの出金](#取引所からのxrpの出金)
4. [取引所でのXRPの取引](#取引所でのxrpの取引)
このリストには、取引所の[前提条件](#xrpをサポートするための前提条件)が含まれていません。
この時点で、 _Alpha Exchange_ はXRP Ledgerの[ホットウォレット、ウォームウォレット、コールドウォレット](#アカウント)を作成し、それらをバランスシートに追加しましたが、ユーザーからの入金はまだ受け付けていません。
<table>
<tr>
<td><b><i>XRP Ledgerの
XRP残高</i></b></td>
<td></td>
<td></td>
<td><b><i>Alpha Exchange
のXRP残高</i></b></td>
<td></td>
<td></td>
</tr>
<tr>
<td><b>ユーザー</b></td>
<td><b>残高</b></td>
<td></td>
<td><b>アカウント番号</b></td>
<td><b>ユーザー</b></td>
<td><b>残高</b></td>
</tr>
<tr>
<td>Dave</td>
<td>25,000</td>
<td></td>
<td>123</td>
<td>Alice</td>
<td>0</td>
</tr>
<tr>
<td>Edward</td>
<td>45,000</td>
<td></td>
<td>456</td>
<td>Bob</td>
<td>0</td>
</tr>
<tr>
<td>Charlie</td>
<td>50,000</td>
<td></td>
<td>789</td>
<td>Charlie</td>
<td>0</td>
</tr>
<tr>
<td><i>Alpha Hot</i></td>
<td>0</td>
<td></td>
<td>...</td>
<td></td>
<td></td>
</tr>
<tr>
<td><i>Alpha Warm</i></td>
<td>0</td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td><i>Alpha Cold</i></td>
<td>0</td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>...</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</table>
### 取引所へのXRPの入金
[台帳外のXRP残高](#台帳上と台帳外)を追跡するには、取引所は新しい[バランスシート](#バランスシート)または類似の会計システムを作成する必要があります。以下の表は、ユーザーがXRPを入金するにつれ、Alpha Exchangeの新しいバランスシートで発生する残高の変化を示すものです。
CharlieというユーザーがAlpha Exchangeに50,000XRPを入金したいと希望しています。これには、以下のステップが伴います。
1. Charlieは50,000XRPの支払いを[RippleAPI](rippleapi-reference.html)または類似のソフトウェアを使用して、Alpha Exchangeの[コールドウォレット](#アカウント)に送信します。
a. Charlieは識別子このケースでは`789`を支払いに追加し、Alpha Exchangeにある自身のアカウントに関連付けます。これは、[ _宛先タグ_ ](become-an-xrp-ledger-gateway.html#source-and-destination-tags)と呼ばれます。これを使用するには、Alpha Exchangeは、すべての入金でCharlieのような宛先タグを必要とするように、すべてのアカウントでasfRequireDestフラグをオンに設定している必要があります。詳細については、[AccountSet Flags](accountset.html#accountsetのフラグ)を参照してください。)
2. Alpha Exchangeのソフトウェアは、受信される支払を検出し、`789`をチャーリーのアカウントの宛先タグとして認識します。
3. 受信される支払を検出すると、Alpha Exchangeのソフトウェアは、入金された50,000XRPがCharlieによって管理されるものであることを示すようにバランスシートを更新します。
Charlieは、これで、取引所で最大50,000XRPまで使用できます。例えば、XRPをBTCやその他のAlpha Exchangeでサポートされている通貨と取引するオファー注文を作成できます。
<table>
<tr>
<td><b><i>XRP Ledgerの
XRP残高</i></b></td>
<td></td>
<td></td>
<td><b><i>Alpha Exchange
のXRP残高</i></b></td>
<td></td>
<td></td>
</tr>
<tr>
<td><b>ユーザー</b></td>
<td><b>残高</b></td>
<td></td>
<td><b>アカウント番号</b></td>
<td><b>ユーザー</b></td>
<td><b>残高</b></td>
</tr>
<tr>
<td>Dave</td>
<td>25,000</td>
<td></td>
<td>123</td>
<td>Alice</td>
<td>0</td>
</tr>
<tr>
<td>Edward</td>
<td>45,000</td>
<td></td>
<td>456</td>
<td>Bob</td>
<td>0</td>
</tr>
<tr>
<td>Charlie</td>
<td><s>100,000</s>
<br>50,000</td>
<td></td>
<td>789</td>
<td>Charlie</td>
<td><s>0</s>
<br>50,000</td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Alpha Hot</td>
<td>0</td>
<td></td>
<td>...</td>
<td></td>
<td></td>
</tr>
<tr>
<td>Alpha Warm</td>
<td>0</td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Alpha Cold</td>
<td><s>0</s>
<br>50,000</td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>...</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</table>
### 取引所でのXRPの取引
Alpha ExchangeユーザーCharlieなどは、Alpha Exchangeでクレジットベースの残高を取引できます。Alpha Exchangeは、これらの取引の作成時に、新しいバランスシートでユーザーの残高を追跡する必要があります。これらの取引は、 _台帳外_ であり、XRP Ledgerから独立しています。このため、この残高の変化はXRP Ledgerには記録されません。
XRPを自身のXRP Ledgerアカウントに保有している顧客は、XRP Ledgerに組み込まれた分散型取引所 を使用して、ゲートウェイによって発行された通貨を取引することもできます。XRP Ledger _上_ での取引の詳細は、[オファーのライフサイクル](offers.html#オファーのライフサイクル)を参照してください。
### XRPの保有高のリバランス
取引所は、いつでもホットウォレットとコールドウォレットの間で残高を調整できます。各残高調整には、[トランザクションコスト](transaction-cost.html)がかかりますが、それ以外にはすべてのアカウントの合計残高に影響はありません。台帳上の合計残高は、取引所で取引に使用できる合計残高を常に上回る必要があります。XRP Ledgerのトランザクションコストをカバーできるだけの十分な余剰が必要です。
以下の表は、XRP Ledgerで[Paymentトランザクション][]を介したAlpha Exchangeのコールドウォレットとホットウォレットの間での80,000XRPの残高調整を示すものです。コールドウォレットから引き落としが行われ、ホットウォレットに入金が行われました。この支払いを逆にするとホットウォレットから引き落としが行われ、コールドウォレットに入金が行われる、ホットウォレットの残高は減少します。このような残高調整は、取引所がオンラインホットウォレットにXRPを保持することに関連するリスクを抑えるために役立ちます。
<table>
<tr>
<td><b><i>Alpha Exchangeの
台帳外のXRP残高</i></b></td>
<td></td>
<td></td>
<td></td>
<td><b><i>Alpha Exchangeの台帳上のXRP残高</i></b></td>
<td></td>
</tr>
<tr>
<td><b>アカウント番号</b></td>
<td><b>ユーザー</b></td>
<td><b>残高</b></td>
<td></td>
<td><b>XRP Ledgerアカウント</b></td>
<td><b>残高</b></td>
</tr>
<tr>
<td>123</td>
<td>Alice</td>
<td>80,000</td>
<td></td>
<td>ホット</td>
<td><s>0</s>
<br>80,000</td>
</tr>
<tr>
<td>456</td>
<td>Bob</td>
<td>50,000</td>
<td></td>
<td>ウォーム</td>
<td>0</td>
</tr>
<tr>
<td>….</td>
<td></td>
<td></td>
<td></td>
<td>….</td>
<td></td>
</tr>
<tr>
<td>789</td>
<td>Charlie</td>
<td>50,000</td>
<td></td>
<td>コールド</td>
<td><s>180,000</s>
<br>100,000</td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>...</td>
<td></td>
<td></td>
<td></td>
<td>...</td>
<td></td>
</tr>
</table>
### 取引所からのXRPの出金
出金により、取引所のユーザーは、取引所の台帳外バランスシートから、XRP LedgerのアカウントにXRPを移動できます。
この例では、Charlieは、Alpha Exchangeから25,000XRPを出金します。これには、以下のステップが伴います。
1. Charlieは、Alpha ExchangeのWebサイトでプロセスを開始します。彼は、25,000XRPをXRP Ledgerの特定のアカウント以下の表では、「Charlie XRP Ledger」という名前に送金する指示を出します。
2. Charlieの指示に対応し、Alpha Exchangeは以下の作業を実行します。
A. その金額25,000XRPを台帳外バランスシートのCharlieのアカウントから引き出します。
B. XRP Ledgerで、Alpha ExchangeのホットウォレットからCharlieのXRP Ledgerアカウントに同じ金額25,000XRPの支払いを送信します。
<table>
<tr>
<td><b><i>XRP Ledger台帳上のXRP残高</td>
<td></td>
<td></td>
<td><b><i>Alpha Exchangeの
台帳外のXRP残高</td>
<td></td>
<td></td>
<td></td>
<td><b><i>Alpha Exchangeの台帳上のXRP残高</td>
<td></td>
</tr>
<tr>
<td><b>ユーザー</td>
<td><b>残高</td>
<td></td>
<td><b>アカウント番号</td>
<td><b>ユーザー</td>
<td><b>残高</td>
<td></td>
<td><b>XRP Ledgerアカウント</td>
<td><b>残高</td>
</tr>
<tr>
<td>Dave</td>
<td>25,000</td>
<td></td>
<td>123</td>
<td>Alice</td>
<td>80,000</td>
<td></td>
<td>ホット</td>
<td><s>80,000</s>
<br>55,000</td>
</tr>
<tr>
<td>Edward</td>
<td>45,000</td>
<td></td>
<td>456</td>
<td>Bob</td>
<td>50,000</td>
<td></td>
<td>ウォーム</td>
<td>0</td>
</tr>
<tr>
<td>….</td>
<td></td>
<td></td>
<td>….</td>
<td></td>
<td></td>
<td></td>
<td>….</td>
<td></td>
</tr>
<tr>
<td>CharlieのXRP Ledger</td>
<td><s>50,000</s>
<br>75,000</td>
<td></td>
<td>789</td>
<td>Charlie</td>
<td><s>50,000</s>
<br>25,000</td>
<td></td>
<td>コールド</td>
<td>100,000</td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>...</td>
<td></td>
<td></td>
<td>...</td>
<td></td>
<td></td>
<td></td>
<td>...</td>
<td></td>
</tr>
</table>
<!--{# common link defs #}-->
{% include '_snippets/rippled-api-links.md' %}
{% include '_snippets/tx-type-links.md' %}
{% include '_snippets/rippled_versions.md' %}

View File

@@ -0,0 +1,189 @@
# XRP Chartsへの取引所の登録
XRP Chartsは、XRP Ledgerネットワークとそのアカウントおよびトランザクションに関するデータの他に、外部取引所の[XRPマーケットデータ](https://xrpcharts.ripple.com/#/xrp-markets)も提供します。このチュートリアルでは、各自の取引所とそのXRP取引、およびオーダーブックのデータをXRP Chartsに登録する方法を説明します。
XRP Chartsの取引所リストに掲載されるには、以下のデータを使用可能にしておく必要があります。取引所に、以下のデータを提供できる既存のRESTful APIエンドポイントがある場合は、タスク1と2を実行する際に必要な開発作業はほとんどありません。
1. [最近実行された取引を返すRESTful APIエンドポイントの提供](#最近実行された取引を返すrestful-apiエンドポイントの提供)。
2. [現行オーダーブックのデータを返すRESTful APIエンドポイントの提供](#現行オーダーブックのデータを返すrestful-apiエンドポイントの提供)。
次に、[XRP Chartsへの取引所登録依頼の送信](#xrp-chartsへの取引所登録依頼の送信)を行う必要があります。
エンドポイントの仕様についてのご質問は、<xrpcharts_support@ripple.com>までお問い合わせください。
## 最近実行された取引を返すRESTful APIエンドポイントの提供
特定のXRPマーケットで実行された最新の5001,000件の個別取引を返すRESTful APIエンドポイントを提供します。
取引の取りこぼしがないようにするため、XRP Chartsはエンドポイントを530秒間隔で頻繁に照会します。これは重複する取引データを含む応答を取得することを目的としています。エンドポイントにより適用されるレート制限が、この照会頻度に対応できることを確認してください。XRP Chartsは、取引が重複する場合でも一意の取引データのみを記録します。
XRP Chartsがレート制限を上回る頻度でエンドポイントを照会する必要がある場合、XRP Chartsから、レート制限を調整するか、`last_tid`パラメーターを指定するように求められます。
### 要求フォーマット
以下のような要求フォーマットを指定します。
```
GET {api_base_url}/v1/trades
```
#### 認証
XRP Chartsでは、一般にアクセス可能なエンドポイントを使用することが望まれます。
#### パラメーター
応答で返される取引をXRP Chartsで絞り込むことを可能にするパラメーターを指定します。パラメーターのフィールド名は一例です。他の名前を使用できます。エンドポイントでは省略可能なパラメーターを指定する必要はありませんが、このようなパラメーターは有用です。
| フィールド | 型 | 説明 |
|:-----------|:--------|:------------------------------------------------------|
| `market` | 文字列 | XRPがベース通貨またはクオート通貨のいずれかである特定の市場で実施された取引を返します。提案されるフォーマット`<basecurrency>_<countercurrency>`)を使用して、有効な値(`xrp_btc``btc_xrp``xrp_usd``usd_xrp`など)を指定します。 |
| `last_tid` | 整数 | _省略可_ 特定の取引IDの後で実行された取引を返します。たとえば、XRP Chartsではこのパラメーターを使用して、サイトデータに記録されている最後の取引セット以降に行われたすべての取引を取得します。これにより、すべての取引が確実に記録されます。 |
| `limit` | 整数 | _省略可_ 応答で特定の数の取引のみを返します。 |
### 応答フォーマット
正常に終了した場合の応答は、各取引を表すオブジェクトのJSON配列である必要があります。パラメーターのフィールド名は一例です。他の名前を使用できます。エンドポイントでは省略可能なパラメーターを指定する必要はありませんが、このようなパラメーターは有用です。
| フィールド | 型 | 説明 |
|:------------|:-----------------|:--------------------------------------------|
| `price` | 文字列または数値 | 取引の為替レート。 |
| `amount` | 文字列または数値 | 売買するXRPの額。 |
| `timestamp` | 文字列 | [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html)の日時フォーマットまたは[Unixの時刻](https://en.wikipedia.org/wiki/Unix_time)フォーマットでの取引実行時刻。 |
| `tid` | 整数 | _省略可_ 取引の一意のID。整数のシーケンス番号であれば理想的です。 |
| `type` | 文字列 | _省略可_ 取引のタイプ。有効な値には`buy``sell`などがあります。 |
| `size` | 文字列または数値 | _省略可_ 取引されたクオート通貨の額。 |
| `count` | 整数 | _省略可_ 応答で返す取引オブジェクトの数。 |
### 例
#### 要求の例
```
GET https://api.example.com/v1/trades?market=xrp_btc&last_tid=75208825&limit=500
```
#### 応答の例
```json
{
"trades":[
{
"tid":75209326,
"type":"buy",
"price":"0.57201",
"amount":"4954.0744",
"size":"2833.7801",
"timestamp":"2018-10-01T12:35:11.000Z"
},
...
{
"tid":75208826,
"type":"sell",
"price":"0.57201",
"amount":"4954.0744",
"size":"2833.7801",
"timestamp":"2018-10-01T12:31:16.000Z"
}
],
"count":"500"
}
```
## 現行オーダーブックのデータを返すRESTful APIエンドポイントの提供
特定マーケットの現行オーダーブックに関するデータを返すRESTful APIエンドポイントを提供します。
XRP Chartsはこのエンドポイントを約30秒間隔で照会します。
### 要求フォーマット
以下のような要求フォーマットを指定します。
```
GET {api_base_url}/v1/orderbook
```
#### 認証
XRP Chartsでは、一般にアクセス可能なエンドポイントを使用することが望まれます。
#### パラメーター
以下のパラメーターを指定します。パラメーターのフィールド名は一例です。他の名前を使用できます。
| `Field` | 型 | 説明 |
|:---------|:-------|:---------------------------------------------------------|
| `market` | 文字列 | XRPがベース通貨またはクオート通貨のいずれかである現行オーダーブックを返します。提案されるフォーマット`<basecurrency>_<countercurrency>`)を使用して、有効な値(`xrp_btc``btc_xrp``xrp_usd``usd_xrp`など)を指定します。 |
### 応答フォーマット
正常に終了した場合の応答は、現行の売値と買値からなる配列とタイムスタンプを含むJSONオブジェクトである必要があります。応答にはオーダーブック全体が含まれている必要はありません。必要とされるのは、マーケットでの現在のXRP流動性を把握するのに十分なデータだけです。パラメーターのフィールド名は一例です。他の名前を使用できます。
| フィールド | 型 | 説明 |
|:------------|:-----------------|:--------------------------------------------|
| `timestamp` | 文字列 | [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html)の日時フォーマットまたは[Unixの時刻](https://en.wikipedia.org/wiki/Unix_time)フォーマットの応答送信時刻。 |
| `bids` | オブジェクトの配列 | オーダーブックでの売値。配列の各オブジェクトには、オファーで示された`price`とその価格で使用可能な`amount`が含まれている必要があります。 |
| `asks` | オブジェクトの配列 | オーダーブックでの買値。配列の各オブジェクトには、オファーで示された`price`とその価格で使用可能な`amount`が含まれている必要があります。 |
### 例
#### 要求の例
```
GET https://api.example.com/v1/orderbook?market=xrp_btc
```
#### 応答の例
```json
{
"timestamp":"2018-10-01T12:41:16.000Z",
"bids":[
{
"price":0.00007103,
"amount":140
},
{
"price":0.000071,
"amount":135
},
{
"price":0.00007092,
"amount":5266
}
],
"asks":[
{
"price":0.00007108,
"amount":140
},
{
"price":0.00007109,
"amount":84
},
{
"price":0.0000711,
"amount":10650
}
]
}
```
## XRP Chartsへの取引所登録依頼の送信
XRP Chartsへの取引所登録のご依頼は、<xrpcharts_support@ripple.com>までご連絡ください。
依頼には、APIドキュメントへのリンクを必ず記述してください。