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

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

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

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

Портируем
Все совсем не так сложно как могло бы показаться на первый взгляд. Ребята из Coinomi не писали ядро с  нуля, а обернули знаменитый bitcoinj. Эта библиотека давно служит мне верой и правдой. На её основе можно делать "легкий" мобильный кошелёк, можно делать "полную ноду" со скачиванием всего блокчейна, а можно и вот такое чудо: кошелёк кошельков. Coinomi добавляет несколько своих абстракций типа WalletAccount, которые позволяют описать специфику разных криптовалют. Вместо этого не нужно беспокоиться о синхронизации и загрузке блокчейна: данные о транзакциях можно получить с серверов Сoinomi по stratum-протоколу. Так же примерно работают остальные "лёгкие" кошельки вроде Bither или Mycelium. 
Ядро кошелька, которое нужно будет взять из проекта Coinomi это два пакета классов com.coinomi.core и com.coinomi.stratumj. Также берём и все зависимости. Структура проекта показана на скрине справа. 

Интерфейс
Проектировать серверные приложения удобно начиная с API, а клиентские (Desktop, Android) удобнее с UI. Поскольку нам нужно универсальное приложение для всех десктопных платформ, мы естественно используем Java, а чтобы рисовать под неё окошки -  Swing JavaFX. Конечно же, на улице ведь 21 век, какой Swing?
Такой выбор инструментов определяет структуру нашего проекта. В Main-классе мы инициализируем приложение, ищем и загружаем существующий кошелёк (в текущей папке) а если не находим - начинаем процесс его создания или импорта. Весь процесс - последовательность экранов. Один экран - один fxml файл из пакета layout и "обслуживающий" её контроллер из пакета controller. Все контроллеры могут вызывать другие экраны по необходимости используя метод refreshLayout из Main. Этот метод принимает ShowListener, реализация которого позволяет вызывающему классу обратиться к вызываемому, когда все поля интерфейса уже проинициализированы и их можно заполнить значениями. Так выполняется передача данных между экранами. 

Чтобы долго не описывать вот вам схема переходов от первого запуска:
Вначале генерируем клиенту мнемонический код мастер-ключа и заставляем клиента ввести его на следующем экране. Так мы убеждаемся что клиент записал код и не потеряет деньги по неосторожности. Потом клиент придумывает и вводит пароль. Этим паролем шифруется файл кошелька, который мы создаём в текущей директории. Следующий шаг (при повторных входах первый) - главный экран. С него можно добавлять новые типы крипровалют в кошелёк. Bitcoin добавлен по умолчанию. Можно отправлять и получать платежи. Все как в обычных кошельках. В разделе "Настройки" можно посмотреть свой код восстановления, если бекап созданный при первом старте почему-то потерялся. Можно сменить пароль. При этом wallet.dat перешифруется. 

Безопасно?
Украсть wallet.dat можно: desktop-платформы более уязвимы чем мобильные. Но кроме как посмотреть баланс сделать мошенник ничего не сможет: ключи, которыми подписываются транзакции зашифрованы тем самым паролем, который клиент задал при входе. 
Код восстановления не шифруется, так что не храните его в электронном виде. На бумажку и в сейф. Если забыли пароль - это ваш шанс вернуть деньги: просто удалите wallet.dat и восстановите кошелёк из кода. 

Надёжно? 
Проекту несколько недель (4-5 дней собственно разработки). Отловить все баги за это время нереально. Исходники открыты, багрепорты приветствуются. Скачать можно тут. Запускаем как обычно: java -jar milticoin.jar

Если нашли баг, есть предложение, идея - пишите в комментариях. Если баг не даёт работать, может привести к потере денег - создавайте issue

2 комментария:

  1. Добрый вечер, как с Вами связаться? Есть вопрос, хотелось бы обсудить, касается qr сканера.

    ОтветитьУдалить
  2. Напишите пожалуйста на 181276@list.ru

    ОтветитьУдалить