diff --git a/tx.py b/tx.py index 2a1b330..7e58971 100644 --- a/tx.py +++ b/tx.py @@ -112,14 +112,21 @@ def fee(self): return input_sum - output_sum - def sig_hash(self, input_index): + def sig_hash(self, input_index: int, redeem_script=None): """ - Compute the signature hash for a transaction + Compute the integer representation of the signature hash (of a transaction) that needs + to get signed fir index input_index. """ s = int_to_little_endian(self.version, 4) + s += encode_varint(len(self.tx_ins)) for i, tx_in in enumerate(self.tx_ins): if i == input_index: + if redeem_script: + script_sig = redeem_script + else: + script_sig = tx_in.script_pubkey(self.testnet) + s += TxIn( prev_tx=tx_in.prev_tx, prev_index=tx_in.prev_index, @@ -142,13 +149,21 @@ def sig_hash(self, input_index): h256 = hash256(s) return int.from_bytes(h256, 'big') - def verify_input(self, input_index): + def verify_input(self, input_index: int): """ Verify a transaction input """ tx_in: TxIn = self.tx_ins[input_index] script_pubkey = tx_in.script_pubkey(testnet=self.testnet) - z = self.sig_hash(input_index) + + if script_pubkey.is_p2sh_script_pubkey(): + cmd = tx_in.script_sig.cmds[-1] + raw_redeem = encode_varint(len(cmd)) + cmd + redeem_script = Script.parse(BytesIO(raw_redeem)) + else: + redeem_script = None + + z = self.sig_hash(input_index, redeem_script) combined: Script = tx_in.script_sig + script_pubkey return combined.evaluate(z)