Merge pull request #149 from polymorphm/tiny-bugfix--history-balance
[electrum-nvc.git] / electrum
index 9f89e22..ff97e47 100755 (executable)
--- a/electrum
+++ b/electrum
@@ -17,7 +17,7 @@
 # along with this program. If not, see <http://www.gnu.org/licenses/>.
 
 import re
-import sys, os, time
+import sys, os, time, ast
 import optparse
 import platform
 
@@ -91,6 +91,7 @@ options:\n  --fee, -f: set transaction fee\n  --fromaddr, -s: send from address
     'unfreeze':'',
     'prioritize':'',
     'unprioritize':'',
+    'dumpprivkey':'',
     'createmultisig':'similar to bitcoind\'s command',
     'createrawtransaction':'similar to bitcoind\'s command',
     'decoderawtransaction':'similar to bitcoind\'s command',
@@ -112,7 +113,7 @@ offline_commands = [ 'password', 'mktx', 'signtx',
                      ]
 
 
-protected_commands = ['payto', 'password', 'mktx', 'signtx', 'seed', 'importprivkey','signmessage', 'signrawtransaction' ]
+protected_commands = ['payto', 'password', 'mktx', 'signtx', 'seed', 'importprivkey','signmessage', 'signrawtransaction','dumpprivkey' ]
 
 # get password routine
 def prompt_password(prompt, confirm=True):
@@ -478,7 +479,6 @@ if __name__ == '__main__':
             except IOError:
                 sys.exit("Error: Seed file not found")
             try:
-                import ast
                 d = ast.literal_eval( data )
                 seed = d['seed']
                 imported_keys = d.get('imported_keys',{})
@@ -632,7 +632,6 @@ if __name__ == '__main__':
         wallet.save()
 
     elif cmd == 'signtx':
-        import ast
         filename = args[1]
         f = open(filename, 'r')
         d = ast.literal_eval(f.read())
@@ -697,8 +696,13 @@ if __name__ == '__main__':
         print_msg(wallet.unprioritize(addr))
 
 
+    elif cmd == 'dumpprivkey':
+        addr = args[1]
+        sec = wallet.get_private_key_base58(addr, password)
+        print_msg( sec )
+
+        
     elif cmd == 'createmultisig':
-        import ast
         from lib.bitcoin import *
         num = int(args[1])
         pubkeys = ast.literal_eval(args[2])
@@ -709,41 +713,71 @@ if __name__ == '__main__':
     
 
     elif cmd == 'createrawtransaction':
-        import ast
         inputs = ast.literal_eval(args[1])
         outputs = ast.literal_eval(args[2])
-        inputs = map(lambda x: (None, None, x["txid"], x["vout"], None, None), inputs)
-        outputs = map(lambda x: (x[0],int(x[1]*1e8)), outputs.items())
-        tx = raw_tx(inputs, outputs, for_sig = -1) # for_sig=-1 means do not sign
+        # convert to own format
+        for i in inputs:
+            i['tx_hash'] = i['txid']
+            i['index'] = i['vout']
+        outputs = map(lambda x: (x[0],int(1e8*x[1])), outputs.items())
+        tx = Transaction.from_io(inputs, outputs)
         print_msg( tx )
 
 
     elif cmd == 'decoderawtransaction':
-        print_json( bitcoin.deserialize(args[1]) )
+        tx = Transaction(args[1])
+        print_json( tx.deserialize() )
 
 
     elif cmd == 'signrawtransaction':
-        d = bitcoin.deserialize(args[1])
-        txouts = args[2] if len(args)>2 else []
-        private_keys = args[3] if len(args)>3 else []
-        
-        inputs = []
-        for x in d['inputs']:
-            txid = x["prevout_hash"]
-            nout = x["prevout_n"]
-            tx = wallet.transactions.get(txid)
-            txout = tx['outputs'][nout]
-            addr = txout['address']
-            v = txout['value']
-            inputs.append( (addr, v, txid, nout, txout['raw_output_script'], [(None,None)] ) )
-
-        outputs = map(lambda x: (x['address'],x['value']), d['outputs'])
-        print_error("inputs", inputs)
-        print_error("outputs", outputs)
+        from lib.bitcoin import *
+        tx = Transaction(args[1])
+        txouts = ast.literal_eval(args[2]) if len(args)>2 else []
+        private_keys = ast.literal_eval(args[3]) if len(args)>3 else {}
+
+        for txin in tx.inputs:
+            txid = txin["prevout_hash"]
+            index = txin["prevout_n"]
+            # convert to own format
+            txin['tx_hash'] = txin['prevout_hash']
+            txin['index'] = txin['prevout_n']
+
+            for txout in txouts:
+                if txout.get('txid') == txid and txout.get('vout') == index:
+                    # compute addr from redeemScript
+                    addr = hash_160_to_bc_address(hash_160(txout['redeemScript'].decode('hex')),5)
+                    txin['address'] = addr
+                    txin['raw_output_script'] = txout['scriptPubKey']
+                    txin['redeemScript'] = txout['redeemScript']
+                    break
+                
+            else:
+                if wallet.transactions.get(txid):
+                    # lookup in my own list of transactions
+                    txout = wallet.transactions[txid]['outputs'][index]
+                    txin['address'] = txout['address']
+                    txin['raw_output_script'] = txout['raw_output_script']
 
-        tx = wallet.signed_tx( inputs, outputs, password )
+                else:
+                    # if neither, we might want to get it from the server..
+                    raise
+
+        if not private_keys:
+            for txin in tx.inputs:
+                addr = txin['address']
+                private_keys[addr] = wallet.get_private_key_base58(addr, password)
+        else:
+            pk = {}
+            for sec in private_keys:
+                address = bitcoin.address_from_private_key(sec)
+                pk[address] = sec
+            private_keys = pk
+
+        tx.sign( private_keys )
         print_msg(tx)
         
 
     if cmd not in offline_commands and not options.offline:
         synchronizer.stop()
+
+