Counterwallet ビットコイン送金時の処理の流れ
はじめに
以前、12-word passphrase作成〜ビットコインアドレスの残高表示までのソースコードを見ましたが、今回はビットコイン送金処理の流れを見てみます。
目次
- MVVMライブラリKnockout.js
- Counterwalletのデータモデル
- プルダウンから"Send"を選択
- 送金ボタンクリック
MVVMライブラリKnockout.js
CounterwalletはMV系フレームワークとしてKnockout.jsを採用しています。データモデルが変更される度に、UIの関連付けられた部分を更新します。参考サイトは多数ありますが、以下書籍はさらっと読めて初めての人には良いと思います。
Knockout.js: Building Dynamic Client-Side Web Applications
- 作者: Jamie Munro
- 出版社/メーカー: O'Reilly Media
- 発売日: 2014/12/09
- メディア: Kindle版
- この商品を含むブログを見る
Counterwalletのデータモデル
ログイン時にpages.init.js内のinitIndex()が呼ばれ、WalletViewModel初期化に伴い、紐づくアドレス(AddressViewModel)とアセット(AssetViewModel)がバインドされます。
// index.html <script src="js/pages.init.js"></script>
// pages.init.js function initIndex() { //main page window.WALLET = new WalletViewModel();
プルダウンから"Send"を選択
アセット毎にAssetViewModelがバインドされており、"Send"プルダウンをクリックすると紐づくsendメソッドが呼ばれます。SEND_MODALはSendModalViewModel(id="sendModal")と紐付いています。ViewModelは大文字の変数名にするルールにしている.. と思います。
// balances.html <li><a data-bind="visible: !$parent.IS_WATCH_ONLY, click: send, locale: 'send'" href="#"></a></li>
// asset.js self.send = function () { if(self.availableBalance()<=0) { bootbox.alert(i18n.t("not_available_asset_to_send", self.ASSET, getAddressLabel(self.ADDRESS))); return; } if(!WALLET.canDoTransaction(self.ADDRESS)) return false; SEND_MODAL.show(self.ADDRESS, self.ASSET, self.rawAvailableBalance(), self.DIVISIBLE); };
// balances.html <div data-bind="showModal: shown, validationOptions: { insertMessages: false }" id="sendModal" class="modal fade" data-backdrop="static" data-keyboard="false" tabindex="-1" role="dialog" aria-labelledby="sendModal" aria-hidden="true"> .. <button type="button" data-bind="click: submitForm, locale: 'send'" class="btn btn-primary"></button> .. </div>
送金ボタンクリック
送金アドレスと金額を入力した後、送金ボタンクリック
// balances.js function SendModalViewModel() { self.submitForm = function() { if (!self.validationModel.isValid()) { self.validationModel.errors.showAllMessages(); return false; } //data entry is valid...submit to the server $('#sendModal form').submit(); }
// balances.html <form class="smart-form" data-bind="submit: doAction"><fieldset>
create_send API呼び出し
SendModalViewModelからWalletViewModelのトランザクション送信処理を呼び出す。WalletViewModelのdoTransactionメソッドで、"create_send"リクエスト、tx_sign、ブロードキャストを実行する。
// balances.js function SendModalViewModel() { self.doAction = function() { WALLET.doTransaction(self.address(), "create_send", { source: self.address(), destination: self.destAddress(), quantity: denormalizeQuantity(parseFloat(self.quantity()), self.divisible()), asset: self.asset(), _divisible: self.divisible() }, function(txHash, data, endpoint, addressType, armoryUTx) { var message = "<b>" + (armoryUTx ? i18n.t("will_be_sent") : i18n.t("were_sent")) + " </b>"; WALLET.showTransactionCompleteDialog(message + " " + i18n.t(ACTION_PENDING_NOTICE), message, armoryUTx); } ); self.shown(false); trackEvent('Balances', 'Send', self.asset()); // Google Analytics }
// wallet.js self.doTransaction = function(address, action, data, onSuccess, onError) {
まとめ
次回はCounterwalletが使用しているフロントエンド用パッケージ管理ツール"Bower"について書きます。