Translation edits, cleanup

This commit is contained in:
mDuo13
2020-06-05 20:50:10 -07:00
parent fcad9d0376
commit 83686c40c6
34 changed files with 1480 additions and 405 deletions

View File

@@ -20,7 +20,7 @@ If you get an error, try upgrading Dactyl before building:
sudo pip3 install --upgrade dactyl sudo pip3 install --upgrade dactyl
For more details, see the [contribution guidelines](CONTRIBUTING.md). For more details, see the [contribution guidelines (EN)](CONTRIBUTING.md) ([日本語](CONTRIBUTING.ja.md)) and the [contributor Code of Conduct (EN)](CODE_OF_CONDUCT.md) ([日本語](CODE_OF_CONDUCT.ja.md)).
## Domain Verification Checker ## Domain Verification Checker

View File

@@ -4,7 +4,7 @@ XRP Ledgerは、「価値のインターネット」を推進および実現可
## スタックレベル ## スタックレベル
[![4層からなるエコシステムの図: 最下層にはXRP Ledgerのピアツーピアネットワーク、その上にプログラミングライブラリー、次にミドルウェア、そして最上層にアプリとサービスがあります。](img/ecosystem.png)](img/ecosystem.png) [![4層からなるエコシステムの図: 最下層にはXRP Ledgerのピアツーピアネットワーク、その上にプログラミングライブラリー、次にミドルウェア、そして最上層にアプリとサービスがあります。](img/ecosystem.ja.png)](img/ecosystem.ja.png)
- [XRP Ledgerの基盤](#rippled-コアサーバー)は、トランザクションを共有し、[コンセンサスプロセス](consensus.html)に関与し、[トランザクション](transaction-basics.html)を処理する常時接続のサーバーのピアツーピアネットワークです。XRP Ledgerエコシステム内の他のすべてのものが、最終的にこのピアツーピアネットワーク上に直接、または間接的に構築されます。 - [XRP Ledgerの基盤](#rippled-コアサーバー)は、トランザクションを共有し、[コンセンサスプロセス](consensus.html)に関与し、[トランザクション](transaction-basics.html)を処理する常時接続のサーバーのピアツーピアネットワークです。XRP Ledgerエコシステム内の他のすべてのものが、最終的にこのピアツーピアネットワーク上に直接、または間接的に構築されます。
@@ -57,5 +57,5 @@ XRPと周辺テクロジーを使用してユーザーとやり取りする
<!--{# common link defs #}--> <!--{# common link defs #}-->
{% include '_snippets/rippled-api-links.md' %} {% include '_snippets/rippled-api-links.md' %}
{% include '_snippets/tx-type-links.md' %} {% include '_snippets/tx-type-links.md' %}
{% include '_snippets/rippled_versions.md' %} {% include '_snippets/rippled_versions.md' %}

View File

@@ -1,6 +1,6 @@
# 発行アドレスと運用アドレス # 発行アドレスと運用アドレス
{% include '_snippets/issuing-and-operational-addresses-intro.md' %} {% include '_snippets/issuing-and-operational-addresses-intro.ja.md' %}
<!--{#_ #}--> <!--{#_ #}-->
## 資金のライフサイクル ## 資金のライフサイクル

View File

@@ -3,7 +3,7 @@
XRP Ledgerの「アカウント」は、XRPの所有者と[トランザクション](transaction-formats.html)の送信者を表します。アカウントの主な要素は次のとおりです。 XRP Ledgerの「アカウント」は、XRPの所有者と[トランザクション](transaction-formats.html)の送信者を表します。アカウントの主な要素は次のとおりです。
- 識別用の**アドレス**。例えば、`rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn` - 識別用の**アドレス**。例えば、`rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn`
**注記:** XRPコミュニティは、取引所およびウォレットで[宛先タグ](https://xrpl.org/source-and-destination-tags.html)の代わりに使用できる新しいフォーマット、**X**アドレスを[提案](https://github.com/xrp-community/standards-drafts/issues/6)(これをサポートする[コーデック](https://github.com/xrp-community/xrpl-tagged-address-codec)も開発)しました。これらの「パック化」したアドレスは、`r`ではなく`X`で開始します。詳細は、[XRPL 𝗫-address format](https://xrpaddress.info/)のサイトを参照してください。 **注記:** XRPコミュニティは、取引所およびウォレットで[宛先タグ](https://xrpl.org/source-and-destination-tags.html)の代わりに使用できる新しいフォーマット、**X**アドレスを[提案](https://github.com/xrp-community/standards-drafts/issues/6)(これをサポートする[コーデック](https://github.com/xrp-community/xrpl-tagged-address-codec)も開発)しました。これらの「パック化」したアドレスは、`r`ではなく`X`で開始します。詳細は、[XRPL 𝗫-address format](https://xrpaddress.info/)のサイトを参照してください。
- **XRPの残高**。このXRPの一部は、[準備金](reserves.html)用に確保されています。 - **XRPの残高**。このXRPの一部は、[準備金](reserves.html)用に確保されています。
@@ -29,14 +29,14 @@ XRP Ledgerでアカウントを取得する一般的な方法は次のとおり
1. ランダム性の強いソースからキーペアを生成し、そのキーペアのアドレスを計算します。(例えば、[wallet_proposeメソッド][]を使用して計算することができます。) 1. ランダム性の強いソースからキーペアを生成し、そのキーペアのアドレスを計算します。(例えば、[wallet_proposeメソッド][]を使用して計算することができます。)
2. XRP Ledgerにアカウントをすでに持っているユーザーに、生成したアドレスにXRPを送信してもらいます。 2. XRP Ledgerにアカウントをすでに持っているユーザーに、生成したアドレスにXRPを送信してもらいます。
- 例えば、一般の取引所でXRPを購入し、その取引所から、指定したアドレスにXRPを引き出すことができます。 - 例えば、一般の取引所でXRPを購入し、その取引所から、指定したアドレスにXRPを引き出すことができます。
**注意:** 自身のXRP Ledgerアドレスで初めてXRPを受け取る場合は[アカウントの準備金](reserves.html)現在は20 XRPを支払う必要があります。この金額のXRPは無期限に使用できなくなります。一方で、一般の取引所では通常、顧客のXRPはすべて、共有されたいくつかのXRP Ledgerアカウントに保有されているため、顧客はその取引所で個々のアカウントの準備金を支払う必要はありません。引き出す前に、XRP Ledgerに直接アカウントを保有することが、金額に見合う価値があるかどうかを検討してください。 **注意:** 自身のXRP Ledgerアドレスで初めてXRPを受け取る場合は[アカウントの準備金](reserves.html)現在は20 XRPを支払う必要があります。この金額のXRPは無期限に使用できなくなります。一方で、一般の取引所では通常、顧客のXRPはすべて、共有されたいくつかのXRP Ledgerアカウントに保有されているため、顧客はその取引所で個々のアカウントの準備金を支払う必要はありません。引き出す前に、XRP Ledgerに直接アカウントを保有することが、金額に見合う価値があるかどうかを検討してください。
## アドレス ## アドレス
{% include '_snippets/data_types/address.md' %} {% include '_snippets/data_types/address.ja.md' %}
有効なアドレスに資金供給することで、そのアドレスを[XRP Ledgerのアカウントにする](#アカウントの作成)ことができます。[レギュラーキー](setregularkey.html)または[署名者リスト](multi-signing.html)のメンバーを表すために資金供給されていないアドレスを使用することもできます。資金供給されたアカウントのみがトランザクションの送信者になることができます。 有効なアドレスに資金供給することで、そのアドレスを[XRP Ledgerのアカウントにする](#アカウントの作成)ことができます。[レギュラーキー](setregularkey.html)または[署名者リスト](multi-signing.html)のメンバーを表すために資金供給されていないアドレスを使用することもできます。資金供給されたアカウントのみがトランザクションの送信者になることができます。
@@ -111,12 +111,12 @@ XRP Ledgerのアドレスは、[base58](https://en.wikipedia.org/wiki/Base58)_
次の図は、キーとアドレスの関係を示しています。 次の図は、キーとアドレスの関係を示しています。
[![マスター公開鍵 + プレフィクスの種類 → アカウントID + チェックサム → アドレス](img/address-encoding.png)](img/address-encoding.png) [![マスター公開鍵 + プレフィクスの種類 → アカウントID + チェックサム → アドレス](img/address-encoding.ja.png)](img/address-encoding.ja.png)
公開鍵からXRP Ledgerアドレスを計算する式は次のとおりです。コード例全体については、[`encode_address.js`](https://github.com/ripple/ripple-dev-portal/blob/master/content/_code-samples/address_encoding/encode_address.js)を参照してください。パスフレーズまたはシード値から公開鍵を導出するプロセスについては、[鍵の導出](cryptographic-keys.html#鍵導出)を参照してください。 公開鍵からXRP Ledgerアドレスを計算する式は次のとおりです。コード例全体については、[`encode_address.js`](https://github.com/ripple/ripple-dev-portal/blob/master/content/_code-samples/address_encoding/encode_address.js)を参照してください。パスフレーズまたはシード値から公開鍵を導出するプロセスについては、[鍵の導出](cryptographic-keys.html#鍵導出)を参照してください。
1. 次の必須アルゴリズムをインポートします。SHA-256、RIPEMD160、base58。base58のディクショナリーを設定します。 1. 次の必須アルゴリズムをインポートします。SHA-256、RIPEMD160、base58。base58のディクショナリーを設定します。
'use strict'; 'use strict';
const assert = require('assert'); const assert = require('assert');
const crypto = require('crypto'); const crypto = require('crypto');
@@ -127,35 +127,35 @@ XRP Ledgerのアドレスは、[base58](https://en.wikipedia.org/wiki/Base58)_
assert(crypto.getHashes().includes('ripemd160')); assert(crypto.getHashes().includes('ripemd160'));
2. 33バイトのECDSA secp256k1公開鍵、または32バイトのEd25519公開鍵で始めます。Ed25519キーの場合は、キーの前にバイト`0xED`を付けます。 2. 33バイトのECDSA secp256k1公開鍵、または32バイトのEd25519公開鍵で始めます。Ed25519キーの場合は、キーの前にバイト`0xED`を付けます。
const pubkey_hex = const pubkey_hex =
'ED9434799226374926EDA3B54B1B461B4ABF7237962EAE18528FEA67595397FA32'; 'ED9434799226374926EDA3B54B1B461B4ABF7237962EAE18528FEA67595397FA32';
const pubkey = Buffer.from(pubkey_hex, 'hex'); const pubkey = Buffer.from(pubkey_hex, 'hex');
assert(pubkey.length == 33); assert(pubkey.length == 33);
3. 公開鍵のSHA-256ハッシュの[RIPEMD160](https://en.wikipedia.org/wiki/RIPEMD)ハッシュを計算します。この値は「Account ID」です。 3. 公開鍵のSHA-256ハッシュの[RIPEMD160](https://en.wikipedia.org/wiki/RIPEMD)ハッシュを計算します。この値は「Account ID」です。
const pubkey_inner_hash = crypto.createHash('sha256').update(pubkey); const pubkey_inner_hash = crypto.createHash('sha256').update(pubkey);
const pubkey_outer_hash = crypto.createHash('ripemd160'); const pubkey_outer_hash = crypto.createHash('ripemd160');
pubkey_outer_hash.update(pubkey_inner_hash.digest()); pubkey_outer_hash.update(pubkey_inner_hash.digest());
const account_id = pubkey_outer_hash.digest(); const account_id = pubkey_outer_hash.digest();
4. アカウントIDのSHA-256ハッシュのSHA-256ハッシュを計算します。最初の4バイトを使用ます。この値が「チェックサム」です。 4. アカウントIDのSHA-256ハッシュのSHA-256ハッシュを計算します。最初の4バイトを使用ます。この値が「チェックサム」です。
const address_type_prefix = Buffer.from([0x00]); const address_type_prefix = Buffer.from([0x00]);
const payload = Buffer.concat([address_type_prefix, account_id]); const payload = Buffer.concat([address_type_prefix, account_id]);
const chksum_hash1 = crypto.createHash('sha256').update(payload).digest(); const chksum_hash1 = crypto.createHash('sha256').update(payload).digest();
const chksum_hash2 = crypto.createHash('sha256').update(chksum_hash1).digest(); const chksum_hash2 = crypto.createHash('sha256').update(chksum_hash1).digest();
const checksum = chksum_hash2.slice(0,4); const checksum = chksum_hash2.slice(0,4);
5. ペイロードとチェックサムを連結します。連結バッファーのbase58値を計算します。この結果が、該当のアドレスになります。 5. ペイロードとチェックサムを連結します。連結バッファーのbase58値を計算します。この結果が、該当のアドレスになります。
const dataToEncode = Buffer.concat([payload, checksum]); const dataToEncode = Buffer.concat([payload, checksum]);
const address = base58.encode(dataToEncode); const address = base58.encode(dataToEncode);
console.log(address); console.log(address);
// rDTXLQ7ZKZVKz33zJbHjgVShjsBnqMBhmN // rDTXLQ7ZKZVKz33zJbHjgVShjsBnqMBhmN
## 関連項目 ## 関連項目
- **コンセプト:** - **コンセプト:**

View File

@@ -140,29 +140,29 @@ XRP Ledgerでは、サポートされているさまざまなタイプのキー
### Ed25519鍵導出 ### Ed25519鍵導出
[[ソース]](https://github.com/ripple/rippled/blob/fc7ecd672a3b9748bfea52ce65996e324553c05f/src/ripple/protocol/impl/SecretKey.cpp#L203 "Source") [[ソース]](https://github.com/ripple/rippled/blob/fc7ecd672a3b9748bfea52ce65996e324553c05f/src/ripple/protocol/impl/SecretKey.cpp#L203 "Source")
[![パスフレーズ → シード → 秘密鍵 → プレフィクス + 公開鍵](img/key-derivation-ed25519.png)](img/key-derivation-ed25519.png) [![パスフレーズ → シード → 秘密鍵 → プレフィクス + 公開鍵](img/key-derivation-ed25519.ja.png)](img/key-derivation-ed25519.ja.png)
1. シード値の[SHA-512Half][]を計算します。32バイトの秘密鍵が導出されます。 1. シード値の[SHA-512Half][]を計算します。32バイトの秘密鍵が導出されます。
**ヒント:** 32バイトの数値はすべて、有効なEd25519秘密鍵です。ただし、秘密鍵として使用する上で安全なのは、十分ランダムに選択された数値のみです。 **ヒント:** 32バイトの数値はすべて、有効なEd25519秘密鍵です。ただし、秘密鍵として使用する上で安全なのは、十分ランダムに選択された数値のみです。
2. Ed25519公開鍵を計算するには、[Ed25519](https://ed25519.cr.yp.to/software.html)の標準公開鍵を導出して、32バイトの公開鍵を導出します。 2. Ed25519公開鍵を計算するには、[Ed25519](https://ed25519.cr.yp.to/software.html)の標準公開鍵を導出して、32バイトの公開鍵を導出します。
**注意:** 暗号化アルゴリズムの場合と同様に、可能な場合は必ず、公的に監査された既知の標準実装を使用します。例えば、[OpenSSL](https://www.openssl.org/)には、コア関数であるEd25519やsecp256k1が実装されています。 **注意:** 暗号化アルゴリズムの場合と同様に、可能な場合は必ず、公的に監査された既知の標準実装を使用します。例えば、[OpenSSL](https://www.openssl.org/)には、コア関数であるEd25519やsecp256k1が実装されています。
3. Ed25519公開鍵を示すには、32バイトの公開鍵の前にシングルバイトのプレフィクス`0xED`を付加し、33バイトにします。 3. Ed25519公開鍵を示すには、32バイトの公開鍵の前にシングルバイトのプレフィクス`0xED`を付加し、33バイトにします。
トランザクションに署名するコードを実装している場合は、プレフィクス`0xED`を削除し、実際の署名プロセスに32バイトキーを使用します。 トランザクションに署名するコードを実装している場合は、プレフィクス`0xED`を削除し、実際の署名プロセスに32バイトキーを使用します。
4. アカウントの公開鍵を[base58][]にシリアル化する場合は、アカウントの公開鍵プレフィクス`0x23`を使用します。 4. アカウントの公開鍵を[base58][]にシリアル化する場合は、アカウントの公開鍵プレフィクス`0x23`を使用します。
バリデータの一時キーにEd25519を使用することはできません。 バリデータの一時キーにEd25519を使用することはできません。
### secp256k1鍵導出 ### secp256k1鍵導出
[[ソース]](https://github.com/ripple/rippled/blob/develop/src/ripple/crypto/impl/GenerateDeterministicKey.cpp "Source") [[ソース]](https://github.com/ripple/rippled/blob/develop/src/ripple/crypto/impl/GenerateDeterministicKey.cpp "Source")
[![パスフレーズ → シード → ルートキーペア → 仲介銀行(機関)キーペア → マスターキーペア](img/key-derivation-secp256k1.png)](img/key-derivation-secp256k1.png) [![パスフレーズ → シード → ルートキーペア → 仲介銀行(機関)キーペア → マスターキーペア](img/key-derivation-secp256k1.ja.png)](img/key-derivation-secp256k1.ja.png)
XRP Ledgerアカウントキーでのsecp256k1鍵導出に、Ed25519鍵導出よりも多くの手順が含まれる理由は次のとおりです。 XRP Ledgerアカウントキーでのsecp256k1鍵導出に、Ed25519鍵導出よりも多くの手順が含まれる理由は次のとおりです。
@@ -172,53 +172,53 @@ XRP Ledgerアカウントキーでのsecp256k1鍵導出に、Ed25519鍵導出よ
シード値からXRP Ledgerのsecp256k1アカウントキーペアを導出する手順は次のとおりです。 シード値からXRP Ledgerのsecp256k1アカウントキーペアを導出する手順は次のとおりです。
1. 次のように、シード値から「ルートキーペア」を計算します。 1. 次のように、シード値から「ルートキーペア」を計算します。
1. 以下を順番に連結して、合計20バイトにします。 1. 以下を順番に連結して、合計20バイトにします。
- シード値16バイト - シード値16バイト
- 「ルートシーケンス」値4バイト。ビッグエンディアンの符号なし整数。ルートシーケンスの開始値として0を使用します。 - 「ルートシーケンス」値4バイト。ビッグエンディアンの符号なし整数。ルートシーケンスの開始値として0を使用します。
2. 連結された(シード+ルートシーケンス)値の[SHA-512Half][]を計算します。 2. 連結された(シード+ルートシーケンス)値の[SHA-512Half][]を計算します。
3. 結果が有効なsecp265k1秘密鍵でない場合は、ルートシーケンスを1増やして最初からやり直します。[[ソース]](https://github.com/ripple/rippled/blob/fc7ecd672a3b9748bfea52ce65996e324553c05f/src/ripple/crypto/impl/GenerateDeterministicKey.cpp#L103 "Source") 3. 結果が有効なsecp265k1秘密鍵でない場合は、ルートシーケンスを1増やして最初からやり直します。[[ソース]](https://github.com/ripple/rippled/blob/fc7ecd672a3b9748bfea52ce65996e324553c05f/src/ripple/crypto/impl/GenerateDeterministicKey.cpp#L103 "Source")
有効なsecp256k1鍵は0であってはならず、 _secp256k1グループ_ の数値順よりも低くなければなりません。secp256k1グループの順序は、定数`0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141`です。 有効なsecp256k1鍵は0であってはならず、 _secp256k1グループ_ の数値順よりも低くなければなりません。secp256k1グループの順序は、定数`0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141`です。
4. 有効なsecp256k1秘密鍵を使用して、secp256k1曲線で標準ECDSA公開鍵を導出し、ルート公開鍵を導出します。暗号化アルゴリズムの場合と同様に、可能な場合は必ず、公的に監査された既知の標準実装を使用します。例えば、[OpenSSL](https://www.openssl.org/)には、コア関数であるEd25519およびsecp256k1が実装されています。 4. 有効なsecp256k1秘密鍵を使用して、secp256k1曲線で標準ECDSA公開鍵を導出し、ルート公開鍵を導出します。暗号化アルゴリズムの場合と同様に、可能な場合は必ず、公的に監査された既知の標準実装を使用します。例えば、[OpenSSL](https://www.openssl.org/)には、コア関数であるEd25519およびsecp256k1が実装されています。
**ヒント:** バリデータではこのルートキーペアを使用します。バリデータのキーペアを計算する場合は、ここで停止できます。この2つのタイプの公開鍵を区別するには、バリデータの公開鍵の[base58][]シリアル化でプレフィクス`0x1c`を使用します。 **ヒント:** バリデータではこのルートキーペアを使用します。バリデータのキーペアを計算する場合は、ここで停止できます。この2つのタイプの公開鍵を区別するには、バリデータの公開鍵の[base58][]シリアル化でプレフィクス`0x1c`を使用します。
2. ルート公開鍵を33バイトの圧縮形式に変換します。 2. ルート公開鍵を33バイトの圧縮形式に変換します。
ECDSA公開鍵の非圧縮形式は、32バイト整数のペアX座標とY座標で構成されます。圧縮形式は、X座標と1バイトのプレフィクスのみで構成されます。Y座標が偶数の場合は`0x02`、Y座標が奇数の場合は`0x03`です。 ECDSA公開鍵の非圧縮形式は、32バイト整数のペアX座標とY座標で構成されます。圧縮形式は、X座標と1バイトのプレフィクスのみで構成されます。Y座標が偶数の場合は`0x02`、Y座標が奇数の場合は`0x03`です。
非圧縮形式の公開鍵を圧縮形式に変換するには、`openssl`コマンドラインツールを使用します。例えば、非圧縮の公開鍵がファイル`ec-pub.pem`にある場合は、次のような圧縮形式を出力できます。 非圧縮形式の公開鍵を圧縮形式に変換するには、`openssl`コマンドラインツールを使用します。例えば、非圧縮の公開鍵がファイル`ec-pub.pem`にある場合は、次のような圧縮形式を出力できます。
$ openssl ec -in ec-pub.pem -pubin -text -noout -conv_form compressed $ openssl ec -in ec-pub.pem -pubin -text -noout -conv_form compressed
3. 次のように、圧縮されたルート公開鍵から「仲介銀行(機関)キーペア」を導出します。 3. 次のように、圧縮されたルート公開鍵から「仲介銀行(機関)キーペア」を導出します。
1. 以下を順番に連結して、合計40バイトにします。 1. 以下を順番に連結して、合計40バイトにします。
- 圧縮されたルート公開鍵33バイト - 圧縮されたルート公開鍵33バイト
- `0x00000000000000000000000000000000` (4バイトのゼロ)この値は、同じファミリーの異なるメンバーの導出に使用することを目的としていましたが、実際には値0のみが使用されます。 - `0x00000000000000000000000000000000` (4バイトのゼロ)この値は、同じファミリーの異なるメンバーの導出に使用することを目的としていましたが、実際には値0のみが使用されます。
- 「キーシーケンス」値4バイト。ビッグエンディアンの符号なし整数。キーシーケンスの開始値として0を使用します。 - 「キーシーケンス」値4バイト。ビッグエンディアンの符号なし整数。キーシーケンスの開始値として0を使用します。
2. 連結された値の[SHA-512Half][]を計算します。 2. 連結された値の[SHA-512Half][]を計算します。
3. 結果が有効なsecp265k1秘密鍵でない場合は、キーシーケンスを1増やし、アカウントの仲介銀行機関キーペアの導出をやり直します。 3. 結果が有効なsecp265k1秘密鍵でない場合は、キーシーケンスを1増やし、アカウントの仲介銀行機関キーペアの導出をやり直します。
4. 有効なsecp256k1秘密鍵を使用して、secp256k1曲線で標準ECDSA公開鍵を導出し、仲介銀行機関公開鍵を導出します。暗号化アルゴリズムの場合と同様に、可能な場合は必ず、公的に監査された既知の標準実装を使用します。例えば、[OpenSSL](https://www.openssl.org/)には、コア関数であるEd25519およびsecp256k1が実装されています。 4. 有効なsecp256k1秘密鍵を使用して、secp256k1曲線で標準ECDSA公開鍵を導出し、仲介銀行機関公開鍵を導出します。暗号化アルゴリズムの場合と同様に、可能な場合は必ず、公的に監査された既知の標準実装を使用します。例えば、[OpenSSL](https://www.openssl.org/)には、コア関数であるEd25519およびsecp256k1が実装されています。
4. 仲介銀行(機関)公開鍵をルート公開鍵に追加して、マスター公開鍵ペアを導出します。同様に、仲介銀行(機関)秘密鍵をルート秘密鍵に追加して秘密鍵を導出します。 4. 仲介銀行(機関)公開鍵をルート公開鍵に追加して、マスター公開鍵ペアを導出します。同様に、仲介銀行(機関)秘密鍵をルート秘密鍵に追加して秘密鍵を導出します。
- ECDSA秘密鍵は非常に大きな整数値であるため、secp256k1グループ順序を法として2つの秘密鍵を合計することで、2つの秘密鍵の合計を計算できます。 - ECDSA秘密鍵は非常に大きな整数値であるため、secp256k1グループ順序を法として2つの秘密鍵を合計することで、2つの秘密鍵の合計を計算できます。
- ECDSA公開鍵は楕円曲線上の点であるため、楕円曲線の数値を使用して点の合計値を計算する必要があります。 - ECDSA公開鍵は楕円曲線上の点であるため、楕円曲線の数値を使用して点の合計値を計算する必要があります。
5. 以前と同様に、マスター公開鍵を33バイトの圧縮形式に変換します。 5. 以前と同様に、マスター公開鍵を33バイトの圧縮形式に変換します。
6. アカウントの公開鍵を[base58][]形式にシリアル化する場合は、アカウントの公開鍵プレフィクス`0x23`を使用します。 6. アカウントの公開鍵を[base58][]形式にシリアル化する場合は、アカウントの公開鍵プレフィクス`0x23`を使用します。
アカウントの公開鍵からそのアドレスに変換するための情報とサンプルコードについては、[アドレスのエンコード](accounts.html#アドレスのエンコード)を参照してください。 アカウントの公開鍵からそのアドレスに変換するための情報とサンプルコードについては、[アドレスのエンコード](accounts.html#アドレスのエンコード)を参照してください。

View File

@@ -11,7 +11,7 @@ _トランザクション取引_ は、XRP Ledgerを変更する唯一の
だれでも最終的なステータスを確認として[ハッシュによってトランザクションを調べる](look-up-transaction-results.html)ことができるため、トランザクションハッシュは「支払いの証明」として使用することができます。 だれでも最終的なステータスを確認として[ハッシュによってトランザクションを調べる](look-up-transaction-results.html)ことができるため、トランザクションハッシュは「支払いの証明」として使用することができます。
{% include '_snippets/setfee_uniqueness_note.md' %} {% include '_snippets/setfee_uniqueness_note.ja.md' %}
<!--_ --> <!--_ -->

View File

@@ -4954,19 +4954,19 @@ XRP Ledgerでの**XRP以外の通貨**の額の精度は次のようになりま
### アドレス ### アドレス
[アドレス]: #アドレス [アドレス]: #アドレス
{% include '_snippets/data_types/address.md' %} {% include '_snippets/data_types/address.ja.md' %}
### 公開鍵 ### 公開鍵
[公開鍵]: #公開鍵 [公開鍵]: #公開鍵
{% include '_snippets/data_types/public_key.md' %} {% include '_snippets/data_types/public_key.ja.md' %}
### ハッシュ ### ハッシュ
[ハッシュ]: #ハッシュ [ハッシュ]: #ハッシュ
{% include '_snippets/data_types/hash.md' %} {% include '_snippets/data_types/hash.ja.md' %}
### タイムスタンプ ### タイムスタンプ
@@ -4989,17 +4989,17 @@ XRP Ledgerでの**XRP以外の通貨**の額の精度は次のようになりま
### レジャーインデックス ### レジャーインデックス
[レジャーインデックス]: #レジャーインデックス [レジャーインデックス]: #レジャーインデックス
{% include '_snippets/data_types/ledger_index.md' %} {% include '_snippets/data_types/ledger_index.ja.md' %}
### アカウントシーケンス ### アカウントシーケンス
[シーケンス番号]: #アカウントシーケンス [シーケンス番号]: #アカウントシーケンス
{% include '_snippets/data_types/account_sequence.md' %} {% include '_snippets/data_types/account_sequence.ja.md' %}
### 通貨コード ### 通貨コード
[通貨コード]: #通貨コード [通貨コード]: #通貨コード
{% include '_snippets/data_types/currency_code.md' %} {% include '_snippets/data_types/currency_code.ja.md' %}
## ページネーション ## ページネーション

View File

@@ -1,7 +1,7 @@
# can_delete # can_delete
[[ソース]<br>](https://github.com/ripple/rippled/blob/master/src/ripple/rpc/handlers/CanDelete.cpp "Source") [[ソース]<br>](https://github.com/ripple/rippled/blob/master/src/ripple/rpc/handlers/CanDelete.cpp "Source")
`can_delete`メソッドは`rippled`サーバーに対し最新のレジャーバージョンを通知します。この最新バージョンは[指示による削除が有効なオンライン削除](online-deletion.html#指示による削除)を使用するときに削除できます。指示による削除が有効ではない場合、このメソッドは何も行いません。<!-- NOTE: I'm pretty sure this is slightly wrong. --@mDuo13 --> `can_delete`メソッドは[指示による削除が有効なオンライン削除](online-deletion.html#指示による削除)を使用する`rippled`サーバーに削除が可能のレジャーバージョンを通知します。指定したレジャーバージョン以前が削除可能になります。指示による削除が有効ではない場合、このメソッドは何も行いません。
_`can_delete`メソッドは、権限のないユーザーは実行できない[管理メソッド](admin-rippled-methods.html)です。_ _`can_delete`メソッドは、権限のないユーザーは実行できない[管理メソッド](admin-rippled-methods.html)です。_

View File

@@ -120,7 +120,7 @@ Connecting to 127.0.0.1:5005
`previous`フィールドが指定されている場合は、このピアリザベーションの以前のステータスが次のフィールドとともに表示されます。 `previous`フィールドが指定されている場合は、このピアリザベーションの以前のステータスが次のフィールドとともに表示されます。
{% include '_snippets/peer_reservation_object.md' %} {% include '_snippets/peer_reservation_object.ja.md' %}
<!--_ --> <!--_ -->

View File

@@ -118,7 +118,7 @@ Connecting to 127.0.0.1:5005
`previous`フィールドが指定されている場合は、このピアリザベーションの以前のステータスが次のフィールドとともに表示されます。 `previous`フィールドが指定されている場合は、このピアリザベーションの以前のステータスが次のフィールドとともに表示されます。
{% include '_snippets/peer_reservation_object.md' %} {% include '_snippets/peer_reservation_object.ja.md' %}
<!--_ --> <!--_ -->
### 考えられるエラー ### 考えられるエラー

View File

@@ -121,7 +121,7 @@ Loading: "/etc/rippled.cfg"
`reservations`配列の各メンバーは、1つの[ピアリザベーション][]を表すJSONオブジェクトです。このオブジェクトのフィールドを次に示します。 `reservations`配列の各メンバーは、1つの[ピアリザベーション][]を表すJSONオブジェクトです。このオブジェクトのフィールドを次に示します。
{% include '_snippets/peer_reservation_object.md' %} {% include '_snippets/peer_reservation_object.ja.md' %}
<!--_ --> <!--_ -->
### 考えられるエラー ### 考えられるエラー

View File

@@ -11,14 +11,14 @@
## アドレス ## アドレス
[アドレス]: #アドレス [アドレス]: #アドレス
{% include '_snippets/data_types/address.md' %} {% include '_snippets/data_types/address.ja.md' %}
<!--{#_ #}--> <!--{#_ #}-->
## ハッシュ ## ハッシュ
[ハッシュ]: #ハッシュ [ハッシュ]: #ハッシュ
{% include '_snippets/data_types/hash.md' %} {% include '_snippets/data_types/hash.ja.md' %}
<!--{#_ #}--> <!--{#_ #}-->
### ハッシュプレフィクス ### ハッシュプレフィクス
@@ -52,14 +52,14 @@
## アカウントシーケンス ## アカウントシーケンス
[シーケンス番号]: #アカウントシーケンス [シーケンス番号]: #アカウントシーケンス
{% include '_snippets/data_types/account_sequence.md' %} {% include '_snippets/data_types/account_sequence.ja.md' %}
<!--{#_ #}--> <!--{#_ #}-->
## レジャーインデックス ## レジャーインデックス
[レジャーインデックス]: #レジャーインデックス [レジャーインデックス]: #レジャーインデックス
{% include '_snippets/data_types/ledger_index.md' %} {% include '_snippets/data_types/ledger_index.ja.md' %}
<!--{#_ #}--> <!--{#_ #}-->
@@ -149,7 +149,7 @@ XRPを金額なしで指定する場合は主に、オーダーブックを
### 通貨コード ### 通貨コード
[通貨コード]: #通貨コードs [通貨コード]: #通貨コードs
{% include '_snippets/data_types/currency_code.md' %} {% include '_snippets/data_types/currency_code.ja.md' %}
<!--{#_ #}--> <!--{#_ #}-->

View File

@@ -18,7 +18,7 @@
## レジャーインデックス ## レジャーインデックス
{% include '_snippets/data_types/ledger_index.md' %} {% include '_snippets/data_types/ledger_index.ja.md' %}
<!--{#_ #}--> <!--{#_ #}-->

View File

@@ -29,7 +29,7 @@
| ReserveIncrement | 符号なし整数 | UInt32 | 増分準備金drop数 | | ReserveIncrement | 符号なし整数 | UInt32 | 増分準備金drop数 |
| LedgerSequence | 数値 | UInt32 | _過去に発生した`SetFee`疑似トランザクションの場合は省略_ この擬似トランザクションが表示されるレジャーバージョンのインデックス。これにより、この疑似トランザクションと別途発生する同様の変更が区別されます。 | | LedgerSequence | 数値 | UInt32 | _過去に発生した`SetFee`疑似トランザクションの場合は省略_ この擬似トランザクションが表示されるレジャーバージョンのインデックス。これにより、この疑似トランザクションと別途発生する同様の変更が区別されます。 |
{% include '_snippets/setfee_uniqueness_note.md' %} {% include '_snippets/setfee_uniqueness_note.ja.md' %}
<!--{# common link defs #}--> <!--{# common link defs #}-->
{% include '_snippets/rippled-api-links.md' %} {% include '_snippets/rippled-api-links.md' %}

View File

@@ -135,7 +135,7 @@
## 4. 検証の待機 ## 4. 検証の待機
{% include '_snippets/wait-for-validation.md' %} <!--#{ fix md highlighting_ #}--> {% include '_snippets/wait-for-validation.ja.md' %} <!--#{ fix md highlighting_ #}-->
## 5. 新しい署名者リストの確認 ## 5. 新しい署名者リストの確認

View File

@@ -165,7 +165,7 @@
## 次のステップ ## 次のステップ
{% include '_snippets/post-rippled-install.md' %}<!--_ --> {% include '_snippets/post-rippled-install.ja.md' %}<!--_ -->
## 関連項目 ## 関連項目

View File

@@ -49,7 +49,7 @@
## 次のステップ ## 次のステップ
{% include '_snippets/post-rippled-install.md' %}<!--_ --> {% include '_snippets/post-rippled-install.ja.md' %}<!--_ -->
## 関連項目 ## 関連項目

View File

@@ -79,7 +79,7 @@
## 次のステップ ## 次のステップ
{% include '_snippets/post-rippled-install.md' %} {% include '_snippets/post-rippled-install.ja.md' %}
<!--_ --> <!--_ -->

View File

@@ -180,7 +180,7 @@ ShardStore:ERR shard 2236: No such file or directory
2018-Aug-28 22:56:22.256065549 Validations:WRN Unable to determine hash of ancestor seq=3 from ledger hash=00B1E512EF558F2FD9A0A6C263B3D922297F26A55AEB56A009341A22895B516E seq=12133675 2018-Aug-28 22:56:22.256065549 Validations:WRN Unable to determine hash of ancestor seq=3 from ledger hash=00B1E512EF558F2FD9A0A6C263B3D922297F26A55AEB56A009341A22895B516E seq=12133675
``` ```
{% include '_snippets/unsynced_warning_logs.md' %} {% include '_snippets/unsynced_warning_logs.ja.md' %}
<!--_ --> <!--_ -->
@@ -194,7 +194,7 @@ ShardStore:ERR shard 2236: No such file or directory
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"} 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"}
``` ```
{% include '_snippets/unsynced_warning_logs.md' %} {% include '_snippets/unsynced_warning_logs.ja.md' %}
<!--_ --> <!--_ -->
@@ -204,7 +204,7 @@ ShardStore:ERR shard 2236: No such file or directory
NetworkOPs:WRN We are not running on the consensus ledger NetworkOPs:WRN We are not running on the consensus ledger
``` ```
{% include '_snippets/unsynced_warning_logs.md' %} {% include '_snippets/unsynced_warning_logs.ja.md' %}
<!--_ --> <!--_ -->

View File

@@ -145,7 +145,7 @@ Checkを取り消す例を以下に示します。
## {{cancel_n.next()}}.検証の待機 ## {{cancel_n.next()}}.検証の待機
{% include '_snippets/wait-for-validation.md' %} <!--#{ fix md highlighting_ #}--> {% include '_snippets/wait-for-validation.ja.md' %} <!--#{ fix md highlighting_ #}-->
## {{cancel_n.next()}}.最終結果の確認 ## {{cancel_n.next()}}.最終結果の確認

View File

@@ -13,7 +13,7 @@ Checkから可能な限りの額を受領したい場合には、変動金額で
## 前提条件 ## 前提条件
{% include '_snippets/checkcash-prereqs.md' %}<!--#{ fix md highlighting_ #}--> {% include '_snippets/checkcash-prereqs.ja.md' %}<!--#{ fix md highlighting_ #}-->
## {{cash_flex_n.next()}}.CheckCashトランザクションの準備 ## {{cash_flex_n.next()}}.CheckCashトランザクションの準備
@@ -113,7 +113,7 @@ Checkを変動金額で換金するためのトランザクションを準備す
## {{cash_flex_n.next()}}.検証の待機 ## {{cash_flex_n.next()}}.検証の待機
{% include '_snippets/wait-for-validation.md' %} <!--#{ fix md highlighting_ #}--> {% include '_snippets/wait-for-validation.ja.md' %} <!--#{ fix md highlighting_ #}-->
## {{cash_flex_n.next()}}.最終結果の確認 ## {{cash_flex_n.next()}}.最終結果の確認

View File

@@ -10,7 +10,7 @@ Checkがレジャーに含まれており有効期限切れではない場合は
## 前提条件 ## 前提条件
{% include '_snippets/checkcash-prereqs.md' %} <!--#{ fix md highlighting_ #}--> {% include '_snippets/checkcash-prereqs.ja.md' %} <!--#{ fix md highlighting_ #}-->
## {{cash_exact_n.next()}}.CheckCashトランザクションの準備 ## {{cash_exact_n.next()}}.CheckCashトランザクションの準備
@@ -112,7 +112,7 @@ Checkを正確な金額で換金するためのトランザクションを準備
## {{cash_exact_n.next()}}.検証の待機 ## {{cash_exact_n.next()}}.検証の待機
{% include '_snippets/wait-for-validation.md' %} <!--#{ fix md highlighting_ #}--> {% include '_snippets/wait-for-validation.ja.md' %} <!--#{ fix md highlighting_ #}-->
## {{cash_exact_n.next()}}.最終結果の確認 ## {{cash_exact_n.next()}}.最終結果の確認

View File

@@ -174,7 +174,7 @@ Checkの額と、Checkを現金化できる当事者を決定します。[CheckC
## {{send_n.next()}}.検証の待機 ## {{send_n.next()}}.検証の待機
{% include '_snippets/wait-for-validation.md' %} {% include '_snippets/wait-for-validation.ja.md' %}
<!--{#_ #}--> <!--{#_ #}-->
## {{send_n.next()}}.最終結果の確認 ## {{send_n.next()}}.最終結果の確認

View File

@@ -89,7 +89,7 @@ _Websocket_
## 3.検証の待機 ## 3.検証の待機
{% include '_snippets/wait-for-validation.md' %} <!--#{ fix md highlighting_ #}--> {% include '_snippets/wait-for-validation.ja.md' %} <!--#{ fix md highlighting_ #}-->
## 4.最終結果の確認 ## 4.最終結果の確認

View File

@@ -96,7 +96,7 @@ print(cancel_after)
## 4.検証の待機 ## 4.検証の待機
{% include '_snippets/wait-for-validation.md' %} <!--#{ fix md highlighting_ #}--> {% include '_snippets/wait-for-validation.ja.md' %} <!--#{ fix md highlighting_ #}-->
## 5.Escrowが作成されたことの確認 ## 5.Escrowが作成されたことの確認
@@ -162,7 +162,7 @@ _Websocket_
## 7.検証の待機 ## 7.検証の待機
{% include '_snippets/wait-for-validation.md' %} <!--#{ fix md highlighting_ #}--> {% include '_snippets/wait-for-validation.ja.md' %} <!--#{ fix md highlighting_ #}-->
## 8.最終結果の確認 ## 8.最終結果の確認

View File

@@ -70,7 +70,7 @@ print(release_date_ripple)
## 3.検証の待機 ## 3.検証の待機
{% include '_snippets/wait-for-validation.md' %} <!--#{ fix md highlighting_ #}--> {% include '_snippets/wait-for-validation.ja.md' %} <!--#{ fix md highlighting_ #}-->
## 4.Escrowが作成されたことの確認 ## 4.Escrowが作成されたことの確認
@@ -169,7 +169,7 @@ Escrowが有効期限切れの場合は、[Escrowの取消し](cancel-an-expired
## 7.検証の待機 ## 7.検証の待機
{% include '_snippets/wait-for-validation.md' %} <!--#{ fix md highlighting_ #}--> {% include '_snippets/wait-for-validation.ja.md' %} <!--#{ fix md highlighting_ #}-->
## 8.最終結果の確認 ## 8.最終結果の確認

View File

@@ -1,6 +1,6 @@
# 信頼できるトランザクションの送信 # 信頼できるトランザクションの送信
XRP Ledgerを使用する金融機関やその他のサービスは、ここで説明するベストプラクティスを使用し、迅速で確認可能な方法で、トランザクションが検証または拒否されるようにする必要があります。 信頼できる(ローカルで運営されている)`rippled`サーバーにトランザクションを送信してください。 XRP Ledgerを使用する金融機関やその他のサービスは、ここで説明するベストプラクティスを使用し、迅速で確認可能な方法で、トランザクションが検証または拒否されるようにする必要があります。信頼できるローカルで運営されている`rippled`サーバーにトランザクションを送信してください。
本書で説明されているベストプラクティスを使用すると、アプリケーションはアーカイブ中にトランザクションをXRP Ledgerに送信できます。 本書で説明されているベストプラクティスを使用すると、アプリケーションはアーカイブ中にトランザクションをXRP Ledgerに送信できます。
@@ -13,98 +13,91 @@ XRP Ledgerを使用する金融機関やその他のサービスは、ここで
2. 暫定的なトランザクションを、最終的で不変の結果として誤判断する。 2. 暫定的なトランザクションを、最終的で不変の結果として誤判断する。
3. レジャーに以前に適用されたトランザクションの正式な結果を検出できない。 3. レジャーに以前に適用されたトランザクションの正式な結果を検出できない。
こういったタイプのエラーは、深刻な問題に繋がる可能性があります。 例えば、以前のPaymentトランザクションを検出できないアプリケーションは、誤ってトランザクションを再送信してしまい、元の支払いが重複してしまう可能性があります。 したがって、本書で説明するテクニックを使用し、アプリケーションが正式なトランザクション結果に基づいてアクションをとることが非常に重要です。 こういったタイプのエラーは、深刻な問題に繋がる可能性があります。例えば、以前のPaymentトランザクションを検出できないアプリケーションは、誤ってトランザクションを再送信してしまい、元の支払いが重複してしまう可能性があります。したがって、本書で説明するテクニックを使用し、アプリケーションが正式なトランザクション結果に基づいてアクションをとることが非常に重要です。
## 背景 ## 背景
XRP Ledgerプロトコルは、ネットワークのすべてのサーバーで共有されるレジャー台帳を提供します。 [コンセンサスと検証のプロセス](https://ripple.com/build/ripple-ledger-consensus-process/)を通じ、ネットワークはトランザクションがレジャーに適用される(または除外される)順序に同意します。 XRP Ledgerプロトコルは、ネットワークのすべてのサーバーで共有されるレジャー台帳を提供します。[コンセンサスと検証のプロセス](consensus.html)を通じ、ネットワークはトランザクションがレジャーに適用される(または除外される)順序に同意します。
正しい形式のトランザクションを信頼できるXRP Ledgerサーバーに送信すると、数秒で検証または拒否されます。 ただし、正しい形式のトランザクションであっても迅速に検証も拒否もされないことがあります。このような特殊なケースは、アプリケーションがトランザクションを送信した後にグーバル[トランザクションコスト](transaction-cost.html)が増加すると発生することがあります。 トランザクションに指定された額よりもトランザクションコストが増加すると、そのトランザクションは次回の検証済みレジャーに含まれません。後日、グローバルトランザクションコストが下がった場合には、そのトランザクションは後のレジャーに含まれます。トランザクションに有効期限が指定されていない場合には、レジャーへの追加はいつになるか分かりません。 正しい形式のトランザクションを信頼できるXRP Ledgerサーバーに送信すると、数秒で検証または拒否されます。ただし、正しい形式のトランザクションであっても迅速に検証も拒否もされないことがあります。このような特殊なケースは、アプリケーションがトランザクションを送信した後にグーバル[トランザクションコスト](transaction-cost.html)が増加すると発生することがあります。トランザクションに指定された額よりもトランザクションコストが増加すると、そのトランザクションは次回の検証済みレジャーに含まれません。後日、グローバルトランザクションコストが下がった場合には、そのトランザクションは後のレジャーに含まれます。トランザクションに有効期限が指定されていない場合には、レジャーへの追加はいつになるか分かりません。
電源やネットワークに障害が発生した場合には、送信済みトランザクションのステータスの検出時にさらに多くの問題に直面します。アプリケーションは、トランザクションの適切な送信と、その後の正式結果の適切な受信の両方に十分な注意を払う必要があります。 電源やネットワークに障害が発生した場合には、送信済みトランザクションのステータスの検出時にさらに多くの問題に直面します。アプリケーションは、トランザクションの適切な送信と、その後の正式結果の適切な受信の両方に十分な注意を払う必要があります。
### トランザクションのタイムライン ### トランザクションのタイムライン
XRP Ledgerには、[`rippled` API](rippled-api.html)や[RippleAPI](rippleapi-reference.html)など、トランザクションを送信するためのAPIがいくつかあります。 使用するAPIにかかわらず、トランザクションは以下のようにレジャーに適用されます。 XRP Ledgerには、[`rippled` API](rippled-api.html)や[RippleAPI](rippleapi-reference.html)など、トランザクションを送信するためのAPIがいくつかあります。使用するAPIにかかわらず、トランザクションは以下のようにレジャーに適用されます。
1. アカウント所有者は、トランザクションを作成して署名します。 1. アカウント所有者は、トランザクションを作成して署名します。
2. 所有者は、トランザクション候補として、そのトランザクションをネットワークに送信します。 2. 所有者は、トランザクション候補として、そのトランザクションをネットワークに送信します。
- 形式が正しくないトランザクションや無意味なトランザクションはただちに拒否されます。 - 形式が正しくないトランザクションや無意味なトランザクションはただちに拒否されます。
- 形式が正しいトランザクションは、暫定的に成功し、後で失敗することもあります。 - 形式が正しいトランザクションは、暫定的に成功し、後で失敗することもあります。
- 形式が正しいトランザクションは、暫定的に失敗し、後で成功することもあります。 - 形式が正しいトランザクションは、暫定的に失敗し、後で成功することもあります。
- 形式が正しいトランザクションは、暫定的に成功し、後で少々異なった形で成功することもあります。(例えば、別のオファーが使用され、暫定的な結果よりも良い(または悪い)替レートになることがあります。) - 形式が正しいトランザクションは、暫定的に成功し、後で少々異なった形で成功することもあります。(例えば、別のオファーが使用され、暫定的な結果よりも良い(または悪い)替レートになることがあります。)
3. コンセンサスと検証を通じ、トランザクションがレジャーに適用されます。ネットワークの伝達のコストを適用するために、一部の失敗したトランザクションも適用されることがあります。 3. コンセンサスと検証を通じ、トランザクションがレジャーに適用されます。ネットワークの伝達のコストを適用するために、一部の失敗したトランザクションも適用されることがあります。
4. 検証されたレジャーにはそのトランザクションが含まれ、その結果がレジャーの状態に反映されます。 4. 検証されたレジャーにはそのトランザクションが含まれ、その結果がレジャーの状態に反映されます。
- トランザクション結果は暫定的なものではなくなり、成功または失敗の結果は最終的かつ不変のものとなります。 - トランザクション結果は暫定的なものではなくなり、成功または失敗の結果は最終的かつ不変のものとなります。
**注記:** `rippled`を介してトランザクションを送信すると、送信コマンドから返される成功ステータスコードによって、`rippled`サーバーがトランザクション候補を受信したことが示されます。このトランザクションは、検証されたレジャーに適用される場合とされない場合があります。 **注記:** `rippled`を介してトランザクションを送信すると、送信コマンドから返される成功ステータスコードによって、`rippled`サーバーがトランザクション候補を受信したことが示されます。このトランザクションは、検証されたレジャーに適用される場合とされない場合があります。
APIは、現在の進行中のレジャーにトランザクション候補を適用した結果に基づいて、暫定的な結果を返すことがあります。アプリケーションでは、この結果を、トランザクションの最終的な*不変の*結果と混同してはなりません。 不変の結果は、検証済みのレジャーだけにあります。 アプリケーションは、トランザクション結果を含むレジャーが検証されるまで、トランザクションのステータスを繰り返し照会する必要があります。 APIは、現在の進行中のレジャーにトランザクション候補を適用した結果に基づいて、暫定的な結果を返すことがあります。アプリケーションでは、この結果を、トランザクションの最終的な*不変の*結果と混同してはなりません。不変の結果は、検証済みのレジャーだけにあります。アプリケーションは、トランザクション結果を含むレジャーが検証されるまで、トランザクションのステータスを繰り返し照会する必要があります。
トランザクションの適用時に、`rippled`サーバーは、*最後に検証されたレジャー*を使用します。これは、すでにネットワーク全体によって検証されたトランザクションに基づくレジャーの状態のスナップショットです。 コンセンサスと検証のプロセスは、新しいトランザクションのセットを、最後に検証されたレジャーに正規の順序で適用します。その結果、新しい検証済みレジャーが出来上がります。 この新しい検証済みレジャーインスタンスとその前のインスタンスがレジャー履歴形成ます。 トランザクションの適用時に、`rippled`サーバーは、*最後に検証されたレジャー*を使用します。これは、すでにネットワーク全体によって検証されたトランザクションに基づくレジャーの状態のスナップショットです。コンセンサスと検証のプロセスは、新しいトランザクションのセットを、最後に検証されたレジャーに正規の順序で適用します。その結果、新しい検証済みレジャーが出来上がります。この新しい検証済みレジャーバージョンとその前のバージョンによって、レジャー履歴形成されます。
検証済みの各レジャーインスタンスにはシーケンス番号が付けられます。これは、前のインスタンスのシーケンス番号よりも1つ大きい番号です。また、各レジャーには識別用のハッシュ値があります。これは、レジャーの内容から決定される固有の値です。進行中のレジャーには多数のバージョンが存在することがあります。その場合、シーケンス番号は同じですが、ハッシュ値が異なります。検証できるのは、1つのバージョンのみです。 レジャーの各バージョンにはレジャーインデックスが付けられており、前のレジャーバージョンのレジャーインデックスよりも1つ大きい値になります。また、各レジャーには識別用のハッシュ値があります。これは、レジャーの内容から決定される固有の値です。進行中のレジャーには多数のバージョンが存在することがあります。その場合、レジャーインデックスは同じですが、ハッシュ値が異なります。検証できるのは、1つのバージョンのみです。
各検証済みレジャーには、トランザクションが適用される正規の順序があります。この順序は、レジャーの最終的なトランザクションセットに基づいて決定されます。これと異なり、各`rippled`サーバーの進行中のレジャーでは、トランザクションの受信時に増分計算されます。トランザクションを暫定的に実行する順序は、新しい検証済みレジャーを構築するためにトランザクションを実行する順序とは通常異なります。これが、トランザクションの暫定的な結果が最終結果とは異なる可能性がある理由の1つです。例えば、ある支払いが、同じオファーを使用する別の支払いの前と後のどちらで実行されるかによって、最終的な為替レートが異なることがあります。 各検証済みレジャーには、トランザクションが適用される正規の順序があります。この順序は、レジャーの最終的なトランザクションセットに基づいて決定されます。これと異なり、各`rippled`サーバーの進行中のレジャーでは、トランザクションの受信時に増分計算されます。トランザクションを暫定的に実行する順序は、新しい検証済みレジャーを構築するためにトランザクションを実行する順序とは通常異なります。これが、トランザクションの暫定的な結果が最終結果とは異なる可能性がある理由の1つです。例えば、ある支払いが、同じオファーを使用する別の支払いの前と後のどちらで実行されるかによって、最終的な為替レートが異なることがあります。
### LastLedgerSequence ### LastLedgerSequence
`LastLedgerSequence`は、省略可能な[全トランザクションに適用されるパラメーター](transaction-common-fields.html)です。 このパラメーターはXRP Ledgerに、トランザクションを特定のレジャーインスタンスで検証する必要があること、またはトランザクションを特定のレジャーインスタンスの前に検証する必要があることを指示します。 XRP Ledgerは、シーケンス番号がトランザクションの`LastLedgerSequence`パラメーターよりも大きいトランザクションをレジャーインスタンスに含めることは決してありません。 `LastLedgerSequence`は、省略可能な[全トランザクションに適用されるパラメーター](transaction-common-fields.html)です。このパラメーターはXRP Ledgerに対して、トランザクションを特定のレジャーバージョンで検証する必要があること、またはトランザクションを特定のレジャーバージョンの前に検証する必要があることを指示します。XRP Ledgerは、レジャーインデックスがトランザクションの`LastLedgerSequence`パラメーターよりも大きいトランザクションをレジャーバージョンに含めることは決してありません。
`LastLedgerSequence`パラメーターを使用すれば、トランザクションが迅速に確認されず、将来のレジャーに含まれるような好ましくないケースを防止できます。 `LastLedgerSequence`パラメーターは、各トランザクションに指定する必要があります。 自動プロセスでは、最後に検証されたレジャーインデックスよりも4つ大きい数値を使用して、トランザクションが予測可能な方法で、かつ迅速に検証または拒否されるようにします。 `LastLedgerSequence`パラメーターを使用すれば、トランザクションが迅速に確認されず、将来のレジャーに含まれるような好ましくないケースを防止できます。`LastLedgerSequence`パラメーターは、各トランザクションに指定する必要があります。自動プロセスでは、最後に検証されたレジャーインデックスよりも4つ大きい数値を使用して、トランザクションが予測可能な方法で、かつ迅速に検証または拒否されるようにします。
`rippled` APIを使用するアプリケーションは、トランザクションの送信時に、`LastLedgerSequence`を明示的に指定する必要があります。 `rippled` APIを使用するアプリケーションは、トランザクションの送信時に、`LastLedgerSequence`を明示的に指定する必要があります。
RippleAPIでは、[Transaction Instructions](rippleapi-reference.html#transaction-instructions)で説明されている`maxLedgerVersion`フィールドを使用して`LastLedgerSequence`を指定します。 RippleAPIは、デフォルトで自動的に適切な値を提供します。 期限なしで実行される可能性のあるトランザクションを実行する場合には、`maxLedgerVersion``null`に指定して故意に`LastLedgerSequence`を省略できますが、これはお勧めできません。 RippleAPIでは、[Transaction Instructions](rippleapi-reference.html#transaction-instructions)で説明されている`maxLedgerVersion`フィールドを使用して`LastLedgerSequence`を指定します。RippleAPIは、デフォルトで自動的に適切な値を提供します。期限なしで実行される可能性のあるトランザクションを実行する場合には、`maxLedgerVersion``null`に指定して故意に`LastLedgerSequence`を省略できますが、これはお勧めできません。
## ベストプラクティス ## ベストプラクティス
次の図は、トランザクションの送信と結果の判断に推奨されるフローを示します。
### 信頼性の高いトランザクション送信 [![信頼できるトランザクション送信フローチャート](img/reliable-tx-submission.svg)](img/reliable-tx-submission.svg)
トランザクションを送信するアプリケーションでは、以下のベストプラクティスを使用し、プロセス終了やその他の問題が発生した場合でも信頼性が高い方法でトランザクションを送信する必要があります。 アプリケーションが最終的で検証済みの結果に基づいて処理できるように、アプリケーションのトランザクション結果を確認する必要があります。 ### 信頼できるトランザクションの送信
トランザクションを送信するアプリケーションでは、以下のベストプラクティスを使用し、プロセス終了やその他の問題が発生した場合でも信頼性が高い方法でトランザクションを送信する必要があります。アプリケーションが最終的で検証済みの結果に基づいて処理できるように、アプリケーションのトランザクション結果を確認する必要があります。
送信と確認は別々の異なる手続きであり、本書の説明に基づいてこれを実装することができます。 送信と確認は別々の異なる手続きであり、本書の説明に基づいてこれを実装することができます。
1. 送信 - トランザクションがネットワークに送信され、暫定的な結果が戻されます。 1. 送信 - トランザクションがネットワークに送信され、暫定的な結果が戻されます。
2. 確認 - 検証済みレジャーを確認し、正式な結果が判断されます。 2. 確認 - 検証済みレジャーを確認し、正式な結果が判断されます。
### 送信 ### 送信
送信が完了する前に電源障害やネットワーク障害が発生する可能性に備え、送信前にトランザクションの詳細を[保持](https://en.wikipedia.org/wiki/Persistence_%28computer_science%29)しておきます。 再起動時に、保持された値により、トランザクションのステータスを確認することが可能になります。 送信が完了する前に電源障害やネットワーク障害が発生する可能性に備え、送信前にトランザクションの詳細を[保持](https://en.wikipedia.org/wiki/Persistence_%28computer_science%29)しておきます。再起動時に、保持された値により、トランザクションのステータスを確認することが可能になります。
送信プロセスは次のとおりです。 送信プロセスは次のとおりです。
1. トランザクションを生成して署名します 1. トランザクションを生成して署名します
- `LastLedgerSequence`パラメーターを指定します - `LastLedgerSequence`パラメーターを指定します
2. 以下を保存して、トランザクション詳細を保持しておきます 2. 以下を保存して、トランザクション詳細を保持しておきます
- トランザクションハッシュ - トランザクションハッシュ
- LastLedgerSequence - `LastLedgerSequence`
- 送信者のアドレスとシーケンス番号 - 送信者のアドレスとシーケンス番号
- 送信時における最新の検証済みレジャーインデックス - 送信時における最新の検証済みレジャーインデックス
- 必要に応じて、アプリケーション固有のデータ - 必要に応じて、アプリケーション固有のデータ
3. トランザクションを送信します 3. トランザクションを送信します
### 確認 ### 確認
通常の操作中に、アプリケーションは、送信されたトランザクションのステータスをハッシュによって確認できます。または、使用するAPIによっては、トランザクションが確認または拒否されたときにその通知を受信できます。 この通常操作は、ネットワーク障害や電源障害などによって中断されることがあります。 そのような中断が発生した場合には、アプリケーションは信頼性の高い方法で、中断前にネットワークに送信された(または送信されなかった)可能性のあるトランザクションのステータスを確認する必要があります。 通常の操作中に、アプリケーションは、送信されたトランザクションのステータスをハッシュによって確認できます。または、使用するAPIによっては、トランザクションが確認または拒否されたときにその通知を受信できます。この通常操作は、ネットワーク障害や電源障害などによって中断されることがあります。そのような中断が発生した場合には、アプリケーションは信頼性の高い方法で、中断前にネットワークに送信されたまたは送信されなかった可能性のあるトランザクションのステータスを確認する必要があります。
再起動時、または最新の検証済みレジャーの確認時の例を示します(擬似コード): 再起動時、または最新の検証済みレジャーの確認時の例を示します(擬似コード):
``` ```
For each persisted transaction without validated result: For each persisted transaction without validated result:
Query transaction by hash Query transaction by hash
If (result appears in validated ledger) If (result appears in any validated ledger)
# Outcome is final # Outcome is final
Persist the final result Persist the final result
If (result code is tesSUCCESS) If (result code is tesSUCCESS)
@@ -122,9 +115,13 @@ For each persisted transaction without validated result:
If (server has continuous ledger history from the ledger when the If (server has continuous ledger history from the ledger when the
transaction was submitted up to and including the ledger transaction was submitted up to and including the ledger
identified by LastLedgerSequence) identified by LastLedgerSequence)
The transaction failed (2)
If appropriate for the application, submit with # Sanity check
new LastLedgerSequence and Fee If (sender account sequence > transaction sequence)
A different transaction with this sequence has a final outcome.
Manual intervention suggested (3)
Else
The transaction failed (2)
Else Else
# Outcome is final, but not known due to a ledger gap # Outcome is final, but not known due to a ledger gap
@@ -138,41 +135,52 @@ For each persisted transaction without validated result:
- 失敗のケース1では、トランザクションはレジャーに含まれ、[XRPトランザクションコスト](transaction-cost.html)は消却されましたが、それ以外には何も起こりませんでした。この原因としては、流動性の欠如、適切でない[パス](paths.html)、またはその他の状況が考えられます。多くの場合、このような失敗の場合には、同様のトランザクションをすぐに試すと同じ結果が出ることが多いです。状況が変わるのを待ってから送信すると、別の結果が得られることがあります。 - 失敗のケース1では、トランザクションはレジャーに含まれ、[XRPトランザクションコスト](transaction-cost.html)は消却されましたが、それ以外には何も起こりませんでした。この原因としては、流動性の欠如、適切でない[パス](paths.html)、またはその他の状況が考えられます。多くの場合、このような失敗の場合には、同様のトランザクションをすぐに試すと同じ結果が出ることが多いです。状況が変わるのを待ってから送信すると、別の結果が得られることがあります。
- 失敗のケース2では、トランザクションは検証済みレジャーには含まれないため、何も起こらず、トランザクションコストも消却されませんでした。これは、XRP Ledgerの現在の負荷に対してトランザクションコストが低すぎる、`LastLedgerSequence`が早すぎる、または不安定なネットワーク接続などの状況が原因である可能性があります。 - 失敗のケース2では、トランザクションは検証済みレジャーには含まれないため、何も起こらず、トランザクションコストも消却されませんでした。これは、XRP Ledgerの現在の負荷に対してトランザクションコストが低すぎる、`LastLedgerSequence`が早すぎる、または不安定なネットワーク接続などの状況が原因である可能性があります。
- 失敗のケース1と異なり、このケースでは`LastLedgerSequence`のみを変更(または`Fee`も変更)するだけで、新しいトランザクションが成功する可能性があります。
- また、トランザクションが成功しないのはレジャーのステータスが原因である可能性もあります。例えば、トランザクションに署名するために使用されたキーペアが送信アドレスで無効になっている場合などです。トランザクションの暫定的な結果が[`tef`-class code](tef-codes.html)の場合には、修正をしない限りそのトランザクションが成功する可能性は低くなります。 - 失敗のケース1と異なり、このケースでは`LastLedgerSequence`のみを変更(または`Fee`も変更)するだけで、新しいトランザクションが成功する可能性があります。元のトランザクションと同じ`Sequence`番号を使用します。
- また、トランザクションが成功しないのはレジャーのステータスが原因である可能性もあります。例えば、トランザクションに署名するために使用されたキーペアが送信アドレスで無効になっている場合などです。トランザクションの暫定的な結果が[`tef`-class code](tef-codes.html)の場合には、修正をしない限りそのトランザクションが成功する可能性は低くなります。
- 失敗のケース3は、予期しない状態を表します。トランザクションが未処理の場合、最新の検証済みレジャーにある送信元アカウントの`Sequence`番号を確認する必要があります。([account_infoメソッド][]を使用して確認できます。)最新の検証済みレジャーにあるアカウントの`Sequence`値がトランザクションの`Sequence`値より大きい場合、同じ`Sequence`値を持つ別のトランザクションが検証済みレジャーに含まれています。システムがこの別のトランザクションを認識していない場合、予期しない状態となり、その原因が特定されるまで処理を停止しなければならなくなります。そうしないと、システムが同じ目標を達成するために複数のトランザクションを送信する可能性があります。行う必要のある手順は、具体的な原因によって変わります。考えられる原因と手順は次のとおりです。
- 前回送信したトランザクションに[展性](transaction-malleability.html)があり、実際に検証済みレジャーに含まれていたが、予想と異なるハッシュだった場合。この問題は、`tfFullyCanonicalSig`フラグが含まれないフラグのセットを指定した場合か、必要以上の署名者によってマルチ署名されたトランザクションであった場合に起こる可能性があります。これに該当する場合は、その異なるハッシュとトランザクションの最終結果を保存し、通常のアクティビティーを再開します。
- トランザクションを[キャンセル](cancel-or-skip-a-transaction.html)して置き換えたため、置き換え後のトランザクションが代わりに処理された場合。障害から復旧しようとしている場合、置き換え後のトランザクションでレコードが失われている可能性があります。その場合、当初確認していたトランザクションは恒久的に失敗し、置き換え後のトランザクションの最終結果が検証済みレジャーバージョンに記録されます。両方の最終結果を保存し、他に欠落したトランザクションや置き換えられたトランザクションがないか確認してから、通常のアクティビティーを再開します。
- アクティブ/パッシブフェイルオーバー構成で、トランザクション送信側のシステムが2台以上あり、パッシブシステムがアクティブシステムで障害が発生したと誤って認識してアクティブになったが、元のアクティブシステムも引き続きトランザクションを送信していた場合。システム間の接続をチェックして、そのうちの1台だけがアクティブであることを確認します。アカウントのトランザクション履歴を確認し[account_txメソッド][]を使用するなど)、検証済みレジャーに含まれていたすべてのトランザクションの最終結果を記録します。`Sequence`番号が同じ別のトランザクションはすべて完全に失敗しています。それらの最終結果も保存します。すべてのシステムの差異の調整を行い、システムが同時にアクティブになった原因となる問題を解決したら、通常のアクティビティーを再開します。
**ヒント:** [`AccountTxnID`フィールド](transaction-common-fields.html#accounttxnid)を使用すると、このような状況で冗長的なトランザクションが成功しないように防ぐことができます。
- 不正使用者に秘密鍵を使われてトランザクションを送信された場合。その場合は、可能であれば[キーペアをローテーション](change-or-remove-a-regular-key-pair.html)して、送信された他のトランザクションを確認します。また、ネットワークを監査して、その秘密鍵が大規模な侵入やセキュリティ侵害に関係していたかどうかを判断する必要があります。キーペアのローテーションに成功して、不正使用者がアカウントやシステムにアクセスできなくなったら、通常のアクティビティーを再開します。
#### レジャーのギャップ #### レジャーのギャップ
サーバーに、トランザクションが最初に送信されてから、レジャーが`LastLedgerSequence`によって識別された時点までを含む、継続したレジャー履歴がない場合には、トランザクションの最終結果を得られない可能性があります。(サーバーにないレジャーバージョンに結果が含まれている場合、成功したか失敗したかが分かりません。) サーバーに、トランザクションが最初に送信されてから、レジャーが`LastLedgerSequence`によって識別された時点までを含む、継続したレジャー履歴がない場合には、トランザクションの最終結果を得られない可能性があります。(サーバーにないレジャーバージョンに結果が含まれている場合、成功したか失敗したかが分かりません。)
`rippled`サーバーにリソースCPU/RAM/ディスクIOの余裕がある場合には、不足しているレジャーバージョンを自動的に取得します。ただし、取得しようとするレジャーが[保管する履歴の設定](https://github.com/ripple/rippled/blob/develop/cfg/rippled-example.cfg#L581)よりも古い場合には取得されません。ギャップのサイズや、サーバーのリソース使用率に基づき、不足しているレジャーバージョンの取得には数分かかります。[ledger_requestメソッド][]を使用して履歴となっているレジャーバージョンを手動で要求することもできます。 `rippled`サーバーにリソースCPU/RAM/ディスクIOの余裕がある場合には、不足しているレジャーバージョンを自動的に取得します。ただし、取得しようとするレジャーが[保管する履歴の設定期間](ledger-history.html)よりも古い場合には取得されません。ギャップのサイズや、サーバーのリソース使用率に基づき、不足しているレジャーバージョンの取得には数分かかります。[ledger_requestメソッド][]を使用して履歴レジャーバージョンを取得するようにサーバーに要求できます。しかし、そうしても、サーバーに設定された履歴範囲外のレジャーバージョンからのトランザクション結果は検索できない場合があります。
あるいは、`s2.ripple.com`にあるRippleの完全履歴サーバーなど、必要なレジャー履歴を含む別の`rippled`サーバーを使用して、トランザクションのステータスを検索することもできます。この目的には、信頼できるサーバーのみを使用してください。不正なサーバーは、トランザクションのステータスや結果について偽の情報を提供するようにプログラムされている可能性があります。 あるいは、`s2.ripple.com`にあるRippleの完全履歴サーバーなど、必要なレジャー履歴を含む別の`rippled`サーバーを使用して、トランザクションのステータスを検索することもできます。この目的には、信頼できるサーバーのみを使用してください。不正なサーバーは、トランザクションのステータスや結果について偽の情報を提供するようにプログラムされている可能性があります。
## 技術的応用 ## 技術的応用
トランザクションの送信および確認のベストプラクティスを実施するには、アプリケーションで以下を実行する必要があります。 トランザクションの送信および確認のベストプラクティスを実施するには、アプリケーションで以下を実行する必要があります。
1. 署名するアカウントの次のシーケンス番号を判断します 1. 署名するアカウントの次のシーケンス番号を判断します
* 各トランザクションにはアカウント固有のシーケンス番号があります。 これにより、アカウントによって署名されたトランザクションの実行順序が保証され、再送信しても同じトランザクションがレジャーに二重に適用されることがなくなります。 * 各トランザクションにはアカウント固有の[シーケンス番号](basic-data-types.html#アカウントシーケンス)があります。これにより、アカウントによって署名されたトランザクションの実行順序が保証され、再送信しても同じトランザクションがレジャーに二重に適用されることがなくなります。
3. `LastLedgerSequence`を決定します 2. `LastLedgerSequence`を決定します
* トランザクションの`LastLedgerSequence`は、最後の検証済みレジャーのシーケンス番号から計算されます。 * トランザクションの`LastLedgerSequence`は、最後の検証済みレジャーインデックスから計算されます。
3. トランザクションを生成して署名します 3. トランザクションを生成して署名します
* 送信前に、署名されたトランザクションの詳細を保持します。 * 送信前に、署名されたトランザクションの詳細を保持します。
4. トランザクションを送信します 4. トランザクションを送信します
* 初期の結果は暫定的なものであり、変化する可能性があります。 * 初期の結果は暫定的なものであり、変化する可能性があります。
5. トランザクションの最終結果を判断します 5. トランザクションの最終結果を判断します
* 最終結果は、レジャー履歴における不変部分です。 * 最終結果は、レジャー履歴における不変部分です。
アプリケーションでのこれらのアクションの実行方法は、アプリケーションが使用するAPIによって異なります。 アプリケーションでは、以下のインターフェイスを使用できます。 アプリケーションでのこれらのアクションの実行方法は、アプリケーションが使用するAPIによって異なります。アプリケーションでは、以下のインターフェイスを使用できます。
1. [`rippled` API](rippled-api.html) 1. [`rippled` API](rippled-api.html)
2. [RippleAPI](rippleapi-reference.html) 2. [RippleAPI](rippleapi-reference.html)
3. `rippled`上にレイヤーされた、任意の数の他のソフトウェアAPI 3. `rippled`上にレイヤーされた、任意の数の他のソフトウェアAPI
### rippled - トランザクションの送信と確認 ### rippled - トランザクションの送信と確認
#### アカウントシーケンスの判断 #### アカウントシーケンスの判断
@@ -218,8 +226,7 @@ JSON-RPC要求:
この例では、最後に検証されたレジャーの時点において(要求の`"ledger": "validated"`と、応答の`"validated": "true"`を参照)、アカウントのシーケンスは**4**です(`"account_data"``"Sequence": 4`を参照)。 この例では、最後に検証されたレジャーの時点において(要求の`"ledger": "validated"`と、応答の`"validated": "true"`を参照)、アカウントのシーケンスは**4**です(`"account_data"``"Sequence": 4`を参照)。
アプリケーションが、このアカウントで署名された3つのトランザクションを送信する場合には、4、5、6のシーケンス番号を使用します。 各トランザクションの検証を待たずに複数のトランザクションを送信するには、アプリケーションで継続的なアカウントシーケンス番号を使用します。 アプリケーションが、このアカウントで署名された3つのトランザクションを送信する場合には、4、5、6のシーケンス番号を使用します。各トランザクションの検証を待たずに複数のトランザクションを送信するには、アプリケーションで継続的なアカウントシーケンス番号を使用します。
#### 最後に検証されたレジャーの判断 #### 最後に検証されたレジャーの判断
@@ -269,12 +276,11 @@ JSON-RPC要求:
} }
``` ```
この例では、最後検証されたレジャーのシーケンス番号は10268596応答の`result.state.validated_ledger`)です。 この例では、レジャー履歴にギャップがあることも示されています。 ここで使用されたサーバーは、ギャップの間レジャー10256383から10256411に適用されたトランザクションに関する情報を提供することはできません。 その部分のレジャー履歴を取得するよう設定されていれば、最終的にサーバーで取得できます。 この例では、最後検証済みレジャーインデックスは10268596応答の`result.state.validated_ledger`の下です。この例では、レジャー履歴にギャップがあることも示されています。ここで使用されたサーバーは、ギャップの間レジャー10256383から10256411に適用されたトランザクションに関する情報を提供することはできません。その部分のレジャー履歴を取得するよう設定されていれば、最終的にサーバーで取得できます。
#### トランザクションの生成 #### トランザクションの生成
`rippled`には、トランザクション送信に備えて準備するための[signメソッド][]があります。 このメソッドは信頼できる<rippled/>インスタンスにのみに渡すことができるアカウントの機密情報を必要とします。信頼できる`rippled`インスタンスにのみ渡 この例では、10 FOO架空の通貨を別のXRP Ledgerアドレスに発行します。 `rippled`には、トランザクション送信に備えて準備するための[signメソッド][]があります。このメソッドは信頼できる`rippled`インスタンスにのみに渡すことができるアカウントの機密情報を必要とします。この例では、10 FOO架空の通貨を別のXRP Ledgerアドレスに発行します。
要求: 要求:
@@ -305,7 +311,7 @@ JSON-RPC要求:
アプリケーションは、`tefPAST_SEQ`エラーを防ぐため、`account_info`への以前の呼び出しで判明した`"Sequence": 4`を使用しています。 アプリケーションは、`tefPAST_SEQ`エラーを防ぐため、`account_info`への以前の呼び出しで判明した`"Sequence": 4`を使用しています。
また、アプリケーションが`server_state`から取得した最後の検証済みレジャーに基づく`LastLedgerSequence`にも注意してください。 バックエンドアプリケーションでは、 *「最後の検証済みレジャーシーケンス + 4」* を使用することをお勧めします。または、 *「現行のレジャー + 3」* の値を使用します。 `LastLedgerSequence`の計算が誤りで、最後の検証済みレジャーの番号よりも小さい場合には、そのトランザクションは`tefMAX_LEDGER`エラーで失敗します。 また、アプリケーションが`server_state`から取得した最後の検証済みレジャーに基づく`LastLedgerSequence`にも注意してください。バックエンドアプリケーションでは、*「最後の検証済みレジャーインデックス + 4」*を使用することをお勧めします。または、*「現行のレジャー + 3」*の値を使用します。`LastLedgerSequence`の計算が誤りで、最後の検証済みレジャーの番号よりも小さい場合には、そのトランザクションは`tefMAX_LEDGER`エラーで失敗します。
応答: 応答:
@@ -335,13 +341,11 @@ JSON-RPC要求:
} }
``` ```
トランザクションを送信する前に、アプリケーションでトランザクションのハッシュを保持しておきます。 `sign`メソッドの結果の`tx_json`の下にハッシュが含まれます。 トランザクションを送信する前に、アプリケーションでトランザクションのハッシュを保持しておきます。`sign`メソッドの結果の`tx_json`の下にハッシュが含まれます。
#### トランザクションの送信 #### トランザクションの送信
`rippled`には、署名されたトランザクションの送信を可能にする、[submitメソッド][]があります。 これは、`sign`メソッドで返された`tx_blob`パラメーターを使用します。 `rippled`には、署名されたトランザクションの送信を可能にする、[submitメソッド][]があります。これは、`sign`メソッドで返された`tx_blob`パラメーターを使用します。
要求: 要求:
@@ -387,8 +391,7 @@ JSON-RPC要求:
} }
``` ```
これは**初期**結果です。 最終結果は検証済みのレジャーのみにあります。 `"validated": true`フィールドがないことが、これが**不変の結果ではない**ことを示しています。 これは**初期**結果です。最終結果は検証済みのレジャーのみにあります。`"validated": true`フィールドがないことが、これが**不変の結果ではない**ことを示しています。
#### トランザクションの確認 #### トランザクションの確認
@@ -442,10 +445,9 @@ JSON-RPC要求:
} }
``` ```
この応答例には、`"validated": true`があります。これは、トランザクションが検証済みレジャーに含まれていること、つまりトランザクション結果が不変であることを示しています。 さらに、メタデータには、トランザクションがレジャーに適用されたことを示す`"TransactionResult": "tesSUCCESS"`が含まれています。 この応答例には、`"validated": true`があります。これは、トランザクションが検証済みレジャーに含まれていること、つまりトランザクション結果が不変であることを示しています。さらに、メタデータには、トランザクションがレジャーに適用されたことを示す`"TransactionResult": "tesSUCCESS"`が含まれています。
応答に`"validated": true`が含まれていない場合には、結果は暫定的であり変化する可能性があります。 最終結果を取得するには、アプリケーションで`tx`メソッドを再度呼び出し、ネットワークでさらに多くのレジャーインスタンスを検証できるよう十分な時間をかけます。 `LastLedgerSequence`で指定されたレジャーが検証されるまで待たなければならない場合もありますが、そのトランザクションが以前の検証済みレジャーに含まれている場合には、その結果はその時点で不変です。
応答に`"validated": true`が含まれていない場合には、結果は暫定的であり変化する可能性があります。最終結果を取得するには、アプリケーションで`tx`メソッドを再度呼び出し、ネットワークでさらに多くのレジャーバージョンを検証できるよう十分な時間をかけます。`LastLedgerSequence`で指定されたレジャーが検証されるまで待たなければならない場合もありますが、そのトランザクションが以前の検証済みレジャーに含まれている場合には、その結果はその時点で不変です。
#### 不明のトランザクションの確認 #### 不明のトランザクションの確認
@@ -467,7 +469,7 @@ JSON-RPC要求:
} }
``` ```
`txnNotFound`結果コードは、トランザクションがどのレジャーにも含まれていない場合に発生します。 ただし、`rippled`インスタンスに完全なレジャー履歴がない場合や、そのトランザクションが`rippled`インスタンスにまだ伝達されていない場合にも発生します。 これにどのように対処すべきかを判断するため、アプリケーションはさらに照会を行う必要があります。 `txnNotFound`結果コードは、トランザクションがどのレジャーにも含まれていない場合に発生します。ただし、`rippled`インスタンスに完全なレジャー履歴がない場合や、そのトランザクションが`rippled`インスタンスにまだ伝達されていない場合にも発生します。これにどのように対処すべきかを判断するため、アプリケーションはさらに照会を行う必要があります。
[server_stateメソッド][](最後の検証済みレジャーを判断するために先に使用する)は、`result.state.complete_ledgers`のもとにレジャー履歴が完全かどうかを示します。 [server_stateメソッド][](最後の検証済みレジャーを判断するために先に使用する)は、`result.state.complete_ledgers`のもとにレジャー履歴が完全かどうかを示します。
@@ -502,18 +504,18 @@ JSON-RPC要求:
} }
``` ```
このトランザクションの例では、その時点の最後の検証済みレジャーに基づいて`LastLedgerSequence` 10268600を指定し、4を足します。 不明のトランザクションが完全に失敗したかどうかを判断するには、`rippled`サーバーに、10268597から10268600のレジャーが必要です。 サーバーの履歴にそれらの検証済みレジャーが存在し、**かつ**`tx``txnNotFound`が返される場合には、そのトランザクションは失敗であり、今後のレジャーに含めることはできません。 この場合、アプリケーションのロジックで、同じアカウントシーケンスと更新された`LastLedgerSequence`を使用して代わりのトランザクションを作成して送信することが可能です。 このトランザクションの例では、その時点の最後の検証済みレジャーに基づいて`LastLedgerSequence` 10268600を指定し、4を足します。不明のトランザクションが完全に失敗したかどうかを判断するには、`rippled`サーバーに、10268597から10268600のレジャーが必要です。サーバーの履歴にそれらの検証済みレジャーが存在し、**かつ**`tx``txnNotFound`が返される場合には、そのトランザクションは失敗であり、今後のレジャーに含めることはできません。この場合、アプリケーションのロジックで、同じアカウントシーケンスと更新された`LastLedgerSequence`を使用して代わりのトランザクションを作成して送信することが可能です。
サーバーは、指定された`LastLedgerSequence`よりも小さい検証済みレジャーシーケンス番号をレポートする場合があります。 その場合、`txnNotFound`に、a送信されたトランザクションがまだネットワークに配布されていないこと、またはbトランザクションがネットワークに配布されたものの、まだ処理されていないことを示します。 最初のケースに対処するために、アプリケーションは再度同じ署名済みのトランザクションを送信できます。 トランザクションには固有のアカウントシーケンス番号がつけられているため、処理されるのは一度のみです。 サーバーは、指定された`LastLedgerSequence`よりも小さい値の最後の検証済みレジャーインデックスをレポートする場合があります。その場合、`txnNotFound`に、a送信されたトランザクションがまだネットワークに配布されていないこと、またはbトランザクションがネットワークに配布されたものの、まだ処理されていないことを示します。最初のケースに対処するために、アプリケーションは再度同じ署名済みのトランザクションを送信できます。トランザクションには固有のアカウントシーケンス番号がつけられているため、処理されるのは一度のみです。
最後に、サーバーにトランザクション履歴のギャップが1つ以上存在する場合があります。上記の応答に示される`completed_ledgers`フィールドは、このrippledインスタンスの10256383から10256411のレジャーが不足していることを示しています。 このトランザクションの例では、(トランザクションの送信時点と`LastLedgerSequence`に基づいてトランザクションは10268597から10268600のレジャーのみに含まれるため、このギャップはここでは関係ありません。 ただし、必要範囲のレジャーが不足している場合には、`txnNotFound`の結果が不変の結果であるかどうかを判断するために、アプリケーションは別のrippledサーバーに照会するまたはこのサーバーによって不足しているレジャーが取得されるまで待つ必要があります。
最後に、サーバーにトランザクション履歴のギャップが1つ以上存在する場合があります。上記の応答に示される`completed_ledgers`フィールドは、このrippledインスタンスの10256383から10256411のレジャーが不足していることを示しています。このトランザクションの例では、トランザクションの送信時点と`LastLedgerSequence`に基づいてトランザクションは10268597から10268600のレジャーのみに含まれるため、このギャップはここでは関係ありません。ただし、必要範囲のレジャーが不足している場合には、`txnNotFound`の結果が不変の結果であるかどうかを判断するために、アプリケーションは別のrippledサーバーに照会するまたはこのサーバーによって不足しているレジャーが取得されるまで待つ必要があります。
## その他のリソース ## その他のリソース
- [トランザクションのフォーマット](transaction-formats.html) - [トランザクションのフォーマット](transaction-formats.html)
- [トランザクションコスト](transaction-cost.html) - [トランザクションコスト](transaction-cost.html)
- [XRP Ledger コンセンサスプロセスの概要](consensus.html) - [トランザクション展性](transaction-malleability.html)
- [XRP Ledgerコンセンサスプロセスの概要](consensus.html)
- [コンセンサスの原理とルール](consensus-principles-and-rules.html) - [コンセンサスの原理とルール](consensus-principles-and-rules.html)
<!--{# common link defs #}--> <!--{# common link defs #}-->

View File

@@ -0,0 +1,507 @@
# XRPの送金
このチュートリアルでは、RippleAPI for JavaScriptを使用してシンプルなXRP送金を行う方法について説明します。まずは、XRP Test Netを使用してプロセスを順に進めます。次に、そのプロセスと、本番で同様の処理を行う場合に発生する追加要件とを比較します。
## 前提条件
<!-- Interactive example use ripple-lib and its prerequisites -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
<script type="application/javascript" src="assets/js/ripple-lib-1.4.1-min.js"></script>
<!-- Helper for interactive tutorial breadcrumbs -->
<script type="application/javascript" src="assets/js/interactive-tutorial.js"></script>
- このページでは、ripple-libRippleAPIライブラリーバージョン1.1.2を使用するJavaScriptの例を紹介します。[RippleAPI入門ガイド](get-started-with-rippleapi-for-javascript.html)に、RippleAPIを使用してJavaScriptからXRP Ledgerデータにアクセスする方法の説明があります。
- XRP Ledgerでトランザクションを送信するには、まずアドレスと秘密鍵、そしていくらかのXRPが必要となります。次のインターフェイスを使用して、XRP Test NetにあるアドレスとTest Net XRPを入手できます。
{{ start_step("Generate") }}
<button id="generate-creds-button" class="btn btn-primary">資格情報を作成する</button>
<div id='loader-0' style="display: none;"><img class='throbber' src="assets/img/xrp-loader-96.png"> Generating Keys...</div>
<div id='address'></div>
<div id='secret'></div>
<div id='balance'></div>
<div id="populate-creds-status"></div>
{{ end_step() }}
<script type="application/javascript">
$(document).ready( () => {
$("#generate-creds-button").click( () => {
// Wipe existing results
$("#address").html("")
$("#secret").html("")
$("#balance").html("")
$("#populate-creds-status").html("")
$("#loader-0").show()
$.ajax({
url: "https://faucet.altnet.rippletest.net/accounts",
type: 'POST',
dataType: 'json',
success: function(data) {
$("#loader-0").hide()
$("#address").hide().html("<strong>Address:</strong> " +
'<span id="test-net-faucet-address">' +
data.account.address
+ "</span>").show()
$("#secret").hide().html('<strong>Secret:</strong> ' +
'<span id="test-net-faucet-secret">' +
data.account.secret +
"</span>").show()
$("#balance").hide().html('<strong>Balance:</strong> ' +
Number(data.balance).toLocaleString('en') +
' XRP').show()
// Automatically populate examples with these credentials...
// Set sender address
let generated_addr = ""
$("code span:contains('"+EXAMPLE_ADDR+"')").each( function() {
let eltext = $(this).text()
$(this).text( eltext.replace(EXAMPLE_ADDR, data.account.address) )
})
// Set sender secret
$("code span:contains('"+EXAMPLE_SECRET+"')").each( function() {
let eltext = $(this).text()
$(this).text( eltext.replace(EXAMPLE_SECRET, data.account.secret) )
})
$("#populate-creds-status").text("Populated this page's examples with these credentials.")
complete_step("Generate")
},
error: function() {
$("#loader-0").hide();
alert("There was an error with the Ripple Test Net, please try again.");
}
})
})
const EXAMPLE_ADDR = "rPT1Sjq2YGrBMTttX4GZHjKu9dyfzbpAYe"
const EXAMPLE_SECRET = "s████████████████████████████"
$("#populate-creds-button").click( () => {
})
})
</script>
**注意:** RippleはXRP Test Netをテストの目的でのみ運用しており、Test Netの状態とすべての残高を定期的にリセットしています。予防措置として、Test Netと本番で同じアドレスを使用**しない**ことをお勧めします。
## Test Netでの送金
{% set n = cycler(* range(1,99)) %}
### {{n.next()}}. Test Netサーバーへの接続
必須の自動入力可能フィールドに入力されるようにするために、ripple-libを、アカウントの現在のステータスと共有レジャー自体を取得できるサーバーに接続する必要があります。セキュリティを高めるために、トランザクションの署名はオフライン中に行うことを推奨します。ただしその場合は、自動入力可能フィールドに手動で入力する必要があります。トランザクションの送信先となるネットワークに接続する必要があります。
以下のサンプルコードでは、新しいRippleAPIインスタンスを作成し、Rippleが運用している公開XRP Test Netサーバーに接続します。
```js
ripple = require('ripple-lib')
api = new ripple.RippleAPI({server: 'wss://s.altnet.rippletest.net:51233'})
api.connect()
```
このチュートリアルでは、以下のボタンをクリックすることでブラウザーから直接接続できます。
{{ start_step("Connect") }}
<button id="connect-button" class="btn btn-primary">TestNetに接続する</button>
<div>
<strong>Connection status:</strong>
<span id="connection-status">Not connected</span>
<div id='loader-{{n.current}}' style="display: none;"><img class='throbber' src="assets/img/xrp-loader-96.png"></div>
</div>
{{ end_step() }}
<script type="application/javascript">
api = new ripple.RippleAPI({server: 'wss://s.altnet.rippletest.net:51233'})
api.on('connected', () => {
$("#connection-status").text("Connected")
$("#connect-button").prop("disabled", true)
$("#loader-{{n.current}}").hide()
// Update breadcrumbs & active next step
complete_step("Connect")
$("#interactive-prepare button").prop("disabled", false)
$("#interactive-prepare button").prop("title", "")
})
api.on('disconnected', (code) => {
$("#connection-status").text( "Disconnected ("+code+")" )
$("#connect-button").prop("disabled", false)
$(".connection-required").prop("disabled", true)
$(".connection-required").prop("title", "Connection to Test Net required")
})
$("#connect-button").click(() => {
$("#connection-status").text( "Connecting..." )
$("#loader-{{n.current}}").show()
api.connect()
})
</script>
### {{n.next()}}. トランザクションの準備
通常は、XRP LedgerトランザクションをオブジェクトとしてJSON[トランザクションフォーマット](transaction-formats.html)で作成します。以下の例に、必要最小限の送金仕様を示します。
```json
{
"TransactionType": "Payment",
"Account": "rPT1Sjq2YGrBMTttX4GZHjKu9dyfzbpAYe",
"Amount": "2000000",
"Destination": "rUCzEr6jrEyMpjhs4wSdQdz4g8Y382NxfM"
}
```
XRP送金に対して指定する必要がある必要最小限の指示は次のとおりです。
- これが送金であることを示すインディケーター(`"TransactionType": "Payment"`
- 送信元アドレス(`"Account"`
- XRPを受け取るアドレス`"Destination"`)。このアドレスは送信元アドレスと同じものではいけません。
- 送金するXRP額`"Amount"`。通常、XRPの「drop数」を示す整数として指定します。1,000,000ドロップは1 XRPです。
技術上、一部の追加のフィールドは実行可能なトランザクションに含める必要があり、また、省略可能なフィールドでも、`LastLedgerSequence`などは含めることを強く推奨します。[`prepareTransaction()`メソッド](rippleapi-reference.html#preparetransaction)は、トランザクションの残りのフィールドに適切なデフォルトを自動的に入力します。上記の送金を準備する際の例を示します。
```js
// Continuing after connecting to the API
async function doPrepare() {
const sender = "rPT1Sjq2YGrBMTttX4GZHjKu9dyfzbpAYe"
const preparedTx = await api.prepareTransaction({
"TransactionType": "Payment",
"Account": sender,
"Amount": api.xrpToDrops("22"), // Same as "Amount": "22000000"
"Destination": "rUCzEr6jrEyMpjhs4wSdQdz4g8Y382NxfM"
}, {
// Expire this transaction if it doesn't execute within ~5 minutes:
"maxLedgerVersionOffset": 75
})
const maxLedgerVersion = preparedTx.instructions.maxLedgerVersion
console.log("Prepared transaction instructions:", preparedTx.txJSON)
console.log("Transaction cost:", preparedTx.instructions.fee, "XRP")
console.log("Transaction expires after ledger:", maxLedgerVersion)
return preparedTx.txJSON
}
txJSON = doPrepare()
```
{{ start_step("Prepare") }}
<button id="prepare-button" class="btn btn-primary connection-required"
title="Connect to Test Net first" disabled>サンプルトランザクションを準備する</button>
<div id="prepare-output"></div>
{{ end_step() }}
<script type="application/javascript">
$("#prepare-button").click( async function() {
// Wipe existing results
$("#prepare-output").html("")
const sender = $("#test-net-faucet-address").text() || "rPT1Sjq2YGrBMTttX4GZHjKu9dyfzbpAYe"
const preparedTx = await api.prepareTransaction({
"TransactionType": "Payment",
"Account": sender,
"Amount": api.xrpToDrops("22"), // Same as "Amount": "22000000"
"Destination": "rUCzEr6jrEyMpjhs4wSdQdz4g8Y382NxfM"
}, {
// Expire this transaction if it doesn't execute within ~5 minutes:
"maxLedgerVersionOffset": 75
})
const maxLedgerVersion = preparedTx.instructions.maxLedgerVersion
$("#tx-lls").text(maxLedgerVersion) //for the table in the later step
$("#prepare-output").html(
"<div><strong>Prepared transaction instructions:</strong> <pre><code id='prepared-tx-json'>" +
JSON.stringify(JSON.parse(preparedTx.txJSON), null, 2) + "</code></pre></div>" +
"<div><strong>Transaction cost:</strong> " +
preparedTx.instructions.fee + " XRP</div>" +
"<div><strong>Transaction expires after ledger:</strong> " +
maxLedgerVersion + "</div>"
)
// Update breadcrumbs & active next step
complete_step("Prepare")
$("#interactive-sign button").prop("disabled", false)
$("#interactive-sign button").prop("title", "")
})
</script>
### {{n.next()}}. トランザクションの指示への署名
RippleAPIの[sign()メソッド](rippleapi-reference.html#sign)を使用して、トランザクションに署名します。最初の引数は、署名するJSONトランザクションの文字列バージョンです。
```js
// Continuing from the previous step...
const response = api.sign(txJSON, "s████████████████████████████")
const txID = response.id
console.log("Identifying hash:", txID)
const txBlob = response.signedTransaction
console.log("Signed blob:", txBlob)
```
署名処理の結果は、署名を含むトランザクションオブジェクトになります。通常、XRP Ledger APIは、署名済みトランザクションがトランザクションの正規の[バイナリーフォーマット](serialization.html)「ブロブ」と呼ばれるの16進数表現になることを想定しています。
署名APIは、トランザクションのID、つまり識別用ハッシュを返します。この識別用ハッシュは、後でトランザクションを検索する際に使用します。識別用ハッシュは、このトランザクションに固有の64文字の16進文字列です。
{{ start_step("Sign") }}
<button id="sign-button" class="btn btn-primary connection-required"
title="Complete all previous steps first" disabled>サンプルトランザクションに署名する</button>
<div id="sign-output"></div>
{{ end_step() }}
<script type="application/javascript">
$("#sign-button").click( function() {
// Wipe previous output
$("#sign-output").html("")
const preparedTxJSON = $("#prepared-tx-json").text()
const secret = $("#test-net-faucet-secret").text()
if (!secret) {
alert("Can't sign transaction without a real secret. Generate credentials first.")
return
}
signResponse = api.sign(preparedTxJSON, secret)
$("#sign-output").html(
"<div><strong>Signed Transaction blob:</strong> <code id='signed-tx-blob' style='overflow-wrap: anywhere; word-wrap: anywhere'>" +
signResponse.signedTransaction + "</code></div>" +
"<div><strong>Identifying hash:</strong> <span id='signed-tx-hash'>" +
signResponse.id + "</span></div>"
)
// Update all breadcrumbs & activate next step
complete_step("Sign")
$("#interactive-submit button").prop("disabled", false)
})
</script>
### {{n.next()}}. 署名済みブロブの送信
[submit()メソッド](rippleapi-reference.html#submit)を使用して、トランザクションをネットワークに送信します。送信する前に、[getLedgerVersion()メソッド](rippleapi-reference.html#getledgerversion)を使用して最新の検証済みレジャーインデックスを書き留めておくことをお勧めします。この送信の結果としてトランザクションが追加される可能性のある最も古いレジャーバージョンは、送信時に最新の検証済みレジャーより1つ大きなバージョンとなります。
ただし、同じトランザクションが以前に送信されたことがある場合、そのトランザクションはすでに以前のレジャーに入っています。2回目の送信は成功しませんが、正しいレジャーバージョンの中を確認しないと、すでに成功していたことに気付かない可能性があります。
```js
// use txBlob from the previous example
async function doSubmit(txBlob) {
const latestLedgerVersion = await api.getLedgerVersion()
const result = await api.submit(txBlob)
console.log("Tentative result code:", result.resultCode)
console.log("Tentative result message:", result.resultMessage)
// Return the earliest ledger index this transaction could appear in
// as a result of this submission, which is the first one after the
// validated ledger at time of submission.
return latestLedgerVersion + 1
}
const earliestLedgerVersion = doSubmit(txBlob)
```
このメソッドは、ローカルでトランザクションを適用しようと試みたときの**一時的な**結果を返します。この結果は、トランザクションが検証済みレジャーに含まれた時点で変わる_可能性があります_。当初は成功していたトランザクションが最終的に失敗となったり、当初失敗していたトランザクションが最終的に成功する場合があります。しかしながら、一時的な結果はほとんどの場合は最終結果と一致するため、ここで`tesSUCCESS`が表示されたらひとまず安心しても問題ありません。😁
他の結果が表示された場合は、以下の点を確認します。
- 送信元および送信先の正しいアドレスを使用しているか。
- トランザクションの他のフィールドへの入力漏れ、ステップのスキップ、その他の入力ミスがないか。
- トランザクションの送信に必要なTest Net XRPが十分にあるか。送金できるXRPの額は、[必要準備金](reserves.html)によって制限されています。現時点では、20XRPに加えて、レジャー内に保有している各「オブジェクト」につき5XRPずつ追加となります。Test Net Faucetを使用して新しいアドレスを生成した場合は、保有するオブジェクトはありません。
- テストネットワークのサーバーに接続しているか。
他の可能性については、[トランザクション結果](transaction-results.html)の完全なリストを参照してください。
{{ start_step("Submit") }}
<button id="submit-button" class="btn btn-primary connection-required"
title="Connection to Test Net required" disabled>サンプルトランザクションを送信する</button>
<div id='loader-{{n.current}}' style="display: none;"><img class='throbber' src="assets/img/xrp-loader-96.png"></div>
<div id="submit-output"></div>
{{ end_step() }}
<script type="application/javascript">
$("#submit-button").click( async function() {
$("#submit-output").html("") // Wipe previous output
$("#loader-{{n.current}}").show()
const txBlob = $("#signed-tx-blob").text()
const earliestLedgerVersion = await api.getLedgerVersion()
$("#earliest-ledger-version").text(earliestLedgerVersion)
try {
const result = await api.submit(txBlob)
$("#loader-{{n.current}}").hide()
$("#submit-output").html(
"<div><strong>Tentative result:</strong> " +
result.resultCode + " - " +
result.resultMessage +
"</div>"
)
// Update breadcrumbs & active next step
complete_step("Submit")
}
catch(error) {
$("#loader-{{n.current}}").hide()
$("#submit-output").text("Error: "+error)
}
})
</script>
### {{n.next()}}. 検証の待機
ほとんどのトランザクションは送信後の次のレジャーバージョンに承認されます。つまり、47秒でトランザクションの結果が最終的なものになる可能性があります。XRP Ledgerがビジーになっているか、ネットワーク接続の品質が悪いためにトランザクションをネットワーク内で中継する処理が遅延した場合は、トランザクション確定までにもう少し時間がかかることがあります。トランザクションの有効期限を設定する方法については、[信頼できるトランザクションの送信](reliable-transaction-submission.html)を参照してください。)
RippleAPIの`ledger`イベントタイプを使用して、新しい検証済みレジャーバージョンがあるときにコードが実行されるようにしておきます。例:
```js
api.on('ledger', ledger => {
console.log("Ledger version", ledger.ledgerVersion, "was just validated.")
if (ledger.ledgerVersion > maxLedgerVersion) {
console.log("If the transaction hasn't succeeded by now, it's expired")
}
})
```
{{ start_step("Wait") }}
<table>
<tr>
<th>Latest Validated Ledger Version:</th>
<td id="current-ledger-version">(Not connected)</td>
</tr>
<tr>
<th>Ledger Version at Time of Submission:</th>
<td id="earliest-ledger-version">(Not submitted)</td>
</tr>
<tr>
<th>Transaction LastLedgerSequence:</th>
<td id="tx-lls"></td>
</tr>
</table>
{{ end_step() }}
<script type="application/javascript">
api.on('ledger', ledger => {
$("#current-ledger-version").text(ledger.ledgerVersion)
if ( $(".breadcrumb-item.bc-wait").hasClass("active") ) {
// Advance to "Check" as soon as we see a ledger close
complete_step("Wait")
$("#get-tx-button").prop("disabled", false)
}
})
</script>
### {{n.next()}}. トランザクションステータスの確認
トランザクションが行った内容を正確に把握するために、トランザクションが検証済みレジャーバージョンに記録されたときにトランザクションの結果を調べる必要があります。例えば、[getTransaction()メソッド](rippleapi-reference.html#gettransaction)を使用して、トランザクションのステータスを確認できます。
```js
// Continues from previous examples.
// earliestLedgerVersion was noted when the transaction was submitted.
// txID was noted when the transaction was signed.
try {
tx = await api.getTransaction(txID, {minLedgerVersion: earliestLedgerVersion})
console.log("Transaction result:", tx.outcome.result)
console.log("Balance changes:", JSON.stringify(tx.outcome.balanceChanges))
} catch(error) {
console.log("Couldn't get transaction outcome:", error)
}
```
RippleAPIの`getTransaction()`メソッドは、トランザクションが検証済みレジャーバージョンに登録された場合にのみ成功を返します。登録されなかった場合は、`await`式が例外を発生させます。
**注意:** 他のAPIは、まだ検証されていないレジャーバージョンからの暫定的な結果を返す場合があります。例えば、`rippled` APIの[txメソッド][]を使用した場合は、応答内の`"validated": true`を探して、データが検証済みレジャーバージョンからのものであることを確認してください。検証済みレジャーバージョンからのものではないトランザクション結果は、変わる可能性があります。詳細は、[結果のファイナリティー](finality-of-results.html)を参照してください。
{{ start_step("Check") }}
<button id="get-tx-button" class="btn btn-primary connection-required"
title="Connection to Test Net required" disabled>トランザクションステータスを確認する</button>
<div id="get-tx-output"></div>
{{ end_step() }}
<script type="application/javascript">
$("#get-tx-button").click( async function() {
// Wipe previous output
$("#get-tx-output").html("")
const txID = $("#signed-tx-hash").text()
const earliestLedgerVersion = parseInt($("#earliest-ledger-version").text(), 10)
try {
const tx = await api.getTransaction(txID, {minLedgerVersion: earliestLedgerVersion})
$("#get-tx-output").html(
"<div><strong>Transaction result:</strong> " +
tx.outcome.result + "</div>" +
"<div><strong>Balance changes:</strong> <pre><code>" +
JSON.stringify(tx.outcome.balanceChanges, null, 2) +
"</pre></code></div>"
)
complete_step("Check")
} catch(error) {
$("#get-tx-output").text("Couldn't get transaction outcome:" + error)
}
})
</script>
## 本番環境の場合の相違点
本番XRP LedgerでXRPを送金する場合も、大部分の手順は同じです。ただし、必要なセットアップでは重要な相違点がいくつかあります。
- [実際のXRPは無料で取得できません。](#実際のxrpアカウントの取得)
- [本番XRP Ledgerネットワークと同期されているサーバーに接続する必要があります。](#本番xrp-ledgerへの接続)
### 実際のXRPアカウントの取得
このチュートリアルでは、Test Net XRPがすでに資金供給されているアドレスをボタンで取得しましたが、それが可能だったのはTest Net XRPに何の価値もないからです。実際のXRPでは、XRPを所有している他者からXRPを入手する必要があります。たとえば、取引所で購入する方法など。RippleAPIの[generateAddress()メソッド](rippleapi-reference.html#generateaddress)を使用して、本番またはTest Netで機能するアドレスとシークレットを生成できます。
```js
const generated = api.generateAddress()
console.log(generated.address) // Example: rGCkuB7PBr5tNy68tPEABEtcdno4hE6Y7f
console.log(generated.secret) // Example: sp6JS7f14BuwFY8Mw6bTtLKWauoUs
```
**警告:** ローカルマシンで安全な方法で生成したアドレスとシークレットのみを使用してください。別のコンピューターでアドレスとシークレットを生成して、ネットワーク経由でそれらを自分に送信した場合は、ネットワーク上の他の人がその情報を見ることができる可能性があります。その情報見ることができる人は、あなたと同じようにあなたのXRPを操作できます。また、Test Netと本番で同じアドレスを使用しないことも推奨します。指定したパラメーターによっては、一方のネットワークに向けて作成したトランザクションが、もう一方のネットワークでも実行可能になるおそれがあるためです。
アドレスとシークレットを生成しても、直接XRPを入手できるわけではありません。単に乱数を選択しているだけです。また、そのアドレスでXRPを受け取って[アカウントに資金供給](accounts.html#アカウントの作成)する必要があります。XRPを取得する方法として最も一般的なのは、取引所から購入し、所有しているアドレスに入れる方法です。詳細は、Rippleの[XRP購入ガイド](https://ripple.com/xrp/buy-xrp/)を参照してください。
### 本番XRP Ledgerへの接続
`RippleAPI`オブジェクトのインスタンスを作成するときに、適切なXRP Ledgerと同期しているサーバーを指定する必要があります。多くの場合はRippleの公開サーバーを、以下のスニペットなどで使用できます。
```js
ripple = require('ripple-lib')
api = new ripple.RippleAPI({server: 'wss://s1.ripple.com:51233'})
api.connect()
```
自分で[`rippled`をインストール](install-rippled.html)した場合は、デフォルトで本番ネットワークに接続されます。(代わりに、[Test Netに接続するように構成](connect-your-rippled-to-the-xrp-test-net.html)することもできます。サーバーが同期されると通常は起動から約15分以内、RippleAPIをサーバーにローカルで接続することができます。そうすると、[さまざまなメリット](rippled-server-modes.html#ストックサーバーを運用する理由)があります。以下の例は、RippleAPIをデフォルト構成で運用されているサーバーに接続する方法を示しています。
```js
ripple = require('ripple-lib')
api = new ripple.RippleAPI({server: 'ws://localhost:6006'})
api.connect()
```
**ヒント:** ローカル接続では、WebSocketプロトコルのTLSで暗号化されたバージョン`wss`)ではなく、暗号化されていないバージョン(`ws`を使用します。この方式は、通信が同じマシンの中だけで行われてマシンの外に出て行かないという点で安全で、TLS証明書が不要であるため設定が簡単です。外部ネットワークとの接続では、必ず`wss`を使用してください。
## 次のステップ
このチュートリアルを完了後は、以下を試してみてください。
- 本番システム向けに[信頼できるトランザクションの送信](reliable-transaction-submission.html)を構築する
- [RippleAPI JavaScriptリファレンス](rippleapi-reference.html)を参照して、XRP Ledgerの全機能を確認する
- [アカウント設定](manage-account-settings.html)をカスタマイズする
- [トランザクションのメタデータ](transaction-metadata.html)にトランザクションの結果の詳細がどのように記述されているかを知る
- escrowやPayment Channelなどの[複雑な支払いタイプ](complex-payment-types.html)について調べる
- [XRP Ledgerビジネス](xrp-ledger-businesses.html)のベストプラクティスを読む
<!--{# common link defs #}-->
{% include '_snippets/rippled-api-links.md' %}
{% include '_snippets/tx-type-links.md' %}
{% include '_snippets/rippled_versions.md' %}

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: XRPL.org v0.0\n" "Project-Id-Version: XRPL.org v0.0\n"
"Report-Msgid-Bugs-To: docs@ripple.com\n" "Report-Msgid-Bugs-To: docs@ripple.com\n"
"POT-Creation-Date: 2020-05-12 16:30-0700\n" "POT-Creation-Date: 2020-06-05 20:39-0700\n"
"PO-Revision-Date: 2020-05-12 15:25-0700\n" "PO-Revision-Date: 2020-05-12 15:25-0700\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: ja\n" "Language: ja\n"
@@ -41,10 +41,10 @@ msgid ""
"like to help, <a href=\"https://github.com/ripple/xrpl-dev-" "like to help, <a href=\"https://github.com/ripple/xrpl-dev-"
"portal/blob/master/CONTRIBUTING.md\">please contribute!</a>" "portal/blob/master/CONTRIBUTING.md\">please contribute!</a>"
msgstr "" msgstr ""
"XRP Ledger Dev Portalをさまざまな言語で提供するよう努力していますが、すべてのページがすべて" "XRP Ledger Dev "
"の言語で利用できるわけではありません。助けたいと思うなら" "Portalをさまざまな言語で提供するよう努力していますが、すべてのページがすべての言語で利用できるわけではありません。助けたいと思うなら<a "
"<a href=\"https://github.com/ripple/xrpl-dev-portal#contributing\">" "href=\"https://github.com/ripple/xrpl-dev-"
"提供して下さい!</a>" "portal/blob/master/CONTRIBUTING.ja.md\">提供して下さい!</a>"
# Table of contents # Table of contents
#: tool/template-doc.html:40 #: tool/template-doc.html:40
@@ -88,8 +88,7 @@ msgstr "価値のインターネットをパワーする。"
msgid "" msgid ""
"The <a href=\"#xrp_ledger_intro\">XRP Ledger</a> is open-source " "The <a href=\"#xrp_ledger_intro\">XRP Ledger</a> is open-source "
"technology that anyone can use." "technology that anyone can use."
msgstr "" msgstr "<a href=\"#xrp_ledger_intro\">XRP Ledger</a>は誰でもが使い得るオープンソース技術。"
"<a href=\"#xrp_ledger_intro\">XRP Ledger</a>は誰でもが使い得るオープンソース技術。"
#: tool/template-home.html:25 #: tool/template-home.html:25
msgid "" msgid ""
@@ -99,15 +98,15 @@ msgstr "このツールと情報でXRPのオープンソースプラットフォ
#: tool/template-home.html:26 #: tool/template-home.html:26
msgid "Want more?" msgid "Want more?"
msgstr ""#TODO msgstr ""
#: tool/template-home.html:27 #: tool/template-home.html:27
msgid "Get updates about XRP Ledger webinars, releases, and documentation!" msgid "Get updates about XRP Ledger webinars, releases, and documentation!"
msgstr ""#TODO msgstr ""
#: tool/template-home.html:29 #: tool/template-home.html:29
msgid "Sign up!" msgid "Sign up!"
msgstr ""#TODO msgstr ""
#: tool/template-home.html:50 #: tool/template-home.html:50
msgid "Learn How It Works" msgid "Learn How It Works"
@@ -157,9 +156,8 @@ msgid ""
"network of peer-to-peer servers. It is the home of XRP, a digital asset " "network of peer-to-peer servers. It is the home of XRP, a digital asset "
"designed to bridge the many different currencies in use worldwide." "designed to bridge the many different currencies in use worldwide."
msgstr "" msgstr ""
"XRP Ledgerは、ピアツーピア・サーバーのネットワーク機能を備えた分散型の暗号台帳です。" "XRP Ledgerは、ピアツーピア・サーバーのネットワーク機能を備えた分散型の暗号台帳です。XRP "
"XRP LedgerはXRPの土台となるものであり、世界中で使用されている様々な通貨の橋渡しをするために" "LedgerはXRPの土台となるものであり、世界中で使用されている様々な通貨の橋渡しをするために設計されたデジタル資産です。"
"設計されたデジタル資産です。"
#: tool/template-home.html:132 #: tool/template-home.html:132
msgid "xrp-ledger-overview.html#the-digital-asset-for-payments" msgid "xrp-ledger-overview.html#the-digital-asset-for-payments"
@@ -256,3 +254,77 @@ msgstr "(分散型取引所アイコン)"
#: tool/template-home.html:176 #: tool/template-home.html:176
msgid "On-Ledger Decentralized Exchange" msgid "On-Ledger Decentralized Exchange"
msgstr "台帳上の分散型取引所" msgstr "台帳上の分散型取引所"
#: tool/template-home.html:185
msgid "Start Building"
msgstr ""
#: tool/template-home.html:187
msgid ""
"Use these tutorials to get step-by-step guidance to perform common tasks "
"with the XRP Ledger."
msgstr ""
#: tool/template-home.html:196
msgid "'list xrp' icon"
msgstr "「XRPを上場」アイコン"
#: tool/template-home.html:215
msgid "'send xrp' icon"
msgstr "「XRPの送金」アイコン"
#: tool/template-home.html:234
msgid "'run rippled' icon"
msgstr ""
#: tool/template-home.html:251
msgid "More Tutorials"
msgstr "他のチュートリアル"
#: tool/template-home.html:264
msgid "All Tutorials"
msgstr "全チュートリアル"
#: tool/template-home.html:273
msgid "Related Projects"
msgstr ""
#: tool/template-home.html:275
msgid ""
"You're not alone in building the Internet of Value. These projects are "
"proudly collaborating with the XRP Ledger to make all the world's money "
"move like information moves today."
msgstr ""
#: tool/template-home.html:283
msgid "Interledger logo"
msgstr "インターレジャーロゴ"
#: tool/template-home.html:284
msgid "Interledger"
msgstr "インターレジャー"
#: tool/template-home.html:287
msgid ""
"Interledger is an open protocol suite for sending payments across "
"different ledgers."
msgstr "インターレジャーは異なるレジャー間でペイメントを送金するためのオープンプロトコルスイートです。"
#: tool/template-home.html:290 tool/template-home.html:304
msgid "Learn More"
msgstr ""
#: tool/template-home.html:297
msgid "Xpring logo"
msgstr "Xpringロゴ"
#: tool/template-home.html:298
msgid "Xpring"
msgstr ""
#: tool/template-home.html:301
msgid ""
"Xpring is Ripples initiative to create an open developer platform for "
"money."
msgstr "Xpringスプリング)はリップルのイニシアチブであり、開発者向けの通貨のオープンプラットフォームを構築することを目的としています。"

View File

@@ -1,14 +1,14 @@
# Translations template for XRPL.org. # Translations template for PROJECT.
# Copyright (C) 2020 XRP Ledger Project # Copyright (C) 2020 ORGANIZATION
# This file is distributed under the same license as the XRPL.org project. # This file is distributed under the same license as the PROJECT project.
# Rome Reginelli <rome@ripple.com>, 2020. # FIRST AUTHOR <EMAIL@ADDRESS>, 2020.
# #
#, fuzzy #, fuzzy
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PROJECT VERSION\n" "Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2020-05-12 16:30-0700\n" "POT-Creation-Date: 2020-06-05 20:39-0700\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -245,3 +245,77 @@ msgstr ""
#: tool/template-home.html:176 #: tool/template-home.html:176
msgid "On-Ledger Decentralized Exchange" msgid "On-Ledger Decentralized Exchange"
msgstr "" msgstr ""
#: tool/template-home.html:185
msgid "Start Building"
msgstr ""
#: tool/template-home.html:187
msgid ""
"Use these tutorials to get step-by-step guidance to perform common tasks "
"with the XRP Ledger."
msgstr ""
#: tool/template-home.html:196
msgid "'list xrp' icon"
msgstr ""
#: tool/template-home.html:215
msgid "'send xrp' icon"
msgstr ""
#: tool/template-home.html:234
msgid "'run rippled' icon"
msgstr ""
#: tool/template-home.html:251
msgid "More Tutorials"
msgstr ""
#: tool/template-home.html:264
msgid "All Tutorials"
msgstr ""
#: tool/template-home.html:273
msgid "Related Projects"
msgstr ""
#: tool/template-home.html:275
msgid ""
"You're not alone in building the Internet of Value. These projects are "
"proudly collaborating with the XRP Ledger to make all the world's money "
"move like information moves today."
msgstr ""
#: tool/template-home.html:283
msgid "Interledger logo"
msgstr ""
#: tool/template-home.html:284
msgid "Interledger"
msgstr ""
#: tool/template-home.html:287
msgid ""
"Interledger is an open protocol suite for sending payments across "
"different ledgers."
msgstr ""
#: tool/template-home.html:290 tool/template-home.html:304
msgid "Learn More"
msgstr ""
#: tool/template-home.html:297
msgid "Xpring logo"
msgstr ""
#: tool/template-home.html:298
msgid "Xpring"
msgstr ""
#: tool/template-home.html:301
msgid ""
"Xpring is Ripples initiative to create an open developer platform for "
"money."
msgstr ""

View File

@@ -22,7 +22,7 @@
{% block main %} {% block main %}
<article class="pt-3 p-md-3"> <article class="pt-3 p-md-3">
{% if target.lang != "en" and "en" in currentpage.targets %} {% if (target.lang != "en" and "en" in currentpage.targets) or currentpage.untranslated_warning %}
{# Add a "sorry this page isn't translated" banner. #} {# Add a "sorry this page isn't translated" banner. #}
<div class="devportal-callout note mb-5"><strong>{% trans %}Sorry, this page is not available in your language.{% endtrans %}</strong> <div class="devportal-callout note mb-5"><strong>{% trans %}Sorry, this page is not available in your language.{% endtrans %}</strong>
<p class="mb-0">{% trans %}We are making an effort to offer the XRP Ledger Dev Portal in a variety of languages, but not all pages are available in all languages. If you'd like to help, <a href="https://github.com/ripple/xrpl-dev-portal/blob/master/CONTRIBUTING.md">please contribute!</a>{% endtrans %}</p> <p class="mb-0">{% trans %}We are making an effort to offer the XRP Ledger Dev Portal in a variety of languages, but not all pages are available in all languages. If you'd like to help, <a href="https://github.com/ripple/xrpl-dev-portal/blob/master/CONTRIBUTING.md">please contribute!</a>{% endtrans %}</p>

View File

@@ -182,62 +182,65 @@
<section class="container-fluid card-grid card-grid-2x2"> <section class="container-fluid card-grid card-grid-2x2">
<div class="section-hero card pl-0"> <div class="section-hero card pl-0">
<h2>Start Building</h2> <h2>{% trans %}Start Building{% endtrans %}</h2>
<div class="blurb"> <div class="blurb">
<p>Use these tutorials to get step-by-step guidance to perform common tasks with the XRP Ledger.</p> <p>{% trans %}Use these tutorials to get step-by-step guidance to perform common tasks with the XRP Ledger.{% endtrans %}</p>
</div> </div>
</div><!--/.section-hero--> </div><!--/.section-hero-->
{% set flag_n = cycler(* range(1,99)) %} {% set flag_n = cycler(* range(1,99)) %}
{% set cardpage = pages|selectattr('html', 'defined_and_equalto', 'list-xrp-in-your-exchange.html')|first %}
<div class="card"> <div class="card">
<div class="card-header"> <div class="card-header">
<a href="list-xrp-in-your-exchange.html" class="header-link"> <a href="{{cardpage.html}}" class="header-link">
<img class="image-icon" src="assets/img/icon-xrp-list-xrp.svg" > <img class="image-icon" src="assets/img/icon-xrp-list-xrp.svg" alt="{% trans %}'list xrp' icon{% endtrans %}">
<h3 class="card-title">List XRP on Your Exchange</h3> <h3 class="card-title">{{cardpage.name}}</h3>
</a> </a>
</div><!--/.card-header--> </div><!--/.card-header-->
<div class="card-body"> <div class="card-body">
<p>Run a digital asset exchange? Follow these steps to add XRP.</p> <p>{{cardpage.blurb}}</p>
</div><!--/.card-body--> </div><!--/.card-body-->
<div class="card-footer"> <div class="card-footer">
<div class="readmore"> <div class="readmore">
<a href="list-xrp-in-your-exchange.html" class="btn btn-outline-secondary">List XRP</a> <a href="{{cardpage.html}}" class="btn btn-outline-secondary">{{cardpage.cta_text}}</a>
</div> </div>
</div><!--/.card-footer--> </div><!--/.card-footer-->
<div class="flag-vertical">{{"%02d"|format(flag_n.next())}}</div> <div class="flag-vertical">{{"%02d"|format(flag_n.next())}}</div>
</div><!--/.card--> </div><!--/.card-->
{% set cardpage = pages|selectattr('html', 'defined_and_equalto', 'send-xrp.html')|first %}
<div class="card"> <div class="card">
<div class="card-header"> <div class="card-header">
<a href="send-xrp.html" class="header-link"> <a href="{{cardpage.html}}" class="header-link">
<img class="image-icon" src="assets/img/icon-xrp-send-xrp.svg" > <img class="image-icon" src="assets/img/icon-xrp-send-xrp.svg" alt="{% trans %}'send xrp' icon{% endtrans %}">
<h3 class="card-title">Send XRP</h3> <h3 class="card-title">{{cardpage.name}}</h3>
</a> </a>
</div><!--/.card-header--> </div><!--/.card-header-->
<div class="card-body"> <div class="card-body">
<p>Learn how to send test payments right from your browser.</p> <p>{{cardpage.blurb}}</p>
</div><!--/.card-body--> </div><!--/.card-body-->
<div class="card-footer"> <div class="card-footer">
<div class="readmore"> <div class="readmore">
<a href="send-xrp.html" class="btn btn-outline-secondary">Send XRP</a> <a href="{{cardpage.html}}" class="btn btn-outline-secondary">{{cardpage.cta_text}}</a>
</div> </div>
</div><!--/.card-footer--> </div><!--/.card-footer-->
<div class="flag-vertical">{{"%02d"|format(flag_n.next())}}</div> <div class="flag-vertical">{{"%02d"|format(flag_n.next())}}</div>
</div><!--/.card--> </div><!--/.card-->
{% set cardpage = pages|selectattr('html', 'defined_and_equalto', 'manage-the-rippled-server.html')|first %}
<div class="card"> <div class="card">
<div class="card-header"> <div class="card-header">
<a href="manage-the-rippled-server.html" class="header-link"> <a href="{{cardpage.html}}" class="header-link">
<img class="image-icon" src="assets/img/icon-xrp-run-rippled.svg" > <img class="image-icon" src="assets/img/icon-xrp-run-rippled.svg" alt="{% trans %}'run rippled' icon{% endtrans %}">
<h3 class="card-title">Run a rippled Server</h3> <h3 class="card-title">{{cardpage.name}}</h3>
</a> </a>
</div><!--/.card-header--> </div><!--/.card-header-->
<div class="card-body"> <div class="card-body">
<p>Install, configure, and manage the core server that powers the XRP Ledger.</p> <p>{{cardpage.blurb}}</p>
</div><!--/.card-body--> </div><!--/.card-body-->
<div class="card-footer"> <div class="card-footer">
<div class="readmore"> <div class="readmore">
<a href="manage-the-rippled-server.html" class="btn btn-outline-secondary">Run rippled</a> <a href="{{cardpage.html}}" class="btn btn-outline-secondary">{{cardpage.cta_text}}</a>
</div> </div>
</div><!--/.card-footer--> </div><!--/.card-footer-->
<div class="flag-vertical">{{"%02d"|format(flag_n.next())}}</div> <div class="flag-vertical">{{"%02d"|format(flag_n.next())}}</div>
@@ -245,20 +248,20 @@
<div class="card"> <div class="card">
<div class="card-header"> <div class="card-header">
<h3 class="card-title"><a href="tutorials.html">More Tutorials</a></h3> <h3 class="card-title"><a href="tutorials.html">{% trans %}More Tutorials{% endtrans %}</a></h3>
</div><!--/.card-header--> </div><!--/.card-header-->
<div class="card-body"> <div class="card-body">
<div class="curated-links"> <div class="curated-links">
<ul> <ul>
<li><a href="assign-a-regular-key-pair.html">Assign a Regular Key Pair</a></li> <li><a href="assign-a-regular-key-pair.html">{{(pages|selectattr('html', 'defined_and_equalto', 'manage-the-rippled-server.html')|first).name}}</a></li>
<li><a href="set-up-multi-signing.html">Set Up Multi-Signing</a></li> <li><a href="set-up-multi-signing.html">{{(pages|selectattr('html', 'defined_and_equalto', 'set-up-multi-signing.html')|first).name}}</a></li>
<li><a href="use-escrows.html">Use Escrows</a></li> <li><a href="use-escrows.html">{{(pages|selectattr('html', 'defined_and_equalto', 'use-escrows.html')|first).name}}</a></li>
<li><a href="use-payment-channels.html">Use Payment Channels</a></li> <li><a href="use-payment-channels.html">{{(pages|selectattr('html', 'defined_and_equalto', 'use-payment-channels.html')|first).name}}</a></li>
</ul> </ul>
</div><!--/.curated-links--> </div><!--/.curated-links-->
</div><!--/.card-body--> </div><!--/.card-body-->
<div class="card-footer"> <div class="card-footer">
<a href="tutorials.html" class="btn btn-outline-secondary">All Tutorials</a> <a href="tutorials.html" class="btn btn-outline-secondary">{% trans %}All Tutorials{% endtrans %}</a>
</div><!--/.card-footer--> </div><!--/.card-footer-->
<div class="flag-vertical">{{"%02d"|format(flag_n.next())}}</div> <div class="flag-vertical">{{"%02d"|format(flag_n.next())}}</div>
</div><!--/.card--> </div><!--/.card-->
@@ -267,9 +270,9 @@
<section class="container-fluid related-projects card-grid card-grid-2x1"> <section class="container-fluid related-projects card-grid card-grid-2x1">
<div class="section-hero card pl-0"> <div class="section-hero card pl-0">
<h2>Related Projects</h2> <h2>{% trans %}Related Projects{% endtrans %}</h2>
<div class="blurb"> <div class="blurb">
<p>You're not alone in building the Internet of Value. These projects are proudly collaborating with the XRP Ledger to make all the world's money move like information moves today.</p> <p>{% trans %}You're not alone in building the Internet of Value. These projects are proudly collaborating with the XRP Ledger to make all the world's money move like information moves today.{% endtrans %}</p>
</div> </div>
</div><!--/.section-hero--> </div><!--/.section-hero-->
@@ -277,28 +280,28 @@
<div class="card interledger-link"> <div class="card interledger-link">
<div class="card-header"> <div class="card-header">
<img class="project-icon" src="assets/img/ilp_logo.svg" /> <img class="project-icon" src="assets/img/ilp_logo.svg" alt="{% trans %}Interledger logo{% endtrans %}" />
<h3 class="card-title">Interledger</h3> <h3 class="card-title">{% trans %}Interledger{% endtrans %}</h3>
</div><!--/.card-header--> </div><!--/.card-header-->
<div class="card-body"> <div class="card-body">
<p class="project-summary">Interledger is an open protocol suite for sending payments across different ledgers.</p> <p class="project-summary">{% trans %}Interledger is an open protocol suite for sending payments across different ledgers.{% endtrans %}</p>
</div><!--/.card-body--> </div><!--/.card-body-->
<div class="card-footer"> <div class="card-footer">
<a class="btn btn-outline-secondary external-link" href="https://interledger.org/" target="_blank">Learn More <i class="fa fa-external-link" aria-hidden="true"></i></a> <a class="btn btn-outline-secondary external-link" href="https://interledger.org/" target="_blank">{% trans %}Learn More{% endtrans %} <i class="fa fa-external-link" aria-hidden="true"></i></a>
</div><!--/.card-footer--> </div><!--/.card-footer-->
<div class="flag-vertical">{{"%02d"|format(flag_n.next())}}</div> <div class="flag-vertical">{{"%02d"|format(flag_n.next())}}</div>
</div><!--/.card--> </div><!--/.card-->
<div class="card xpring-link"> <div class="card xpring-link">
<div class="card-header"> <div class="card-header">
<img class="project-icon" src="assets/img/xpring-logo.svg" alt="Xpring" /> <img class="project-icon" src="assets/img/xpring-logo.svg" alt="{% trans %}Xpring logo{% endtrans %}" />
<h3 class="card-title">Xpring</h3> <h3 class="card-title">{% trans %}Xpring{% endtrans %}</h3>
</div><!--/.card-header--> </div><!--/.card-header-->
<div class="card-body"> <div class="card-body">
<p class="project-summary">Xpring (pronounced “spring”) is a Ripple initiative that builds infrastructure and helps innovative blockchain projects grow through investments and partnerships.</p> <p class="project-summary">{% trans %}Xpring is Ripples initiative to create an open developer platform for money.{% endtrans %}</p>
</div><!--/.card-body--> </div><!--/.card-body-->
<div class="card-footer"> <div class="card-footer">
<a class="btn btn-outline-secondary external-link" href="https://xpring.io/" target="_blank">Learn More <i class="fa fa-external-link" aria-hidden="true"></i></a> <a class="btn btn-outline-secondary external-link" href="https://xpring.io/" target="_blank">{% trans %}Learn More{% endtrans %} <i class="fa fa-external-link" aria-hidden="true"></i></a>
</div><!--/.card-footer--> </div><!--/.card-footer-->
<div class="flag-vertical">{{"%02d"|format(flag_n.next())}}</div> <div class="flag-vertical">{{"%02d"|format(flag_n.next())}}</div>
</div><!--/.card--> </div><!--/.card-->