Привет, Хабр! На связи компания B2Broker, провайдер ликвидности и технологических решений для брокерской и биржевой индустрии. Один из наших продуктов — трейдинговая платформа B2BX.exchange. Когда летом 2017 года мы запускали платформу, то задумались о том, как принимать криптовалюты и какой процессинг использовать. Увы, никто на тот момент не был готов дать хоть какие-либо гарантии по уязвимости контракта, да и история с атакой платформы DAO была еще на слуху. Мы не хотели идти по стопам DAO. К тому же, у нас были некоторые наработки по приему платежей через блокчейн. Так что мы решили самостоятельно проработать весь цикл проведения блокчейн-платежей. В этом посте мы расскажем о том, что у нас получилось, и, что самое интересное, — о том, какие проблемы нам пришлось решить в процессе.


Источник: ripplecoinnews.com

В процессе работы над платежной системой мы поняли, что можем сделать сервис не только для нашей платформы B2BX.exchange, но и полностью самостоятельный продукт. Мы назвали его B2BinPay.

Из чего состоит B2BinPay


Платежная система разделена на несколько базовых частей. Все они написаны на PHP.

Первая часть системы отвечает за взаимодействие с блокчейнами, то есть за прием, отправку и отслеживание платежей.

Вторая часть — это API. Он занимается взаимодействием с потребителями услуг и биржами: оповещает о поступлении средств, осуществляет обмен криптовалют. API написан с использованием фреймворка Laravel.

Третья часть — кабинет эквайринга для потребителей. В нем отражаются состояние системы в целом, подключенные кошельки и их балансы, активные транзакции и счета. Возможно, скоро мы подключим и классический фиатный эквайринг. Для создания кабинета мы задействовали Yii2.

Отдельный блок — это система работы с ICO-проектами. Она позволяет распределять токены на всех этапах распродажи. К ней дополнительно идет возможность разработки контракта (ERC-20) и личный кабинет. С помощью этих инструментов мы предоставляем услугу ICO «под ключ».



В целях безопасности все данные о кошельках хранятся в БД в зашифрованном виде, поэтому даже если злоумышленник получит к ним доступ, он не сможет вывести средства с кошельков. Подключена двухфакторная аутентификация пользователей. Наконец, мерчант может создать белый список IP-адресов, которые могут работать с API.

Отказоустойчивость системы мы обеспечиваем большим количеством серверов, в том числе и резервных. Каждая блокчейн-нода располагается на отдельном сервере с ограничением доступа извне.

С какими проблемами мы столкнулись?


Блокчейны бывают разные. Некоторые плохо документированы и не имеют активного комьюнити. В основном это и стало причиной наших основных проблем.

1. У API Ethereum нет возможности возвращать списки входящих транзакций аккаунта

При создании счета наша платежная система генерирует уникальный адрес, на который пользователь должен перевести определенную сумму в выбранной валюте. С заданной периодичностью мы получаем список входящих транзакций и сверяем адреса их кошельков. Потом сверяем адреса кошельков с адресами еще неоплаченных счетов. Как выяснилось, эфир не позволяет получить информацию о входящих транзакциях.

Что делать? Мы решили получать транзакции с помощью стороннего сервиса — etherscan.io. Но у него вскрылись некоторые проблемы, так что мы переходим на explorer — сервис, написанный нашими программистами.

2. У некоторых блокчейнов чрезвычайно скудная документация

Вот типичный случай: как-то развернули мы ноду одной из малоизвестных криптовалют, а через несколько дней она перестала принимать транзакции, не сообщая о каких-либо ошибках. Мы ее перезапустили, но через несколько дней ситуация повторилась.

Что делать? Когда начали разбираться, выяснили, что проблема — в одном из параметров в файле конфигурации. В документации об этом параметре не было ни слова, поэтому пришлось все настраивать методом проб и ошибок.



3. Приватный блокчейн для тестирования функциональности сложно или просто невозможно развернуть

Однажды нам понадобилось развернуть блокчейн для криптовалюты NEO. Мы нашли готовый docker образ, сделали все по инструкции и получили ошибку. Беглый анализ скриптов ни к чему не привел, Гугл тоже ничего не подсказал.

Что делать? Мы создали issue на github, потратили около месяца на обсуждения и в итоге все-таки решили разворачивать testnet. Но далеко не каждая криптовалюта имеет testnet. А если и имеет, то чаще всего нужно отправлять заявку на получение тестовых койнов и ждать некоторое время. Развертка приватного блокчейна на официальных сайтах в большинстве случаев даже не рассматривается, поэтому приходится использовать сторонние решения.

Справедливости ради стоит сказать, что в большинстве случаев получить ответы на вопросы, связанные с инфраструктурой той или иной криптовалюты, можно. Самый полезный ресурс в этом смысле — Github, затем стоит идти на официальные форумы и Reddit.

