Checkの変動金額での換金

Checks Amendmentが必要です。

Checkがレジャーに記録されており有効期限切れではない場合は、指定受取人はDeliverMinフィールドを指定したCheckCashトランザクションを送信することで、Checkを変動金額で換金して受領できます。この方法でCheckを換金すると、受取人は送金を最大限受領でき、Checkの送金元からは、CheckのSendMaxの全額が引き落とされるか、または可能な限りの額が引き落とされます。Checkの受取人にDeliverMin以上の額を送金できない場合は換金が失敗します。

Checkから可能な限りの額を受領したい場合には、変動金額でCheckを換金できます。

指定受取人は、Checkを正確な金額で換金することもできます。

前提条件

Checkを換金するための前提条件は、正確な金額を換金する場合も変動金額を換金する場合も同じです。

  • 現在レジャーに記録されているCheckオブジェクトのIDが必要です。
  • 例えば、以下の例では、あるCheckのIDとして838766BA2B995C00744175F69A1B11E32C3DBC40E64801A4056FCBD657F57334を使用していますが、各ステップをご自分で行う際には、異なるIDを使用する必要があります。
  • Checkに記載されている受取人のアドレス秘密鍵。このアドレスは、CheckオブジェクトのDestinationアドレスと一致している必要があります。
  • 発行済み通貨用のCheckの場合は、ご自身(受取人)にイシュアーに対するトラストラインがある必要があります。このトラストライン上のご自身の限度額は、受け取る金額を追加するための残高より十分高くなければなりません。
  • トラストラインと限度額について詳しくは、発行済み通貨およびトラストラインと発行を参照してください。
  • トランザクションに安全に署名できる手段(RippleAPIや各自のrippledサーバーなど)。
  • rippledサーバーに接続できるクライアントライブラリ(RippleAPI、HTTPライブラリ、WebSocketライブラリなど)。
  • 詳細は、rippled APIの使用開始を参照してください。

1.CheckCashトランザクションの準備

CheckCashトランザクションのフィールドの値を決定します。Checkを変動金額で換金する場合、以下のフィールドは必要最小限です。それ以外のフィールドはオプションまたは署名時に自動入力可能なフィールドです。

フィールド 説明
TransactionType 文字列 値がCheckCashの場合、これはCheckCashトランザクションです。
Account 文字列(アドレス) Checkを換金する送信者のアドレス。(あなたのアドレスです。)
CheckID 文字列 レジャーで換金するCheckオブジェクトのID。この情報を確認するには、txメソッドを使用してCheckCreateトランザクションのメタデータを調べるか、またはaccount_objectsメソッドを使用してCheckを探します。
DeliverMin 文字列またはオブジェクト(額) Checkから受領する最小額。この額を受領できない場合はCheckの換金が失敗し、Checkがレジャーに残るので、後で換金を再試行できます。XRPの場合、XRPのdrop数を示す文字列でなければなりません。発行済み通貨の場合、これはcurrencyissuer、およびvalue フィールドを持つオブジェクトです。currencyフィールドとissuerフィールドは、Checkオブジェクトの対応するフィールドに一致しており、valueはCheckオブジェクトの額以下でなければなりません。詳細は、通貨額の指定を参照してください。

変動金額で換金するCheckCashトランザクションの準備の例

Checkを変動金額で換金するためのトランザクションを準備する手順を以下の例に示します。

{
 "Account": "rGPnRH1EBpHeTF2QG8DCAgM7z5pb75LAis",
 "TransactionType": "CheckCash",
 "DeliverMin": "95000000",
 "CheckID": "2E0AD0740B79BE0AAE5EDD1D5FC79E3C5C221D23C6A7F771D85569B5B91195C2"
}
'use strict'
const RippleAPI = require('ripple-lib').RippleAPI

