electrum

Electrum Bitcoin wallet
git clone https://git.parazyd.org/electrum
Log | Files | Refs | Submodules

commit f6e393d7b602029aad82fc138abd5e5f32390d91
parent 5733a5d125266fd596922cdf7c1019c520c28272
Author: ThomasV <thomasv@electrum.org>
Date:   Wed, 17 Aug 2016 10:39:30 +0200

fix: import addresses and private keys

Diffstat:
Mgui/qt/address_list.py | 2+-
Mgui/qt/main_window.py | 55+++++++++++++++++++++++++++++++------------------------
Mlib/base_wizard.py | 2+-
Mlib/wallet.py | 36++++++++++++++++++++----------------
4 files changed, 53 insertions(+), 42 deletions(-)

diff --git a/gui/qt/address_list.py b/gui/qt/address_list.py @@ -132,7 +132,7 @@ class AddressList(MyTreeWidget): menu.addAction(_("Sign/verify message"), lambda: self.parent.sign_verify_message(addr)) menu.addAction(_("Encrypt/decrypt message"), lambda: self.parent.encrypt_message(addr)) if is_imported: - menu.addAction(_("Remove from wallet"), lambda: self.parent.delete_imported_key(addr)) + menu.addAction(_("Remove from wallet"), lambda: self.parent.remove_address(addr)) addr_URL = block_explorer_URL(self.config, 'addr', addr) if addr_URL: menu.addAction(_("View on block explorer"), lambda: webbrowser.open(addr_URL)) diff --git a/gui/qt/main_window.py b/gui/qt/main_window.py @@ -297,7 +297,8 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError): title += ' [%s]' % (_('watching only')) self.setWindowTitle(title) self.password_menu.setEnabled(self.wallet.can_change_password()) - self.import_menu.setVisible(self.wallet.can_import()) + self.import_privkey_menu.setVisible(self.wallet.can_import_privkey()) + self.import_address_menu.setVisible(self.wallet.can_import_address()) self.export_menu.setEnabled(self.wallet.can_export()) def warn_if_watching_only(self): @@ -395,8 +396,9 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError): self.private_keys_menu = wallet_menu.addMenu(_("&Private keys")) self.private_keys_menu.addAction(_("&Sweep"), self.sweep_key_dialog) - self.import_menu = self.private_keys_menu.addAction(_("&Import"), self.do_import_privkey) + self.import_privkey_menu = self.private_keys_menu.addAction(_("&Import"), self.do_import_privkey) self.export_menu = self.private_keys_menu.addAction(_("&Export"), self.export_privkeys_dialog) + self.import_address_menu = wallet_menu.addAction(_("Import addresses"), self.import_addresses) wallet_menu.addAction(_("&Export History"), self.export_history_dialog) wallet_menu.addAction(_("Search"), self.toggle_search).setShortcut(QKeySequence("Ctrl+S")) wallet_menu.addAction(_("Addresses"), self.toggle_addresses_tab).setShortcut(QKeySequence("Ctrl+A")) @@ -1408,9 +1410,9 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError): self.contact_list = l = ContactList(self) return self.create_list_tab(l) - def delete_imported_key(self, addr): + def remove_address(self, addr): if self.question(_("Do you want to remove")+" %s "%addr +_("from your wallet?")): - self.wallet.delete_imported_key(addr) + self.wallet.delete_address(addr) self.address_list.update() self.history_list.update() @@ -2196,34 +2198,39 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError): self.warn_if_watching_only() self.show_transaction(tx) - - @protected - def do_import_privkey(self, password): - if not self.wallet.keystore.can_import(): - return - text = text_dialog(self, _('Import private keys'), _("Enter private keys")+':', _("Import")) + def _do_import(self, title, msg, func): + text = text_dialog(self, title, msg + ' :', _('Import')) if not text: return - text = str(text).split() - badkeys = [] - addrlist = [] - for key in text: + bad = [] + good = [] + for key in str(text).split(): try: - addr = self.wallet.import_key(key, password) + addr = func(key) + good.append(addr) except BaseException as e: - badkeys.append(key) + bad.append(key) continue - if not addr: - badkeys.append(key) - else: - addrlist.append(addr) - if addrlist: - self.show_message(_("The following addresses were added") + ':\n' + '\n'.join(addrlist)) - if badkeys: - self.show_critical(_("The following inputs could not be imported") + ':\n'+ '\n'.join(badkeys)) + if good: + self.show_message(_("The following addresses were added") + ':\n' + '\n'.join(good)) + if bad: + self.show_critical(_("The following inputs could not be imported") + ':\n'+ '\n'.join(bad)) self.address_list.update() self.history_list.update() + def import_addresses(self): + if not self.wallet.can_import_address(): + return + title, msg = _('Import addresses'), _("Enter addresses") + self._do_import(title, msg, self.wallet.import_address) + + @protected + def do_import_privkey(self, password): + if not self.wallet.can_import_privkey(): + return + title, msg = _('Import private keys'), _("Enter private keys") + self._do_import(title, msg, lambda x: self.wallet.import_key(x, password)) + def settings_dialog(self): self.need_restart = False diff --git a/lib/base_wizard.py b/lib/base_wizard.py @@ -124,7 +124,7 @@ class BaseWizard(object): if keystore.is_address_list(text): self.wallet = Imported_Wallet(self.storage) for x in text.split(): - self.wallet.add_address(x) + self.wallet.import_address(x) self.terminate() elif keystore.is_private(text): self.add_password(text) diff --git a/lib/wallet.py b/lib/wallet.py @@ -1152,9 +1152,17 @@ class Abstract_Wallet(PrintError): def get_fingerprint(self): raise NotImplementedError() - def can_import(self): + def can_import_privkey(self): return False + def can_import_address(self): + return False + + def add_address(self, address): + if address not in self.history: + self.history[address] = [] + if self.synchronizer: + self.synchronizer.add(address) class Imported_Wallet(Abstract_Wallet): @@ -1177,7 +1185,7 @@ class Imported_Wallet(Abstract_Wallet): def can_change_password(self): return False - def can_import(self): + def can_import_address(self): return True def is_watching_only(self): @@ -1204,20 +1212,22 @@ class Imported_Wallet(Abstract_Wallet): def get_addresses(self, include_change=False): return self.addresses - def add_address(self, address): + def import_address(self, address): if address in self.addresses: return self.addresses.append(address) self.storage.put('addresses', self.addresses) self.storage.write() - - # force resynchronization, because we need to re-run add_transaction - if address in self.history: - self.history.pop(address) - if self.synchronizer: - self.synchronizer.add(address) + self.add_address(address) return address + def delete_address(self, address): + if address not in self.addresses: + return + self.addresses.remove(address) + self.storage.put('addresses', self.addresses) + self.storage.write() + def get_receiving_addresses(self): return self.addresses[:] @@ -1332,12 +1342,6 @@ class Deterministic_Wallet(Abstract_Wallet): if n > nmax: nmax = n return nmax + 1 - def add_address(self, address): - if address not in self.history: - self.history[address] = [] - if self.synchronizer: - self.synchronizer.add(address) - def create_new_address(self, for_change): pubkey_list = self.change_pubkeys if for_change else self.receiving_pubkeys n = len(pubkey_list) @@ -1432,7 +1436,7 @@ class Standard_Wallet(Deterministic_Wallet, P2PK_Wallet): self.keystore.update_password(old_pw, new_pw) self.keystore.save(self.storage, self.root_name) - def can_import(self): + def can_import_privkey(self): return self.keystore.can_import() def import_key(self, pk, pw):