commit b8a71ff00cdf025eefea637f4c1b23516dccb76e
parent c4f7ce6baea95e26a8ca5c56485d06e7144a1ca7
Author: ThomasV <thomasv@gitorious>
Date: Mon, 25 Feb 2013 09:05:45 +0100
offline wallets sign transactions using KeyID
Diffstat:
3 files changed, 50 insertions(+), 18 deletions(-)
diff --git a/electrum b/electrum
@@ -636,7 +636,11 @@ if __name__ == '__main__':
r, h = wallet.sendtx( tx )
print_msg(h)
else:
- print_json({"hex":str(tx), "complete":tx.is_complete})
+ out = {"hex":str(tx), "complete":tx.is_complete}
+ if not tx.is_complete:
+ import json
+ out['input_info'] = repr(tx.inputs_info).replace(' ','')
+ print_json(out)
if is_temporary:
wallet.imported_keys.pop(from_addr)
@@ -732,41 +736,55 @@ if __name__ == '__main__':
elif cmd == 'signrawtransaction':
tx = Transaction(args[1])
- txouts = ast.literal_eval(args[2]) if len(args)>2 else []
+ inputs_info = ast.literal_eval(args[2]) if len(args)>2 else []
private_keys = ast.literal_eval(args[3]) if len(args)>3 else {}
unspent_coins = wallet.get_unspent_coins()
+ # convert private_keys to dict
+ pk = {}
+ for sec in private_keys:
+ address = bitcoin.address_from_private_key(sec)
+ pk[address] = sec
+ private_keys = pk
+
for txin in tx.inputs:
# convert to own format
txin['tx_hash'] = txin['prevout_hash']
txin['index'] = txin['prevout_n']
- for txout in txouts:
- if txout.get('txid') == txin['tx_hash'] and txout.get('vout') == txin['index']:
- txin['raw_output_script'] = txout['scriptPubKey']
- txin['redeemScript'] = txout['redeemScript']
+ for item in inputs_info:
+ if item.get('txid') == txin['tx_hash'] and item.get('vout') == txin['index']:
+ txin['raw_output_script'] = item['scriptPubKey']
+ txin['redeemScript'] = item.get('redeemScript')
+ txin['electrumKeyID'] = item.get('electrumKeyID')
break
-
else:
for item in unspent_coins:
if txin['tx_hash'] == item['tx_hash'] and txin['index'] == item['index']:
- txin['address'] = item['address']
txin['raw_output_script'] = item['raw_output_script']
break
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(addr, password)
- else:
- pk = {}
- for sec in private_keys:
+ # find the address:
+ from lib import deserialize
+ if txin.get('electrumKeyID'):
+ n, for_change = txin.get('electrumKeyID')
+ sec = wallet.sequence.get_private_key(n, for_change, seed)
address = bitcoin.address_from_private_key(sec)
- pk[address] = sec
- private_keys = pk
+ txin['address'] = address
+ private_keys[address] = sec
+
+ elif txin.get("redeemScript"):
+ txin['address'] = hash_160_to_bc_address(hash_160(txin.get("redeemScript").decode('hex')), 5)
+
+ elif txin.get("raw_output_script"):
+ addr = deserialize.get_address_from_output_script(txin.get("raw_output_script").decode('hex'))
+ sec = wallet.get_private_key(addr, password)
+ if sec:
+ private_keys[addr] = sec
+ txin['address'] = addr
tx.sign( private_keys )
print_json({ "hex":str(tx),"complete":tx.is_complete})
diff --git a/lib/bitcoin.py b/lib/bitcoin.py
@@ -479,6 +479,12 @@ class Transaction:
self.is_complete = False
self.inputs = inputs
self.outputs = outputs
+ extras = []
+ for i in self.inputs:
+ print i
+ e = { 'txid':i['tx_hash'], 'vout':i['index'],'scriptPubKey':i['raw_output_script'] }
+ extras.append(e)
+ self.inputs_info = extras
return self
def __str__(self):
diff --git a/lib/wallet.py b/lib/wallet.py
@@ -190,7 +190,7 @@ class Wallet:
def get_master_public_key(self):
return self.sequence.master_public_key
- def get_public_key(self, address):
+ def get_address_index(self, address):
if address in self.imported_keys.keys():
raise BaseException("imported key")
@@ -200,7 +200,10 @@ class Wallet:
elif address in self.change_addresses:
n = self.change_addresses.index(address)
for_change = True
+ return n,for_change
+ def get_public_key(self, address):
+ n, for_change = self.get_address_index(address)
return self.sequence.get_pubkey(n, for_change)
@@ -666,6 +669,11 @@ class Wallet:
outputs = self.add_tx_change(outputs, amount, fee, total, change_addr)
tx = Transaction.from_io(inputs, outputs)
+ for i in range(len(tx.inputs)):
+ addr = tx.inputs[i]['address']
+ n, is_change = self.get_address_index(addr)
+ tx.inputs_info[i]['electrumKeyID'] = (n, is_change)
+
if not self.seed:
return tx