// This example connects to a public Test Net server
const api = new RippleAPI({server: 'wss://s.altnet.rippletest.net:51233'})
api.connect().then(() => {
  console.log('Connected')

  const sender = 'rGPnRH1EBpHeTF2QG8DCAgM7z5pb75LAis'
  const options = {
    // Allow up to 60 ledger versions (~5 min) instead of the default 3 versions
    // before this transaction fails permanently.
    "maxLedgerVersionOffset": 60
  }
  return api.prepareCheckCash(sender, {
    "checkID": "C0B27D20669BAB837B3CDF4B8148B988F17CE1EF8EDF48C806AE9BF69E16F441",
    "deliverMin": {
      "currency": "XRP",
      "value": "95" // Cash for at least 95 XRP
    }
  }, options)

}).then(prepared => {
  console.log("txJSON:", prepared.txJSON);

// Disconnect and return
}).then(() => {
  api.disconnect().then(() => {
    console.log('Disconnected')
    process.exit()
  })
}).catch(console.error)


// Example output:
//
// Connected
// txJSON: {"Account":"rGPnRH1EBpHeTF2QG8DCAgM7z5pb75LAis",
//   "TransactionType":"CheckCash",
//   "CheckID":"C0B27D20669BAB837B3CDF4B8148B988F17CE1EF8EDF48C806AE9BF69E16F441",
//   "DeliverMin":"95000000",
//   "Flags":2147483648,
//   "LastLedgerSequence":8006858,
//   "Fee":"12",
//   "Sequence":5}
// Disconnected

2.CheckCashトランザクションの署名

The most secure way to sign a transaction is to do it locally with a signing library, such as RippleAPI. Alternatively, you can sign the transaction using the sign method, but this must be done through a trusted and encrypted connection, or through a local connection, and only to a server you control.

In all cases, note the signed transaction's identifying hash for later.

要求の例

rippled sign s████████████████████████████ '{
  "Account": "rGPnRH1EBpHeTF2QG8DCAgM7z5pb75LAis",
  "TransactionType": "CheckCash",
  "DeliverMin": "95000000",
  "CheckID": "84C61BE9B39B2C4A2267F67504404F1EC76678806C1B901EA781D1E3B4CE0CD9"
}'

応答の例

Loading: "/etc/opt/ripple/rippled.cfg"
2018-Apr-03 00:09:53 HTTPClient:NFO Connecting to 127.0.0.1:5005

{
   "result" : {
      "status" : "success",
      "tx_blob" : "12001122800000002400000004501884C61BE9B39B2C4A2267F67504404F1EC76678806C1B901EA781D1E3B4CE0CD968400000000000000A6A4000000005A995C073210361ACFCB478BCAE01451F95060AF94F70365BF00D7B4661EC2C69EA383762516C7446304402203D7EC220D48AA040D6915C160275D202F7F808E2B58F11B1AB05FB5E5CFCC6C00220304BBD3AD32E13150E0ED7247F2ADFAE83D0ECE329E20CFE0F8DF352934DD2FC8114A8B6B9FF3246856CADC4A0106198C066EA1F9C39",
      "tx_json" : {
         "Account" : "rGPnRH1EBpHeTF2QG8DCAgM7z5pb75LAis",
         "CheckID" : "84C61BE9B39B2C4A2267F67504404F1EC76678806C1B901EA781D1E3B4CE0CD9",
         "DeliverMin" : "95000000",
         "Fee" : "10",
         "Flags" : 2147483648,
         "Sequence" : 4,
         "SigningPubKey" : "0361ACFCB478BCAE01451F95060AF94F70365BF00D7B4661EC2C69EA383762516C",
         "TransactionType" : "CheckCash",
         "TxnSignature" : "304402203D7EC220D48AA040D6915C160275D202F7F808E2B58F11B1AB05FB5E5CFCC6C00220304BBD3AD32E13150E0ED7247F2ADFAE83D0ECE329E20CFE0F8DF352934DD2FC",
         "hash" : "A0AFE572E4736CBF49FF4D0D3FF8FDB0C4D31BD10CB4EB542230F85F0F2DD222"
      }
   }
}

3.署名済みCheckCashトランザクションの送信

Take the signed transaction blob from the previous step and submit it to a rippled server. You can do this safely even if you do not run the rippled server. The response contains a provisional result, which should be tesSUCCESS, but this result is usually not final. A provisional response of terQUEUED is also OK, since queued transactions are generally included in the next open ledger version (usually about 10 seconds after submission).

Tip: If the preliminary result is tefMAX_LEDGER, the transaction has failed permanently because its LastLedgerSequence parameter is lower than the current ledger. This happens when you take longer than the expected number of ledger versions between preparing and submitting the transaction. If this occurs, start over from step 1 with a higher LastLedgerSequence value.

要求の例

rippled submit 12001122800000002400000004501884C61BE9B39B2C4A2267F67504404F1EC76678806C1B901EA781D1E3B4CE0CD968400000000000000A6A4000000005A995C073210361ACFCB478BCAE01451F95060AF94F70365BF00D7B4661EC2C69EA383762516C7446304402203D7EC220D48AA040D6915C160275D202F7F808E2B58F11B1AB05FB5E5CFCC6C00220304BBD3AD32E13150E0ED7247F2ADFAE83D0ECE329E20CFE0F8DF352934DD2FC8114A8B6B9FF3246856CADC4A0106198C066EA1F9C39

応答の例

Loading: "/etc/opt/ripple/rippled.cfg"
2018-Apr-03 00:10:30 HTTPClient:NFO Connecting to 127.0.0.1:5005

{
   "result" : {
      "engine_result" : "tesSUCCESS",
      "engine_result_code" : 0,
      "engine_result_message" : "The transaction was applied. Only final in a validated ledger.",
      "status" : "success",
      "tx_blob" : "12001122800000002400000004501884C61BE9B39B2C4A2267F67504404F1EC76678806C1B901EA781D1E3B4CE0CD968400000000000000A6A4000000005A995C073210361ACFCB478BCAE01451F95060AF94F70365BF00D7B4661EC2C69EA383762516C7446304402203D7EC220D48AA040D6915C160275D202F7F808E2B58F11B1AB05FB5E5CFCC6C00220304BBD3AD32E13150E0ED7247F2ADFAE83D0ECE329E20CFE0F8DF352934DD2FC8114A8B6B9FF3246856CADC4A0106198C066EA1F9C39",
      "tx_json" : {
         "Account" : "rGPnRH1EBpHeTF2QG8DCAgM7z5pb75LAis",
         "CheckID" : "84C61BE9B39B2C4A2267F67504404F1EC76678806C1B901EA781D1E3B4CE0CD9",
         "DeliverMin" : "95000000",
         "Fee" : "10",
         "Flags" : 2147483648,
         "Sequence" : 4,
         "SigningPubKey" : "0361ACFCB478BCAE01451F95060AF94F70365BF00D7B4661EC2C69EA383762516C",
         "TransactionType" : "CheckCash",
         "TxnSignature" : "304402203D7EC220D48AA040D6915C160275D202F7F808E2B58F11B1AB05FB5E5CFCC6C00220304BBD3AD32E13150E0ED7247F2ADFAE83D0ECE329E20CFE0F8DF352934DD2FC",
         "hash" : "A0AFE572E4736CBF49FF4D0D3FF8FDB0C4D31BD10CB4EB542230F85F0F2DD222"
      }
   }
}

4.検証の待機

本番環境のネットワークやTestnetでは、レジャーが自動的に閉鎖するまでに4~7秒かかる場合があります。

スタンドアロンモードでrippledを実行している場合は、ledger_acceptメソッドを使用してレジャーを手動で閉鎖します。

5.最終結果の確認

