16 KiB
アカウント
XRP Ledgerの「アカウント」は、XRPの所有者とトランザクションの送信者を表します。アカウントの主な要素は次のとおりです。
- 識別用のアドレス。例えば、
rf1BiGeXwwQoi8Z2ueFYTEXSwuJYfV2Jpn - XRPの残高。このXRPの一部は、準備金用に確保されています。
- シーケンス番号は1から始まり、このアカウントからトランザクションが送信されるたびに1つ増加します。トランザクションのシーケンス番号がその送信者の次のシーケンス番号と一致しない限り、トランザクションをレジャーに含めることはできません。
- このアカウントと残高に影響を及ぼした取引の履歴。
- 取引の承認方法。以下に例を示します。
- アカウント固有のマスターキーのペア。(無効にできますが、変更はできません。)
- ローテーションで使用できる「レギュラー」キーペア。
- マルチ署名の署名者のリスト。(アカウントのコアデータとは別に保存されます。)
アカウントのコアデータは、レジャーのデータツリーのAccountRootレジャーのオブジェクトタイプに保存されます。アカウントは、他の複数のタイプのデータの所有者(または部分的な所有者)になることもできます。
ヒント: XRP Ledgerの「アカウント」は、財務上の用途(例:「銀行口座」)やコンピューター上の用途(例:「UNIXアカウント」)で使用されます。XRP以外の通貨および資産はXRP Ledgerアカウント自体には保存されません。そのような資産はそれぞれ、両当事者を結ぶ「トラストライン」と呼ばれる会計関係に保存されます。
アカウントの作成
「アカウント作成」専用のトランザクションはありません。Paymentトランザクション でまだアカウントを所有していない数学的に有効なアドレスにアカウントの準備金以上のXRPが送信されると、[Paymentトランザクション][]で自動的に新しいアカウントが作成されます。これはアカウントの 資金提供 と呼ばれ、レジャーにAccountRootオブジェクトが作成されます。それ以外のトランザクションでアカウントを作成することはできません。
注意: アカウントを資金提供することによって、そのアカウントに対して特別な権限を持つことにはなりません。アカウントのアドレスに対応するシークレットキーを持っている人なら誰でも、アカウントとそれに含まれるすべてのXRPの完全制御権を持っています。一部のアドレスでは、誰もシークレットキーを持っていない場合があります。その場合、アカウントはブラックホールになり、XRPは永久に失われます。
XRP Ledgerでアカウントを取得する一般的な方法は次のとおりです。
-
ランダム性の強いソースからキーペアを生成し、そのキーペアのアドレスを計算します。(例えば、[wallet_proposeメソッド][]を使用して計算することができます。)
-
XRP Ledgerにアカウントをすでに持っているユーザーに、生成したアドレスにXRPを送信してもらいます。
-
例えば、一般の取引所でXRPを購入し、その取引所から、指定したアドレスにXRPを引き出すことができます。
注意: 自身のXRP Ledgerアドレスで初めてXRPを受け取る場合はアカウントの準備金(現在は20 XRP)を支払う必要があります。この金額のXRPは無期限に使用できなくなります。一方で、一般の取引所では通常、顧客のXRPはすべて、共有されたいくつかのXRP Ledgerアカウントに保有されているため、顧客はその取引所で個々のアカウントの準備金を支払う必要はありません。引き出す前に、XRP Ledgerに直接アカウントを保有することが、金額に見合う価値があるかどうかを検討してください。
-
アドレス
{% include '_snippets/data_types/address.md' %}
有効なアドレスに資金供給することで、そのアドレスをXRP Ledgerのアカウントにすることができます。レギュラーキーまたは署名者リストのメンバーを表すために資金供給されていないアドレスを使用することもできます。資金供給されたアカウントのみがトランザクションの送信者になることができます。
キーペアを始め、有効なアドレスの作成は、厳密な数学的演算です。キーペアの生成と、そのアドレスの計算は完全にオフラインで行うことができます。XRP Ledgerやその他の関係者と通信する必要はありません。公開鍵からアドレスへの変換には一方向のハッシュ関数が含まれるため、公開鍵がアドレスと一致することは確認できますが、アドレスのみから公開鍵を導出することはできません。(このことが、署名付きのトランザクションに送信者の公開鍵 と アドレスが含まれる理由の1つとなっています。)
XRP Ledgerアドレスの計算方法の技術的な詳細については、アドレスのエンコードを参照してください。
特別なアドレス
XRP Ledgerでは、過去の使用という点で、一部のアドレスに特別な意味があります。多くの場合、これらのアドレスは「ブラックホール」アドレスです。つまり、このアドレスは既知のシークレットキーから派生したものではありません。アドレスのみからシークレットキーを推測することは事実上不可能なため、ブラックホールアドレスが保有しているXRPは永久に失われます。
| アドレス | 名前 | 意味 | ブラックホール? |
|---|---|---|---|
| rrrrrrrrrrrrrrrrrrrrrhoLvTp | ACCOUNT_ZERO | 値0を[base58][]形式にエンコードしたXRP Ledgerのアドレス。ピアツーピア通信では、このアドレスは、XRPの発行者としてrippledで使用されます。 |
はい |
| rrrrrrrrrrrrrrrrrrrrBZbvji | ACCOUNT_ONE | 値1を[base58][]形式にエンコードしたXRP Ledgerのアドレス。レジャーのRippleState項目では、このアドレスは、トラストライン残高の発行者のプレースホルダーとして使用されます。 |
はい |
| rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh | ジェネシスアカウント | rippledで新しいジェネシスレジャーが一から開始される場合(例えば、スタンドアロンモード)、このアカウントはすべてのXRPを保持します。このアドレスは、シード値「masterpassphrase」から生成されており、この値はハードコーディングされています。 |
いいえ |
| rrrrrrrrrrrrrrrrrNAMEtxvNvQ | Ripple名予約のブラックホール | 以前は、Rippleでは、このアカウントにXRPを送信してRipple名を予約するようユーザーに求めていました。 | はい |
| rrrrrrrrrrrrrrrrrrrn5RM1rHd | NaNアドレス | 以前のバージョンのripple-libでは、XRP Ledgerの[base58][]文字列エンコード形式を使用して、値NaNをエンコードするときにこのアドレスを生成しました。 | はい |
アカウントの永続性
一度作成されたアカウントはXRP Ledgerのデータツリーに永続的に存在します。これは、古いトランザクションを2回処理できないように、トランザクションの現在のシーケンス番号を永続的に追跡する必要があるためです。
Bitcoinや他の多くの暗号資産とは異なり、XRP Ledgerの公開レジャーチェーンの新しい各バージョンにはレジャーの詳細なステータスが含まれており、このサイズは、新規アカウントが増えるごとに大きくなります。そのため、Rippleでは、本当に必要でない限り、新しいアカウントを作成することは推奨していません。多くのユーザーに代わって価値を送受信する金融機関などは、XRP Ledgerでは1つ(または少数)のアカウントのみを使用し、顧客との間の個別の決済を区別するためにソースタグと宛先タグを使用できます。
トランザクション履歴
XRP Ledgerでは、トランザクション(取引)履歴をトランザクションの「スレッド」によって追跡することができます。これはトランザクションの識別用のハッシュとレジャーインデックスにリンクされています。AccountRootレジャーオブジェクトには、それを最後に修正したトランザクションの識別用のハッシュとレジャーが含まれます。そのトランザクションのメタデータには、AccountRootノードの前の状態が含まれているため、この方法で1つのアカウントの履歴を繰り返すことができます。このトランザクション履歴には、AccountRootノードを直接変更するトランザクションが含まれます。以下に例を示します。
- アカウントによって送信されるトランザクション。アカウントの
Sequence番号が変更されるため。このようなトランザクションでは、トランザクションコストによりアカウントのXRP残高も変更されます。 - アカウントのXRP残高を変更したトランザクション。例えば、着信する[Paymentトランザクション][]や他のタイプの取引(例:[PaymentChannelClaim][]や[EscrowFinish][])。
アカウントの 概念的な トランザクション履歴には、アカウントの所有オブジェクトとXRP以外の残高を変更したトランザクションも含まれます。これらのオブジェクトは別個のレジャーオブジェクトであり、それぞれに影響を及ぼした独自のトランザクションスレッドが含まれます。アカウントのレジャーの履歴全体がある場合は、それをたどって、その履歴によって作成または変更されたレジャーオブジェクトを見つけることができます。「完全」なトランザクション履歴には、トランザクションで所有されているオブジェクトの履歴が含まれます。例を以下に示します。
RippleStateオブジェクト(トラストライン)。アカウントに関連付けられています。DirectoryNodeオブジェクト(特にアカウントの所有オブジェクトを追跡する所有者ディレクトリ)。Offerオブジェクト。分散型取引所でのアカウントの未処理の取引注文を表すオブジェクト。PayChannelアカウントとの間の非同期のPayment Channelを表すオブジェクト。Escrow時間または暗号条件によってロックされ、アカウントとの間の保留中の支払いを表すオブジェクト。SignerListマルチ署名によってアカウントのトランザクションを承認できるアドレスのリストを表すオブジェクト。
これらの各オブジェクトの詳細については、レジャーフォーマットのリファレンスを参照してください。
アドレスのエンコード
ヒント: これらの技術的な詳細は、XRP Ledgerとの互換性を保つために低レベルのライブラリソフトウェアを構築しているユーザーのみを対象としています。
XRP Ledgerのアドレスは、次のRipple ディクショナリー のbase58を使用してエンコードされています。rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz。XRP Ledgerはbase58でいくつかのタイプのキーをエンコードするため、それらを区別するためにエンコードされたデータの前に1バイトの「タイププレフィクス」(「バージョンプレフィクス」とも呼ばれます)を付けます。タイププレフィクスによりアドレスは通常、base58形式の異なる文字で始まります。
次の図は、キーとアドレスの関係を示しています。
XRP Ledgerアドレスの計算式は次のとおりです。コード例全体については、encode_address.jsを参照してください。
-
次の必須アルゴリズムをインポートします。SHA-256、RIPEMD160、base58。base58のディクショナリーを設定します。
'use strict'; const assert = require('assert'); const crypto = require('crypto'); const R_B58_DICT = 'rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz'; const base58 = require('base-x')(R_B58_DICT); assert(crypto.getHashes().includes('sha256')); assert(crypto.getHashes().includes('ripemd160')); -
33バイトのECDSA secp256k1公開鍵、または32バイトのEd25119公開鍵で始めます。Ed25519キーの場合は、キーの前にバイト
0xEDを付けます。const pubkey_hex = 'ED9434799226374926EDA3B54B1B461B4ABF7237962EAE18528FEA67595397FA32'; const pubkey = Buffer.from(pubkey_hex, 'hex'); assert(pubkey.length == 33); -
公開鍵のSHA-256ハッシュのRIPEMD160ハッシュを計算します。この値は「Account ID」です。
const pubkey_inner_hash = crypto.createHash('sha256').update(pubkey); const pubkey_outer_hash = crypto.createHash('ripemd160'); pubkey_outer_hash.update(pubkey_inner_hash.digest()); const account_id = pubkey_outer_hash.digest(); -
アカウントIDのSHA-256ハッシュのSHA-256ハッシュを計算します。最初の4バイトを使用ます。この値が「チェックサム」です。
const address_type_prefix = Buffer.from([0x00]); const payload = Buffer.concat([address_type_prefix, account_id]); const chksum_hash1 = crypto.createHash('sha256').update(payload).digest(); const chksum_hash2 = crypto.createHash('sha256').update(chksum_hash1).digest(); const checksum = chksum_hash2.slice(0,4); -
ペイロードとチェックサムを連結します。連結バッファーのbase58値を計算します。この結果が、該当のアドレスになります。
const dataToEncode = Buffer.concat([payload, checksum]); const address = base58.encode(dataToEncode); console.log(address); // rDTXLQ7ZKZVKz33zJbHjgVShjsBnqMBhmN
{% include '_snippets/rippled-api-links.md' %} {% include '_snippets/tx-type-links.md' %} {% include '_snippets/rippled_versions.md' %}
