воскресенье, 13 марта 2016 г.

Один кошелёк для 30+ криптовалют

Давным-давно я увлекался bitcoin, потом забыл на пару лет, а вот теперь вспомнил. Форки bitcoin и просто альтернативные криптовалюты подросли с тех пор. Кое-кто уже перевалил за миллиард по рыночной капитализации. И подумалось мне, а не запастись ли сотней-другой монеток нескольких перспективных форков? Вдруг подорожают?
Сказано-сделано. Читаем о криптовалютах, выбираем "инвестиционный инструмент". Выбрали, покупаем на бирже. И выводим с биржи от греха подальше. А то мало ли что...
Сохраняем монеты на своей машине в локальных кошельках, чтобы не рисковать внезапным отказом какого-нибудь стороннего сервиса. Бекапим, все как положено... 
И вот тут первая проблема: много разных кошельков. Каждый требует установки, синхронизации, обновления, бекапа... Нет, если бы речь шла о миллионах - не жалко. Но пока наши монетки стоят недорого и возиться со всем этим как-то не хочется. И если бы просто сбекапить кошельки и забыть... Но нет, хочется иногда и поторговать, монеты нужно заводить на биржу, выводить. 

Итак, ищем "мультикошелёк"
Такой есть. Замечательное приложение Coinomi позволит убрать с вашего мобильного десяток разнокалиберных кошельков, заменив их одним удобным и приятным интерфейсом. Все монеты хранятся в одном кошельке. Это позволяет их бекапить и восстанавливать одним движением, что не может не радовать. 
Это возможно благодаря тому, что криптография всех поддерживаемых валют работает одинаково. Есть один root - ключ, от которого можно произвести любое количество "ветвей"-кошельков. Каждый адрес для получения средств каждой монеты может быть заново получен из корневого ключа. Сам же корневой ключ может быть представлен как последовательность из нескольких слов. Такой бекап можно в конце концов просто запомнить. 
Попробовав Coinomi на Android вы, несомненно захотите держать такой же кошелёк на вашем ноутбуке. Бекапим кошелёк на одном устройстве и восстанавливаем на другом. Теперь ваши монеты доступны или "на ходу" с мобильного или в спокойной "десктопной" обстановке. И тут разочарование... Нет десктопной версии Coinomi. Обещали ещё год назад, но увы... 
Но мы же программисты! А лучший кошелёк - тот в котором ты на 100% уверен. А значит тот, что написан (в нашем случае портирован из открытых исходников) "вот этими руками" :)

четверг, 18 июня 2015 г.

Git: делаем удалённый репозиторий

Ещё одно простое решение для простой задачи.
Немного предистории. Когда-то давно я задумался о том как хранить свои исходники в репозитории на своём vds. Тогда я пользовался Subversion и не считал ssh-туннели для доступа к репозиторию избыточной сложностью. Теперь я постарел, стал ленивым и полюбил git.
Что может быть проще, чем git init в корне проекта? И уже можно пользоваться всеми преимуществами контроля версий без всякого сервера.
Следующий шаг: проект уже вырос и паранойя выросла вместе с ним. Все разработчики делятся не два вида: одни ещё ни разу не теряли исходники а другие уже делают git push в конце каждого рабочего дня :)

среда, 27 мая 2015 г.

Https в Android: делаем правильно

To что я опишу ниже - не открытие и не тайна. Это есть даже в официальной документации. Проблема в том, что большинство программистов под Android (и я в том числе) пришли из других, более старых платформ, где проблемы с ssl решались иначе или не возникали вообще.
Например, если сертификат вашего сервера почему-то не в порядке (например он самоподписной), то решение отключить проверку сертификата напрашивается само собой. Такое себе "быстрое решение". В результате вроде бы https и все круто, но на публичном wifi ваш клиент рискует пообщаться по "защищенному" каналу с мошенником. Или, к примеру, вы подключаетесь по ip к своему серверу, а в сертификате прописан домен. Отключаем проверку домена? Давайте не будем спешить. Есть решение которое в "особых" случаях не только не снижает безопасность соединения вашего приложения с сервером но и повышает её до воистину параноидального уровня.

среда, 21 января 2015 г.

