try catch and ...release
ページ
ホーム
Chromeアプリ開発Tips
公開アプリ
Ubuntu
Linuxコマンド
#!/bin/bash
ブロックチェーンと暗号通貨
2018年1月30日火曜日
Ripple: Multi-Sign (マルチシグ) のやり方
某暗号通貨取引所のNEMがクラックされた事件をうけて、暗号通貨界隈では [*マルチシグ*] という概念に改めて注目が集まっています。*マルチシグ*というのはざっくりというと、共同口座のようなものを作ることができる機能です。マルチシグを利用することで、あるひとつの口座(アドレス)を複数のアドレスで管理することができるようになります。組織で特定のアドレスを管理する必要があるなら必須の機能と言えるかもしれません。 Ripple にも [Multi-Sign](https://ripple.com/build/how-to-multi-sign/) (マルチシグ、マルチサイン) の仕様があります。 この記事ではRippleにおけるマルチシグのやり方をまとめてみました。 なお今回は、筆者が開発した [RippleウォレットChrome拡張機能](https://chrome.google.com/webstore/detail/ripple-wallet/pbdihppojjickcoendiloibpjokjaobc)の [*RPCツール*] 機能と [*マルチサイン・ツール*] 機能 (v0.7.0以降で利用可能) を使ってトランザクションを発行したいと思います。
## 前提 - マルチシグ・アドレスと他に4つアドレスを用意、そのうち1人はマルチシグ・アドレスからのXRP送金の宛先用 - マルチシグ・アドレスへの決定権を持つ投票者は全員で3人、そのうち1人は2票分の権利を持つ - マルチシグ・アドレスからの送金には、3票の投票(署名)が必要 ## 登場するアドレス - アドレスA〜Cで共同管理するマルチシグ・アドレス: `rHfNbbyoPxkfYUB6Hq3nASGMpNFzZQYoLq` - アドレスA (2票分の権利を保有): `rhBz8ofEXjmtEyQtY6jju9we3ycXmDYhzp` - アドレスB (1票分の権利を保有): `rHDmrpkLZJ4XsvfgUeniSkBtjTGdiisFzr` - アドレスC (1票分の権利を保有): `rQK8mxyBuskB2gzLU7Lqi6ZNvghWejNED1` - アドレスX (マルチシグ・アドレスからXRP送金を受け取るアドレス): `rDs6jo2YmKtVKvARtV5CAMiCkrGUA336Hy` ## マルチシグ・アドレスを作成 まずはマルチシグ・アドレスの秘密鍵を使いマルチシグ・アドレスの設定を行いましょう。 Rippleウォレットの *RPC ツール* 機能を使い、以下のトランザクションを投げます(コメントは削除してください): ``` { "Flags": 0, "TransactionType": "SignerListSet", "Account": "rHfNbbyoPxkfYUB6Hq3nASGMpNFzZQYoLq", // マルチシグ・アドレス "Fee": "10000", "SignerQuorum": 3, // 必要票数は3票 "SignerEntries": [{ "SignerEntry": { "Account": "rhBz8ofEXjmtEyQtY6jju9we3ycXmDYhzp", // アドレスA "SignerWeight": 2 // 権利は2票 } }, { "SignerEntry": { "Account": "rHDmrpkLZJ4XsvfgUeniSkBtjTGdiisFzr", // アドレスB "SignerWeight": 1 // 権利は1票 } }, { "SignerEntry": { "Account": "rQK8mxyBuskB2gzLU7Lqi6ZNvghWejNED1", // アドレスC "SignerWeight": 1 // 権利は1票 } } ] } ``` `tesSUCCESS`なレスポンスが返ってきました: ``` { "engine_result": "tesSUCCESS", "engine_result_code": 0, "engine_result_message": "The transaction was applied. Only final in a validated ledger.", "status": "success", "tx_blob": "12000C22000000002400000001201B005F7BC9202300000003684000000000002710732103BC64FEE05D126327403EE7FEBC1AB321172B5379090DFA224FFE5882CC9324FF7446304402203F9CC61B1EBC4CD830153201456B4DEDDC4785D9AA46BA1E9F2C48F8809EAE7E02202ECC6078D6055D58DBD2B2CBA027BF1EC40DC3265FAB861F6D06B44F9A9DD4048114B0AFDBB20B21CDA373D813CE145A8C268A54ABC5F4EB130002811422FCC6FB43800E0107AA0C3A1A4554BAC782316DE1EB1300018114B1EBBBDEA0E96DA47AD4E20A03ADEC7175D77472E1EB1300018114FFD897731F44A65AEE2705ADB62AB2766AFE565AE1F1", "tx_json": { "Account": "rHfNbbyoPxkfYUB6Hq3nASGMpNFzZQYoLq", "Fee": "10000", "Flags": 0, "LastLedgerSequence": 6257609, "Sequence": 1, "SignerEntries": [ { "SignerEntry": { "Account": "rhBz8ofEXjmtEyQtY6jju9we3ycXmDYhzp", "SignerWeight": 2 } }, { "SignerEntry": { "Account": "rHDmrpkLZJ4XsvfgUeniSkBtjTGdiisFzr", "SignerWeight": 1 } }, { "SignerEntry": { "Account": "rQK8mxyBuskB2gzLU7Lqi6ZNvghWejNED1", "SignerWeight": 1 } } ], "SignerQuorum": 3, "SigningPubKey": "03BC64FEE05D126327403EE7FEBC1AB321172B5379090DFA224FFE5882CC9324FF", "TransactionType": "SignerListSet", "TxnSignature": "304402203F9CC61B1EBC4CD830153201456B4DEDDC4785D9AA46BA1E9F2C48F8809EAE7E02202ECC6078D6055D58DBD2B2CBA027BF1EC40DC3265FAB861F6D06B44F9A9DD404", "hash": "463BD95469E1194D8BF58C3445BC010EE2E246B1572E6CA540986B77B0A5B872" } } ``` 送信したトランザクションは、通常は遅くても約7秒以内にレジャーに取り込まれます。取り込まれたら完了です。 ## マルチシグ・アドレスのマスターキーペアを無効化 マルチシグ・アドレスの残高は合議でのみで動かせるようにするため鍵を使えなくしておきましょう: ``` { "TransactionType": "AccountSet", "Account" : "rHfNbbyoPxkfYUB6Hq3nASGMpNFzZQYoLq", "Fee": "10000", "SetFlag": 4 // asfDisableMaster } ``` `"engine_result": "tesSUCCESS"` なレスポンスが返ってきたら成功です。後はレジャーに取り込まれるのを待ちます。 ## マルチシグ・アドレスから送金 それでは、実際のマルチシグの例として、 **マルチシグ・アドレス** (rHfN..) から **アドレスX** (rDs6..) へ 100 XRP 送金するトランザクションを作成してみましょう。 #### 署名付きトランザクションデータを作成 まずは、マルチシグ・アドレスの管理者の一人である **アドレスA** (rhBz..) が署名します。Rippleウォレットの *設定* から **アドレスA** (rhBz..) の秘密鍵を設定後、*マルチサイン・ツール* から以下の json データに署名します。 送信元`Account`は**マルチシグ・アドレス** (rHfN..)、宛先`Destination`は **アドレスX** (rDs6..) になっています: ``` { "TransactionType" : "Payment", "Account" : "rHfNbbyoPxkfYUB6Hq3nASGMpNFzZQYoLq", "Destination" : "rDs6jo2YmKtVKvARtV5CAMiCkrGUA336Hy", "Amount" : "100000000", "SigningPubKey": "", "Fee": "30000" } ``` *サイン* ボタンを押すと以下のような **アドレスA** (rhBz..) の署名付きデータが生成されます: ``` { "TransactionType": "Payment", "Account": "rHfNbbyoPxkfYUB6Hq3nASGMpNFzZQYoLq", "Destination": "rDs6jo2YmKtVKvARtV5CAMiCkrGUA336Hy", "Amount": "100000000", "SigningPubKey": "", "Fee": "30000", "Sequence": 4, "Signers": [ { "Signer": { "Account": "rhBz8ofEXjmtEyQtY6jju9we3ycXmDYhzp", "SigningPubKey": "03A95E457506F7D6D026260EC4BAE1627172ECF4BED1EA6189B741DBF25AA805F3", "TxnSignature": "30440220029ECC55E90303FDCB7B69E25B53020625396D60AF91BE118F639FD95C0AA46102200FF11FAE6073F61E62D20037482695A97FC4FFE457390D2C5D6128ECC187A3ED" } } ], "hash": "FF6C4977F8F45AF271E70D3BC26510ADFEA3C6BB3BECB4882D258B3C7D3AAB1D" } ``` **TIPS: `tefBAD_QUORUM` エラー** この後このトランザクションをすぐにサブミットとしても`tefBAD_QUORUM: Signatures provided do not meet the quorum.`というエラーが出るはずです。理由は、この時点ではまだ署名数が足りないからです。 #### トランザクションデータに署名を追加 では、先ほどのトランザクションに **アドレスB** (rHDm..) の署名も追加してみましょう。 Rippleウォレットの *設定* から **アドレスB** (rHDm..) の秘密鍵を設定し、**アドレスB** (rHDm..) になっておきます。 そして、**マルチサイン・ツール** で先ほどのトランザクションデータをそのまま貼り付けし、再び *サイン* ボタンを押下します: ``` { "TransactionType": "Payment", "Account": "rHfNbbyoPxkfYUB6Hq3nASGMpNFzZQYoLq", "Destination": "rDs6jo2YmKtVKvARtV5CAMiCkrGUA336Hy", "Amount": "100000000", "SigningPubKey": "", "Fee": "30000", "Sequence": 4, "Signers": [ { "Signer": { "Account": "rhBz8ofEXjmtEyQtY6jju9we3ycXmDYhzp", "SigningPubKey": "03A95E457506F7D6D026260EC4BAE1627172ECF4BED1EA6189B741DBF25AA805F3", "TxnSignature": "30440220029ECC55E90303FDCB7B69E25B53020625396D60AF91BE118F639FD95C0AA46102200FF11FAE6073F61E62D20037482695A97FC4FFE457390D2C5D6128ECC187A3ED" } } ], "hash": "FF6C4977F8F45AF271E70D3BC26510ADFEA3C6BB3BECB4882D258B3C7D3AAB1D" } ``` すると、以下のような **アドレスB** (rHDm..) の署名が追加されたトランザクションデータが作成されます: ``` { "TransactionType": "Payment", "Account": "rHfNbbyoPxkfYUB6Hq3nASGMpNFzZQYoLq", "Destination": "rDs6jo2YmKtVKvARtV5CAMiCkrGUA336Hy", "Amount": "100000000", "SigningPubKey": "", "Fee": "30000", "Sequence": 4, "hash": "1C475DCC20E90380FA5567C7DE733131CF341B2FAA1FA1DC531E62EC301C74F5", "Signers": [ { "Signer": { "Account": "rHDmrpkLZJ4XsvfgUeniSkBtjTGdiisFzr", "SigningPubKey": "0365C70DB32FC1D52A472954AEB2FBCC3C132716EB914DE8E68CCB636C059BBC2A", "TxnSignature": "304402202A1A511240449B05CA4ED5422D63104938593E258C2802F98D3897F231A65CBD02205A6C70D21A1F353132A2FC7848DF606E094A66FB14370C728038C6AD58360CA5" } }, { "Signer": { "Account": "rhBz8ofEXjmtEyQtY6jju9we3ycXmDYhzp", "SigningPubKey": "03A95E457506F7D6D026260EC4BAE1627172ECF4BED1EA6189B741DBF25AA805F3", "TxnSignature": "30440220029ECC55E90303FDCB7B69E25B53020625396D60AF91BE118F639FD95C0AA46102200FF11FAE6073F61E62D20037482695A97FC4FFE457390D2C5D6128ECC187A3ED" } } ] } ``` **TIPS: `Singers`の順序** 上記のデータの`Signers` 配列の並び順は`Signer.Account`プロパティの**昇順**でなければなりません。 #### トランザクションデータをサブミット 先ほど完成したトランザクションデータをネットワークへ投げてみましょう。 そのまま同じ画面(**マルチサイン・ツール**)の下部にある *リクエスト* ボタンを押下してみてください。成功すれば、マルチシグ・アドレスから **アドレスX** (rDs6) へ 100 XRP が予定どおりに送金されるはずです。 実際には、[submit_multisigned](https://ripple.com/build/rippled-apis/#submit-multisigned)なトランザクションとして投げられています。 レスポンス: ``` { "engine_result": "tesSUCCESS", "engine_result_code": 0, "engine_result_message": "The transaction was applied. Only final in a validated ledger.", "status": "success", "tx_blob": "1200002400000004614000000005F5E10068400000000000753073008114B0AFDBB20B21CDA373D813CE145A8C268A54ABC5831484245901EA1B3B0657C9E75074F40C7AC70C3C62F3E010732103A95E457506F7D6D026260EC4BAE1627172ECF4BED1EA6189B741DBF25AA805F3744630440220029ECC55E90303FDCB7B69E25B53020625396D60AF91BE118F639FD95C0AA46102200FF11FAE6073F61E62D20037482695A97FC4FFE457390D2C5D6128ECC187A3ED811422FCC6FB43800E0107AA0C3A1A4554BAC782316DE1E01073210365C70DB32FC1D52A472954AEB2FBCC3C132716EB914DE8E68CCB636C059BBC2A7446304402202A1A511240449B05CA4ED5422D63104938593E258C2802F98D3897F231A65CBD02205A6C70D21A1F353132A2FC7848DF606E094A66FB14370C728038C6AD58360CA58114B1EBBBDEA0E96DA47AD4E20A03ADEC7175D77472E1F1", "tx_json": { "Account": "rHfNbbyoPxkfYUB6Hq3nASGMpNFzZQYoLq", "Amount": "100000000", "Destination": "rDs6jo2YmKtVKvARtV5CAMiCkrGUA336Hy", "Fee": "30000", "Sequence": 4, "Signers": [ { "Signer": { "Account": "rhBz8ofEXjmtEyQtY6jju9we3ycXmDYhzp", "SigningPubKey": "03A95E457506F7D6D026260EC4BAE1627172ECF4BED1EA6189B741DBF25AA805F3", "TxnSignature": "30440220029ECC55E90303FDCB7B69E25B53020625396D60AF91BE118F639FD95C0AA46102200FF11FAE6073F61E62D20037482695A97FC4FFE457390D2C5D6128ECC187A3ED" } }, { "Signer": { "Account": "rHDmrpkLZJ4XsvfgUeniSkBtjTGdiisFzr", "SigningPubKey": "0365C70DB32FC1D52A472954AEB2FBCC3C132716EB914DE8E68CCB636C059BBC2A", "TxnSignature": "304402202A1A511240449B05CA4ED5422D63104938593E258C2802F98D3897F231A65CBD02205A6C70D21A1F353132A2FC7848DF606E094A66FB14370C728038C6AD58360CA5" } } ], "SigningPubKey": "", "TransactionType": "Payment", "hash": "39A679381CF84099D80635A9DEC3D07BD97B97A797768B4EE5B0E12F3F4FE20F" } } ``` 上記のようなレスポンスが返ってくれば成功です。トランザクションは、txハッシュ`hash`の値`39A679381CF84099D80635A9DEC3D07BD97B97A797768B4EE5B0E12F3F4FE20F`で確認できます。 **TIPS: `tefMAX_LEDGER` エラー** トランザクションを投げた時に`tefMAX_LEDGER`なエラーが出たときは `"LastLedgerSequence"` を +3 ぐらいで微調整すると良いかもしれません。このエラーの原因は、トランザクションデータを作成後に時間をおきすぎたことが原因だと思います。 #### 注意点 - **TXの `Sequence`** TXにセットする `Sequence` は送信者`Account`(今回の例だとマルチシグアドレス)のSequence番号なのでご注意。 - **submit時の `LastLedgerSequence`** マルチサインTXをsubmitする際には `LastLedgerSequence` をセットしてはいけません。 以上です。
0 件のコメント:
コメントを投稿
次の投稿
前の投稿
ホーム
登録:
コメントの投稿 (Atom)
0 件のコメント:
コメントを投稿