rippled 1.4.0のリリース
2019年12月2日にdeployされたXRP Ledger(rippled server) version 1.4.0から、バリデーターによるDeletableAccounts Amendmentsの投票が開始されました。その他にもfixCheckThreadingやfixPayChanRecipeintOwnerDir Amendmentの投票も開始されています。
現在投票期間から2週間以上経過しているので、そろそろ有効になるのではないかと思います。
Known AmendmentsのページではまだPlannedですね。
今回はアカウント全体に関わる部分のDeletableAccounts Amendmentに関して見ていきます。
DeletableAccounts Amendment
DeletableAccounts Amendmentとは、端的に言うと、XRPアカウントの削除が可能になる
Amendmentです。
詳細はXRP Community Standards Draft 7をご確認ください。
簡単にまとめると以下のとおりです。
- XRPアカウントを有効にするためにはreserve(準備金)が必要。
- reserveを回収したい!
- でも、大量にXRPアカウントを作られて、回収してを繰り返して、XRP Ledger上に負荷をかけられたくない。(元々reserveが存在するのもこのため。)
- 再作成されたアカウント1で、過去のトランザクションを実行したくない。
- これらの問題を解決するトランザクションタイプを追加しよう!
こうやって追加されたトランザクションタイプがAccountDelete
と呼ばれるトランザクションになります。
AccountDelete Transactionを実際に投げてみる
ものは試しで、AccountDeleteトランザクションを投げてみましょう。
TestnetでもDeletableAccounts Amendmentは有効になっていないので、今回はDevnetを使います。
Devnetは最近作られたXRP Ledger networkで、testnetよりも不安定な開発寄りブランチで、rippledのdevelopmentブランチがdeployされるようです。
今回のように、まだ適用されていないAmendmentsのテストをするときなどに利用できます。
Devnetノードを立てる(署名の準備)
AccountDeleteトランザクションを投げるためには、トランザクションへの署名が必要です。
現在、rippledへのRPCやWebsocketでのsignコマンドはデフォルトでoffになっているので、自身で立てたrippled上でsignコマンドを利用したり、ripple-libなどを利用したlocal signなどを行う必要があります。
今回は弊社Wallet開発の都合もあり、自身でrippledをDevnetモードで起動し、そのrippledを使って署名を行うことにしました。
rippledをDevnetモードで起動するためには、Connect Your rippled to an XRPL Altnetをご確認ください。
アカウントの準備
削除対象アカウントとreserve回収用アカウントの2つをXRP faucetで準備しておきましょう。
選択するのはDevnet用なので、そこだけご注意ください。
今回は下記2つのアカウントで試してみます。2
[削除対象アカウント]
- Address
rUdz5dJF4AeZQ5g9L7PsYYdfTpNab5r1QW
- Secret
shGaJTEc1Ewp95ZmXhz4oYFPZBUTZ
- Balance
10,000 XRP
[reserve回収用アカウント]
- Address
rrhfuJcbQRxtiwBdrvWmAKSXPLqM5QEery
- Secret
ssdLbcqMgKYxHiR63d5EKR1JUCzEb
- Balance
10,000 XRP
Devnetアカウントの確認
Devnetアカウントの状態をrippledやJSON-RPCを叩いて確認するのは面倒なので、ripplermさんのripple-walletを少し手直しして、Devnet用のripple-walletを用意しました。3
左上のNetworkをTEST
にし、状態がonline
になり、ページ中央上部のServerがs.devnet.rippletest.net
になっていればDevnetにつながっています。
この状態のページを2つ用意し、Faucetより取得したsecretを利用して、アカウントの状態を見てみます。
Wallet Account: address文字列
の横にある大きな[Change]というボタンを押して、[use secretkey]ボタンから、secretを設定して、XRP Balanceに10000と表示されていればOKです。
以下のような感じになります。削除対象アカウント、reserve回収用アカウント共に確認しましょう。
AccountDeleteトランザクションを作る
次に、トランザクションを作っていきます。
トランザクションフォーマットをAccountDeleteよりコピペします。
そして、削除対象アカウントのアドレスをAccount
に。
reserve回収用アカウントのアドレスをDestination
に設定します。
Fee
は5000000
固定です。
忘れてはならないのが、Sequence
で、前項のripple-wallet
の右下に表示されているNext Sequence
の値を設定します。
{
"TransactionType": "AccountDelete",
"Account": "rUdz5dJF4AeZQ5g9L7PsYYdfTpNab5r1QW",
"Destination": "rrhfuJcbQRxtiwBdrvWmAKSXPLqM5QEery",
"DestinationTag": 13,
"Fee": "5000000",
"Sequence": 3317673,
"Flags": 2147483648
}
これで完璧です。4
署名->ブロードキャスト
あとは署名して、ブロードキャストするだけです。
自分で立てたrippled devnetノード上で、以下のコマンドを実行します。
sign
コマンドで使用するsecretは削除対象アカウントのものを使います。
$ rippled sign shGaJTEc1Ewp95ZmXhz4oYFPZBUTZ '{"TransactionType": "AccountDelete","Account": "rUdz5dJF4AeZQ5g9L7PsYYdfTpNab5r1QW","Destination": "rrhfuJcbQRxtiwBdrvWmAKSXPLqM5QEery","DestinationTag": 13,"Fee": "5000000","Sequence": 3317673,"Flags": 2147483648}' offline
そうすると、署名済み生トランザクションとしてtx_blob
が以下のように返ってきます。
{
"result" : {
"deprecated" : "This command has been deprecated and will be removed in a future version of the server. Please migrate to a standalone signing tool.",
"status" : "success",
"tx_blob" : "120015228000000024002F0CB82E0000000D6840000000004C4B407321027DBB242DB5897F8B8C2317091BD81F05DBB60B91FD909B44855B890782DF120E74473045022100F09AB624D65899C549AB5E7B32FE0BC225ACAFE8EA547DCA56870C7AFC8E7DBB0220755AA58A3B7CD1282702818B46BF8A2DEEE9C138417B5F597DC0F1206A09451A81147FA889DE3319F8826DD9E77C322032028F9B348C83140097025B6D4EB217C4448EF8C681CF8D9C5E9379",
"tx_json" : ...
}
}
こちらをsubmit
コマンドでブロードキャストします。
$ rippled submit 12001522800000002400329FA92E0000000D6840000000004C4B407321027DBB242DB5897F8B8C2317091BD81F05DBB60B91FD909B44855B890782DF120E7446304402203D18889E98B419BDB03D5BBA6088CEB1550847CFD710F4146E5C8B09F2E1162902203FAB4BB9FA64DB1CCA9516BA8518DDB929A52CB9BD3424C6B5FBDF63C95D20B081147FA889DE3319F8826DD9E77C322032028F9B348C83140097025B6D4EB217C4448EF8C681CF8D9C5E9379
Loading: "/etc/opt/ripple/rippled.cfg"
2019-Dec-20 09:12:04.845053121 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",
...
}
成功しました。
なお、terPRE_SEQ
エラーでsubmitに失敗した場合は、Sequenceの値を1つ加算して、10分程度待ってからもう一度sign
->submit
を行ってみてください。5
アカウントの状態を確認
ripple-walletでアカウントの状態を確認してみましょう。
削除対象アカウントはBalanceの値が消えており、reserve回収対象アカウントにFee
として5XRPが消費された9995XRP
が移動しています。
AccountDeleteトランザクションを使用すると、reserveはすべて回収されず、5XRPが手数料として消費されるため、「大量にXRPアカウントを作られて、回収してを繰り返して、XRP Ledger上に負荷をかけられたくない。」の抑止になります。
Account仕様の変更
もしXRPに堪能な方はここまでで、Faucetで作成したアカウントのSequence値がやけに高いことに気づかれたかも知れません。
DeletableAccounts Amendmentが適用されると、新規に作成されるアカウントはその時のLedgerSequence
の値になります。
これまではSequenceの値は0
から始まっていましたが、「再作成されたアカウントで、過去のトランザクションを実行したくない。」を実現するために、アカウント作成時(reserve入金時)のLedger SequenceがSequenceの値に適用されることになりました。
ここは弊社のようなWallet開発をしている会社では非常に注意すべき変更点で、Sequenceの値が0からシーケンシャルになるような実装をしている場合は変更が必要な箇所になります。
まとめ
DeletableAccounts Amendmentが適用されると以下の効果が適用されます。
- AccountDeleteトランザクションが有効になる。
- AccountDeleteトランザクションでは、reserveが回収できるが、5XRPは手数料として消費させられる。
- 新しく作成される、もしくは再作成したアカウントのSequenceは、その時のLedgerSequenceの値となる。
なお、アカウントに設定されている属性によっては特殊な振る舞いをするものもあるため、詳細はXRP Community Standards Draft 7をご確認ください。
-
以前と同じアドレスにreserveを送ることで、そのアカウントが再度有効になります。復活したアカウントはアドレスが同じだけで、全く別物になります。 ↩
-
今回はDevnetかつ、このアカウントを使い捨てるので、secretを載せてますが、基本的にsecretの情報を公開してはいけません。 ↩
-
接続先を変えただけの超お手軽対応です。ripple-walletはほんと使いやすいです。 ↩
-
DestinationTagはOptionalなので、あってもなくても良いです。 ↩
-
AccountDeleteトランザクションは、そのアカウントが作成されたLedgerSequenceから少なくとも256以上経過していなければ承認されません。 ↩