Самый "легкий" Java - сервер

Когда я начинал работать в Java EE, серверная инфраструктура казалась мне загадочным капризным монстром. И это при том, что в программирование я пришёл из админов. Залил ear в Resin, проверь, поднялся ли? Успешно ли распаковался? Однажды мы с админами потратили полночи чтобы понять, почему после успешного вроде бы деплоя на запросы отвечает по-прежнему старая копия приложения. При таких танцах с бубном переход на GlassFish казался хорошим решением, а отказ от ejb - ещё лучшим. Кто-то из моих коллег радовался могуществу Spring, кто-то искал что-то попроще... Я писал сервлеты под tomcat, а когда делал что-то совсем маленькое - просто встраивал jetty.
Чем проще, тем лучше. Понятно, что есть нетривиальные требования, есть сложные задачи. Но признаемся себе, сколько простых ненагруженных сервисов вы реализовали используя слишком мощные и сложные инструменты? "Я привык к этому фреймфорку и не хочу терять скилл" - слышу я обычно. "Ты уйдёшь и тот, кто будет поддерживать этот монстрокод, проклянёт тебя" - думаю я в ответ.
Может я и не убедил вас писать простые вещи простыми средствами, но посмотрите все-таки как можно сделать серверное java-приложение вообще без сервера. Это, в конце концов, интересно.

четверг, 6 февраля 2014 г.

Netty: делаем лёгкий сервер с блэкджеком и аннотациями

Допустим вам нужно обрабатывать http-запросы в своём приложении... Пишем на servlet-ах! Spring!! ЕщёКакойТоФреймворк!!!
A теперь нам нужно слушать websocket... Выбор сужается? А завтра потребуется добавить поддержку SMPP или какого-нибудь ещё "необычного" протокола? Рано или поздно вам прийдётся создать консольное java-приложение и начать изучать "встраиваемые" сервера. Встроить можно много чего, но что если фантазия разработчиков "с той стороны internet-а" родит совсем уже неведомый протокол? И тут мы вспомним о Netty. На его основе можно реализовать практически что угодно, при чём такая универсальность не пойдёт в ущерб ни производительности ни простоте. Чтобы подтвердить свою мысль я ниже сделаю свой "крошечный" http-сервер, в который можно будет добавлять "сервлетообразные" обработчики, "навешивая" их на url с помощью аннотаций.

пятница, 24 января 2014 г.

Handler - маленький помошник Android разработчика

Всем привет, хочу поделиться методологией применения инструмента созданного облегчить разработку приложений (на сцену выходит Handler).

В кратце android.os.Handler это абстракция позволяющая "выполнять" в указаной очередности другие абстракции - события. А что же такое событие? На реализации событиями являются android.os.Message и обычные Runnable.

Немного по делу. Знакомо CalledFromWrongThreadException? Если да, то runOnUiThread не будет открытием, иначе все впереди:).  Рано или поздно у каждого из нас возникает необходимость обновить views после получения данных которое чаще всего выполняется в другом(не главном) потоке. "AsyncTask!" - скажите вы, "Отлично!" - отвечу я. Что общего между runOnUiThread и AsyncTask? Версия выхода не считается;)
Давайте посмотрим на реализацию в фреймфорке.

Случай №1:

    public final void runOnUiThread(Runnable action) {
        if (Thread.currentThread() != mUiThread) {
            mHandler.post(action);
        } else {
            action.run();
        }
    }

Случай №2. Реализация вызова onPostExecute в AsyncTask:

   private Result postResult(Result result) {
        Message message = sHandler.obtainMessage(MESSAGE_POST_RESULT,
                new AsyncTaskResult<Result>(this, result));
        message.sendToTarget();
        return result;
    }
    private void finish(Result result) {
        if (isCancelled()) {
            onCancelled(result);
        } else {
            onPostExecute(result);
        }
    }
    private static class InternalHandler extends Handler {
        public void handleMessage(Message msg) {
            AsyncTaskResult result = (AsyncTaskResult) msg.obj;
            switch (msg.what) {
                case MESSAGE_POST_RESULT:
                    result.mTask.finish(result.mData[0]);
                    break;
                .........................
            }
        }
    }