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(self): # get the raw serialization (no prepended length) result = self.raw_serialize() # get the length of the whole thing total = len(result) # encode_varint the total length of the result and prepend return encode_varint(total) + result
def serialize(self): '''Serialize this message to send over the network''' # version is 4 bytes little endian result = int_to_little_endian(self.version, 4) # services is 8 bytes little endian result += int_to_little_endian(self.services, 8) # timestamp is 8 bytes little endian result += int_to_little_endian(self.timestamp, 8) # receiver services is 8 bytes little endian result += int_to_little_endian(self.receiver_services, 8) # IPV4 is 10 00 bytes and 2 ff bytes then receiver ip result += b'\x00' * 10 + b'\xff\xff' + self.receiver_ip # receiver port is 2 bytes, big endian result += self.receiver_port.to_bytes(2, 'big') # sender services is 8 bytes little endian result += int_to_little_endian(self.sender_services, 8) # IPV4 is 10 00 bytes and 2 ff bytes then sender ip result += b'\x00' * 10 + b'\xff\xff' + self.sender_ip # sender port is 2 bytes, big endian result += self.sender_port.to_bytes(2, 'big') # nonce should be 8 bytes result += self.nonce # useragent is a variable string, so varint first result += encode_varint(len(self.user_agent)) result += self.user_agent # latest block is 4 bytes little endian result += int_to_little_endian(self.latest_block, 4) # relay is 00 if false, 01 if true if self.relay: result += b'\x01' else: result += b'\x00' return result
def evaluate(self, z, witness): # create a copy as we may need to add to this list if we have a # RedeemScript cmds = self.cmds[:] stack = [] altstack = [] while len(cmds) > 0: cmd = cmds.pop(0) if type(cmd) == int: # do what the opcode says operation = OP_CODE_FUNCTIONS[cmd] if cmd in (99, 100): # op_if/op_notif require the cmds array if not operation(stack, cmds): LOGGER.info('bad op: {}'.format(OP_CODE_NAMES[cmd])) return False elif cmd in (107, 108): # op_toaltstack/op_fromaltstack require the altstack if not operation(stack, altstack): LOGGER.info('bad op: {}'.format(OP_CODE_NAMES[cmd])) return False elif cmd in (172, 173, 174, 175): # these are signing operations, they need a sig_hash # to check against 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: # add the cmd to the stack stack.append(cmd) # p2sh rule. if the next three cmds are: # OP_HASH160 <20 byte hash> OP_EQUAL this is the RedeemScript # OP_HASH160 == 0xa9 and OP_EQUAL == 0x87 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 # we execute the next three opcodes cmds.pop() h160 = cmds.pop() cmds.pop() if not op_hash160(stack): return False stack.append(h160) if not op_equal(stack): return False # final result should be a 1 if not op_verify(stack): LOGGER.info('bad p2sh h160') return False # hashes match! now add the RedeemScript redeem_script = encode_varint(len(cmd)) + cmd stream = BytesIO(redeem_script) cmds.extend(Script.parse(stream).cmds) # witness program version 0 rule. if stack cmds are: # 0 <20 byte hash> this is p2wpkh # tag::source3[] if len(stack) == 2 and stack[0] == b'' and len(stack[1]) == 20: # <1> h160 = stack.pop() stack.pop() cmds.extend(witness) cmds.extend(p2pkh_script(h160).cmds) # end::source3[] # witness program version 0 rule. if stack cmds are: # 0 <32 byte hash> this is p2wsh # tag::source6[] if len(stack) == 2 and stack[0] == b'' and len(stack[1]) == 32: s256 = stack.pop() # <1> stack.pop() # <2> cmds.extend(witness[:-1]) # <3> witness_script = witness[-1] # <4> if s256 != sha256(witness_script): # <5> 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 # <6> cmds.extend(witness_script_cmds) # end::source6[] if len(stack) == 0: return False if stack.pop() == b'': return False return True
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 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