def serialize_transaction(tx_ins: list, tx_outs: list, lock_time: bytes = LOCK_TIME) -> bytes: """Serialize signed transaction""" # version raw_transaction = VERSION # inputs raw_transaction += int_to_varint(len(tx_ins)) for tx_in in tx_ins: raw_transaction += tx_in.txid + tx_in.index + tx_in.unlocking_script_len + tx_in.unlocking_script + tx_in.sequence # outputs raw_transaction += int_to_varint(len(tx_outs)) + serialize_outputs(tx_outs) # lock_time raw_transaction += lock_time return raw_transaction
def __init__(self, satoshi: int, txid: str, index: int, locking_script: str, sequence: bytes = SEQUENCE) -> None: self.satoshi = satoshi.to_bytes(8, byteorder='little') self.txid = unhexlify(txid)[::-1] self.index = index.to_bytes(4, byteorder='little') self.locking_script = unhexlify(locking_script) self.locking_script_len = int_to_varint(len(self.locking_script)) self.unlocking_script = b'' self.unlocking_script_len = b'' self.sequence = sequence
# Verify the ECDSA signature of a signed transaction # 4674da699de44c9c5d182870207ba89e5ccf395e5101dab6b0900bbf2f3b16cb # tx_inputs = inputs[0:1] tx_outputs = [TxOut(address='1JDZRGf5fPjGTpqLNwjHFFZnagcZbwDsxw', satoshi=800)] tx_digest = transaction_digest(tx_inputs, tx_outputs)[0] serialized_sig = unhexlify('304402207e2c6eb8c4b20e251a71c580373a2836e209c50726e5f8b0f4f59f8af00eee1a022019ae1690e2eb4455add6ca5b86695d65d3261d914bc1d7abb40b188c7f46c9a5') sig = deserialize_signature(serialized_sig) print(verify_signature(pub_key, tx_digest, sig)) # # Sign an unsigned transaction then broadcast # c04bbd007ad3987f9b2ea8534175b5e436e43d64471bf32139b5851adf9f477e # serialized_pub_key = serialize_public_key(pub_key) tx_inputs = inputs[1:] tx_outputs = [TxOut(address='18CgRLx9hFZqDZv75J5kED7ANnDriwvpi1', satoshi=1700)] tx_digests = transaction_digest(tx_inputs, tx_outputs) for i in range(len(tx_digests)): tx_digest = tx_digests[i] sig = sign(priv_key, tx_digest) serialized_sig = serialize_signature(sig) # unlocking_script = LEN + der + sighash + LEN + public_key tx_inputs[i].unlocking_script = bytes([len(serialized_sig) + 1]) + serialized_sig + bytes([SIGHASH_ALL, len(serialized_pub_key)]) + serialized_pub_key print(hexlify(tx_inputs[i].unlocking_script)) tx_inputs[i].unlocking_script_len = int_to_varint(len(tx_inputs[i].unlocking_script)) print(hexlify(tx_inputs[i].unlocking_script_len)) raw = serialize_transaction(tx_inputs, tx_outputs) print(hexlify(raw)) tx_id = double_sha256(raw)[::-1] print(hexlify(tx_id))
def message_bytes(message: str) -> bytes: """Serialize plain text message to format (LEN || message.utf-8)""" msg_bytes = message.encode('utf-8') return int_to_varint(len(msg_bytes)) + msg_bytes