Files
xrpl-dev-portal/content/concepts/transactions/reliable-transaction-submission.ja.md
Rome Reginelli b51bcb4ea3 Information Architecture v3 (#1934)
* Update look up escrows to remove redundant info about lookups via sender/destination. Modify cancel expired escrow for brevity.

* Cancel escrow: fix notes

* Add draft of updated cancel-escrow.js.

* Update intro to escrows.

* Add Escrow Tutorial

* Minor corrections

* Fix headings, add HTML

* Update escrow docs

This commit re-creates f205a92db2 with
some adjustments:

- Omit the accidentally-created dir full of junk
- Fix some typos and one mistake in the Escrow limitations section
- Add a table to the EscrowCreate ref to clarify valid combos of fields.

* Concept info from send-a-time-held-escrow added to escrow.md

* IA: Move "Consensus Network" files

This re-creates some work from the original commit 56fffe0b9f

* Rewrite escrows article (re-created)

This commit re-creates relevant work from the following commits:

9a4a588f2b Update escrow.md context info
e1b017dc83 Remove references to using escrow for interledger payments.

* IA: Move "XRPL servers" files

This re-creates some work from original commit 7611979abf

* IA: move "production readiness" files.

Re-creates work from the following commit:

692438693a  Move tutorials to concepts

* New intro articles

Original commit: 56fffe0b9f

* IA: Reorg account concepts

Re-creates some work from original commit 56fffe0b9f

* IA: reorg transaction concepts

Original commits:
9d4eff9940  WIP - reorg accounts
7611979abf  WIP dir. reorg

* IA: reorg consensus concepts

Original commit: 56fffe0b9f

* IA: Reorg ledger docs

Original commit: 56fffe0b9f

- Rephrased some details of the section

* IA: rename issuing/operational addresses page

Original commit: 56fffe0b9f

* Moving use cases

* Fleshing out Use Cases

Note, the dactyl-config.yml file has not been fully updated.

* Clean up checks conceptual info.

* Remove redundant checks use case section

Original commit: 3c29e9c05e

* IA: move Dex under tokens

Original commit: d08b3ba7d7

* Touch up stablecoin issuer use case (#1856)

* Consolidate stablecoin use case

* Stablecoin issuer: cleanup progress through sending

* Stablecoin issuer: reorg second half

(Note: the dactyl-config.yml is not fully reconciled yet)

* Move rippled and clio tutorials into infrastructure

* Remove link to checks amendement.

* Add note to account_objects.md about commandline interface type field.

* Merge expiration case with lifecycle section.

* Interoperability Use Cases

* Add graphics to intro

* Move escrow use cases to dedicated page.

* Update use case page intros and corresponding concept info.

* Clarify meaning of direct XRP payments.

* Intro link updates

* Payment use cases

* Remove some unnecessary links in transactions section

Original commit: e6fcf4a4dc

* Link cleanup in Tokens section

Original commit: 9588dd5e70

* Touch up 'Configure Peering' section

Original commit: fc8f0990b8

* Clean up links in accounts section

Original commit: 3da5fde7a8

* Add NFT mkt use case

* p2p payments: edits to Wallets

* Clean up payments use cases

* Refine history description

* IA: use case cleanup

* IA: reconcile servers, ledgers sections

* IA: reconcile payment types, tx, tokens

* IA: reconcile accounts section

* IA: reconcile infra

* IA: Fix most broken links

* Full Docs Index: omit from sidebar

* IA: fix up most broken links

* fix Absolute path link to internal content

* Quick updates to Software Ecosystem

* Remove some absolute links to internal resources

* Fix remaining broken links in JA target

* Contributing: tweak formatting

* Tutorials: fix some minor issues

* remove interop use cases

* remove intro image and personal references to dennis

* alphabetize-transaction-nav

* Remove unused files

* Add QS escrow tutorials

* IA: move ledgers, consensus protocol files around

* IA: update nav for new page hierarchy

* reordering of topics under new networks and servers top-nav

* Move "Naming" to "What is XRP?"

* Update dactyl-config.yml

Remove xrp.md from the TOC.

* Update list-xrp-as-an-exchange.md

Update link to what-is-xrp

* Update list-xrp-as-an-exchange.ja.md

Change link to what-is-xrp

* Update currency-formats.md

Change link to what-is-xrp

* Update currency-formats.ja.md

Change link to what-is-xrp

* Update cancel-an-expired-escrow.md

Change link to what-is-xrp

* Update paymentchannelfund.md

Change link to what-is-xml

* Update look-up-escrows.md

Change link to what-is-xrp

* Update tokens.md

change link to what-is-xrp

* Update use-payment-channels.md

* Update send-a-time-held-escrow.md

Update link to what-is-xml

* fix broken links

* Update parallel-networks.md

Change link to what-is-xml

* Update parallel-networks.ja.md

* Update invariant-checking.md

Remove link to xrp.html

* Update invariant-checking.ja.md

Remove link to xrp.html

* Update transaction-cost.md

Change link to what-is-xrp

* Update transaction-cost.ja.md

Change link to what-is-xrp

* Update send-a-conditionally-held-escrow.md

Change link to what-is-xrp

* Update stablecoin-issuer.md

Change link to what-is-xrp

* Update tokens.ja.md

Change link to what-is-xml

* Update autobridging.ja.md

Change link to what-is-xrp

* Update currency-formats.md

update text

* reorganize infrastructure nav section

* Update currency-formats.md

Try removing link altogether.

* Update currency-formats.ja.md

Remove link to what-is-xrp.html

* move commandline usage topic to infrastructure

* initial intro rewrite

* minor update to language

* IA.v3: rm Production Readiness

* Delete xrp.md

* Update xrp link in snippet

* Add redirect for old xrp.html URL

* Small edits to 'What is XRP?' article

* Add missing imgs

* XRP - copy edit per @DennisDawson

* restructure tutorials nav and pages

* fix broken links

* more broken link fixes

* Algo trading: 1st draft

* Algo trading: notes on taxes

* Algo trading: edits per review

* algo trading: fix broken link

* Ledger structure: rewrite for accuracy and clarity

* Update links to removed 'tree format' header

* Ledger Structure: Update diagrams

* Re-gen CSS for ledger structure changes

* Ledger structure: edits per review

* IA.v3: fix broken NFT links introduced by rebase

* Desktop Wallet (py): update little stuff

* Update some capacity/storage details

* contribute doc nav update

* fix image link in create diagram page

* IAv3: Fix 'Ledgers' blurb

* Update full history requirements with details from community members

* add reviewer suggestions

* Edits per @trippled review

* Apply suggestions from peer review

Co-authored-by: oeggert <117319296+oeggert@users.noreply.github.com>

* FH: reword file size limit note per review

* Update software ecosystem

* updates per review

* Minor tweaks to graphics

* fixTypos

* Update content/concepts/introduction/software-ecosystem.md

Co-authored-by: Amarantha Kulkarni <amarantha-k@users.noreply.github.com>

* Update content/concepts/introduction/software-ecosystem.md

Co-authored-by: Amarantha Kulkarni <amarantha-k@users.noreply.github.com>

* [JA] update AccountDelete cost

* custom transactors doc

* add doc to dactyl config

* [JA] fix NonFungibleTokensV1_1 amendment status

* [JA] update NFTokenOffer page

* Remove old, unused XRP article (#2039)

* add reviewer suggestions

* Add tooling to check for file/nav consistency

- From the repo top, run tool/check_file_consistency.py to look for
  Markdown files that exist in the "content/" directory but aren't used
  in the documentation.
- New "enforce_filenames" filter prints a warning to console when
  building, if a file's path and filename don't match expectations
  based on its place in the nav and top heading.

* File consistency checker: correctly handle filenames starting in _

* Remove unused old 'get started' and associated code

* Create Resources section & reorg some files

- Rename some files/folders based on their place in the nav
- Move a bunch of non-documentation stuff, and docs on contributing code
  and/or docs to the new "Resources" section.
- Known issue: nav spills into a second row on page widths between
  993px-1110px. To be fixed in a later CSS update, maybe along with
  making the Resources dropdown multi-column.

* Fix #2078 code tab bug

CSS not built yet, to reduce merge conflicts. Won't have any effect
until that happens.

* fix Transaction JSON

* [JA] translate contributing contents

* fix contributing-to-documentation parent

* fix contribute-code blurb

* Top nav: add cols for Resources, fix broken links

* CSS: fix top nav overflows

* Fix broken link from redirect not in JA target

* Top nav: add Infra to article types

* Update contrib info & rename intro file

* [ja] Update link to suggested first page to translate

* [ja] fix contribute docs organization

* Run private network with docker tutorial (#2065)

* [NO-ISSUE] Run private network with docker tutorial

Adds a tutorial page in the Infrastructure section on how to run a private XRPL network with Docker.

Please let me know if you think this is a useful page to include for developers, whether the steps are clear or not, and if you have suggestions on what can be added to it.

* Add minor link fixes and Japanese target

* Apply suggestions from code review

Co-authored-by: Amarantha Kulkarni <amarantha-k@users.noreply.github.com>

* Add link to ripple-docker-testnet setup scripts in See Also section

* Update repo URL

---------

Co-authored-by: Amarantha Kulkarni <amarantha-k@users.noreply.github.com>

* add intro gfx (#2036)

* add intro gfx

* Move graphic up

* Update some graphics with their revised versions

* Add updated version of the custodial vs non-custodial graphic

---------

Co-authored-by: Amarantha Kulkarni <amarantha-k@users.noreply.github.com>
Co-authored-by: Amarantha Kulkarni <akulkarni@ripple.com>

* Update to reflect current UNL publishers

* [ja] update contributing

Co-authored-by: tequ <git@tequ.dev>

* Incorporate feedback on "What is XRP" page. (#2099)

* Add trademark info for XRP

* Revert section to previous state

* Fix broken link (#2101)

---------

Co-authored-by: Oliver Eggert <oeggert@ripple.com>
Co-authored-by: ddawson <dennis.s.dawson@gmail.com>
Co-authored-by: Maria Shodunke <mshodunke@ripple.com>
Co-authored-by: tequ <git@tequ.dev>
Co-authored-by: oeggert <117319296+oeggert@users.noreply.github.com>
Co-authored-by: Amarantha Kulkarni <amarantha-k@users.noreply.github.com>
Co-authored-by: develoQ <develoQ.jp@gmail.com>
Co-authored-by: Maria Shodunke <maria-robobug@users.noreply.github.com>
Co-authored-by: Amarantha Kulkarni <akulkarni@ripple.com>
2023-09-01 12:40:18 -07:00

41 KiB
Raw Blame History

html, parent, blurb, labels
html parent blurb labels
reliable-transaction-submission.html transactions.html XRP Ledgerにトランザクションを送信することができるシステムを構築し、最終結果を素早く安全に受け取ります。
トランザクション送信
開発

信頼できるトランザクションの送信

XRP Ledgerを使用する金融機関やその他のサービスは、ここで説明するベストプラクティスを使用し、迅速で確認可能な方法で、トランザクションが検証または拒否されるようにする必要があります。信頼できるローカルで運営されているrippledサーバーにトランザクションを送信してください。

本書で説明されているベストプラクティスを使用すると、アプリケーションはアーカイブ中にトランザクションをXRP Ledgerに送信できます。

  1. べき等性 - トランザクションは、一度のみ処理するか、またはまったく処理しないようにします。
  2. 検証可能性 - アプリケーションはトランザクションの最終結果を判断できます。

ベストプラクティスを導入しないと、アプリケーションに以下のエラーが発生する可能性があります。

  1. 誤って実行されなかったトランザクションを送信する。
  2. 暫定的なトランザクションを、最終的で不変の結果として誤判断する。
  3. レジャーに以前に適用されたトランザクションの正式な結果を検出できない。

こういったタイプのエラーは、深刻な問題に繋がる可能性があります。例えば、以前のPaymentトランザクションを検出できないアプリケーションは、誤ってトランザクションを再送信してしまい、元の支払いが重複してしまう可能性があります。したがって、本書で説明するテクニックを使用し、アプリケーションが正式なトランザクション結果に基づいてアクションをとることが非常に重要です。

背景

XRP Ledgerプロトコルは、ネットワークのすべてのサーバーで共有されるレジャー台帳を提供します。コンセンサスと検証のプロセスを通じ、ネットワークはトランザクションがレジャーに適用される(または除外される)順序に同意します。

正しい形式のトランザクションを信頼できるXRP Ledgerサーバーに送信すると、数秒で検証または拒否されます。ただし、正しい形式のトランザクションであっても迅速に検証も拒否もされないことがあります。このような特殊なケースは、アプリケーションがトランザクションを送信した後にグローバルトランザクションコストが増加すると発生することがあります。トランザクションに指定された額よりもトランザクションコストが増加すると、そのトランザクションは次回の検証済みレジャーに含まれません。後日、グローバルトランザクションコストが下がった場合には、そのトランザクションは後のレジャーに含まれます。トランザクションに有効期限が指定されていない場合には、レジャーへの追加はいつになるか分かりません。

電源やネットワークに障害が発生した場合には、送信済みトランザクションのステータスの検出時にさらに多くの問題に直面します。アプリケーションは、トランザクションの適切な送信と、その後の正式結果の適切な受信の両方に十分な注意を払う必要があります。

トランザクションのタイムライン

XRP Ledgerには、HTTP / WebSocket APIクライアントライブラリなど、トランザクションを送信するためのAPIがいくつかあります。使用するAPIにかかわらず、トランザクションは以下のようにレジャーに適用されます。

  1. アカウント所有者は、トランザクションを作成して署名します。
  2. 所有者は、トランザクション候補として、そのトランザクションをネットワークに送信します。
    • 形式が正しくないトランザクションや無意味なトランザクションはただちに拒否されます。
    • 形式が正しいトランザクションは、暫定的に成功し、後で失敗することもあります。
    • 形式が正しいトランザクションは、暫定的に失敗し、後で成功することもあります。
    • 形式が正しいトランザクションは、暫定的に成功し、後で少々異なった形で成功することもあります。(例えば、別のオファーが使用され、暫定的な結果よりも良い(または悪い)両替レートになることがあります。)
  3. コンセンサスと検証を通じ、トランザクションがレジャーに適用されます。ネットワークの伝達のコストを適用するために、一部の失敗したトランザクションも適用されることがあります。
  4. 検証されたレジャーにはそのトランザクションが含まれ、その結果がレジャーの状態に反映されます。
    • トランザクション結果は暫定的なものではなくなり、成功または失敗の結果は最終的かつ不変のものとなります。

注記: rippledを介してトランザクションを送信すると、送信コマンドから返される成功ステータスコードによって、rippledサーバーがトランザクション候補を受信したことが示されます。このトランザクションは、検証されたレジャーに適用される場合とされない場合があります。

APIは、現在の進行中のレジャーにトランザクション候補を適用した結果に基づいて、暫定的な結果を返すことがあります。アプリケーションでは、この結果を、トランザクションの最終的な不変の結果と混同してはなりません。不変の結果は、検証済みのレジャーだけにあります。アプリケーションは、トランザクション結果を含むレジャーが検証されるまで、トランザクションのステータスを繰り返し照会する必要があります。

トランザクションの適用時に、rippledサーバーは、最後に検証されたレジャーを使用します。これは、すでにネットワーク全体によって検証されたトランザクションに基づくレジャーの状態のスナップショットです。コンセンサスと検証のプロセスは、新しいトランザクションのセットを、最後に検証されたレジャーに正規の順序で適用します。その結果、新しい検証済みレジャーが出来上がります。この新しい検証済みレジャーバージョンとその前のバージョンによって、レジャー履歴が形成されます。

レジャーの各バージョンにはレジャーインデックスが付けられており、前のレジャーバージョンのレジャーインデックスよりも1つ大きい値になります。また、各レジャーには識別用のハッシュ値があります。これは、レジャーの内容から決定される固有の値です。進行中のレジャーには多数のバージョンが存在することがあります。その場合、レジャーインデックスは同じですが、ハッシュ値が異なります。検証できるのは、1つのバージョンのみです。

各検証済みレジャーには、トランザクションが適用される正規の順序があります。この順序は、レジャーの最終的なトランザクションセットに基づいて決定されます。これと異なり、各rippledサーバーの進行中のレジャーでは、トランザクションの受信時に増分計算されます。トランザクションを暫定的に実行する順序は、新しい検証済みレジャーを構築するためにトランザクションを実行する順序とは通常異なります。これが、トランザクションの暫定的な結果が最終結果とは異なる可能性がある理由の1つです。例えば、ある支払いが、同じオファーを使用する別の支払いの前と後のどちらで実行されるかによって、最終的な為替レートが異なることがあります。

LastLedgerSequence

LastLedgerSequenceは、省略可能な全トランザクションに適用されるパラメーターです。このパラメーターはXRP Ledgerに対して、トランザクションを特定のレジャーバージョンで検証する必要があること、またはトランザクションを特定のレジャーバージョンの前に検証する必要があることを指示します。XRP Ledgerは、レジャーインデックスがトランザクションのLastLedgerSequenceパラメーターよりも大きいトランザクションをレジャーバージョンに含めることは決してありません。

LastLedgerSequenceパラメーターを使用すれば、トランザクションが迅速に確認されず、将来のレジャーに含まれるような好ましくないケースを防止できます。LastLedgerSequenceパラメーターは、各トランザクションに指定する必要があります。自動プロセスでは、最後に検証されたレジャーインデックスよりも4つ大きい数値を使用して、トランザクションが予測可能な方法で、かつ迅速に検証または拒否されるようにします。

トランザクションの送信時に、LastLedgerSequenceを明示的に指定する必要があります。

ベストプラクティス

次の図は、トランザクションの送信と結果の判断に推奨されるフローを示します。

信頼できるトランザクションの送信フローチャート

信頼できるトランザクションの送信

トランザクションを送信するアプリケーションでは、以下のベストプラクティスを使用し、プロセス終了やその他の問題が発生した場合でも信頼性が高い方法でトランザクションを送信する必要があります。アプリケーションが最終的で検証済みの結果に基づいて処理できるように、アプリケーションのトランザクション結果を確認する必要があります。

送信と確認は別々の異なる手続きであり、本書の説明に基づいてこれを実装することができます。

  1. 送信 - トランザクションがネットワークに送信され、暫定的な結果が戻されます。
  2. 確認 - 検証済みレジャーを確認し、正式な結果が判断されます。

送信

送信が完了する前に電源障害やネットワーク障害が発生する可能性に備え、送信前にトランザクションの詳細を保持しておきます。再起動時に、保持された値により、トランザクションのステータスを確認することが可能になります。

送信プロセスは次のとおりです。

  1. トランザクションを生成して署名します
    • LastLedgerSequenceパラメーターを指定します
  2. 以下を保存して、トランザクション詳細を保持しておきます
    • トランザクションハッシュ
    • LastLedgerSequence
    • 送信者のアドレスとシーケンス番号
    • 送信時における最新の検証済みレジャーインデックス
    • 必要に応じて、アプリケーション固有のデータ
  3. トランザクションを送信します

確認

通常の操作中に、アプリケーションは、送信されたトランザクションのステータスをハッシュによって確認できます。または、使用するAPIによっては、トランザクションが確認または拒否されたときにその通知を受信できます。この通常操作は、ネットワーク障害や電源障害などによって中断されることがあります。そのような中断が発生した場合には、アプリケーションは信頼性の高い方法で、中断前にネットワークに送信されたまたは送信されなかった可能性のあるトランザクションのステータスを確認する必要があります。

再起動時、または最新の検証済みレジャーの確認時の例を示します(擬似コード):

For each persisted transaction without validated result:
    Query transaction by hash
    If (result appears in any validated ledger)
        # Outcome is final
        Persist the final result
        If (result code is tesSUCCESS)
            Application may act based on successful transaction
        Else
            The transaction failed (1)
            If appropriate for the application and failure type, submit with
                new LastLedgerSequence and Fee

    Else if (LastLedgerSequence > newest validated ledger)
        # Outcome is not yet final
        Wait for more ledgers to be validated

    Else
        If (server has continuous ledger history from the ledger when the
              transaction was submitted up to and including the ledger
              identified by LastLedgerSequence)

            # Sanity check
            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
            # Outcome is final, but not known due to a ledger gap
            Wait to acquire continuous ledger history

失敗のケース

2つのトランザクション失敗のケース疑似コードの12の間の違いは、トランザクションが検証されたレジャーに含まれていたかどうかです。いずれのケースにおいても、失敗の処理には十分な注意が必要です。

  • 失敗のケース1では、トランザクションはレジャーに含まれ、XRPトランザクションコストは消却されましたが、それ以外には何も起こりませんでした。この原因としては、流動性の欠如、適切でないパス、またはその他の状況が考えられます。多くの場合、このような失敗の場合には、同様のトランザクションをすぐに試すと同じ結果が出ることが多いです。状況が変わるのを待ってから送信すると、別の結果が得られることがあります。

  • 失敗のケース2では、トランザクションは検証済みレジャーには含まれないため、何も起こらず、トランザクションコストも消却されませんでした。これは、XRP Ledgerの現在の負荷に対してトランザクションコストが低すぎる、LastLedgerSequenceが早すぎる、または不安定なネットワーク接続などの状況が原因である可能性があります。

    • 失敗のケース1と異なり、このケースではLastLedgerSequenceのみを変更(またはFeeも変更)するだけで、新しいトランザクションが成功する可能性があります。元のトランザクションと同じSequence番号を使用します。

    • また、トランザクションが成功しないのはレジャーのステータスが原因である可能性もあります。例えば、トランザクションに署名するために使用されたキーペアが送信アドレスで無効になっている場合などです。トランザクションの暫定的な結果がtef-class codeの場合には、修正をしない限りそのトランザクションが成功する可能性は低くなります。

  • 失敗のケース3は、予期しない状態を表します。トランザクションが未処理の場合、最新の検証済みレジャーにある送信元アカウントのSequence番号を確認する必要があります。([account_infoメソッド][]を使用して確認できます。)最新の検証済みレジャーにあるアカウントのSequence値がトランザクションのSequence値より大きい場合、同じSequence値を持つ別のトランザクションが検証済みレジャーに含まれています。システムがこの別のトランザクションを認識していない場合、予期しない状態となり、その原因が特定されるまで処理を停止しなければならなくなります。そうしないと、システムが同じ目標を達成するために複数のトランザクションを送信する可能性があります。行う必要のある手順は、具体的な原因によって変わります。考えられる原因と手順は次のとおりです。

    • 前回送信したトランザクションに展性があり、実際に検証済みレジャーに含まれていたが、予想と異なるハッシュだった場合。この問題は、tfFullyCanonicalSigフラグが含まれないフラグのセットを指定した場合か、必要以上の署名者によってマルチシグされたトランザクションであった場合に起こる可能性があります。これに該当する場合は、その異なるハッシュとトランザクションの最終結果を保存し、通常のアクティビティーを再開します。

    • トランザクションをキャンセルして置き換えたため、置き換え後のトランザクションが代わりに処理された場合。障害から復旧しようとしている場合、置き換え後のトランザクションでレコードが失われている可能性があります。その場合、当初確認していたトランザクションは恒久的に失敗し、置き換え後のトランザクションの最終結果が検証済みレジャーバージョンに記録されます。両方の最終結果を保存し、他に欠落したトランザクションや置き換えられたトランザクションがないか確認してから、通常のアクティビティーを再開します。

    • アクティブ/パッシブフェイルオーバー構成で、トランザクション送信側のシステムが2台以上あり、パッシブシステムがアクティブシステムで障害が発生したと誤って認識してアクティブになったが、元のアクティブシステムも引き続きトランザクションを送信していた場合。システム間の接続をチェックして、そのうちの1台だけがアクティブであることを確認します。アカウントのトランザクション履歴を確認し[account_txメソッド][]を使用するなど)、検証済みレジャーに含まれていたすべてのトランザクションの最終結果を記録します。Sequence番号が同じ別のトランザクションはすべて完全に失敗しています。それらの最終結果も保存します。すべてのシステムの差異の調整を行い、システムが同時にアクティブになった原因となる問題を解決したら、通常のアクティビティーを再開します。

      ヒント: AccountTxnIDフィールドを使用すると、このような状況で冗長的なトランザクションが成功しないように防ぐことができます。

    • 不正使用者に秘密鍵を使われてトランザクションを送信された場合。その場合は、可能であればキーペアをローテーションして、送信された他のトランザクションを確認します。また、ネットワークを監査して、その秘密鍵が大規模な侵入やセキュリティ侵害に関係していたかどうかを判断する必要があります。キーペアのローテーションに成功して、不正使用者がアカウントやシステムにアクセスできなくなったら、通常のアクティビティーを再開します。

レジャーのギャップ

サーバーに、トランザクションが最初に送信されてから、レジャーがLastLedgerSequenceによって識別された時点までを含む、継続したレジャー履歴がない場合には、トランザクションの最終結果を得られない可能性があります。(サーバーにないレジャーバージョンに結果が含まれている場合、成功したか失敗したかが分かりません。)

rippledサーバーにリソースCPU/RAM/ディスクIOの余裕がある場合には、不足しているレジャーバージョンを自動的に取得します。ただし、取得しようとするレジャーが保管する履歴の設定期間よりも古い場合には取得されません。ギャップのサイズや、サーバーのリソース使用率に基づき、不足しているレジャーバージョンの取得には数分かかります。[ledger_requestメソッド][]を使用して、履歴レジャーバージョンを取得するようにサーバーに要求できます。しかし、そうしても、サーバーに設定された履歴範囲外のレジャーバージョンからのトランザクション結果は検索できない場合があります。

あるいは、s2.ripple.comにあるRippleの完全履歴サーバーなど、必要なレジャー履歴を含む別のrippledサーバーを使用して、トランザクションのステータスを検索することもできます。この目的には、信頼できるサーバーのみを使用してください。不正なサーバーは、トランザクションのステータスや結果について偽の情報を提供するようにプログラムされている可能性があります。

技術的応用

トランザクションの送信および確認のベストプラクティスを実施するには、アプリケーションで以下を実行する必要があります。

  1. 署名するアカウントの次のシーケンス番号を判断します
    • 各トランザクションにはアカウント固有のシーケンス番号があります。これにより、アカウントによって署名されたトランザクションの実行順序が保証され、再送信しても同じトランザクションがレジャーに二重に適用されることがなくなります。
  2. LastLedgerSequenceを決定します
    • トランザクションのLastLedgerSequenceは、最後の検証済みレジャーインデックスから計算されます。
  3. トランザクションを生成して署名します
    • 送信前に、署名されたトランザクションの詳細を保持します。
  4. トランザクションを送信します
    • 初期の結果は暫定的なものであり、変化する可能性があります。
  5. トランザクションの最終結果を判断します
    • 最終結果は、レジャー履歴における不変部分です。

アプリケーションでのこれらのアクションの実行方法は、アプリケーションが使用するAPIによって異なります。アプリケーションでは、以下のインターフェイスを使用できます。

  1. HTTP / WebSocket API
  2. クライアントライブラリ
  3. 任意の数の他のソフトウェアAPI

rippled - トランザクションの送信と確認

アカウントシーケンスの判断

rippledには、最後に検証されたレジャーでのアカウントのシーケンス番号を知るための[account_infoメソッド][]があります。

JSON-RPC要求:

{
  "method": "account_info",
  "params": [
    {
      "account": "rG5Ro9e3uGEZVCh3zu5gB9ydKUskCs221W",
      "ledger_index": "validated"
    }
  ]
}

応答の本文:

{
    "result": {
        "validated": true,
        "status": "success",
        "ledger_index": 10266396,
        "account_data": {
            "index": "96AB97A1BBC37F4F8A22CE28109E0D39D709689BDF412FE8EDAFB57A55E37F38",
            "Sequence": 4,
            "PreviousTxnLgrSeq": 9905632,
            "PreviousTxnID": "CAEE0E34B3DB50A7A0CA486E3A236513531DE9E52EAC47CE4C26332CC847DE26",
            "OwnerCount": 2,
            "LedgerEntryType": "AccountRoot",
            "Flags": 0,
            "Balance": "49975988",
            "Account": "rG5Ro9e3uGEZVCh3zu5gB9ydKUskCs221W"
        }
    }
}

この例では、最後に検証されたレジャーの時点において(要求の"ledger_index": "validated"と、応答の"validated": "true"を参照)、アカウントのシーケンスは4です("account_data""Sequence": 4を参照)。

アプリケーションが、このアカウントで署名された3つのトランザクションを送信する場合には、4、5、6のシーケンス番号を使用します。各トランザクションの検証を待たずに複数のトランザクションを送信するには、アプリケーションで継続的なアカウントシーケンス番号を使用します。

最後に検証されたレジャーの判断

[server_stateメソッド][]は、最後に検証されたレジャーのレジャーインデックスを返します。

要求:

{
  "id": "client id 1",
  "method": "server_state"
}

応答:

{
    "result": {
        "status": "success",
        "state": {
            "validation_quorum": 3,
            "validated_ledger": {
                "seq": 10268596,
                "reserve_inc": 5000000,
                "reserve_base": 20000000,
                "hash": "0E0901DA980251B8A4CCA17AB4CA6C3168FE83FA1D3F781AFC5B9B097FD209EF",
                "close_time": 470798600,
                "base_fee": 10
            },
            "server_state": "full",
            "published_ledger": 10268596,
            "pubkey_node": "n9LGg37Ya2SS9TdJ4XEuictrJmHaicdgTKiPJYi8QRSdvQd3xMnK",
            "peers": 58,
            "load_factor": 256000,
            "load_base": 256,
            "last_close": {
                "proposers": 5,
                "converge_time": 3004
            },
            "io_latency_ms": 2,
            "fetch_pack": 10121,
            "complete_ledgers": "10256331-10256382,10256412-10268596",
            "build_version": "0.26.4-sp3-private"
        }
    }
}

この例では、最後の検証済みレジャーインデックスは10268596応答のresult.state.validated_ledgerの下です。この例では、レジャー履歴にギャップがあることも示されています。ここで使用されたサーバーは、ギャップの間レジャー10256383から10256411に適用されたトランザクションに関する情報を提供することはできません。その部分のレジャー履歴を取得するよう設定されていれば、最終的にサーバーで取得できます。

トランザクションの生成

rippledには、トランザクション送信に備えて準備するための[signメソッド][]があります。このメソッドは信頼できるrippledインスタンスにのみに渡すことができるアカウントの機密情報を必要とします。この例では、10 FOO架空の通貨を別のXRP Ledgerアドレスに発行します。

要求:

{
    "method": "sign",
    "params": [
        {
            "offline": true,
            "secret": "s████████████████████████████",
            "tx_json": {
               "Account": "rG5Ro9e3uGEZVCh3zu5gB9ydKUskCs221W",
                "Sequence": 4,
                "LastLedgerSequence": 10268600,
                "Fee": "10000",
                "Amount": {
                    "currency": "FOO",
                    "issuer": "rG5Ro9e3uGEZVCh3zu5gB9ydKUskCs221W",
                    "value": "10"
                },
                "Destination": "rawz2WQ8i9FdTHp4KSNpBdyxgFqNpKe8fM",
                "TransactionType": "Payment"
            }
        }
    ]
}

アプリケーションは、tefPAST_SEQエラーを防ぐため、account_infoへの以前の呼び出しで判明した"Sequence": 4を使用しています。

また、アプリケーションがserver_stateから取得した最後の検証済みレジャーに基づくLastLedgerSequenceにも注意してください。バックエンドアプリケーションでは、*「最後の検証済みレジャーインデックス + 4」を使用することをお勧めします。または、「現行のレジャー + 3」*の値を使用します。LastLedgerSequenceの計算が誤りで、最後の検証済みレジャーの番号よりも小さい場合には、そのトランザクションはtefMAX_LEDGERエラーで失敗します。

応答:

{
    "result": {
        "tx_json": {
            "hash": "395C313F6F11F70FEBAF3785529A6D6DE3F44C7AF679515A7EAE22B30146DE57",
            "TxnSignature": "304402202646962A21EC0516FCE62DC9280F79E7265778C571E9410D795E67BB72A2D8E402202FF4AF7B2E2160F5BCA93011CB548014626CAC7FCBEBDB81FE8193CEFF69C753",
            "TransactionType": "Payment",
            "SigningPubKey": "0267268EE0DDDEE6A862C9FF9DDAF898CF17060A673AF771B565AA2F4AE24E3FC5",
            "Sequence": 4,
            "LastLedgerSequence": 10268600,
            "Flags": 2147483648,
            "Fee": "10000",
            "Destination": "rawz2WQ8i9FdTHp4KSNpBdyxgFqNpKe8fM",
            "Amount": {
                "value": "10",
                "issuer": "rG5Ro9e3uGEZVCh3zu5gB9ydKUskCs221W",
                "currency": "FOO"
            },
            "Account": "rG5Ro9e3uGEZVCh3zu5gB9ydKUskCs221W"
        },
        "tx_blob": "12000022800000002400000004201B009CAFB861D4C38D7EA4C68000000000000000000000000000464F4F0000000000AC5FA3BB28A09BD2EC1AE0EED2315060E83D796A68400000000000271073210267268EE0DDDEE6A862C9FF9DDAF898CF17060A673AF771B565AA2F4AE24E3FC57446304402202646962A21EC0516FCE62DC9280F79E7265778C571E9410D795E67BB72A2D8E402202FF4AF7B2E2160F5BCA93011CB548014626CAC7FCBEBDB81FE8193CEFF69C7538114AC5FA3BB28A09BD2EC1AE0EED2315060E83D796A831438BC6F9F5A6F6C4E474DB0D59892E90C2C7CED5C",
        "status": "success"
    }
}

トランザクションを送信する前に、アプリケーションでトランザクションのハッシュを保持しておきます。signメソッドの結果のtx_jsonの下にハッシュが含まれます。

トランザクションの送信

rippledには、署名されたトランザクションの送信を可能にする、[submitメソッド][]があります。これは、signメソッドで返されたtx_blobパラメーターを使用します。

要求:

{
    "method": "submit",
    "params": [
        {
        "tx_blob": "12000022800000002400000004201B009CAFB861D4C38D7EA4C68000000000000000000000000000464F4F0000000000AC5FA3BB28A09BD2EC1AE0EED2315060E83D796A68400000000000271073210267268EE0DDDEE6A862C9FF9DDAF898CF17060A673AF771B565AA2F4AE24E3FC57446304402202646962A21EC0516FCE62DC9280F79E7265778C571E9410D795E67BB72A2D8E402202FF4AF7B2E2160F5BCA93011CB548014626CAC7FCBEBDB81FE8193CEFF69C7538114AC5FA3BB28A09BD2EC1AE0EED2315060E83D796A831438BC6F9F5A6F6C4E474DB0D59892E90C2C7CED5C"
        }
    ]
}

応答:

{
    "result": {
        "tx_json": {
            "hash": "395C313F6F11F70FEBAF3785529A6D6DE3F44C7AF679515A7EAE22B30146DE57",
            "TxnSignature": "304402202646962A21EC0516FCE62DC9280F79E7265778C571E9410D795E67BB72A2D8E402202FF4AF7B2E2160F5BCA93011CB548014626CAC7FCBEBDB81FE8193CEFF69C753",
            "TransactionType": "Payment",
            "SigningPubKey": "0267268EE0DDDEE6A862C9FF9DDAF898CF17060A673AF771B565AA2F4AE24E3FC5",
            "Sequence": 4,
            "LastLedgerSequence": 10268600,
            "Flags": 2147483648,
            "Fee": "10000",
            "Destination": "rawz2WQ8i9FdTHp4KSNpBdyxgFqNpKe8fM",
            "Amount": {
                "value": "10",
                "issuer": "rG5Ro9e3uGEZVCh3zu5gB9ydKUskCs221W",
                "currency": "FOO"
            },
            "Account": "rG5Ro9e3uGEZVCh3zu5gB9ydKUskCs221W"
        },
        "tx_blob": "12000022800000002400000004201B009CAFB861D4C38D7EA4C68000000000000000000000000000464F4F0000000000AC5FA3BB28A09BD2EC1AE0EED2315060E83D796A68400000000000271073210267268EE0DDDEE6A862C9FF9DDAF898CF17060A673AF771B565AA2F4AE24E3FC57446304402202646962A21EC0516FCE62DC9280F79E7265778C571E9410D795E67BB72A2D8E402202FF4AF7B2E2160F5BCA93011CB548014626CAC7FCBEBDB81FE8193CEFF69C7538114AC5FA3BB28A09BD2EC1AE0EED2315060E83D796A831438BC6F9F5A6F6C4E474DB0D59892E90C2C7CED5C",
        "status": "success",
        "engine_result_message": "The transaction was applied.",
        "engine_result_code": 0,
        "engine_result": "tesSUCCESS"
    }
}

これは初期結果です。最終結果は検証済みのレジャーのみにあります。"validated": trueフィールドがないことが、これが不変の結果ではないことを示しています。

トランザクションの確認

トランザクションの結果を取得するために、トランザクションが署名された時に生成されるトランザクションハッシュが[txメソッド][]に渡されます。

要求:

{
    "method": "tx",
    "params": [
        {
            "transaction": "395C313F6F11F70FEBAF3785529A6D6DE3F44C7AF679515A7EAE22B30146DE57",
            "binary": false
        }
    ]
}

応答:

{
    "result": {
        "validated": true,
        "status": "success",
        "meta": {
            "TransactionResult": "tesSUCCESS",
            "TransactionIndex": 2,
            "AffectedNodes": [...]
        },
        "ledger_index": 10268599[d],
        "inLedger": 10268599,
        "hash": "395C313F6F11F70FEBAF3785529A6D6DE3F44C7AF679515A7EAE22B30146DE57",
        "date": 470798270,
        "TxnSignature": "304402202646962A21EC0516FCE62DC9280F79E7265778C571E9410D795E67BB72A2D8E402202FF4AF7B2E2160F5BCA93011CB548014626CAC7FCBEBDB81FE8193CEFF69C753",
        "TransactionType": "Payment",
        "SigningPubKey": "0267268EE0DDDEE6A862C9FF9DDAF898CF17060A673AF771B565AA2F4AE24E3FC5",
        "Sequence": 4,
        "LastLedgerSequence": 10268600,
        "Flags": 2147483648,
        "Fee": "10000",
        "Destination": "rawz2WQ8i9FdTHp4KSNpBdyxgFqNpKe8fM",
        "Amount": {
            "value": "10",
            "issuer": "rG5Ro9e3uGEZVCh3zu5gB9ydKUskCs221W",
            "currency": "FOO"
        },
        "Account": "rG5Ro9e3uGEZVCh3zu5gB9ydKUskCs221W"
    }
}

この応答例には、"validated": trueがあります。これは、トランザクションが検証済みレジャーに含まれていること、つまりトランザクション結果が不変であることを示しています。さらに、メタデータには、トランザクションがレジャーに適用されたことを示す"TransactionResult": "tesSUCCESS"が含まれています。

応答に"validated": trueが含まれていない場合には、結果は暫定的であり変化する可能性があります。最終結果を取得するには、アプリケーションでtxメソッドを再度呼び出し、ネットワークでさらに多くのレジャーバージョンを検証できるよう十分な時間をかけます。LastLedgerSequenceで指定されたレジャーが検証されるまで待たなければならない場合もありますが、そのトランザクションが以前の検証済みレジャーに含まれている場合には、その結果はその時点で不変です。

不明のトランザクションの確認

[txメソッド][]への呼び出しにtxnNotFoundエラーが返された場合には、アプリケーションで対処する必要があります。

{
    "result": {
        "status": "error",
        "request": {
            "transaction": "395C313F6F11F70FEBAF3785529A6D6DE3F44C7AF679515A7EAE22B30146DE56",
            "command": "tx",
            "binary": false
        },
        "error_message": "Transaction not found.",
        "error_code": 24,
        "error": "txnNotFound"
    }
}

txnNotFound結果コードは、トランザクションがどのレジャーにも含まれていない場合に発生します。ただし、rippledインスタンスに完全なレジャー履歴がない場合や、そのトランザクションがrippledインスタンスにまだ伝達されていない場合にも発生します。これにどのように対処すべきかを判断するため、アプリケーションはさらに照会を行う必要があります。

[server_stateメソッド][](最後の検証済みレジャーを判断するために先に使用する)は、result.state.complete_ledgersのもとにレジャー履歴が完全かどうかを示します。

{
    "result": {
        "status": "success",
        "state": {
            "validation_quorum": 3,
            "validated_ledger": {
                "seq": 10269447,
                "reserve_inc": 5000000,
                "reserve_base": 20000000,
                "hash": "D05C7ECC66DD6F4FEA3A6394F209EB5D6824A76C16438F562A1749CCCE7EAFC2",
                "close_time": 470802340,
                "base_fee": 10
            },
            "server_state": "full",
            "pubkey_node": "n9LJ5eCNjeUXQpNXHCcLv9PQ8LMFYy4W8R1BdVNcpjc1oDwe6XZF",
            "peers": 84,
            "load_factor": 256000,
            "load_base": 256,
            "last_close": {
                "proposers": 5,
                "converge_time": 2002
            },
            "io_latency_ms": 1,
            "complete_ledgers": "10256331-10256382,10256412-10269447",
            "build_version": "0.26.4-sp3-private"
        }
    }
}

このトランザクションの例では、その時点の最後の検証済みレジャーに基づいてLastLedgerSequence 10268600を指定し、4を足します。不明のトランザクションが完全に失敗したかどうかを判断するには、rippledサーバーに、10268597から10268600のレジャーが必要です。サーバーの履歴にそれらの検証済みレジャーが存在し、かつtxtxnNotFoundが返される場合には、そのトランザクションは失敗であり、今後のレジャーに含めることはできません。この場合、アプリケーションのロジックで、同じアカウントシーケンスと更新されたLastLedgerSequenceを使用して代わりのトランザクションを作成して送信することが可能です。

サーバーは、指定されたLastLedgerSequenceよりも小さい値の最後の検証済みレジャーインデックスをレポートする場合があります。その場合、txnNotFoundに、a送信されたトランザクションがまだネットワークに配布されていないこと、またはbトランザクションがネットワークに配布されたものの、まだ処理されていないことを示します。最初のケースに対処するために、アプリケーションは再度同じ署名済みのトランザクションを送信できます。トランザクションには固有のアカウントシーケンス番号がつけられているため、処理されるのは一度のみです。

最後に、サーバーにトランザクション履歴のギャップが1つ以上存在する場合があります。上記の応答に示されるcompleted_ledgersフィールドは、このrippledインスタンスの10256383から10256411のレジャーが不足していることを示しています。このトランザクションの例では、トランザクションの送信時点とLastLedgerSequenceに基づいてトランザクションは10268597から10268600のレジャーのみに含まれるため、このギャップはここでは関係ありません。ただし、必要範囲のレジャーが不足している場合には、txnNotFoundの結果が不変の結果であるかどうかを判断するために、アプリケーションは別のrippledサーバーに照会するまたはこのサーバーによって不足しているレジャーが取得されるまで待つ必要があります。

その他のリソース

{% include '_snippets/rippled-api-links.md' %} {% include '_snippets/tx-type-links.md' %} {% include '_snippets/rippled_versions.md' %}