fix pubkey indexing in imported wallets

This commit is contained in:
ThomasV 2016-10-12 12:03:56 +02:00
parent f4d5efbf3b
commit f0611c4569
3 changed files with 55 additions and 32 deletions

View File

@ -95,9 +95,9 @@ class AddressList(MyTreeWidget):
address_item.addChild(utxo_item)
def create_menu(self, position):
from electrum.wallet import Multisig_Wallet, Imported_Wallet
from electrum.wallet import Multisig_Wallet
is_multisig = isinstance(self.wallet, Multisig_Wallet)
is_imported = isinstance(self.wallet, Imported_Wallet)
can_delete = self.wallet.can_delete_address()
selected = self.selectedItems()
multi_select = len(selected) > 1
addrs = [unicode(item.text(0)) for item in selected]
@ -131,7 +131,7 @@ class AddressList(MyTreeWidget):
if not is_multisig and not self.wallet.is_watching_only():
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:
if can_delete:
menu.addAction(_("Remove from wallet"), lambda: self.parent.remove_address(addr))
addr_URL = block_explorer_URL(self.config, 'addr', addr)
if addr_URL:

View File

@ -116,8 +116,6 @@ class Imported_KeyStore(Software_KeyStore):
def __init__(self, d):
Software_KeyStore.__init__(self)
self.keypairs = d.get('keypairs', {})
self.receiving_pubkeys = self.keypairs.keys()
self.change_pubkeys = []
def is_deterministic(self):
return False
@ -138,7 +136,8 @@ class Imported_KeyStore(Software_KeyStore):
return True
def check_password(self, password):
self.get_private_key((0,0), password)
pubkey = self.keypairs.keys()[0]
self.get_private_key(pubkey, password)
def import_key(self, sec, password):
try:
@ -147,24 +146,12 @@ class Imported_KeyStore(Software_KeyStore):
raise BaseException('Invalid private key')
# allow overwrite
self.keypairs[pubkey] = pw_encode(sec, password)
self.receiving_pubkeys = self.keypairs.keys()
return pubkey
def delete_imported_key(self, key):
self.keypairs.pop(key)
def get_public_key(self, sequence):
for_change, i = sequence
pubkey = (self.change_pubkeys if for_change else self.receiving_pubkeys)[i]
return pubkey
def get_xpubkey(self, c, i):
return self.get_public_key((c,i))
def get_private_key(self, sequence, password):
for_change, i = sequence
assert for_change == 0
pubkey = self.receiving_pubkeys[i]
def get_private_key(self, pubkey, password):
pk = pw_decode(self.keypairs[pubkey], password)
# this checks the password
if pubkey != public_key_from_private_key(pk):
@ -173,15 +160,14 @@ class Imported_KeyStore(Software_KeyStore):
def get_pubkey_derivation(self, x_pubkey):
if x_pubkey[0:2] in ['02', '03', '04']:
if x_pubkey in self.receiving_pubkeys:
i = self.receiving_pubkeys.index(x_pubkey)
return (False, i)
if x_pubkey in self.keypairs.keys():
return x_pubkey
elif x_pubkey[0:2] == 'fd':
# fixme: this assumes p2pkh
_, addr = xpubkey_to_address(x_pubkey)
for i, pubkey in enumerate(self.receiving_pubkeys):
for pubkey in self.keypairs.keys():
if public_key_to_bc_address(pubkey.decode('hex')) == addr:
return (False, i)
return pubkey
def update_password(self, old_password, new_password):
self.check_password(old_password)

View File

@ -269,8 +269,23 @@ class Abstract_Wallet(PrintError):
def get_private_key(self, address, password):
if self.is_watching_only():
return []
sequence = self.get_address_index(address)
return [ self.keystore.get_private_key(sequence, password) ]
if self.keystore.can_import():
i = self.receiving_addresses.index(address)
pubkey = self.receiving_pubkeys[i]
pk = self.keystore.get_private_key(pubkey, password)
else:
sequence = self.get_address_index(address)
pk = self.keystore.get_private_key(sequence, password)
return [pk]
def get_public_key(self, address):
if self.keystore.can_import():
i = self.receiving_addresses.index(address)
pubkey = self.receiving_pubkeys[i]
else:
sequence = self.get_address_index(address)
pubkey = self.get_pubkey(*sequence)
return pubkey
def get_public_keys(self, address):
sequence = self.get_address_index(address)
@ -1170,7 +1185,6 @@ class Abstract_Wallet(PrintError):
self.receive_requests[key] = req
self.storage.put('payment_requests', self.receive_requests)
def add_payment_request(self, req, config):
import os
addr = req['address']
@ -1231,6 +1245,9 @@ class Abstract_Wallet(PrintError):
def can_import_address(self):
return False
def can_delete_address(self):
return False
def add_address(self, address):
if address not in self.history:
self.history[address] = []
@ -1302,6 +1319,9 @@ class Imported_Wallet(Abstract_Wallet):
self.add_address(address)
return address
def can_delete_address(self):
return True
def delete_address(self, address):
if address not in self.addresses:
return
@ -1336,8 +1356,7 @@ class P2PK_Wallet(Abstract_Wallet):
return pubkey_list[i]
def get_public_keys(self, address):
sequence = self.get_address_index(address)
return [self.get_pubkey(*sequence)]
return [self.get_public_key(address)]
def get_pubkey_index(self, pubkey):
if pubkey in self.receiving_pubkeys:
@ -1347,9 +1366,15 @@ class P2PK_Wallet(Abstract_Wallet):
raise BaseExeption('pubkey not found')
def add_input_sig_info(self, txin, address):
txin['derivation'] = derivation = self.get_address_index(address)
x_pubkey = self.keystore.get_xpubkey(*derivation)
pubkey = self.get_pubkey(*derivation)
if not self.keystore.can_import():
txin['derivation'] = derivation = self.get_address_index(address)
x_pubkey = self.keystore.get_xpubkey(*derivation)
pubkey = self.get_pubkey(*derivation)
else:
pubkey = self.get_public_key(address)
assert pubkey is not None
x_pubkey = pubkey
txin['x_pubkeys'] = [x_pubkey]
txin['pubkeys'] = [pubkey]
txin['signatures'] = [None]
@ -1527,6 +1552,17 @@ class Standard_Wallet(Deterministic_Wallet, P2PK_Wallet):
def save_keystore(self):
self.storage.put('keystore', self.keystore.dump())
def can_delete_address(self):
return self.keystore.can_import()
def delete_address(self, address):
pubkey = self.get_public_key(address)
self.keystore.delete_imported_key(pubkey)
self.save_keystore()
self.receiving_pubkeys.remove(pubkey)
self.receiving_addresses.remove(addr)
self.storage.write()
def can_import_privkey(self):
return self.keystore.can_import()
@ -1537,6 +1573,7 @@ class Standard_Wallet(Deterministic_Wallet, P2PK_Wallet):
self.save_pubkeys()
addr = self.pubkeys_to_address(pubkey)
self.receiving_addresses.append(addr)
self.storage.write()
self.add_address(addr)
return addr