4. Нерациональное повторное использование кода

У биткойна со временем появилось множество копий с отдельными блокчейнами и блоками — не стоит путать их с форками. В большинстве случаев такие криптовалюты имеют абсолютно идентичный биткойну API. Чтобы не множить одинаковый код, для работы с такими копиями мы используем тот же класс, что и для работы с валютой Сатоши Накамото.

Но здесь может быть не все так просто. Когда нам потребовалось интегрировать Dogecoin, мы поступили по описанному сценарию, настроили и развернули testnet. В итоге некоторые тесты упали и появились проблемы с созданием транзакций.

Что делать? Сначала мы прогнали тест через дебаггер. Выяснилось, что Dogecoin в запросе на создание транзакции не позволяет передавать сумму в виде строки, как это делает биткойн. Из-за этого нам пришлось переопределять метод в дочернем классе. К слову, это единственное выявленное различие в API Dogecoin и Bitcoin. В чем его смысл — непонятно.

5. Не все криптовалюты позволяют генерировать неограниченное количество уникальных адресов

Здесь все просто: без этой генерации мы не можем использовать идентификацию платежа по адресу.

Что делать? В таких ситуациях мы используем уникальное сообщение, которое прикрепляется к транзакции при отправке платежа. К сожалению, некоторые клиенты забывают указывать эти сообщения и потом удивляются, почему платеж не зачислился в автоматическом режиме.

Как интегрироваться в CMS?


Мы сделали плагины B2BinPay для WordPress, Woocommerce, Magento, PrestaShop. Здесь аппетит пришел во время еды — изначально мы не планировали продвигать систему через плагины для CMS. Для каждого плагина мы делали ревью в системе. Самое серьезное получилось для плагина Magento, расскажем об этом ревью подробней.

Ревью делится на две части — Technical и Marketing. Техническая проверка состоит из четырех этапов:

  • Code Sniffer
  • Installation & Varnish Test
  • Copy Paste Detector
  • Manual QA

Первые три этапа полностью автоматизированы, так что здесь лучше учесть некоторые вещи на этапе разработки. Чтобы упростить себе жизнь во время проверки, прежде всего, нужно помнить о правилах для Code Sniffer.

Правила Magento для Code Sniffer соответствуют стандартам PSR-1 и PSR-2, это одна из немногих CMS, разработчики которой придерживаются современных подходов к разработке на PHP. Кроме того, ребята из Magento опубликовали отдельный набор правил, который помогает найти ошибки в xml-конфигурациях структуры расширения и дополняет общепринятые проверки. Также на их github-аккаунте опубликован скрипт проверки содержимого готового пакета, которым также стоит воспользоваться перед тем, как отправлять свою разработку на автоматизированную проверку.

Базовая установка Magento содержит бутстрап-класс для phpunit: его можно использовать для написания тестов к своему плагину. Честно говоря, мы так и не выяснили, способствует ли наличие тестов быстрому прохождению Technical Review.



Три первых этапа технической проверки проходят автоматически. Для четвертого этапа и для Marketing Review придется запастись терпением: оба процесса выполняются людьми и из-за этого образуются очереди.

Мы ждали результатов Manual QA около 5 дней, что в принципе нормально. А вот каждая наша заявка на Marketing Review обрабатывалась больше недели. Здесь проверяющим было важно, чтобы в первых абзацах мы написали, интеграцию с каким сервисом предоставляем и какая у него модель ценообразования, и только потом указывали достоинства нашего плагина.

Планы на будущее


Мы рассчитываем, что B2BinPay получился достаточно простым в плане взаимодействия с пользователями и поэтому будет удобен как компаниям-новичкам на рынке крипты, так и продвинутому бизнесу — например, в сфере интернет-продаж — где нужен стабильный и безопасный продукт.

На старте первичного обращения монет мы принимали Bitcoin, Bitcoin CASH, Litecoin, DASH, Ethereum, Monero и другие. Сейчас мы предлагаем сервисы для мерчантов и кошельки для энтерпрайз-клиентов под нашей эстонской компанией, на которую мы получили две лицензии — для обмена криптовалют и для кошельков.

При онбординге клиентов мы делаем полноценный KYC по каждому мерчанту, после чего мерчант может начать прием криптовалют, которые автоматически конвертируется в доллары, евро или фунты и выплачивается на банковский счет мерчанту.

Будем рады ответить на ваши вопросы по созданию B2BinPay и по самому продукту в принципе. Кроме того, сейчас мы активно ищем единомышленников, которые обладают навыками программирования на Python и готовы присоединиться к нашей команде. Сейчас у нас в Санкт-Петербурге открыты вакансии тимлида и senior-разработчика. Будем рады вашим резюме!

