Перейти к основному содержимому
Unlisted page
This page is unlisted. Search engines will not index it, and only users having a direct link can access it.

Интеграция для бирж и мерчантов

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

Пользовательских депозитных адресов не существует

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

  • В реестре нет адресов. См. модель MimbleWimble.
  • Нет запроса баланса или истории. Нечего опрашивать.
  • Единственный идентификатор в цепочке — обязательство (commitment) выхода, ослеплённая точка, не раскрывающая ни участника, ни сумму.
  • Депозит не может поступить без участия получателя. Перевод в Epic является интерактивным, поэтому ваша сторона должна участвовать в его построении. См. интерактивные транзакции.

Атрибуция, следовательно, не может исходить из цепочки. Она должна исходить из транспорта.

Что их заменяет

Передавайте идентификатор аккаунта в эндпоинте депозита. Предоставьте каждому пользователю отдельный URL, пусть кошелёк пользователя отправляет на этот URL, и фиксируйте отправителя по пути. Транспорт несёт идентификацию; цепочка — нет.

Разверните слушателей кошелька за обратным прокси, который отображает каждый пользовательский путь на Foreign API кошелька, и записывайте атрибуцию при поступлении слейта (slate).

Привязать пользовательский путь к слушателю

Специфичная для Epic часть — один блок location внутри вашего существующего TLS-сервера. Он извлекает идентификатор аккаунта из пути, передаёт его в ваш сервис атрибуции в виде заголовка и отклоняет все остальные пути:

/etc/nginx/conf.d/epic-deposits.conf
location ~ ^/deposit/([A-Za-z0-9_-]{1,64})$ {
proxy_set_header X-Epic-Account $1;
proxy_pass http://127.0.0.1:8080/receive;

client_max_body_size 1m; # slates are small
proxy_read_timeout 120s; # the exchange is interactive
}

location / { return 404; }

proxy_read_timeout должен переживать один раунд построения слейта. Foreign API кошелька никогда не является непосредственной целью proxy_pass. Ею является сервис атрибуции, поэтому аккаунт фиксируется до того, как что-либо подписывается.

Записать аккаунт до совместной подписи

Ваш сервис по адресу 127.0.0.1:8080 записывает X-Epic-Account против идентификатора входящего слейта, затем вызывает receive_tx на Foreign API кошелька. Пример receive демонстрирует этот вызов. Специфичное для Epic требование — порядок выполнения:

# Сначала запишите атрибуцию и зафиксируйте её. Неатрибутированный кредит не может быть
# восстановлен из цепочки позднее, поэтому при ошибке записи депозит отклоняется.
await record_pending_deposit(account=x_epic_account, slate_id=slate["id"])
return await receive_tx(slate)

Идентификатор слейта является ключом объединения. Это поле id переданного вам слейта, и то же значение фигурирует как tx_slate_id в собственном журнале транзакций кошелька, поэтому атрибуцию можно сверить с кошельком впоследствии, даже если её нельзя сверить с цепочкой.

Your database is the only record of who paid you

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

Архитектура

  1. Собственный полностью валидирующий узел. См. настройку узла и кошелька.
  2. Горячие кошельки, запускающие Foreign API для получения и Owner API для управления со стороны вашего бэкенда.
  3. Обратный прокси, завершающий TLS, отображающий пользовательские пути на слушателей и открывающий только эти пути. Foreign API не требует учётных данных, поскольку контрагент не может их предоставить, поэтому прокси является единственным средством контроля доступа на этой поверхности.
  4. Учётные данные для Owner API. Эта поверхность их требует, и ваш бэкенд является её единственным клиентом. См. поверхности.
  5. База данных атрибуции, записываемая синхронно по мере поступления слейтов.
  6. Обработка вывода средств через Owner API с логикой повторных попыток и отмены.

Вывод средств требует конечного автомата

Вывод средств — это обмен с кошельком пользователя, который может не завершиться.

  • Начало отправки немедленно резервирует ваши выходы (outputs), поэтому очередь незавершённых выводов средств постепенно иммобилизует баланс вашего горячего кошелька. См. что резервирует выходы.
  • Ничто не истекает само по себе. Вы сами решаете, когда прекратить ожидание, и явно выполняете отмену. См. предусловия отмены.
  • Путь отправки блокируется во время опроса мемпула, поэтому не запускайте его в потоке обработки запросов. См. отправка зависает.

Моделируйте вывод средств со следующими состояниями: создан, ожидает контрагента, финализирован, опубликован, подтверждён или отменён. Устанавливайте собственный дедлайн, поскольку протокол его не предусматривает, и выполняйте отмену по истечении срока для освобождения выходов.

Глубина подтверждения

Протокол не предписывает глубину подтверждения депозита. Он фиксирует стоимость одного блока глубины — 60 секунд при целевом времени блока. 1,440 блоков — это глубина, которую сам консенсус требует перед тем, как coinbase можно потратить (время эмиссии).

Читайте глубину конкретного депозита как высоту вершины цепочки минус значение confirmation_height транзакции, описанное в глубина подтверждения транзакции. Оба значения поступают из вызовов, которые ваш бэкенд уже делает: get_status на узле и retrieve_txs на кошельке.

Холодное хранение

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

Транспорт file — строительный блок, отделяющий сеть от ключей. Он не требует сетевого подключения ни на одном из концов, а слейт (slate) является файлом. Принимающий кошелёк может поэтому находиться вне сети: слейт доставляется к нему, а ответ возвращается обратно — ценой того, что обмен перестаёт быть автоматическим. Транспорты и требования каждого из них к наличию онлайн-подключения описаны в транспорты.

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

Далее