commit f550b452bebc47af473ced0d82f379188f23e7a5
parent 94829db701515e4d7b44167408852877680b2572
Author: ThomasV <thomasv@gitorious>
Date: Mon, 7 Apr 2014 11:03:12 +0200
transaction: add_signature(), is_complete() methods
Diffstat:
2 files changed, 32 insertions(+), 22 deletions(-)
diff --git a/gui/qt/main_window.py b/gui/qt/main_window.py
@@ -920,7 +920,7 @@ class ElectrumWindow(QMainWindow):
if label:
self.wallet.set_label(tx.hash(), label)
- if not tx.is_complete:
+ if not tx.is_complete():
self.show_transaction(tx)
return
diff --git a/lib/transaction.py b/lib/transaction.py
@@ -377,7 +377,7 @@ class Transaction:
self.outputs = self.d['outputs']
self.outputs = map(lambda x: (x['address'],x['value']), self.outputs)
self.locktime = self.d['lockTime']
- self.is_complete = is_complete
+
def __str__(self):
return self.raw
@@ -386,7 +386,6 @@ class Transaction:
def from_io(klass, inputs, outputs):
raw = klass.serialize(inputs, outputs, for_sig = -1) # for_sig=-1 means do not sign
self = klass(raw)
- self.is_complete = False
self.inputs = inputs
self.outputs = outputs
return self
@@ -487,17 +486,37 @@ class Transaction:
return s
- def for_sig(self,i):
+ def tx_for_sig(self,i):
return self.serialize(self.inputs, self.outputs, for_sig = i)
def hash(self):
return Hash(self.raw.decode('hex') )[::-1].encode('hex')
+ def add_signature(self, i, pubkey, sig):
+ txin = self.inputs[i]
+ signatures = txin.get("signatures",{})
+ signatures[pubkey] = sig
+ txin["signatures"] = signatures
+ self.inputs[i] = txin
+ print_error("adding signature for", pubkey)
+ self.raw = self.serialize( self.inputs, self.outputs )
+
+
+ def is_complete(self):
+ for i, txin in enumerate(self.inputs):
+ redeem_script = txin.get('redeemScript')
+ num, redeem_pubkeys = parse_redeemScript(redeem_script) if redeem_script else (1, [txin.get('redeemPubkey')])
+ signatures = txin.get("signatures",{})
+ if len(signatures) == num:
+ continue
+ else:
+ return False
+ return True
+
def sign(self, keypairs):
- is_complete = True
print_error("tx.sign(), keypairs:", keypairs)
for i, txin in enumerate(self.inputs):
@@ -514,34 +533,25 @@ class Transaction:
if len(signatures) == num:
continue
- tx_for_sig = self.serialize( self.inputs, self.outputs, for_sig = i )
-
- print_error("redeem pubkeys input %d"%i, redeem_pubkeys)
+ for_sig = Hash(self.tx_for_sig(i).decode('hex'))
for pubkey in redeem_pubkeys:
- # check if we have the corresponding private key
if pubkey in keypairs.keys():
# add signature
sec = keypairs[pubkey]
- compressed = is_compressed(sec)
pkey = regenerate_key(sec)
secexp = pkey.secret
private_key = ecdsa.SigningKey.from_secret_exponent( secexp, curve = SECP256k1 )
public_key = private_key.get_verifying_key()
- sig = private_key.sign_digest_deterministic( Hash( tx_for_sig.decode('hex') ), hashfunc=hashlib.sha256, sigencode = ecdsa.util.sigencode_der )
- assert public_key.verify_digest( sig, Hash( tx_for_sig.decode('hex') ), sigdecode = ecdsa.util.sigdecode_der)
+ sig = private_key.sign_digest_deterministic( for_sig, hashfunc=hashlib.sha256, sigencode = ecdsa.util.sigencode_der )
+ assert public_key.verify_digest( sig, for_sig, sigdecode = ecdsa.util.sigdecode_der)
+ self.add_signature(i, pubkey, sig.encode('hex'))
- # insert signature in the list
- signatures[pubkey] = sig.encode('hex')
- print_error("adding signature for", pubkey)
-
- txin["signatures"] = signatures
- is_complete = is_complete and len(signatures) == num
- print_error("is_complete", is_complete)
- self.is_complete = is_complete
+ print_error("is_complete", self.is_complete())
self.raw = self.serialize( self.inputs, self.outputs )
+
def deserialize(self):
vds = BCDataStream()
vds.write(self.raw.decode('hex'))
@@ -691,10 +701,10 @@ class Transaction:
import json
out = {
"hex":self.raw,
- "complete":self.is_complete
+ "complete":self.is_complete()
}
- if not self.is_complete:
+ if not self.is_complete():
input_info = self.get_input_info()
out['input_info'] = json.dumps(input_info).replace(' ','')