def __deserialize_stack_item(reader: BinaryReader) -> dict or bytearray: param_type = reader.read_byte() if param_type == BuildParams.Type.bytearray_type.value: b = reader.read_var_bytes() return b elif param_type == BuildParams.Type.bool_type.value: return reader.read_bool() elif param_type == BuildParams.Type.int_type.value: b = reader.read_var_bytes() return ContractDataParser.__big_int_from_bytes(bytearray(b)) elif param_type == BuildParams.Type.struct_type.value or param_type == BuildParams.Type.array_type.value: count = reader.read_var_int() item_list = list() for _ in range(count): item = ContractDataParser.__deserialize_stack_item(reader) item_list.append(item) if param_type == BuildParams.Type.struct_type.value: return Struct(item_list) return item_list elif param_type == BuildParams.Type.dict_type.value: count = reader.read_var_int() item_dict = dict() for _ in range(count): key = ContractDataParser.__deserialize_stack_item(reader) value = ContractDataParser.__deserialize_stack_item(reader) item_dict[key] = value return item_dict else: raise SDKException(ErrorCode.other_error('type error'))
def deserialize(self, reader: BinaryReader): self.index = reader.read_int32() self.peer_pubkey = a2b_hex(reader.read_var_str()).hex() self.address = Address(reader.read_bytes(20)) self.status = reader.read_byte() self.init_pos = reader.read_int64() self.total_pos = reader.read_int64()
def deserialize_stack_item(reader: BinaryReader) -> dict: t = reader.read_byte() if t == BuildParams.Type.bytearray_type.value: b = reader.read_var_bytes() return b elif t == BuildParams.Type.bool_type.value: return reader.read_bool() elif t == BuildParams.Type.int_type.value: b = reader.read_var_bytes() return bigint_from_bytes(b) elif t == BuildParams.Type.struct_type.value or t == BuildParams.Type.array_type.value: count = reader.read_var_int() # TODO item_list = list() for _ in range(count): item = deserialize_stack_item(reader) item_list.append(item) if t == t == BuildParams.Type.struct_type.value: return Struct(item_list) return item_list elif t == BuildParams.Type.dict_type.value: count = reader.read_var_int() item_dict = dict() for _ in range(count): key = deserialize_stack_item(reader) value = deserialize_stack_item(reader) item_dict[key] = value return item_dict else: raise SDKException(ErrorCode.other_error('type error'))
class VmReader(object): def __init__(self, bys: bytearray): self.ms = StreamManager.GetStream(bys) self.reader = BinaryReader(self.ms) self.code = bys def read_byte(self): return self.reader.read_byte() def read_bool(self): b = self.reader.read_byte() return b == 1 def read_bytes(self, count: int): return self.reader.read_bytes(count) def read_var_bytes(self): return self.reader.read_var_bytes() def read_uint16(self): return self.read_uint16() def read_uint32(self): return self.reader.read_int32() def read_uint64(self): return self.reader.read_int64() def position(self): return self.reader.stream.tell() def read_int16(self): try: res = bytearray(self.reader.read_bytes(2)) res.reverse() return int(res.hex(), 16) except Exception as e: return 0 def read_var_int(self): return self.reader.read_var_int() def seek(self, offset: int): return self.reader.stream.seek(offset)
def read_bytes(reader: BinaryReader): code = reader.read_byte() if code == int.from_bytes(PUSHDATA4, 'little'): temp = reader.read_uint32() key_len = temp elif code == int.from_bytes(PUSHDATA2, 'little'): temp = reader.read_uint16() key_len = int(temp) elif code == int.from_bytes(PUSHDATA1, 'little'): temp = reader.read_uint8() key_len = int(temp) elif int.from_bytes(PUSHBYTES75, 'little') >= code >= int.from_bytes(PUSHBYTES1, 'little'): key_len = code - int.from_bytes(PUSHBYTES1, 'little') + 1 else: key_len = 0 res = reader.read_bytes(key_len) return res
def get_program_info(program: bytes) -> ProgramInfo: length = len(program) end = program[length - 1] temp = program[:length - 1] ms = StreamManager.get_stream(temp) reader = BinaryReader(ms) info = ProgramInfo() if end == int.from_bytes(CHECKSIG, 'little'): pub_keys = ProgramBuilder.read_bytes(reader) info.set_pubkey([pub_keys]) info.set_m(1) elif end == int.from_bytes(CHECKMULTISIG, 'little'): length = program[len(program) - 2] - int.from_bytes(PUSH1, 'little') + 1 m = reader.read_byte() - int.from_bytes(PUSH1, 'little') + 1 pub = [] for _ in range(length): pub.append(reader.read_var_bytes()) info.set_pubkey(pub) info.set_m(m) return info