electrum

Electrum Bitcoin wallet
git clone https://git.parazyd.org/electrum
Log | Files | Refs | Submodules

commit 255458da0af34d75f7b49803cf5e90fdf3bf26c5
parent b1083572cafbe6ae7f489dcf12843068dac95ab1
Author: ThomasV <thomasv@electrum.org>
Date:   Sun,  2 Jul 2017 11:44:48 +0200

fix #2400

Diffstat:
Melectrum | 6++----
Mlib/commands.py | 68++++++++++++++++++++++++++++++++------------------------------------
Mlib/daemon.py | 4++--
3 files changed, 36 insertions(+), 42 deletions(-)

diff --git a/electrum b/electrum @@ -280,10 +280,8 @@ def run_offline_command(config, config_options): # decode json arguments args = map(json_decode, args) # options - args += map(lambda x: config.get(x), cmd.options) - cmd_runner = Commands(config, wallet, None, - password=config_options.get('password'), - new_password=config_options.get('new_password')) + args += map(lambda x: (config_options.get(x) if x in ['password', 'new_password'] else config.get(x)), cmd.options) + cmd_runner = Commands(config, wallet, None) func = getattr(cmd_runner, cmd.name) result = func(*args) # save wallet diff --git a/lib/commands.py b/lib/commands.py @@ -87,23 +87,21 @@ def command(s): class Commands: - def __init__(self, config, wallet, network, callback = None, password=None, new_password=None): + def __init__(self, config, wallet, network, callback = None): self.config = config self.wallet = wallet self.network = network self._callback = callback - self._password = password - self.new_password = new_password def _run(self, method, args, password_getter): + # this wrapper is called from the python console cmd = known_commands[method] if cmd.requires_password and self.wallet.has_password(): - self._password = apply(password_getter,()) - if self._password is None: + password = apply(password_getter, ()) + if password is None: return f = getattr(self, method) - result = f(*args) - self._password = None + result = f(*args, **{'password':password}) if self._callback: apply(self._callback, ()) return result @@ -127,11 +125,11 @@ class Commands: raise BaseException('Not a JSON-RPC command') @command('wp') - def password(self): + def password(self, password=None, new_password=None): """Change wallet password. """ - self.wallet.update_password(self._password, self.new_password) + self.wallet.update_password(password, new_password) self.wallet.storage.write() - return {'password':self.wallet.use_encryption} + return {'password':self.wallet.has_password()} @command('') def getconfig(self, key): @@ -225,7 +223,7 @@ class Commands: return tx.as_dict() @command('wp') - def signtransaction(self, tx, privkey=None): + def signtransaction(self, tx, privkey=None, password=None): """Sign a transaction. The wallet keys will be used unless a private key is provided.""" tx = Transaction(tx) if privkey: @@ -234,7 +232,7 @@ class Commands: x_pubkey = 'fd' + (chr(0) + h160).encode('hex') tx.sign({x_pubkey:privkey}) else: - self.wallet.sign_transaction(tx, self._password) + self.wallet.sign_transaction(tx, password) return tx.as_dict() @command('') @@ -268,12 +266,12 @@ class Commands: return self.wallet.set_frozen_state([address], False) @command('wp') - def getprivatekeys(self, address): + def getprivatekeys(self, address, password=None): """Get private keys of addresses. You may pass a single wallet address, or a list of wallet addresses.""" if is_address(address): - return self.wallet.get_private_key(address, self._password) + return self.wallet.get_private_key(address, password) domain = address - return [self.wallet.get_private_key(address, self._password) for address in domain] + return [self.wallet.get_private_key(address, password) for address in domain] @command('w') def ismine(self, address): @@ -348,23 +346,23 @@ class Commands: return self.wallet.get_master_public_key() @command('wp') - def getmasterprivate(self): + def getmasterprivate(self, password=None): """Get master private key. Return your wallet\'s master private key""" - return str(self.wallet.keystore.get_master_private_key(self._password)) + return str(self.wallet.keystore.get_master_private_key(password)) @command('wp') - def getseed(self): + def getseed(self, password=None): """Get seed phrase. Print the generation seed of your wallet.""" - s = self.wallet.get_seed(self._password) + s = self.wallet.get_seed(password) return s.encode('utf8') @command('wp') - def importprivkey(self, privkey): + def importprivkey(self, privkey, password=None): """Import a private key. """ if not self.wallet.can_import_privkey(): return "Error: This type of wallet cannot import private keys. Try to create a new wallet with that key." try: - addr = self.wallet.import_key(privkey, self._password) + addr = self.wallet.import_key(privkey, password) out = "Keypair imported: " + addr except BaseException as e: out = "Error: " + str(e) @@ -391,10 +389,10 @@ class Commands: return tx.as_dict() if tx else None @command('wp') - def signmessage(self, address, message): + def signmessage(self, address, message, password=None): """Sign a message with a key. Use quotes if your message contains whitespaces""" - sig = self.wallet.sign_message(address, message, self._password) + sig = self.wallet.sign_message(address, message, password) return base64.b64encode(sig) @command('') @@ -403,7 +401,7 @@ class Commands: sig = base64.b64decode(signature) return bitcoin.verify_message(address, sig, message) - def _mktx(self, outputs, fee, change_addr, domain, nocheck, unsigned, rbf): + def _mktx(self, outputs, fee, change_addr, domain, nocheck, unsigned, rbf, password): self.nocheck = nocheck change_addr = self._resolver(change_addr) domain = None if domain is None else map(self._resolver, domain) @@ -418,23 +416,23 @@ class Commands: if rbf: tx.set_rbf(True) if not unsigned: - self.wallet.sign_transaction(tx, self._password) + self.wallet.sign_transaction(tx, password) return tx @command('wp') - def payto(self, destination, amount, tx_fee=None, from_addr=None, change_addr=None, nocheck=False, unsigned=False, rbf=False): + def payto(self, destination, amount, tx_fee=None, from_addr=None, change_addr=None, nocheck=False, unsigned=False, rbf=False, password=None): """Create a transaction. """ tx_fee = satoshis(tx_fee) domain = [from_addr] if from_addr else None - tx = self._mktx([(destination, amount)], tx_fee, change_addr, domain, nocheck, unsigned, rbf) + tx = self._mktx([(destination, amount)], tx_fee, change_addr, domain, nocheck, unsigned, rbf, password) return tx.as_dict() @command('wp') - def paytomany(self, outputs, tx_fee=None, from_addr=None, change_addr=None, nocheck=False, unsigned=False, rbf=False): + def paytomany(self, outputs, tx_fee=None, from_addr=None, change_addr=None, nocheck=False, unsigned=False, rbf=False, password=None): """Create a multi-output transaction. """ tx_fee = satoshis(tx_fee) domain = [from_addr] if from_addr else None - tx = self._mktx(outputs, tx_fee, change_addr, domain, nocheck, unsigned, rbf) + tx = self._mktx(outputs, tx_fee, change_addr, domain, nocheck, unsigned, rbf, password) return tx.as_dict() @command('w') @@ -546,9 +544,9 @@ class Commands: return bitcoin.encrypt_message(message, pubkey) @command('wp') - def decrypt(self, pubkey, encrypted): + def decrypt(self, pubkey, encrypted, password=None): """Decrypt a message encrypted with a public key.""" - return self.wallet.decrypt_message(pubkey, encrypted, self._password) + return self.wallet.decrypt_message(pubkey, encrypted, password) def _format_request(self, out): pr_str = { @@ -620,13 +618,13 @@ class Commands: return self._format_request(out) @command('wp') - def signrequest(self, address): + def signrequest(self, address, password=None): "Sign payment request with an OpenAlias" alias = self.config.get('alias') if not alias: raise BaseException('No alias in your configuration') alias_addr = self.wallet.contacts.resolve(alias)['address'] - self.wallet.sign_payment_request(address, alias, alias_addr, self._password) + self.wallet.sign_payment_request(address, alias, alias_addr, password) @command('w') def rmrequest(self, address): @@ -685,6 +683,7 @@ param_descriptions = { command_options = { 'password': ("-W", "--password", "Password"), + 'new_password':(None, "--new_password","New Password"), 'receiving': (None, "--receiving", "Show only receiving addresses"), 'change': (None, "--change", "Show only change addresses"), 'frozen': (None, "--frozen", "Show only frozen addresses"), @@ -840,9 +839,6 @@ def get_parser(): add_global_options(p) if cmdname == 'restore': p.add_argument("-o", "--offline", action="store_true", dest="offline", default=False, help="Run offline") - #p.set_defaults(func=run_cmdline) - if cmd.requires_password: - p.add_argument("-W", "--password", dest="password", default=None, help="password") for optname, default in zip(cmd.options, cmd.defaults): a, b, help = command_options[optname] action = "store_true" if type(default) is bool else 'store' diff --git a/lib/daemon.py b/lib/daemon.py @@ -252,8 +252,8 @@ class Daemon(DaemonThread): # decode json arguments args = map(json_decode, args) # options - args += map(lambda x: config.get(x), cmd.options) - cmd_runner = Commands(config, wallet, self.network, password=password, new_password=new_password) + args += map(lambda x: (config_options.get(x) if x in ['password', 'new_password'] else config.get(x)), cmd.options) + cmd_runner = Commands(config, wallet, self.network) func = getattr(cmd_runner, cmd.name) result = func(*args) return result