def sign(self, keypairs): for i, txin in enumerate(self.inputs()): num = txin['num_sig'] for x_pubkey in txin['x_pubkeys']: signatures = filter(None, txin['signatures']) if len(signatures) == num: # txin is complete break if x_pubkey in keypairs.keys(): log.debug("adding signature for %s", x_pubkey) # add pubkey to txin txin = self._inputs[i] x_pubkeys = txin['x_pubkeys'] ii = x_pubkeys.index(x_pubkey) sec = keypairs[x_pubkey] pubkey = public_key_from_private_key(sec) txin['x_pubkeys'][ii] = pubkey txin['pubkeys'][ii] = pubkey self._inputs[i] = txin # add signature for_sig = Hash(self.tx_for_sig(i).decode('hex')) pkey = regenerate_key(sec) secexp = pkey.secret private_key = MySigningKey.from_secret_exponent(secexp, curve=SECP256k1) public_key = private_key.get_verifying_key() 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) txin['signatures'][ii] = sig.encode('hex') self._inputs[i] = txin log.debug("is_complete: %s", self.is_complete()) self.raw = self.serialize()
def sweep(cls, privkeys, network, to_address, fee): inputs = [] keypairs = {} for privkey in privkeys: pubkey = public_key_from_private_key(privkey) address = address_from_private_key(privkey) u = network.synchronous_get( ('blockchain.address.listunspent', [address])) pay_script = cls.pay_script(TYPE_ADDRESS, address) for item in u: item['scriptPubKey'] = pay_script item['redeemPubkey'] = pubkey item['address'] = address item['prevout_hash'] = item['tx_hash'] item['prevout_n'] = item['tx_pos'] item['pubkeys'] = [pubkey] item['x_pubkeys'] = [pubkey] item['signatures'] = [None] item['num_sig'] = 1 inputs += u keypairs[pubkey] = privkey if not inputs: return total = sum(i.get('value') for i in inputs) - fee outputs = [(TYPE_ADDRESS, to_address, total)] self = cls.from_io(inputs, outputs) self.sign(keypairs) return self
def sign(self, keypairs): for i, txin in enumerate(self.inputs()): num = txin['num_sig'] for x_pubkey in txin['x_pubkeys']: signatures = filter(None, txin['signatures']) if len(signatures) == num: # txin is complete break if x_pubkey in keypairs.keys(): print_error("adding signature for", x_pubkey) # add pubkey to txin txin = self._inputs[i] x_pubkeys = txin['x_pubkeys'] ii = x_pubkeys.index(x_pubkey) sec = keypairs[x_pubkey] pubkey = public_key_from_private_key(sec) txin['x_pubkeys'][ii] = pubkey txin['pubkeys'][ii] = pubkey self._inputs[i] = txin # add signature for_sig = Hash(self.tx_for_sig(i).decode('hex')) pkey = regenerate_key(sec) secexp = pkey.secret private_key = MySigningKey.from_secret_exponent(secexp, curve=SECP256k1) public_key = private_key.get_verifying_key() 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) txin['signatures'][ii] = sig.encode('hex') self._inputs[i] = txin print_error("is_complete", self.is_complete()) self.raw = self.serialize()
def test_public_key_from_private_key(self): result = public_key_from_private_key(self.private_key) self.assertEqual(self.public_key_hex, result)