リップルの送金の流れ
ビットコインにおいては送金にUTXOが必要なのでブロックチェーンからどの入金データを使うかユーザー側が選ばなくてはならないがリップルにおいては残高ベースなので必要がない
以下のような流れとなる
- 送金データを作る
- 送金データから未署名のペイメントトランザクション(JSON)を作成する
- 未署名のペイメントトランザクションに秘密鍵で署名し、署名済みトランザクション(HEX値)を作成する
- 署名済みトランザクションをリップルネットワークに送信する
送金データを作る
- 通貨はXRP固定
- source_addressに送金元のアドレスを入れます
- dest_addressに送金先のアドレスを入れます
- amountにXRPの金額を入れます(0.1など単位はXRP)
- optionsには宛先タグを格納します
const createPaymentXRP = (source_address, dest_address, amount, options) => {
const symbol = "XRP"
const result = {
"source": {
"address": source_address,
"maxAmount": {
"value": amount.toString(),
"currency": symbol,
}
},
"destination": {
"address": dest_address,
"amount": {
"value": amount.toString(),
"currency": symbol,
}
}
};
if(options.destination_tag) result.destination.tag = options.destination_tag
return result
}
未署名の支払いトランザクションを作る
送金データを作る関数を使ってトランザクションを作ります
ここで手数料などを指定します(自動で設定されるはずですがうまくいかないときもあります)
maxLedgerVersionOffsetは tefMAX_LEDGER が頻発するようなら引き上げるようにします
ここで指定した値のledgerが経過するまではtxidを見つけられなくても再送しないようにします
const createPaymentTransaction = (api, wallet_address, dest_address, amount, options) => {
const instructions = {
maxLedgerVersionOffset: 5,
fee: '0.1',
};
const data = createPaymentXRP(wallet_address, dest_address, amount, options)
return api.preparePayment(wallet_address, data, instructions)
}
支払いトランザクションに署名してネットワークに流す
- 秘密鍵が必要になります
- 署名後にトランザクションIDが取得できます
const secret = "secret key"
const wallet_address = "rXXXXXXXX1"
const dest_address = "rXXXXXXXX2"
const amount = "0.1"
createPaymentTransaction(api, wallet_address, dest_address, amount, {}).then(prepared => {
const sign = api.sign(prepared.txJSON, secret)
const tx = JSON.parse(prepared.txJSON)
tx.txid = sign.id
tx.hex = sign.signedTransaction
return api.submit(sign.signedTransaction).then(res => {
if(res.resultCode !== 'tesSUCCESS'){
throw new Error(res.resultMessage)
}
return tx
})
})
エラー処理
戻り値にエラー定数があるのできちんとハンドリングする
tesSUCCESSなどのtesXXXXは検証に成功したトランザクション。実際に送金できたかどうかの確認はTXIDを台帳から調査することができる
tecUNFUNDED_PAYMENTのようなtecXXXのコードは検証に失敗したトランザクションで台帳に含まれTXIDで調査できる。
(失敗したトランザクションでもXRPの手数料は支払う必要がある)
他のステータスは結果コードから台帳に含まれるか予測困難である
送金のステータスは以下のリンクに書いてある
https://ripple.com/build/transactions/#finality-of-results
tefMAX_LEDGERはネットワークが混んでいるときに出て、取り込まれるかどうかわからない(だいたい取り込まれないが取り込まれることもある。少したってからトランザクションを確認する(maxLedgerVersionOffsetで指定したレジャー経過後))。
頻発時には以下の対応
- 手数料をあげる
- maxLedgerVersionOffsetをあげる
https://forum.ripple.com/viewtopic.php?f=2&t=15927
https://www.xrpchat.com/topic/4324-lastledgersequence-exceeded/
(余談ですがこの問題はいつもジョエルカッツさんが答えています)
LastLedgerSequenceを設定しないトランザクション(オフライン署名とか?)はtesSUCCESS以外のtesXXXXXが返却されるので注意する必要がある
成功でも失敗でもTXIDは取れるので後検知でハンドリングする機構をいれることで対応可能になる