def stream(self, f, blank_solutions=False, include_unspents=False, include_witness_data=True): """Stream a Bitcoin transaction Tx to the file-like object f.""" include_witnesses = include_witness_data and self.has_witness_data() #### if TransactionUtils.isCFTransation(self): stream_struct("L", f, 2) stream_struct("#", f, self.cf_header.original_hash) stream_struct("Q", f, self.cf_header.target_amount) stream_struct("S", f, self.cf_header.pubkey.encode(encoding="utf-8")) stream_struct("L", f, self.cf_header.end_time) stream_struct("#", f, self.cf_header.pre_hash) stream_struct("Q", f, self.cf_header.lack_amount) else: stream_struct("L", f, 1) #### stream_struct("L", f, self.version) if include_witnesses: f.write(b'\0\1') stream_struct("I", f, len(self.txs_in)) for t in self.txs_in: t.stream(f, blank_solutions=blank_solutions) stream_struct("I", f, len(self.txs_out)) for t in self.txs_out: t.stream(f) if include_witnesses: for tx_in in self.txs_in: witness = tx_in.witness stream_struct("I", f, len(witness)) for w in witness: stream_bc_string(f, w) stream_struct("L", f, self.lock_time) if include_unspents and not self.missing_unspents(): self.stream_unspents(f)
def sign(self, message, compact=True): """Signs the supplied message with the private key""" if compact: fd = io.BytesIO() stream_bc_string(fd, bytearray('Bitcoin Signed Message:\n', 'ascii')) stream_bc_string(fd, bytearray(message, 'utf-8')) mhash = from_bytes_32(double_sha256(fd.getvalue())) G = generator_secp256k1 n = G.order() k = from_bytes_32(os.urandom(32)) p1 = k * G r = p1.x() if r == 0: raise RuntimeError("amazingly unlucky random number r") s = (numbertheory.inverse_mod(k, n) * (mhash + (self.keypair.secret_exponent() * r) % n)) % n if s == 0: raise RuntimeError("amazingly unlucky random number s") y_odd = p1.y() % 2 assert y_odd in (0, 1) first = 27 + y_odd + (4 if not self.keypair._use_uncompressed(False) else 0) sig = binascii.b2a_base64(bytearray([first]) + to_bytes_32(r) + to_bytes_32(s)).strip() if not isinstance(sig, str): # python3 b2a wrongness sig = str(sig, 'ascii') return sig else: return keys.sign_sha256(self.private_key, message)
def segwit_signature_preimage(self, script, tx_in_idx, hash_type): f = io.BytesIO() stream_struct("L", f, self.version) # calculate hash prevouts f.write(self.hash_prevouts(hash_type)) f.write(self.hash_sequence(hash_type)) tx_in = self.txs_in[tx_in_idx] f.write(tx_in.previous_hash) stream_struct("L", f, tx_in.previous_index) tx_out = self.unspents[tx_in_idx] stream_bc_string(f, script) stream_struct("Q", f, tx_out.coin_value) stream_struct("L", f, tx_in.sequence) f.write(self.hash_outputs(hash_type, tx_in_idx)) stream_struct("L", f, self.lock_time) stream_struct("L", f, hash_type) return f.getvalue()