def verify_input(self, input_index): tx_in = self.tx_ins[input_index] script_pubkey = tx_in.script_pubkey(testnet=self.testnet) if script_pubkey.is_p2sh_script_pubkey(): cmd = tx_in.script_sig.cmds[-1] raw_redeem = int_to_little_endian(len(cmd), 1) + cmd redeem_script = Script.parse(BytesIO(raw_redeem)) if redeem_script.is_p2wpkh_script_pubkey(): z = self.sig_hash_bip143(input_index, redeem_script) witness = tx_in.witness elif redeem_script.is_p2wsh_script_pubkey(): cmd = tx_in.witness[-1] raw_witness = encode_varint(len(cmd)) + cmd witness_script = Script.parse(BytesIO(raw_witness)) z = self.sig_hash_bip143(input_index, witness_script=witness_script) witness = tx_in.witness else: z = self.sig_hash(input_index, redeem_script) witness = None else: if script_pubkey.is_p2wpkh_script_pubkey(): z = self.sig_hash_bip143(input_index) witness = tx_in.witness elif script_pubkey.is_p2wsh_script_pubkey(): cmd = tx_in.witness[-1] raw_witness = encode_varint(len(cmd)) + cmd witness_script = Script.parse(BytesIO(raw_witness)) z = self.sig_hash_bip143(input_index, witness_script=witness_script) witness = tx_in.witness else: z = self.sig_hash(input_index) witness = None combined = tx_in.script_sig + script_pubkey return combined.evaluate(z, witness)
def serialize_legacy(self): result = int_to_little_endian(self.version, 4) result += encode_varint(len(self.tx_ins)) for tx_in in self.tx_ins: result += tx_in.serialize() result += encode_varint(len(self.tx_outs)) for tx_out in self.tx_outs: result += tx_out.serialize() result += int_to_little_endian(self.locktime, 4) return result
def filterload(self, flag=1): payload = encode_varint(self.size) payload += self.filter_bytes() payload += int_to_little_endian(self.function_count, 4) payload += int_to_little_endian(self.tweak, 4) payload += int_to_little_endian(flag, 1) return GenericMessage(b"filterload", payload)
def serialize_segwit(self): result = int_to_little_endian(self.version, 4) result += b"\x00\x01" result += encode_varint(len(self.tx_ins)) for tx_in in self.tx_ins: result += tx_in.serialize() result += encode_varint(len(self.tx_outs)) for tx_out in self.tx_outs: result += tx_out.serialize() for tx_in in self.tx_ins: result += int_to_little_endian(len(tx_in.witness), 1) for item in tx_in.witness: if type(item) == int: result += int_to_little_endian(item, 1) else: result += encode_varint(len(item)) + item result += int_to_little_endian(self.locktime, 4) return result
def sig_hash(self, input_index, redeem_script=None): 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) else: script_sig = None s += TxIn( prev_tx=tx_in.prev_tx, prev_index=tx_in.prev_index, script_sig=script_sig, sequence=tx_in.sequence, ).serialize() s += encode_varint(len(self.tx_outs)) for tx_out in self.tx_outs: s += tx_out.serialize() s += int_to_little_endian(self.locktime, 4) s += int_to_little_endian(SIGHASH_ALL, 4) h256 = hash256(s) return int.from_bytes(h256, "big")
def serialize(self): result = int_to_little_endian(self.version, 4) result += int_to_little_endian(self.services, 8) result += int_to_little_endian(self.timestamp, 8) result += int_to_little_endian(self.receiver_services, 8) result += b"\x00" * 10 + b"\xff\xff" + self.receiver_ip result += self.receiver_port.to_bytes(2, "big") result += int_to_little_endian(self.sender_services, 8) result += b"\x00" * 10 + b"\xff\xff" + self.sender_ip result += self.sender_port.to_bytes(2, "big") result += self.nonce result += encode_varint(len(self.user_agent)) result += self.user_agent result += int_to_little_endian(self.latest_block, 4) if self.relay: result += b"\x01" else: result += b"\x00" return result
def serialize(self): result = int_to_little_endian(self.version, 4) result += encode_varint(self.num_hashes) result += self.start_block[::-1] result += self.end_block[::-1] return result
def serialize(self): result = encode_varint(len(self.data)) for data_type, identifier in self.data: result += int_to_little_endian(data_type, 4) result += identifier[::-1] return result
def evaluate(self, z, witness): cmds = self.cmds[:] stack = [] altstack = [] while len(cmds) > 0: cmd = cmds.pop(0) if type(cmd) == int: operation = OP_CODE_FUNCTIONS[cmd] if cmd in (99, 100): if not operation(stack, cmds): LOGGER.info("bad op: {}".format(OP_CODE_NAMES[cmd])) return False elif cmd in (107, 108): if not operation(stack, altstack): LOGGER.info("bad op: {}".format(OP_CODE_NAMES[cmd])) return False elif cmd in (172, 173, 174, 175): if not operation(stack, z): LOGGER.info("bad op: {}".format(OP_CODE_NAMES[cmd])) return False else: if not operation(stack): LOGGER.info("bad op: {}".format(OP_CODE_NAMES[cmd])) return False else: stack.append(cmd) if (len(cmds) == 3 and cmds[0] == 0xA9 and type(cmds[1]) == bytes and len(cmds[1]) == 20 and cmds[2] == 0x87): redeem_script = encode_varint(len(cmd)) + cmd cmds.pop() h160 = cmds.pop() cmds.pop() if not op_hash160(stack): return False stack.append(h160) if not op_equal(stack): return False if not op_verify(stack): LOGGER.info("bad p2sh h160") return False redeem_script = encode_varint(len(cmd)) + cmd stream = BytesIO(redeem_script) cmds.extend(Script.parse(stream).cmds) if len(stack) == 2 and stack[0] == b"" and len(stack[1]) == 20: h160 = stack.pop() stack.pop() cmds.extend(witness) cmds.extend(p2pkh_script(h160).cmds) if len(stack) == 2 and stack[0] == b"" and len(stack[1]) == 32: s256 = stack.pop() stack.pop() cmds.extend(witness[:-1]) witness_script = witness[-1] if s256 != sha256(witness_script): print("bad sha256 {} vs {}".format( s256.hex(), sha256(witness_script).hex())) return False stream = BytesIO( encode_varint(len(witness_script)) + witness_script) witness_script_cmds = Script.parse(stream).cmds cmds.extend(witness_script_cmds) if len(stack) == 0: return False if stack.pop() == b"": return False return True
def serialize(self): result = self.raw_serialize() total = len(result) return encode_varint(total) + result