トランザクションのステータスを確認するには、CheckCashトランザクションの識別用ハッシュを指定したtxメソッドを使用します。トランザクションが成功したことを示す"TransactionResult": "tesSUCCESS"フィールドをトランザクションメタデータから検索し、またこの結果が最終結果であることを示す"validated": trueフィールドを結果から検索します。

要求の例

rippled tx A0AFE572E4736CBF49FF4D0D3FF8FDB0C4D31BD10CB4EB542230F85F0F2DD222

応答の例

Loading: "/etc/opt/ripple/rippled.cfg"
2018-Apr-03 00:11:17 HTTPClient:NFO Connecting to 127.0.0.1:5005

{
   "result" : {
      "Account" : "rGPnRH1EBpHeTF2QG8DCAgM7z5pb75LAis",
      "CheckID" : "84C61BE9B39B2C4A2267F67504404F1EC76678806C1B901EA781D1E3B4CE0CD9",
      "DeliverMin" : "95000000",
      "Fee" : "10",
      "Flags" : 2147483648,
      "Sequence" : 4,
      "SigningPubKey" : "0361ACFCB478BCAE01451F95060AF94F70365BF00D7B4661EC2C69EA383762516C",
      "TransactionType" : "CheckCash",
      "TxnSignature" : "304402203D7EC220D48AA040D6915C160275D202F7F808E2B58F11B1AB05FB5E5CFCC6C00220304BBD3AD32E13150E0ED7247F2ADFAE83D0ECE329E20CFE0F8DF352934DD2FC",
      "date" : 576029432,
      "hash" : "A0AFE572E4736CBF49FF4D0D3FF8FDB0C4D31BD10CB4EB542230F85F0F2DD222",
      "inLedger" : 8005386,
      "ledger_index" : 8005386,
      "meta" : {
         "AffectedNodes" : [
            {
               "ModifiedNode" : {
                  "FinalFields" : {
                     "Flags" : 0,
                     "Owner" : "rBXsgNkPcDN2runsvWmwxk3Lh97zdgo9za",
                     "RootIndex" : "3F248A0715ECCAFC3BEE0C63C8F429ACE54ABC403AAF5F2885C2B65D62D1FAC1"
                  },
                  "LedgerEntryType" : "DirectoryNode",
                  "LedgerIndex" : "3F248A0715ECCAFC3BEE0C63C8F429ACE54ABC403AAF5F2885C2B65D62D1FAC1"
               }
            },
            {
               "ModifiedNode" : {
                  "FinalFields" : {
                     "Account" : "rGPnRH1EBpHeTF2QG8DCAgM7z5pb75LAis",
                     "Balance" : "10099999960",
                     "Flags" : 0,
                     "OwnerCount" : 2,
                     "Sequence" : 5
                  },
                  "LedgerEntryType" : "AccountRoot",
                  "LedgerIndex" : "7939126A732EBBDEC715FD3CCB056EB31E65228CA17E3B2901E7D30B90FD03D3",
                  "PreviousFields" : {
                     "Balance" : "9999999970",
                     "Sequence" : 4
                  },
                  "PreviousTxnID" : "0283465F0D21BE6B1E91ABDE17266C24C1B4915BAAA9A88CC098A98D5ECD3E9E",
                  "PreviousTxnLgrSeq" : 8005334
               }
            },
            {
               "DeletedNode" : {
                  "FinalFields" : {
                     "Account" : "rBXsgNkPcDN2runsvWmwxk3Lh97zdgo9za",
                     "Destination" : "rGPnRH1EBpHeTF2QG8DCAgM7z5pb75LAis",
                     "DestinationNode" : "0000000000000000",
                     "DestinationTag" : 1,
                     "Flags" : 0,
                     "InvoiceID" : "46060241FABCF692D4D934BA2A6C4427CD4279083E38C77CBE642243E43BE291",
                     "OwnerNode" : "0000000000000000",
                     "PreviousTxnID" : "09D992D4C89E2A24D4BA9BB57ED81C7003815940F39B7C87ADBF2E49034380BB",
                     "PreviousTxnLgrSeq" : 7841263,
                     "SendMax" : "100000000",
                     "Sequence" : 4
                  },
                  "LedgerEntryType" : "Check",
                  "LedgerIndex" : "84C61BE9B39B2C4A2267F67504404F1EC76678806C1B901EA781D1E3B4CE0CD9"
               }
            },
            {
               "ModifiedNode" : {
                  "FinalFields" : {
                     "Account" : "rBXsgNkPcDN2runsvWmwxk3Lh97zdgo9za",
                     "Balance" : "9899999920",
                     "Flags" : 0,
                     "OwnerCount" : 2,
                     "Sequence" : 8
                  },
                  "LedgerEntryType" : "AccountRoot",
                  "LedgerIndex" : "A9A591BA661F69433D5BEAA49F10BA2B8DEA5183EF414B9130BFE5E0328FE875",
                  "PreviousFields" : {
                     "Balance" : "9999999920",
                     "OwnerCount" : 3
                  },
                  "PreviousTxnID" : "54A7A917BE9AC13962251BCF1D09803C7BBE75882B8BFC987B5933A566A48215",
                  "PreviousTxnLgrSeq" : 8004870
               }
            },
            {
               "ModifiedNode" : {
                  "FinalFields" : {
                     "Flags" : 0,
                     "Owner" : "rGPnRH1EBpHeTF2QG8DCAgM7z5pb75LAis",
                     "RootIndex" : "C6A30AD85346718C7148D161663F84A96A4F0CE7F4D68C3C74D176A6C50BA6B9"
                  },
                  "LedgerEntryType" : "DirectoryNode",
                  "LedgerIndex" : "C6A30AD85346718C7148D161663F84A96A4F0CE7F4D68C3C74D176A6C50BA6B9"
               }
            }
         ],
         "TransactionIndex" : 4,
         "TransactionResult" : "tesSUCCESS"
      },
      "status" : "success",
      "validated" : true
   }
}

エラー処理

Checkの換金がtecクラスコードで失敗した場合は、すべてのトランザクション応答のリストでコードを確認し、適切に対処してください。CheckCashトランザクションでよく返される結果コードの一部を次に示します。

結果コード 意味 対処
tecEXPIRED Checkが有効期限切れです。 Checkを取り消して、以前より長い有効期限を設定して新しいCheckを作成するように送金元に依頼します。
tecNO_ENTRY Check IDが存在していません。 CheckCashトランザクションのCheckIDが正しいことを確認してください。Checkがまだ取り消されていないこと、または正常に換金されていないことを確認してください。
tecNO_LINE 受取人がCheckの通貨のトラストラインを所有していません。 このイシュアーからのこの通貨を保有するには、指定された通貨とイシュアーのトラストラインを作成し、TrustSetトランザクションを使用してこのトラストラインに適切な限度額を設定してから、Checkの換金を再試行します。
tecNO_PERMISSION CheckCashトランザクションの送信者はCheckのDestinationではありません。 CheckのDestinationを再度確認します。
tecNO_AUTH このCheckの通貨のイシュアーはAuthorized Trust Lineを使用していますが、受取人からイシュアーへのトラストラインが承認されていません。 このトラストラインを承認するようイシュアーに依頼し、承認されたらCheckの換金を再試行します。
tecPATH_PARTIAL トラストラインの限度額、または送金元に送金通貨の残高(イシュアーの送金手数料がある場合はこの手数料を含む)が十分になかったことが原因で、Checkでは十分な発行済み通貨を送金できませんでした。 原因がトラストラインの限度額である場合は、(希望する場合には)限度額を引き上げるTrustSetトランザクションを送信するか、または通貨の一部を消費して残高を減らしてから、Checkの換金を再試行します。原因が送金元の残高である場合は、送金元にCheckの通貨が積み増しされるまで待つか、または以前よりも低い額でCheckの換金を再試行します。
tecUNFUNDED_PAYMENT Checkで十分なXRPを送金できませんでした。 送金元にXRPが積み増しされるまで待つか、または以前よりも低い額でCheckの換金を再試行します。

