separate class for bip32 HD

This commit is contained in:
ThomasV 2014-08-19 12:38:01 +02:00
parent 57e50ee326
commit cebc942ccb
1 changed files with 65 additions and 58 deletions

View File

@ -961,6 +961,10 @@ class Abstract_Wallet(object):
def get_accounts(self):
return self.accounts
def add_account(self, account_id, account):
self.accounts[account_id] = account
self.save_accounts()
def save_accounts(self):
d = {}
for k, v in self.accounts.items():
@ -1136,13 +1140,7 @@ class Deterministic_Wallet(Abstract_Wallet):
self.create_new_address(account, for_change)
def check_pending_accounts(self):
for account_id, addr in self.next_addresses.items():
if self.address_is_old(addr):
print_error( "creating account", account_id )
xpub = self.master_public_keys[account_id]
account = BIP32_Account({'xpub':xpub})
self.add_account(account_id, account)
self.next_addresses.pop(account_id)
pass
def synchronize_account(self, account):
self.synchronize_sequence(account, 0)
@ -1184,35 +1182,6 @@ class Deterministic_Wallet(Abstract_Wallet):
self.synchronize()
self.fill_addressbook()
def create_account(self, name, password):
i = self.num_accounts()
account_id = self.account_id(i)
account = self.make_account(account_id, password)
self.add_account(account_id, account)
if name:
self.set_label(account_id, name)
# add address of the next account
_, _ = self.next_account_address(password)
def add_account(self, account_id, account):
self.accounts[account_id] = account
self.save_accounts()
def account_is_pending(self, k):
return type(self.accounts.get(k)) == PendingAccount
def delete_pending_account(self, k):
assert self.account_is_pending(k)
self.accounts.pop(k)
self.save_accounts()
def create_pending_account(self, name, password):
account_id, addr = self.next_account_address(password)
self.set_label(account_id, name)
self.accounts[account_id] = PendingAccount({'pending':addr})
self.save_accounts()
def is_beyond_limit(self, address, account, is_change):
if type(account) == ImportedAccount:
@ -1236,7 +1205,9 @@ class Deterministic_Wallet(Abstract_Wallet):
return 'create_accounts'
class NewWallet(Deterministic_Wallet):
class BIP32_Wallet(Deterministic_Wallet):
# bip32 derivation
def __init__(self, storage):
Deterministic_Wallet.__init__(self, storage)
@ -1283,7 +1254,7 @@ class NewWallet(Deterministic_Wallet):
self.add_master_public_key(account_id, xpub)
self.add_account(account_id, account)
def create_watching_only_wallet(self, xpub):
def create_xpub_wallet(self, xpub):
account = BIP32_Account({'xpub':xpub})
account_id = 'm/' + bitcoin.get_xkey_name(xpub)
self.storage.put('seed_version', self.seed_version, True)
@ -1338,31 +1309,52 @@ class NewWallet(Deterministic_Wallet):
return True
return False
def num_accounts(self):
keys = []
for k, v in self.accounts.items():
if type(v) != BIP32_Account:
continue
keys.append(k)
i = 0
while True:
account_id = self.account_id(i)
if account_id not in keys: break
i += 1
return i
class BIP32_HD_Wallet(BIP32_Wallet):
# sequence of accounts
def create_account(self, name, password):
i = self.num_accounts()
account_id = self.account_id(i)
account = self.make_account(account_id, password)
self.add_account(account_id, account)
if name:
self.set_label(account_id, name)
# add address of the next account
_, _ = self.next_account_address(password)
def account_is_pending(self, k):
return type(self.accounts.get(k)) == PendingAccount
def delete_pending_account(self, k):
assert self.account_is_pending(k)
self.accounts.pop(k)
self.save_accounts()
def create_pending_account(self, name, password):
account_id, addr = self.next_account_address(password)
self.set_label(account_id, name)
self.accounts[account_id] = PendingAccount({'pending':addr})
self.save_accounts()
def check_pending_accounts(self):
for account_id, addr in self.next_addresses.items():
if self.address_is_old(addr):
print_error( "creating account", account_id )
xpub = self.master_public_keys[account_id]
account = BIP32_Account({'xpub':xpub})
self.add_account(account_id, account)
self.next_addresses.pop(account_id)
def next_account_address(self, password):
i = self.num_accounts()
account_id = self.account_id(i)
addr = self.next_addresses.get(account_id)
if not addr:
account = self.make_account(account_id, password)
addr = account.first_address()
self.next_addresses[account_id] = addr
self.storage.put('next_addresses', self.next_addresses)
return account_id, addr
def account_id(self, i):
@ -1374,6 +1366,22 @@ class NewWallet(Deterministic_Wallet):
account = BIP32_Account({'xpub':xpub})
return account
def num_accounts(self):
keys = []
for k, v in self.accounts.items():
if type(v) != BIP32_Account:
continue
keys.append(k)
i = 0
while True:
account_id = self.account_id(i)
if account_id not in keys: break
i += 1
return i
class NewWallet(BIP32_HD_Wallet):
# BIP39 seed generation
@classmethod
def make_seed(self, custom_entropy=1):
@ -1403,6 +1411,8 @@ class NewWallet(Deterministic_Wallet):
return NEW_SEED_VERSION, unicodedata.normalize('NFC', unicode(seed.strip()))
class Wallet_2of2(NewWallet):
""" This class is used for multisignature addresses"""
@ -1539,9 +1549,6 @@ class OldWallet(Deterministic_Wallet):
s = self.get_seed(password)
return ' '.join(mnemonic.mn_encode(s))
def check_pending_accounts(self):
pass
def can_sign(self, tx):
if self.is_watching_only():
return False
@ -1684,12 +1691,12 @@ class Wallet(object):
@classmethod
def from_xpub(self, xpub, storage):
w = NewWallet(storage)
w.create_watching_only_wallet(xpub)
w = BIP32_Wallet(storage)
w.create_xpub_wallet(xpub)
return w
@classmethod
def from_xprv(self, xprv, password, storage):
w = NewWallet(storage)
w = BIP32_Wallet(storage)
w.create_xprv_wallet(xprv, password)
return w