URI: 
       tuse dumpprivkeys to efficiently dump private keys - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit 96d459ab887757610d825670e567733a39cbfb5b
   DIR parent f58e54138436b810201d4dc4b2faf9384f78d84c
  HTML Author: thomasv <thomasv@gitorious>
       Date:   Tue, 26 Feb 2013 16:03:04 +0100
       
       use dumpprivkeys to efficiently dump private keys
       
       Diffstat:
         M electrum                            |      18 +++++++++++-------
         M lib/bitcoin.py                      |       7 +++++--
         M lib/commands.py                     |       9 ++++++---
         M lib/wallet.py                       |      30 ++++++++++++++++++------------
       
       4 files changed, 40 insertions(+), 24 deletions(-)
       ---
   DIR diff --git a/electrum b/electrum
       t@@ -89,6 +89,7 @@ options:\n  --fee, -f: set transaction fee\n  --fromaddr, -s: send from address 
            'prioritize':'',
            'unprioritize':'',
            'dumpprivkey':'similar to bitcoind\'s command',
       +    'dumpprivkeys':'dump all private keys',
            'listunspent':'similar to bitcoind\'s command',
            'createmultisig':'similar to bitcoind\'s command',
            'createrawtransaction':'similar to bitcoind\'s command',
       t@@ -138,7 +139,6 @@ def arg_parser():
            parser.add_option("-o", "--offline", action="store_true", dest="offline", default=False, help="remain offline")
            parser.add_option("-a", "--all", action="store_true", dest="show_all", default=False, help="show all addresses")
            parser.add_option("-b", "--balance", action="store_true", dest="show_balance", default=False, help="show the balance at listed addresses")
       -    parser.add_option("-k", "--keys",action="store_true", dest="show_keys",default=False, help="show the private keys of listed addresses")
            parser.add_option("-f", "--fee", dest="tx_fee", default="0.005", help="set tx fee")
            parser.add_option("-F", "--fromaddr", dest="from_addr", default=None, help="set source address for payto/mktx. if it isn't in the wallet, it will ask for the private key unless supplied in the format public_key:private_key. It's not saved in the wallet.")
            parser.add_option("-c", "--changeaddr", dest="change_addr", default=None, help="set the change address for payto/mktx. default is a spare address, or the source address if it's not in the wallet")
       t@@ -384,13 +384,13 @@ if __name__ == '__main__':
        
                        
            # important warning
       -    if cmd=='addresses' and options.show_keys:
       +    if cmd in ['dumpprivkey', 'dumpprivkeys']:
                print_msg("WARNING: ALL your private keys are secret.")
                print_msg("Exposing a single private key can compromise your entire wallet!")
                print_msg("In particular, DO NOT use 'redeem private key' services proposed by third parties.")
        
            # commands needing password
       -    if cmd in protected_commands or ( cmd=='addresses' and options.show_keys):
       +    if cmd in protected_commands:
                if wallet.use_encryption:
                    password = prompt_password('Password:', False)
                    if not password:
       t@@ -440,7 +440,6 @@ if __name__ == '__main__':
                args = [ cmd, address, signature, message]
        
            elif cmd == 'signrawtransaction':
       -        
                args = [ cmd, args[1], ast.literal_eval(args[2]) if len(args)>2 else [], ast.literal_eval(args[3]) if len(args)>3 else []]
        
            elif cmd == 'createmultisig':
       t@@ -448,6 +447,13 @@ if __name__ == '__main__':
        
            elif cmd == 'createrawtransaction':
                args = [ cmd, ast.literal_eval(args[1]), ast.literal_eval(args[2])]
       +
       +    elif cmd == 'dumpprivkeys':
       +        if options.show_all:
       +            addresses = wallet.all_addresses()
       +        else:
       +            addresses = wallet.addresses + wallet.imported_keys.keys()
       +        args = [cmd, addresses]
                        
            elif cmd == 'setlabel':
                try:
       t@@ -565,8 +571,6 @@ if __name__ == '__main__':
                            b = format_satoshis(wallet.get_addr_balance(addr)[0])
                        else: b=''
                        m_addr = "%34s"%addr
       -                if options.show_keys:
       -                    m_addr += ':' + str(wallet.get_private_key(addr, password))
                        print_msg(flags, m_addr, b, label)
        
        
       t@@ -580,7 +584,7 @@ if __name__ == '__main__':
                cmd_runner = Commands(wallet, interface)
                func = eval('cmd_runner.' + cmd)
                if password: 
       -            args.append( password )
       +            cmd_runner.password = password
                func(*args[1:])
                
        
   DIR diff --git a/lib/bitcoin.py b/lib/bitcoin.py
       t@@ -435,13 +435,16 @@ class DeterministicSequence:
                public_key2 = ecdsa.VerifyingKey.from_public_point( pubkey_point, curve = SECP256k1 )
                return '04' + public_key2.to_string().encode('hex')
        
       -    def get_private_key(self, n, for_change, seed):
       +    def get_private_key_from_stretched_exponent(self, n, for_change, secexp):
                order = generator_secp256k1.order()
       -        secexp = self.stretch_key(seed)
                secexp = ( secexp + self.get_sequence(n,for_change) ) % order
                pk = number_to_string( secexp, generator_secp256k1.order() )
                compressed = False
                return SecretToASecret( pk, compressed )
       +        
       +    def get_private_key(self, n, for_change, seed):
       +        secexp = self.stretch_key(seed)
       +        return self.get_private_key_from_stretched_exponent(n, for_change, secexp)
        
            def check_seed(self, seed):
                curve = SECP256k1
   DIR diff --git a/lib/commands.py b/lib/commands.py
       t@@ -22,7 +22,7 @@ from bitcoin import *
        from decimal import Decimal
        import bitcoin
        
       -protected_commands = ['payto', 'password', 'mktx', 'get_seed', 'importprivkey','signmessage', 'signrawtransaction','dumpprivkey' ]
       +protected_commands = ['payto', 'password', 'mktx', 'get_seed', 'importprivkey','signmessage', 'signrawtransaction', 'dumpprivkey', 'dumpprivkeys' ]
        
        class Commands:
        
       t@@ -135,8 +135,11 @@ class Commands:
                print_msg(self.wallet.unprioritize(addr))
        
            def dumpprivkey(self, addr):
       -        sec = self.wallet.get_private_key(addr, self.password)
       -        print_msg( sec )
       +        print_msg( self.wallet.get_private_key(addr, self.password) )
       +
       +    def dumpprivkeys(self, addresses):
       +        print_json( self.wallet.get_private_keys(addresses, self.password) )
       +
        
            def validateaddress(self,addr):
                is_valid = self.wallet.is_valid(addr)
   DIR diff --git a/lib/wallet.py b/lib/wallet.py
       t@@ -213,23 +213,29 @@ class Wallet:
                return seed
                
            def get_private_key(self, address, password):
       +        return self.get_private_keys([address], password)[address]
        
       +    def get_private_keys(self, addresses, password):
                # decode seed in any case, in order to test the password
                seed = self.decode_seed(password)
       -
       -        if address in self.imported_keys.keys():
       -            return pw_decode( self.imported_keys[address], password )
       -        else:
       -            if address in self.addresses:
       -                n = self.addresses.index(address)
       -                for_change = False
       -            elif address in self.change_addresses:
       -                n = self.change_addresses.index(address)
       -                for_change = True
       +        secexp = self.sequence.stretch_key(seed)
       +        out = {}
       +        for address in addresses:
       +            if address in self.imported_keys.keys():
       +                pk = pw_decode( self.imported_keys[address], password )
                    else:
       -                raise BaseException("unknown address", address)
       +                if address in self.addresses:
       +                    n = self.addresses.index(address)
       +                    for_change = False
       +                elif address in self.change_addresses:
       +                    n = self.change_addresses.index(address)
       +                    for_change = True
       +                else:
       +                    raise BaseException("unknown address", address)
       +                pk = self.sequence.get_private_key_from_stretched_exponent(n, for_change, secexp)
       +            out[address] = pk
       +        return out
                    
       -            return self.sequence.get_private_key(n, for_change, seed)
        
        
            def sign_message(self, address, message, password):