@ -55,8 +55,8 @@ def pw_decode(s, password):
secret = Hash ( password )
secret = Hash ( password )
try :
try :
d = DecodeAES ( secret , s )
d = DecodeAES ( secret , s )
except :
except Exception :
raise Base Exception( ' Invalid password ' )
raise Exception ( ' Invalid password ' )
return d
return d
else :
else :
return s
return s
@ -117,7 +117,7 @@ class WalletStorage:
return
return
try :
try :
d = ast . literal_eval ( data ) #parse raw data from reading wallet file
d = ast . literal_eval ( data ) #parse raw data from reading wallet file
except :
except Exception :
raise IOError ( " Cannot read wallet file. " )
raise IOError ( " Cannot read wallet file. " )
self . data = d
self . data = d
@ -192,7 +192,7 @@ class Wallet:
for k , v in tx_list . items ( ) :
for k , v in tx_list . items ( ) :
try :
try :
tx = Transaction ( v )
tx = Transaction ( v )
except :
except Exception :
print_msg ( " Warning: Cannot deserialize transactions. skipping " )
print_msg ( " Warning: Cannot deserialize transactions. skipping " )
continue
continue
@ -256,11 +256,11 @@ class Wallet:
seed = self . get_seed ( password )
seed = self . get_seed ( password )
try :
try :
address = address_from_private_key ( sec )
address = address_from_private_key ( sec )
except :
except Exception :
raise Base Exception( ' Invalid private key ' )
raise Exception ( ' Invalid private key ' )
if self . is_mine ( address ) :
if self . is_mine ( address ) :
raise Base Exception( ' Address already in wallet ' )
raise Exception ( ' Address already in wallet ' )
# store the originally requested keypair into the imported keys table
# store the originally requested keypair into the imported keys table
self . imported_keys [ address ] = pw_encode ( sec , password )
self . imported_keys [ address ] = pw_encode ( sec , password )
@ -296,7 +296,7 @@ class Wallet:
import mnemonic
import mnemonic
if self . seed :
if self . seed :
raise Base Exception( " a seed exists " )
raise Exception ( " a seed exists " )
if not seed :
if not seed :
self . seed = random_seed ( 128 )
self . seed = random_seed ( 128 )
@ -314,7 +314,7 @@ class Wallet:
self . seed_version = 4
self . seed_version = 4
self . seed = str ( seed )
self . seed = str ( seed )
return
return
except :
except Exception :
pass
pass
words = seed . split ( )
words = seed . split ( )
@ -324,7 +324,7 @@ class Wallet:
#try:
#try:
# mnemonic.mn_decode(words)
# mnemonic.mn_decode(words)
# uses_electrum_words = True
# uses_electrum_words = True
#except:
#except Exception :
# uses_electrum_words = False
# uses_electrum_words = False
#
#
#if uses_electrum_words and len(words) != 13:
#if uses_electrum_words and len(words) != 13:
@ -347,6 +347,7 @@ class Wallet:
if not c0 :
if not c0 :
self . seed_version = 4
self . seed_version = 4
self . storage . put ( ' seed_version ' , self . seed_version , True )
self . create_old_account ( K0 )
self . create_old_account ( K0 )
return
return
@ -355,6 +356,7 @@ class Wallet:
" m/0 ' / " : ( c0 , K0 , cK0 ) ,
" m/0 ' / " : ( c0 , K0 , cK0 ) ,
}
}
self . storage . put ( ' master_public_keys ' , self . master_public_keys , True )
self . storage . put ( ' master_public_keys ' , self . master_public_keys , True )
self . storage . put ( ' seed_version ' , self . seed_version , True )
self . create_account ( ' 1 ' , ' Main account ' )
self . create_account ( ' 1 ' , ' Main account ' )
@ -436,7 +438,7 @@ class Wallet:
elif account_type == ' 2of3 ' :
elif account_type == ' 2of3 ' :
return " m/3 ' / %d & m/4 ' / %d & m/5 ' / %d " % ( i , i , i )
return " m/3 ' / %d & m/4 ' / %d & m/5 ' / %d " % ( i , i , i )
else :
else :
raise Base Exception( ' unknown account type ' )
raise Exception ( ' unknown account type ' )
def num_accounts ( self , account_type ) :
def num_accounts ( self , account_type ) :
@ -606,8 +608,8 @@ class Wallet:
try :
try :
K , Kc = get_pubkeys_from_secret ( master_k . decode ( ' hex ' ) )
K , Kc = get_pubkeys_from_secret ( master_k . decode ( ' hex ' ) )
assert K . encode ( ' hex ' ) == master_K
assert K . encode ( ' hex ' ) == master_K
except :
except Exception :
raise Base Exception( " Invalid password " )
raise Exception ( " Invalid password " )
return master_k
return master_k
@ -626,7 +628,7 @@ class Wallet:
if v == address :
if v == address :
return k , ( 0 , 0 )
return k , ( 0 , 0 )
raise Base Exception( " Address not found " , address )
raise Exception ( " Address not found " , address )
def get_roots ( self , account ) :
def get_roots ( self , account ) :
@ -678,9 +680,9 @@ class Wallet:
s = pw_decode ( self . seed , password )
s = pw_decode ( self . seed , password )
if self . seed_version == 4 :
if self . seed_version == 4 :
seed = s
seed = s
self . accounts [ 0 ] . check_seed ( seed )
else :
else :
seed = mnemonic_hash ( s )
seed = mnemonic_hash ( s )
#todo: #self.sequences[0].check_seed(seed)
return seed
return seed
@ -695,13 +697,15 @@ class Wallet:
def get_private_key ( self , address , password ) :
def get_private_key ( self , address , password ) :
# first check the provided password
seed = self . get_seed ( password )
out = [ ]
out = [ ]
if address in self . imported_keys . keys ( ) :
if address in self . imported_keys . keys ( ) :
out . append ( pw_decode ( self . imported_keys [ address ] , password ) )
out . append ( pw_decode ( self . imported_keys [ address ] , password ) )
else :
else :
account , sequence = self . get_address_index ( address )
account , sequence = self . get_address_index ( address )
if account == 0 :
if account == 0 :
seed = self . get_seed ( password )
pk = self . accounts [ account ] . get_private_key ( seed , sequence )
pk = self . accounts [ account ] . get_private_key ( seed , sequence )
out . append ( pk )
out . append ( pk )
return out
return out
@ -1108,7 +1112,7 @@ class Wallet:
if h == [ ' * ' ] : continue
if h == [ ' * ' ] : continue
for tx_hash , tx_height in h :
for tx_hash , tx_height in h :
tx = self . transactions . get ( tx_hash )
tx = self . transactions . get ( tx_hash )
if tx is None : raise Base Exception( " Wallet not synchronized " )
if tx is None : raise Exception ( " Wallet not synchronized " )
is_coinbase = tx . inputs [ 0 ] . get ( ' prevout_hash ' ) == ' 0 ' * 64
is_coinbase = tx . inputs [ 0 ] . get ( ' prevout_hash ' ) == ' 0 ' * 64
for output in tx . d . get ( ' outputs ' ) :
for output in tx . d . get ( ' outputs ' ) :
if output . get ( ' address ' ) != addr : continue
if output . get ( ' address ' ) != addr : continue
@ -1243,7 +1247,7 @@ class Wallet:
def receive_history_callback ( self , addr , hist ) :
def receive_history_callback ( self , addr , hist ) :
if not self . check_new_history ( addr , hist ) :
if not self . check_new_history ( addr , hist ) :
raise Base Exception( " error: received history for %s is not consistent with known transactions " % addr )
raise Exception ( " error: received history for %s is not consistent with known transactions " % addr )
with self . lock :
with self . lock :
self . history [ addr ] = hist
self . history [ addr ] = hist
@ -1406,8 +1410,7 @@ class Wallet:
def update_password ( self , old_password , new_password ) :
def update_password ( self , old_password , new_password ) :
if new_password == ' ' : new_password = None
if new_password == ' ' : new_password = None
# this will throw an exception if unicode cannot be converted
decoded = self . get_seed ( old_password )
decoded = pw_decode ( self . seed , old_password )
self . seed = pw_encode ( decoded , new_password )
self . seed = pw_encode ( decoded , new_password )
self . storage . put ( ' seed ' , self . seed , True )
self . storage . put ( ' seed ' , self . seed , True )
self . use_encryption = ( new_password != None )
self . use_encryption = ( new_password != None )
@ -1752,12 +1755,12 @@ class WalletSynchronizer(threading.Thread):
hist . append ( ( tx_hash , item [ ' height ' ] ) )
hist . append ( ( tx_hash , item [ ' height ' ] ) )
if len ( hist ) != len ( result ) :
if len ( hist ) != len ( result ) :
raise Base Exception( " error: server sent history with non-unique txid " , result )
raise Exception ( " error: server sent history with non-unique txid " , result )
# check that the status corresponds to what was announced
# check that the status corresponds to what was announced
rs = requested_histories . pop ( addr )
rs = requested_histories . pop ( addr )
if self . wallet . get_status ( hist ) != rs :
if self . wallet . get_status ( hist ) != rs :
raise Base Exception( " error: status mismatch: %s " % addr )
raise Exception ( " error: status mismatch: %s " % addr )
# store received history
# store received history
self . wallet . receive_history_callback ( addr , hist )
self . wallet . receive_history_callback ( addr , hist )