6.送金された額の確認

Checkが変動するDeliverMinの額で換金された場合は、Checkは少なくともDeliverMinの額で換金されたと想定できます。送金された額を正確に得るには、トランザクションメタデータを調べます。メタデータのAffectedNodes配列には、通貨のタイプに応じて、Checkの換金による残高の変更を反映した1~2つのオブジェクトが含まれています。

  • XRPの場合、Checkの送金元のAccountRootオブジェクトのXRP Balance フィールドから引き落しが行われます。Checkの受取人(CheckCashトランザクションを送信したユーザー)のAccountRootオブジェクトでは、最低でもCheckCashトランザクションのDeliverMinから、トランザクションの送信にかかるトランザクションコストを差し引いた額が、XRP Balanceに入金されます。

    たとえば以下のModifiedNodeは、アカウントrGPnRH1EBpHeTF2QG8DCAgM7z5pb75LAis(Checkの受取人でありこのCheckCashトランザクションの送信者)のXRP残高が9999999970 dropから10099999960 dropに変更されています。つまり、このトランザクションを処理した結果として、受取人に対し 正味 99.99999 XRPが入金されています。

      {
        "ModifiedNode": {
          "FinalFields": {
             "Account": "rGPnRH1EBpHeTF2QG8DCAgM7z5pb75LAis",
             "Balance": "10099999960",
             "Flags": 0,
             "OwnerCount": 2,
             "Sequence": 5
          },
          "LedgerEntryType": "AccountRoot",
          "LedgerIndex": "7939126A732EBBDEC715FD3CCB056EB31E65228CA17E3B2901E7D30B90FD03D3",
          "PreviousFields": {
             "Balance": "9999999970",
             "Sequence": 4
          },
          "PreviousTxnID": "0283465F0D21BE6B1E91ABDE17266C24C1B4915BAAA9A88CC098A98D5ECD3E9E",
          "PreviousTxnLgrSeq": 8005334
        }
      }
    

    正味金額99.99999 XRPは、このCheckCashトランザクションを送信するにあたり、トランザクションコストを支払うために消却された額を差し引いた後の金額です。以下のトランザクション指示(抜粋)は、トランザクションコスト(Feeフィールド)がXRPの10 dropであることを示しています。これを正味残高の変更に追加することで、このCheckの換金のために受取人rGPnRH1EBpHeTF2QG8DCAgM7z5pb75LAisに 総額 100 XRPが入金されます。

    "Account" : "rGPnRH1EBpHeTF2QG8DCAgM7z5pb75LAis",
    "TransactionType" : "CheckCash",
    "DeliverMin" : "95000000",
    "Fee" : "10",
    
  • Checkの送金元または受取人がイシュアーである発行済み通貨の場合、これらのアカウント間のトラストラインを表すRippleStateオブジェクトでは、BalanceがCheckの受取人に有利な方法で調整されています。

  • イシュアーが第三者である発行済み通貨の場合、2つのRippleState(送金元からイシュアーへのトラストラインとイシュアーから受取人へのトラストライン)に対する変更があります。Checkの送金元とイシュアーの関係を表すRippleStateオブジェクトではそのBalanceがイシュアーに有利に変更され、イシュアーと受取人の間の関係を表すRippleStateオブジェクトではそのBalanceが受取人に有利に変更されます。

    • 発行済み通貨に送金手数料がある場合、受取人への入金額を上回る額がCheckの送金元から引き落とされます。(この差額が送金手数料であり、これがイシュアーに戻されることによりイシュアーの正味の債務は減少します。)