separate create and restore; allow user to create a wallet when offline
This commit is contained in:
parent
ec9118da42
commit
0dc3c595a5
@ -27,7 +27,7 @@ from decimal import Decimal
|
|||||||
from wallet import format_satoshis
|
from wallet import format_satoshis
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
known_commands = ['help', 'validateaddress', 'balance', 'contacts', 'create', 'payto', 'sendtx', 'password', 'newaddress', 'addresses', 'history', 'label', 'mktx','seed','import','signmessage','verifymessage','eval', 'gtk','qt']
|
known_commands = ['help', 'validateaddress', 'balance', 'contacts', 'create', 'restore', 'payto', 'sendtx', 'password', 'addresses', 'history', 'label', 'mktx','seed','import','signmessage','verifymessage','eval', 'gtk','qt']
|
||||||
|
|
||||||
usage = "usage: %prog [options] command args\nCommands: "+ (', '.join(known_commands))
|
usage = "usage: %prog [options] command args\nCommands: "+ (', '.join(known_commands))
|
||||||
|
|
||||||
@ -88,12 +88,13 @@ if __name__ == '__main__':
|
|||||||
if cmd not in known_commands:
|
if cmd not in known_commands:
|
||||||
cmd = 'help'
|
cmd = 'help'
|
||||||
|
|
||||||
if not wallet.read() and cmd not in ['help','create']:
|
if not wallet.read() and cmd not in ['help','create','restore']:
|
||||||
print "Wallet file not found."
|
print "Wallet file not found."
|
||||||
print "Type 'electrum.py create' to create a new wallet, or provide a path to a wallet with the -d option"
|
print "Type 'electrum.py create' to create a new wallet, or provide a path to a wallet with the -d option"
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
if cmd == 'create':
|
if cmd in ['create', 'restore']:
|
||||||
|
import mnemonic
|
||||||
if wallet.read():
|
if wallet.read():
|
||||||
print "remove the existing wallet first!"
|
print "remove the existing wallet first!"
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
@ -110,27 +111,38 @@ if __name__ == '__main__':
|
|||||||
port = raw_input("port (default:%d):"%interface.port)
|
port = raw_input("port (default:%d):"%interface.port)
|
||||||
fee = raw_input("fee (default:%s):"%( str(Decimal(wallet.fee)/100000000)) )
|
fee = raw_input("fee (default:%s):"%( str(Decimal(wallet.fee)/100000000)) )
|
||||||
gap = raw_input("gap limit (default 5):")
|
gap = raw_input("gap limit (default 5):")
|
||||||
if fee: wallet.fee = float(fee)
|
|
||||||
if host: interface.host = host
|
if host: interface.host = host
|
||||||
if port: interface.port = int(port)
|
if port: interface.port = int(port)
|
||||||
|
if fee: wallet.fee = float(fee)
|
||||||
if gap: wallet.gap_limit = int(gap)
|
if gap: wallet.gap_limit = int(gap)
|
||||||
seed = raw_input("if you are restoring an existing wallet, enter the seed. otherwise just press enter: ")
|
|
||||||
if seed:
|
if cmd == 'restore':
|
||||||
wallet.seed = seed
|
seed = raw_input("seed:")
|
||||||
|
try:
|
||||||
|
seed.decode('hex')
|
||||||
|
except:
|
||||||
|
print "not hex, trying decode"
|
||||||
|
seed = mnemonic.mn_decode( seed.split(' ') )
|
||||||
|
if not seed:
|
||||||
|
print "no seed"
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
wallet.seed = str(seed)
|
||||||
print "recovering wallet..."
|
print "recovering wallet..."
|
||||||
|
wallet.init_mpk( wallet.seed ) # not encrypted at this point
|
||||||
wallet.synchronize()
|
wallet.synchronize()
|
||||||
if wallet.is_found():
|
if wallet.is_found():
|
||||||
wallet.fill_addressbook()
|
wallet.fill_addressbook()
|
||||||
wallet.save()
|
wallet.save()
|
||||||
print "recovery successful"
|
print "recovery successful"
|
||||||
else:
|
else:
|
||||||
print "no wallet found"
|
print "found no history for this wallet"
|
||||||
else:
|
else:
|
||||||
wallet.new_seed(None)
|
wallet.new_seed(None)
|
||||||
print "Your seed is", wallet.seed
|
print "Your wallet generation seed is: " + wallet.seed
|
||||||
print "Please store it safely"
|
print "Please keep it in a safe place; if you lose it, you will not be able to restore your wallet."
|
||||||
# generate first key
|
print "Equivalently, your wallet seed can be stored and recovered with the following mnemonic code:"
|
||||||
wallet.synchronize()
|
print "\""+' '.join(mnemonic.mn_encode(wallet.seed))+"\""
|
||||||
|
|
||||||
# check syntax
|
# check syntax
|
||||||
if cmd in ['payto', 'mktx']:
|
if cmd in ['payto', 'mktx']:
|
||||||
@ -197,8 +209,6 @@ if __name__ == '__main__':
|
|||||||
print "broadcast a transaction to the network. <tx> must be in hexadecimal"
|
print "broadcast a transaction to the network. <tx> must be in hexadecimal"
|
||||||
elif cmd2 == 'password':
|
elif cmd2 == 'password':
|
||||||
print "change your password"
|
print "change your password"
|
||||||
elif cmd2 == 'newaddress':
|
|
||||||
print "create a new receiving address. password is needed."
|
|
||||||
elif cmd2 == 'addresses':
|
elif cmd2 == 'addresses':
|
||||||
print "show your list of addresses. options: -a, -k, -b"
|
print "show your list of addresses. options: -a, -k, -b"
|
||||||
elif cmd2 == 'history':
|
elif cmd2 == 'history':
|
||||||
@ -350,10 +360,6 @@ if __name__ == '__main__':
|
|||||||
r, h = wallet.sendtx( tx )
|
r, h = wallet.sendtx( tx )
|
||||||
print h
|
print h
|
||||||
|
|
||||||
elif cmd == 'newaddress':
|
|
||||||
s, a = wallet.get_new_address()
|
|
||||||
print a
|
|
||||||
|
|
||||||
elif cmd == 'password':
|
elif cmd == 'password':
|
||||||
try:
|
try:
|
||||||
seed = wallet.pw_decode( wallet.seed, password)
|
seed = wallet.pw_decode( wallet.seed, password)
|
||||||
|
|||||||
@ -303,6 +303,12 @@ class Wallet:
|
|||||||
# encrypt
|
# encrypt
|
||||||
self.seed = self.pw_encode( seed, password )
|
self.seed = self.pw_encode( seed, password )
|
||||||
|
|
||||||
|
# create addresses
|
||||||
|
self.create_new_address_without_history(True)
|
||||||
|
for i in range(self.gap_limit):
|
||||||
|
self.create_new_address_without_history(False)
|
||||||
|
|
||||||
|
|
||||||
def init_mpk(self,seed):
|
def init_mpk(self,seed):
|
||||||
# public key
|
# public key
|
||||||
curve = SECP256k1
|
curve = SECP256k1
|
||||||
@ -418,7 +424,7 @@ class Wallet:
|
|||||||
raise BaseException("Bad signature")
|
raise BaseException("Bad signature")
|
||||||
|
|
||||||
|
|
||||||
def create_new_address(self, for_change):
|
def create_new_address_without_history(self, for_change):
|
||||||
""" Publickey(type,n) = Master_public_key + H(n|S|type)*point """
|
""" Publickey(type,n) = Master_public_key + H(n|S|type)*point """
|
||||||
curve = SECP256k1
|
curve = SECP256k1
|
||||||
n = len(self.change_addresses) if for_change else len(self.addresses)
|
n = len(self.change_addresses) if for_change else len(self.addresses)
|
||||||
@ -432,8 +438,14 @@ class Wallet:
|
|||||||
else:
|
else:
|
||||||
self.addresses.append(address)
|
self.addresses.append(address)
|
||||||
|
|
||||||
# updates
|
self.history[address] = []
|
||||||
|
self.status[address] = None
|
||||||
print address
|
print address
|
||||||
|
return address
|
||||||
|
|
||||||
|
|
||||||
|
def create_new_address(self, bool):
|
||||||
|
address = self.create_new_address_without_history(bool)
|
||||||
self.history[address] = h = self.interface.retrieve_history(address)
|
self.history[address] = h = self.interface.retrieve_history(address)
|
||||||
self.status[address] = h[-1]['blk_hash'] if h else None
|
self.status[address] = h[-1]['blk_hash'] if h else None
|
||||||
return address
|
return address
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user