Checkの取消し
Checks Amendmentが必要です。
このチュートリアルでは、Checkを取り消す手順を説明します。この手順を実行すると、送金を行わずにレジャーのCheckオブジェクトが削除されます。
着信したCheckが不要な場合、取り消すことができます。送信時に内容を誤って入力した場合や状況が変化した場合に、送信したCheckを取り消すこともできます。有効期限切れのCheckはレジャーから削除する必要があります。これにより、送金元に所有者準備金が戻ります。
前提条件
このチュートリアルでCheckを取り消すには、以下が必要です。
- 現在レジャーに記録されているCheckオブジェクトのIDが必要です。
- たとえばこのチュートリアルの例では、IDが
49647F0D748DC3FE26BDACBC57F251AADEFFF391403EC9BF87C97F67E9977FB0
のCheckを取り消しますが、この手順を自身で実行する場合は異なるIDを使用する必要があります。
- たとえばこのチュートリアルの例では、IDが
- CheckCancelトランザクションを送信する資金供給のあるアカウントのアドレスとシークレットキー。Checkが有効期限切れでない限り、このアドレスは、Checkの送金元または受取人のいずれかでなければなりません。
- トランザクションに安全に署名できる手段(RippleAPIや各自の
rippled
サーバーなど)。 rippled
サーバーに接続できるクライアントライブラリ(RippleAPI、HTTPライブラリ、またはWebSocketライブラリなど)。- 詳細は、
rippled
APIの使用開始を参照してください。
- 詳細は、
1.CheckCancelトランザクションの準備
CheckCancelトランザクションのフィールドの値を決定します。以下のフィールドは必要最小限のフィールドです。その他のフィールドはオプションまたは署名時に自動入力可能なフィールドです。
フィールド | 値 | 説明 |
---|---|---|
TransactionType |
文字列 | Checkを取り消す場合は文字列CheckCancel を使用します。 |
Account |
文字列(アドレス) | Checkを取り消す送信元のアドレス。(あなたのアドレスです。) |
CheckID |
文字列 | レジャーで取り消すCheckオブジェクトのID。この情報を確認するには、txメソッドを使用してCheckCreateトランザクションのメタデータを調べるか、またはaccount_objectsメソッドを使用してCheckを探します。 |
RippleAPIを使用している場合は、prepareCheckCancel()
ヘルパーメソッドを使用できます。
注記: CheckはRippleAPIバージョン0.19.0以降でサポートされています。
CheckCancelトランザクションの準備の例
Checkを取り消す例を以下に示します。
{
"TransactionType": "CheckCancel",
"Account": "rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo",
"CheckID": "49647F0D748DC3FE26BDACBC57F251AADEFFF391403EC9BF87C97F67E9977FB0",
"Fee": "12"
}
'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 = 'rBXsgNkPcDN2runsvWmwxk3Lh97zdgo9za'
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.prepareCheckCancel(sender, {
"checkID": "2E0AD0740B79BE0AAE5EDD1D5FC79E3C5C221D23C6A7F771D85569B5B91195C2"
}, 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":"rBXsgNkPcDN2runsvWmwxk3Lh97zdgo9za",
// "TransactionType":"CheckCancel",
// "CheckID":"2E0AD0740B79BE0AAE5EDD1D5FC79E3C5C221D23C6A7F771D85569B5B91195C2",
// "Flags":2147483648,
// "LastLedgerSequence":8004884,
// "Fee":"12",
// "Sequence":7}
// Disconnected
2.CheckCancelトランザクションの署名
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.
要求の例
'use strict'
const RippleAPI = require('ripple-lib').RippleAPI
// Can sign offline if the txJSON has all required fields
const api = new RippleAPI()
const txJSON = '{"Account":"rBXsgNkPcDN2runsvWmwxk3Lh97zdgo9za","TransactionType":"CheckCancel","CheckID":"2E0AD0740B79BE0AAE5EDD1D5FC79E3C5C221D23C6A7F771D85569B5B91195C2","Flags":2147483648,"LastLedgerSequence":8004884,"Fee":"12","Sequence":7}'
// Be careful where you store your real secret.
const secret = 's████████████████████████████'
const signed = api.sign(txJSON, secret)
console.log("tx_blob is:", signed.signedTransaction)
console.log("tx hash is:", signed.id)
rippled sign s████████████████████████████ '{
"TransactionType": "CheckCancel",
"Account": "rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo",
"CheckID": "49647F0D748DC3FE26BDACBC57F251AADEFFF391403EC9BF87C97F67E9977FB0",
"Fee": "12"
}'
応答の例
tx_blob is: 12001222800000002400000007201B007A251450182E0AD0740B79BE0AAE5EDD1D5FC79E3C5C221D23C6A7F771D85569B5B91195C268400000000000000C732103B6FCD7FAC4F665FE92415DD6E8450AD90F7D6B3D45A6CFCF2E359045FF4BB4007446304402205D77451B0D7BCDA1FE5B98763C5B3B2837453371FE93C2B86157C44B1867AE36022003800273848BC2F8E1C6EC7EE4B0CB2425A888AE80E586886C306C796B25678B8114735FF88E5269C80CD7F7AF10530DAB840BBF6FDF
tx hash is: 54A7A917BE9AC13962251BCF1D09803C7BBE75882B8BFC987B5933A566A48215
Loading: "/etc/opt/ripple/rippled.cfg"
2018-Jan-24 01:11:07 HTTPClient:NFO Connecting to 127.0.0.1:5005
{
"result" : {
"status" : "success",
"tx_blob" : "12001222800000002400000003501849647F0D748DC3FE26BDACBC57F251AADEFFF391403EC9BF87C97F67E9977FB068400000000000000C7321022C53CD19049F32F31848DD3B3BE5CEF6A2DD1EFDA7971AB3FA49B1BAF12AEF78744630440220615F9D19FA182F08530CD978A4C216C8676D0BA9EDB53A620AC909AA0EF0FE7E02203A09CC34C3DB85CCCB3137E78081F8F2B441FB0A3B9E40901F312D3CBA0A67A181147990EC5D1D8DF69E070A968D4B186986FDF06ED0",
"tx_json" : {
"Account" : "rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo",
"CheckID" : "49647F0D748DC3FE26BDACBC57F251AADEFFF391403EC9BF87C97F67E9977FB0",
"Fee" : "12",
"Flags" : 2147483648,
"Sequence" : 3,
"SigningPubKey" : "022C53CD19049F32F31848DD3B3BE5CEF6A2DD1EFDA7971AB3FA49B1BAF12AEF78",
"TransactionType" : "CheckCancel",
"TxnSignature" : "30440220615F9D19FA182F08530CD978A4C216C8676D0BA9EDB53A620AC909AA0EF0FE7E02203A09CC34C3DB85CCCB3137E78081F8F2B441FB0A3B9E40901F312D3CBA0A67A1",
"hash" : "414558223CA8595916BB1FEF238B3BB601B7C0E52659292251CE613E6B4370F9"
}
}
}
3.署名済みCheckCancelトランザクションの送信
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.
要求の例
'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 tx_blob = "12001222800000002400000007201B007A251450182E0AD0740B79BE0AAE5EDD1D5FC79E3C5C221D23C6A7F771D85569B5B91195C268400000000000000C732103B6FCD7FAC4F665FE92415DD6E8450AD90F7D6B3D45A6CFCF2E359045FF4BB4007446304402205D77451B0D7BCDA1FE5B98763C5B3B2837453371FE93C2B86157C44B1867AE36022003800273848BC2F8E1C6EC7EE4B0CB2425A888AE80E586886C306C796B25678B8114735FF88E5269C80CD7F7AF10530DAB840BBF6FDF"
return api.submit(tx_blob)
}).then(response => {
console.log("Preliminary transaction result:", response.resultCode)
// Disconnect and return
}).then(() => {
api.disconnect().then(() => {
console.log('Disconnected')
process.exit()
})
}).catch(console.error)
rippled submit 12001222800000002400000003501849647F0D748DC3FE26BDACBC57F251AADEFFF391403EC9BF87C97F67E9977FB068400000000000000C7321022C53CD19049F32F31848DD3B3BE5CEF6A2DD1EFDA7971AB3FA49B1BAF12AEF78744630440220615F9D19FA182F08530CD978A4C216C8676D0BA9EDB53A620AC909AA0EF0FE7E02203A09CC34C3DB85CCCB3137E78081F8F2B441FB0A3B9E40901F312D3CBA0A67A181147990EC5D1D8DF69E070A968D4B186986FDF06ED0
応答の例
Connected
Preliminary transaction result: tesSUCCESS
Disconnected
Loading: "/etc/opt/ripple/rippled.cfg"
2018-Jan-24 01:11:07 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" : "12001222800000002400000003501849647F0D748DC3FE26BDACBC57F251AADEFFF391403EC9BF87C97F67E9977FB068400000000000000C7321022C53CD19049F32F31848DD3B3BE5CEF6A2DD1EFDA7971AB3FA49B1BAF12AEF78744630440220615F9D19FA182F08530CD978A4C216C8676D0BA9EDB53A620AC909AA0EF0FE7E02203A09CC34C3DB85CCCB3137E78081F8F2B441FB0A3B9E40901F312D3CBA0A67A181147990EC5D1D8DF69E070A968D4B186986FDF06ED0",
"tx_json" : {
"Account" : "rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo",
"CheckID" : "49647F0D748DC3FE26BDACBC57F251AADEFFF391403EC9BF87C97F67E9977FB0",
"Fee" : "12",
"Flags" : 2147483648,
"Sequence" : 3,
"SigningPubKey" : "022C53CD19049F32F31848DD3B3BE5CEF6A2DD1EFDA7971AB3FA49B1BAF12AEF78",
"TransactionType" : "CheckCancel",
"TxnSignature" : "30440220615F9D19FA182F08530CD978A4C216C8676D0BA9EDB53A620AC909AA0EF0FE7E02203A09CC34C3DB85CCCB3137E78081F8F2B441FB0A3B9E40901F312D3CBA0A67A1",
"hash" : "414558223CA8595916BB1FEF238B3BB601B7C0E52659292251CE613E6B4370F9"
}
}
}
4.検証の待機
本番環境のネットワークやRipple Test Netでは、レジャーが自動的に閉鎖するまでに4~7秒かかる場合があります。
スタンドアロンモードでrippled
を実行している場合は、ledger_acceptメソッドを使用してレジャーを手動で閉鎖します。
5.最終結果の確認
トランザクションのステータスを確認するには、CheckCancelトランザクションの識別用ハッシュを指定したtxメソッドを使用します。トランザクションが成功したことを示す"TransactionResult": "tesSUCCESS"
フィールドをトランザクションメタデータから検索し、またこの結果が最終結果であることを示す"validated": true
フィールドを結果から検索します。
トランザクションによってCheckレジャーオブジェクトが削除されたことを示す"LedgerEntryType": "Check"
を含むDeletedNode
オブジェクトを、トランザクションメタデータから検索します。このオブジェクトのLedgerIndex
はCheckのIDに一致している必要があります。
要求の例
'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 tx_hash = "54A7A917BE9AC13962251BCF1D09803C7BBE75882B8BFC987B5933A566A48215"
return api.getTransaction(tx_hash)
}).then(response => {
console.log("Final transaction result:", response)
// Disconnect and return
}).then(() => {
api.disconnect().then(() => {
console.log('Disconnected')
process.exit()
})
}).catch(console.error)
rippled tx 414558223CA8595916BB1FEF238B3BB601B7C0E52659292251CE613E6B4370F9
応答の例
Connected
Final transaction result: { type: 'checkCancel',
address: 'rBXsgNkPcDN2runsvWmwxk3Lh97zdgo9za',
sequence: 7,
id: '54A7A917BE9AC13962251BCF1D09803C7BBE75882B8BFC987B5933A566A48215',
specification:
{ checkID: '2E0AD0740B79BE0AAE5EDD1D5FC79E3C5C221D23C6A7F771D85569B5B91195C2' },
outcome:
{ result: 'tesSUCCESS',
timestamp: '2018-04-02T23:42:22.000Z',
fee: '0.000012',
balanceChanges: { rBXsgNkPcDN2runsvWmwxk3Lh97zdgo9za: [Array] },
orderbookChanges: {},
ledgerVersion: 8004870,
indexInLedger: 3 } }
Disconnected
Loading: "/etc/opt/ripple/rippled.cfg"
2018-Jan-24 01:11:53 HTTPClient:NFO Connecting to 127.0.0.1:5005
{
"result" : {
"Account" : "rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo",
"CheckID" : "49647F0D748DC3FE26BDACBC57F251AADEFFF391403EC9BF87C97F67E9977FB0",
"Fee" : "12",
"Flags" : 2147483648,
"Sequence" : 3,
"SigningPubKey" : "022C53CD19049F32F31848DD3B3BE5CEF6A2DD1EFDA7971AB3FA49B1BAF12AEF78",
"TransactionType" : "CheckCancel",
"TxnSignature" : "30440220615F9D19FA182F08530CD978A4C216C8676D0BA9EDB53A620AC909AA0EF0FE7E02203A09CC34C3DB85CCCB3137E78081F8F2B441FB0A3B9E40901F312D3CBA0A67A1",
"date" : 570071520,
"hash" : "414558223CA8595916BB1FEF238B3BB601B7C0E52659292251CE613E6B4370F9",
"inLedger" : 7,
"ledger_index" : 7,
"meta" : {
"AffectedNodes" : [
{
"ModifiedNode" : {
"FinalFields" : {
"Flags" : 0,
"Owner" : "rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy",
"RootIndex" : "032D861D151E38E86F46805ED1896D1A50144F65459717B6D12470A9E6E3B66E"
},
"LedgerEntryType" : "DirectoryNode",
"LedgerIndex" : "032D861D151E38E86F46805ED1896D1A50144F65459717B6D12470A9E6E3B66E"
}
},
{
"DeletedNode" : {
"FinalFields" : {
"Account" : "rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo",
"Destination" : "rfkE1aSy9G8Upk4JssnwBxhEv5p4mn2KTy",
"DestinationNode" : "0000000000000000",
"DestinationTag" : 1,
"Expiration" : 570113521,
"Flags" : 0,
"InvoiceID" : "46060241FABCF692D4D934BA2A6C4427CD4279083E38C77CBE642243E43BE291",
"OwnerNode" : "0000000000000000",
"PreviousTxnID" : "5463C6E08862A1FAE5EDAC12D70ADB16546A1F674930521295BC082494B62924",
"PreviousTxnLgrSeq" : 6,
"SendMax" : "100000000",
"Sequence" : 2
},
"LedgerEntryType" : "Check",
"LedgerIndex" : "49647F0D748DC3FE26BDACBC57F251AADEFFF391403EC9BF87C97F67E9977FB0"
}
},
{
"ModifiedNode" : {
"FinalFields" : {
"Flags" : 0,
"Owner" : "rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo",
"RootIndex" : "AD136EC2A266027D8F202C97D294BBE32F6FC2AD5501D9853F785FE77AB94C94"
},
"LedgerEntryType" : "DirectoryNode",
"LedgerIndex" : "AD136EC2A266027D8F202C97D294BBE32F6FC2AD5501D9853F785FE77AB94C94"
}
},
{
"ModifiedNode" : {
"FinalFields" : {
"Account" : "rUn84CUYbNjRoTQ6mSW7BVJPSVJNLb1QLo",
"Balance" : "4999999999964",
"Flags" : 0,
"OwnerCount" : 1,
"Sequence" : 4
},
"LedgerEntryType" : "AccountRoot",
"LedgerIndex" : "D3A1DBAA28717975A9119EC4CBC891BA9A66236C484F03C9911F463AD3B66DE0",
"PreviousFields" : {
"Balance" : "4999999999976",
"OwnerCount" : 2,
"Sequence" : 3
},
"PreviousTxnID" : "5463C6E08862A1FAE5EDAC12D70ADB16546A1F674930521295BC082494B62924",
"PreviousTxnLgrSeq" : 6
}
}
],
"TransactionIndex" : 0,
"TransactionResult" : "tesSUCCESS"
},
"status" : "success",
"validated" : true
}
}