Комментарии (18)


  1. hazratgs
    26.02.2019 12:51

    Есть еще замечательный open source решение btcpay, но там только btc и ltc
    Удобно выставлять счет в нужной валюте


    1. trase8
      26.02.2019 14:20

      Чет не открывается линк



    1. b2broker Автор
      26.02.2019 19:14

      Вообще не отрицаем замечательность. Но мы не забываем про легкость интеграции и про удобство использования мерчантом, а не только покупателем.

      Мы только пришли на Хабр, нет возможности поставить вам ни плюс, ни минус :)


      1. hazratgs
        26.02.2019 19:31

        Там как раз легкость интеграции, можно просто html форму добавить и все, они реализуют полностью api bitpay


  1. Luxo
    26.02.2019 20:29

    Относительно проблемы с Ethereum.
    Правильно ли я догадываюсь, что вы не можете через API узнать о входящей транзакции, если она пришла с контракта, а не с адреса?


    1. b2broker Автор
      27.02.2019 13:36

      Как мы написали в статье, через RPC-API эфира мы не можем получить список входящих транзакций аккаунта, независимо от того, была ли отправлена транзакция с обычного адреса или с адреса контракта.
      Сторонние же сервисы (например, etherscan) позволяют получить список всех входящих транзакций со всех типов адресов.


    1. stepancher
      27.02.2019 14:48

      У Ethereum нет API. Есть только RPC, в котором нет метода — дай мне все транзакции по «Аккаунту 1». Поэтому приходится мониторить все блоки и смотреть, а не было ли там транзакции по нужному аккаунту))

      API есть у etherscan.io, но использовать сторонний инструмент в своем процессинге — не комильфо…


      1. Luxo
        28.02.2019 00:22

        Ну, я написал «API Ethereum» просто потому что так было написано в статье)
        Справляется ли ваше решение с приходом денег с контрактов? Потому что в моём понимании (возможно неверном) это почти невозможно.


        1. b2broker Автор
          01.03.2019 12:18

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


  1. lavilav
    27.02.2019 19:20

    сейчас у bitcoin rpc есть нормальный api для работы с мультикошельками?
    когда-то давно нельзя было сделать на одной ноде динамическое управление кошельками, нужно было рестартовать демон при добавлении кошелька.
    Затем в 2017 был ряд комитов для работы с этим добром, но как-то через пень колоду казалось на тот момент.


  1. Psychosynthesis
    28.02.2019 06:46

    А опишите вкратце какую задачу вы решаете? Что-то типа универсального обменника со своим API, насколько я понял. Чем это принципиально отличается от бирж в таком случае?


    1. b2broker Автор
      28.02.2019 15:44

      Нет, мы не обмениваем одну валюту на другую, а предоставляем технологическое решение для приёма платежей в криптовалюте. Биржи — это не конкуренты, а, скорее, клиенты для нас. Вам судить уместно ли такое сравнение, но мы выполняем функции PayPal в криптовалютном мире.

      Задача, которую мы решаем — прием криптоплатежей. Сейчас легко купить холодильник за доллары или пополнить счет у брокера через интернет, потому что для этого есть вся инфраструктура. Попробуйте купить холодильник за риппл? Мы — это инфраструктура, чтобы вы могли купить холодильник за рипплы, а продавец мог принять такой платеж.


      1. Psychosynthesis
        28.02.2019 15:59

        Так, вообще звучит интересно.

        Мы — это инфраструктура, чтобы вы могли купить холодильник за рипплы, а продавец мог принять такой платеж.
        А продавцу вы такой платёж будете фиатом зачислять?


        1. b2broker Автор
          01.03.2019 12:17

          Такая возможность есть. Система довольна гибкая в этом плане.
          Продавец может получить свои средства как в фиате (USD, EUR), так и в любой из множества поддерживаемых криптовалют (необязательно в той, в которой пришел платеж нам).


  1. Magestro
    28.02.2019 11:59

    Не хотите в тегах исправить `python` на `PHP` (либо наоборот в тексте)?)


    1. b2broker Автор
      01.03.2019 11:58

      Мы в данный момент ищем python-разработчиков. Возможно, благодаря тегу, такие люди прочитают статью и узнают о нас)


  1. maxtm
    01.03.2019 11:39

    Не все криптовалюты позволяют генерировать неограниченное количество уникальных адресов

    Уточните, пожалуйста, какие например?

    Увы, никто на тот момент не был готов дать хоть какие-либо гарантии по уязвимости контракта, да и история с атакой платформы DAO была еще на слуху.

    Контракты — это только в эфире (не считая новомодных монет), вам же нужен был bitcoin, ripple, litecoin и т.д. дак при чем тут гарантии на контракт?