def get_funds_fields_from_struct(self, buf: bytes) -> bytes: """ Gets all funds fields for a transaction from a buffer. :param buf: Bytes of a serialized transaction :type buf: bytes :return: A buffer containing the remaining struct bytes :rtype: bytes :raises ValueError: when the sequence of bytes is incorect """ (self.version, inputs_len, outputs_len), buf = unpack(_FUNDS_FORMAT_STRING, buf) for _ in range(inputs_len): txin, buf = TxInput.create_from_bytes(buf) self.inputs.append(txin) for _ in range(outputs_len): txout, buf = TxOutput.create_from_bytes(buf) self.outputs.append(txout) # token name and symbol self.token_name, self.token_symbol, buf = TokenCreationTransaction.deserialize_token_info(buf) return buf
def deserialize_token_info(cls, buf: bytes) -> Tuple[str, str, bytes]: """ Gets the token name and symbol from serialized format """ (token_info_version,), buf = unpack('!B', buf) if token_info_version != TOKEN_INFO_VERSION: raise ValueError('unknown token info version: {}'.format(token_info_version)) (name_len,), buf = unpack('!B', buf) name, buf = unpack_len(name_len, buf) (symbol_len,), buf = unpack('!B', buf) symbol, buf = unpack_len(symbol_len, buf) # Token name and symbol can be only utf-8 valid strings for now decoded_name = decode_string_utf8(name, 'Token name') decoded_symbol = decode_string_utf8(symbol, 'Token symbol') return decoded_name, decoded_symbol, buf
def bytes_to_output_value(buf: bytes) -> Tuple[int, bytes]: (value_high_byte, ), _ = unpack('!b', buf) if value_high_byte < 0: output_struct = '!q' value_sign = -1 else: output_struct = '!i' value_sign = 1 try: (signed_value, ), buf = unpack(output_struct, buf) except StructError as e: raise InvalidOutputValue('Invalid byte struct for output') from e value = signed_value * value_sign assert value >= 0 if value < _MAX_OUTPUT_VALUE_32 and value_high_byte < 0: raise ValueError('Value fits in 4 bytes but is using 8 bytes') return value, buf
def create_from_bytes(cls, buf: bytes) -> Tuple['TxOutput', bytes]: """ Creates a TxOutput from a serialized output. Returns the output and remaining bytes """ value, buf = bytes_to_output_value(buf) (token_data, script_len), buf = unpack('!BH', buf) script, buf = unpack_len(script_len, buf) txout = cls(value, script, token_data) return txout, buf
def create_from_bytes(cls, buf: bytes) -> Tuple['TxInput', bytes]: """ Creates a TxInput from a serialized input. Returns the input and remaining bytes """ input_tx_id, buf = unpack_len(TX_HASH_SIZE, buf) (input_index, data_len), buf = unpack('!BH', buf) input_data, buf = unpack_len(data_len, buf) txin = cls(input_tx_id, input_index, input_data) return txin, buf
def get_graph_fields_from_struct(self, buf: bytes) -> bytes: """ Gets graph fields for a block from a buffer. :param buf: Bytes of a serialized transaction :type buf: bytes :return: A buffer containing the remaining struct bytes :rtype: bytes :raises ValueError: when the sequence of bytes is incorect """ buf = super().get_graph_fields_from_struct(buf) (data_bytes,), buf = unpack('!B', buf) self.data, buf = unpack_len(data_bytes, buf) return buf
def create_from_struct(cls, struct_bytes: bytes) -> 'Transaction': try: tx = cls() buf = tx.get_fields_from_struct(struct_bytes) if len(buf) != cls.SERIALIZATION_NONCE_SIZE: raise ValueError('Invalid sequence of bytes') [ tx.nonce, ], buf = unpack('!I', buf) except struct.error: raise ValueError('Invalid sequence of bytes') tx.update_hash() return tx
def get_funds_fields_from_struct(self, buf: bytes) -> bytes: """ Gets all funds fields for a block from a buffer. :param buf: Bytes of a serialized block :type buf: bytes :return: A buffer containing the remaining struct bytes :rtype: bytes :raises ValueError: when the sequence of bytes is incorect """ (self.version, outputs_len), buf = unpack(_FUNDS_FORMAT_STRING, buf) for _ in range(outputs_len): txout, buf = TxOutput.create_from_bytes(buf) self.outputs.append(txout) return buf
def get_graph_fields_from_struct(self, buf: bytes) -> bytes: """ Gets all common graph fields for a Transaction and a Block from a buffer. :param buf: Bytes of a serialized transaction :type buf: bytes :return: A buffer containing the remaining struct bytes :rtype: bytes :raises ValueError: when the sequence of bytes is incorect """ (self.weight, self.timestamp, parents_len), buf = unpack(_GRAPH_FORMAT_STRING, buf) for _ in range(parents_len): parent, buf = unpack_len(TX_HASH_SIZE, buf) # 256bits self.parents.append(parent) return buf