From: ThomasV Date: Fri, 16 Aug 2013 20:05:31 +0000 (+0200) Subject: simplify tx.sign() X-Git-Url: https://git.novaco.in/?a=commitdiff_plain;h=e91e02f2ce851500d640b3f925a68359356c6300;p=electrum-nvc.git simplify tx.sign() --- diff --git a/lib/bitcoin.py b/lib/bitcoin.py index 8281bb1..82320cb 100644 --- a/lib/bitcoin.py +++ b/lib/bitcoin.py @@ -526,17 +526,17 @@ class Transaction: s += int_to_hex(txin['index'],4) # prev index if for_sig is None: - pubkeysig = txin.get('pubkeysig') - if pubkeysig: - pubkey, sig = pubkeysig[0] - sig = sig + chr(1) # hashtype - script = op_push( len(sig)) - script += sig.encode('hex') - script += op_push( len(pubkey)) - script += pubkey.encode('hex') + signatures = txin['signatures'] + pubkeys = txin['pubkeys'] + if not txin.get('redeemScript'): + pubkey = pubkeys[0] + sig = signatures[0] + sig = sig + '01' # hashtype + script = op_push(len(sig)/2) + script += sig + script += op_push(len(pubkey)/2) + script += pubkey else: - signatures = txin['signatures'] - pubkeys = txin['pubkeys'] script = '00' # op_0 for sig in signatures: sig = sig + '01' @@ -595,76 +595,51 @@ class Transaction: def sign(self, private_keys): import deserialize - is_complete = True for i, txin in enumerate(self.inputs): - tx_for_sig = self.serialize( self.inputs, self.outputs, for_sig = i ) - txin_pk = private_keys.get( txin.get('address') ) - redeem_script = txin.get('redeemScript') + # build list of public/private keys + keypairs = {} + for sec in private_keys.get( txin.get('address') ): + compressed = is_compressed(sec) + pkey = regenerate_key(sec) + pubkey = GetPubKey(pkey.pubkey, compressed) + keypairs[ pubkey.encode('hex') ] = sec + redeem_script = txin.get('redeemScript') if redeem_script: - # parse the redeem script num, redeem_pubkeys = deserialize.parse_redeemScript(redeem_script) - txin["pubkeys"] = redeem_pubkeys - - # list of already existing signatures - signatures = txin.get("signatures",[]) + else: + num = 1 + redeem_pubkeys = keypairs.keys() - # continue if this txin is complete - if len(signatures) == num: - continue + # get list of already existing signatures + signatures = txin.get("signatures",[]) + # continue if this txin is complete + if len(signatures) == num: + continue - # build list of public/private keys - keypairs = {} - for sec in txin_pk: + tx_for_sig = self.serialize( self.inputs, self.outputs, for_sig = i ) + 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) - pubkey = GetPubKey(pkey.pubkey, compressed) - keypairs[ pubkey.encode('hex') ] = sec - - for pubkey in redeem_pubkeys: - - # check if we have a key corresponding to the redeem script - 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( Hash( tx_for_sig.decode('hex') ), sigencode = ecdsa.util.sigencode_der ) - assert public_key.verify_digest( sig, Hash( tx_for_sig.decode('hex') ), sigdecode = ecdsa.util.sigdecode_der) - signatures.append( sig.encode('hex') ) + 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( Hash( tx_for_sig.decode('hex') ), sigencode = ecdsa.util.sigencode_der ) + assert public_key.verify_digest( sig, Hash( tx_for_sig.decode('hex') ), sigdecode = ecdsa.util.sigdecode_der) + signatures.append( sig.encode('hex') ) - # for p2sh, pubkeysig is a tuple (may be incomplete) - txin["signatures"] = signatures - print_error("signatures", signatures) - is_complete = is_complete and len(signatures) == num - - else: - - if txin.get("pubkeysig"): - continue - - if not txin_pk: - is_complete = False - continue - - sec = txin_pk[0] - 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() - pkey = EC_KEY(secexp) - pubkey = GetPubKey(pkey.pubkey, compressed) - sig = private_key.sign_digest( Hash( tx_for_sig.decode('hex') ), sigencode = ecdsa.util.sigencode_der ) - assert public_key.verify_digest( sig, Hash( tx_for_sig.decode('hex') ), sigdecode = ecdsa.util.sigdecode_der) - txin["pubkeysig"] = [(pubkey, sig)] + txin["signatures"] = signatures + txin["pubkeys"] = redeem_pubkeys + print_error("signatures", signatures) + is_complete = is_complete and len(signatures) == num self.is_complete = is_complete self.raw = self.serialize( self.inputs, self.outputs )