fix pubkey indexing in imported wallets
This commit is contained in:
parent
f4d5efbf3b
commit
f0611c4569
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue