code: def parse_transaction_bytes(tx_bytes):
      
      tx = messages.StellarSignTx()
      unpacker = xdrlib.Unpacker(tx_bytes)
  
      tx.source_account = _xdr_read_address(unpacker)
      tx.fee = unpacker.unpack_uint()
      tx.sequence_number = unpacker.unpack_uhyper()
  
      # Timebounds is an optional field
      if unpacker.unpack_bool():
          max_timebound = 2 ** 32 - 1  # max unsigned 32-bit int
          # (trezor does not support the full 64-bit time value)
  
          tx.timebounds_start = unpacker.unpack_uhyper()
          tx.timebounds_end = unpacker.unpack_uhyper()
  
          if tx.timebounds_start > max_timebound or tx.timebounds_start < 0:
              raise ValueError(
                  "Starting timebound out of range (must be between 0 and "
                  + max_timebound
              )
          if tx.timebounds_end > max_timebound or tx.timebounds_end < 0:
              raise ValueError(
                  "Ending timebound out of range (must be between 0 and " + max_timebound
              )
  
      # memo type determines what optional fields are set
      tx.memo_type = unpacker.unpack_uint()
  
      # text
      if tx.memo_type == MEMO_TYPE_TEXT:
          tx.memo_text = unpacker.unpack_string()
      # id (64-bit uint)
      if tx.memo_type == MEMO_TYPE_ID:
          tx.memo_id = unpacker.unpack_uhyper()
      # hash / return are the same structure (32 bytes representing a hash)
      if tx.memo_type == MEMO_TYPE_HASH or tx.memo_type == MEMO_TYPE_RETURN:
          tx.memo_hash = unpacker.unpack_fopaque(32)
  
      tx.num_operations = unpacker.unpack_uint()
  
      operations = []
      for _ in range(tx.num_operations):
          operations.append(_parse_operation_bytes(unpacker))
  
      return tx, operations
docs: Parses base64data into a map with the following keys:
          tx - a StellarSignTx describing the transaction header
          operations - an array of protobuf message objects for each operation