def _verify_input(self, input_index, sub_script, partial_multisig=False): p2sh = sub_script.is_p2sh() sig_script = self.inputs[input_index].script si = ScriptInterpreter(txn=self, input_index=input_index, sub_script=sub_script) try: si.run_script(sig_script) except ScriptInterpreterError: return False # This copy_stack and the restore_stack emulate the behavior # found in bitcoin core for evaluating P2SH scripts. See: # https://github.com/bitcoin/bitcoin/blob/master/src/script/interpreter.cpp#L1170 if p2sh: si.copy_stack() try: si.run_script(sub_script) except ScriptInterpreterError: return False rv = si.valid if p2sh: si.restore_stack() redeem_script = Script(si.stack.pop()) si._sub_script = redeem_script try: if sig_script.is_multisig_sig() and partial_multisig: # This is a hack for partial verification partial_script = copy.deepcopy(redeem_script) partial_script.ast[-1] = 'OP_CHECKPARTIALMULTISIG' sig_info = sig_script.extract_multisig_sig_info() si.run_script(partial_script) rv &= si.match_count > 0 and si.match_count <= len(sig_info['signatures']) else: si.run_script(redeem_script) rv &= si.valid except: rv = False return rv