Когда писал свою приемку нигде не мог найти нормальную статью и посвятил около 3-ех дней чтобы понять ситуацию и оценить рынок данных сервисов. Около недели ушло на то, чтобы найти подходящие API сервисы и стабильно парсить блокчейн. Информацию можно найти, но вся она недостоверная либо устаревшая.
Набрался реальный опыт продакшена и обслуживания нескольких шопов, чтобы рассказать как конкретно реализовать действительно работающую приемку оплаты в крипте. В этой же статье я опишу подход и сделаю подробный анализ подводных камней, на которые наткнется каждый, кто решиться написать свой прием платежей в крипте.
Формулируем цель: простая, бесплатная, стабильная приемка оплаты для минимальной vps’ки с zero trust подходом (без приватного ключа)
Чтобы принимать платежи в крипте, есть несколько вариантов, точнее один – это парсить блокчейн, а вот вариантов реализаций несколько:
Мерчанты
Минусы:
С мерчантами не хотелось возиться, потому что они берут процент, брендируют окно оплаты, собирают мета данные, что вообще не трушно. Ну и само собой, большинство из них слишком бюрократичные и не заботятся о нашей анонимности.
АПИ сервисы
Есть множество АПИ сервисов, которые могут предоставлять ту или иную информацию, но это не всегда про прием оплаты. Я потратил некоторое время чтобы обнаружить, что некоторые сервисы предоставляют лишь экономический анализ волатильности, стакана и пр. Некоторые, имеют сложную регистрацию, порою с ручной модерацией, а некоторые и вовсе не работают.
Бесплатных, действительно мало и они имеют сильные лимиты, у платных же, ценообразование у них Х запроов в Y времени, например 1000 запросов в минуту при общих 100 000 в месяц. Несколько прикинув в голове кол-во запросов я неожиданно обнаружил, что мерчантом будет пользоваться даже выгодней.
Локальный блокчейн журнал на один кошелек
Поднимать свою блокчейн ноду на сервере необходимо под каждую криптовалюту, это требует не только времени и дальнейшей поддержки работоспособности но и дискового пространства. Биткоин журнал уже давно перевалил за 300 гигабайт.
И пока я, как стрелка компаса, дергался между мерчантами и апи сервисами, внутренняя жаба квакнула и сказала что будет парсить все транзакции кошельков сама и сохранять их в локальную базу данных для последующей сверки.
Это решение необходимо было оставить до следующего утра, обдумать и проснувшись, я уже не чесал репу, а думал какую базу для хранения взять и что может пойти не так. Это хорошее решение, так как можно использовать несколько апи сервисов, ротируя их, пока не закончаться лимиты, а если и их не хватит – всегда можно прикрутить самые дешевые прокси. Тор, кстати, уже активно экплоатировался на многих АПИ сервисах и с его помощью не всегда получается спарсить блочейн, но это самый доступный и простой ротируемый прокси.
Взяв несколько сервисов, написав под них парсер, объеденив в общий пул, пришлось половить несколько багов, посверять хеши транзакций, посуммировать транзакции в одном большом блоке, вообщем обкатать это решение. Но зато, не нужно никому платить, не зависить от 1-ого провайдера данных, иметь свободу и независимость.
Бесплатные blockchain explorer API
Про Chainso уже было описано в одной статье, с реализацией на php, поэтому про этот сервис не буду писать, у него хорошие бесплатные лимиты, 300 запросов в минуту, но он не поддерживает Segwit адресса, а именно bn*** и 3***, только 1***, и на практике - иногда просто неработает, т.к. разрабы все никак не выкатят платную версию, поэтому не могут обещать стабильности
Поэтому, в данной статье я рассмотрю blockcypher, а чейнсо можно использовать как второй, резервный провайдер данных. в случае есть блоксайфер будет недоступен или порежет IP на лимит.
Сайфер нам скромно предоставляет 3 запроса в секунду и 200 запросов в час. Тут я чуть было не отказался от своей затеи, ведь по сравнению с чейнсо, данные лимиты совершенно крохоборские. Но несколько раз обдумав общий подход к проверке транзакций я понял, что этого будет достаточно. Ведь к локальной базе данных можно обращаться безлимитно, а вот синхронизировать ее с блокчейном можно в ленивом режиме, например 1 раз в минуту. Получается 60 запросов в час на один кошелек в одной валюте. Для четырех валют выходит 1 запрос в 72 секунды. Вполне оперативно. Например, на сервисе sms-activate для ждал зачисление баланса более 10 минут после подтверждения транзакции.
И это только с помощью одного сервиса и без прокси. Chainso может подстраховать LTC и часть BTC кошельков, но в данном случае, я бы рекомендовал blockchain.info, хоть там и cloudflare на фронтенде.
Парсим API Blockcypher
Рассмотрим на примере парсинга BTC блокчейна.
АПИ Сайфера достаточно простое с одной лишь загвоздкой, по запросу на кошелек – выдает транзакции с максимум в 20 input/output чанков, если их больше, то необходимо делать дополнительный АПИ запрос на хеш транзакции, чтобы собрать общую сумму транзакции. Поэтому на и нужен chainso, а так же, можно поставить лимит на кол-во транзакций по АПИ. Вот так устроен блокчейн, вы возможно видели нечто подобное:
Поэтому, чтобы собрать сумму перевода, необходимо пройтись по всем инпутами и аутпутам и просуммировать value, если в адресах есть необходимый нам кошелек. Намного проще это можно объяснить с помощью кода:
В input собираем исходящую транзакцию, в output собираем входящую, которая нам и необходима для сверки с плательщиком
Безопасность
Но как нам понять, кто именно из пользователей сделал перевод, если кошелек для всех один общий? В случае QIWI или Yoomoney – можно написать примечание, а в случае криптовалюты – нельзя (ну кроме эфира). В таком случаем мы можем ориентировать только на сумму перевода.
Восьмизначное число исчесляемое сатошами, в случае Bitcoin, довольно уникально, но вдруг, у вас тысячи пользователей которые могут платить одновременно и это число совпадет двоих и больше пользователей? Можем начислить им всем по мере подтверждения транзакций,но кому первому и опять, вдруга, кто из них, случайно или умышленно, мог указать слишком маленькую комиссию и транзакция не прошла, но была ему зачислена вместо более добросовестного покупателя?
Это редкий случай и он просто решается добавлением 1 сатоши к общей сумме ожидаемой транзакции. Вообщем, сумма транзакции должна быть всегда уникальна.
Итог
Имеем простую приемку платажей, которая будет работать на сервере и с 128 Mbit RAM, которая не хранит ни приватных ключей ни каких-либо данных, ей нет оснований не доверять или ожидать подлог и довольно надежная из-за несколких источников данных, достаточно добавить столько необходимых резервных функций с парсилкой любого публичного блокчейна, чтобы приобрести ощущение стабильности, в моем случае 4-ех сервисов хватило.
Набрался реальный опыт продакшена и обслуживания нескольких шопов, чтобы рассказать как конкретно реализовать действительно работающую приемку оплаты в крипте. В этой же статье я опишу подход и сделаю подробный анализ подводных камней, на которые наткнется каждый, кто решиться написать свой прием платежей в крипте.
Формулируем цель: простая, бесплатная, стабильная приемка оплаты для минимальной vps’ки с zero trust подходом (без приватного ключа)
Чтобы принимать платежи в крипте, есть несколько вариантов, точнее один – это парсить блокчейн, а вот вариантов реализаций несколько:
- Своя блокчейн нода
- Мерчант сервис
- АПИ сервисы
Мерчанты
Минусы:
- берут от 1% и иногда закладывают скрытую комиссию в fee.
- иногда просят приват ключ
- множество монеток для оплаты, erc20 и bnb токены тоже
С мерчантами не хотелось возиться, потому что они берут процент, брендируют окно оплаты, собирают мета данные, что вообще не трушно. Ну и само собой, большинство из них слишком бюрократичные и не заботятся о нашей анонимности.
АПИ сервисы
Есть множество АПИ сервисов, которые могут предоставлять ту или иную информацию, но это не всегда про прием оплаты. Я потратил некоторое время чтобы обнаружить, что некоторые сервисы предоставляют лишь экономический анализ волатильности, стакана и пр. Некоторые, имеют сложную регистрацию, порою с ручной модерацией, а некоторые и вовсе не работают.
Бесплатных, действительно мало и они имеют сильные лимиты, у платных же, ценообразование у них Х запроов в Y времени, например 1000 запросов в минуту при общих 100 000 в месяц. Несколько прикинув в голове кол-во запросов я неожиданно обнаружил, что мерчантом будет пользоваться даже выгодней.
Локальный блокчейн журнал на один кошелек
Поднимать свою блокчейн ноду на сервере необходимо под каждую криптовалюту, это требует не только времени и дальнейшей поддержки работоспособности но и дискового пространства. Биткоин журнал уже давно перевалил за 300 гигабайт.
И пока я, как стрелка компаса, дергался между мерчантами и апи сервисами, внутренняя жаба квакнула и сказала что будет парсить все транзакции кошельков сама и сохранять их в локальную базу данных для последующей сверки.
Это решение необходимо было оставить до следующего утра, обдумать и проснувшись, я уже не чесал репу, а думал какую базу для хранения взять и что может пойти не так. Это хорошее решение, так как можно использовать несколько апи сервисов, ротируя их, пока не закончаться лимиты, а если и их не хватит – всегда можно прикрутить самые дешевые прокси. Тор, кстати, уже активно экплоатировался на многих АПИ сервисах и с его помощью не всегда получается спарсить блочейн, но это самый доступный и простой ротируемый прокси.
Взяв несколько сервисов, написав под них парсер, объеденив в общий пул, пришлось половить несколько багов, посверять хеши транзакций, посуммировать транзакции в одном большом блоке, вообщем обкатать это решение. Но зато, не нужно никому платить, не зависить от 1-ого провайдера данных, иметь свободу и независимость.
Python:
try:
txs = parse_blockcypher(wallet, ticker)
except:
print(f"Something wrong with blockcypther")
try:
txs = parse_chainso(wallet, ticker)
except:
print(f"Something wrong with chainso")
Бесплатные blockchain explorer API
Про Chainso уже было описано в одной статье, с реализацией на php, поэтому про этот сервис не буду писать, у него хорошие бесплатные лимиты, 300 запросов в минуту, но он не поддерживает Segwit адресса, а именно bn*** и 3***, только 1***, и на практике - иногда просто неработает, т.к. разрабы все никак не выкатят платную версию, поэтому не могут обещать стабильности
Поэтому, в данной статье я рассмотрю blockcypher, а чейнсо можно использовать как второй, резервный провайдер данных. в случае есть блоксайфер будет недоступен или порежет IP на лимит.
Сайфер нам скромно предоставляет 3 запроса в секунду и 200 запросов в час. Тут я чуть было не отказался от своей затеи, ведь по сравнению с чейнсо, данные лимиты совершенно крохоборские. Но несколько раз обдумав общий подход к проверке транзакций я понял, что этого будет достаточно. Ведь к локальной базе данных можно обращаться безлимитно, а вот синхронизировать ее с блокчейном можно в ленивом режиме, например 1 раз в минуту. Получается 60 запросов в час на один кошелек в одной валюте. Для четырех валют выходит 1 запрос в 72 секунды. Вполне оперативно. Например, на сервисе sms-activate для ждал зачисление баланса более 10 минут после подтверждения транзакции.
И это только с помощью одного сервиса и без прокси. Chainso может подстраховать LTC и часть BTC кошельков, но в данном случае, я бы рекомендовал blockchain.info, хоть там и cloudflare на фронтенде.
Парсим API Blockcypher
Рассмотрим на примере парсинга BTC блокчейна.
Python:
url = "https://api.blockcypher.com/v1/btc/main/addrs/37mFrx7otSSzUizXmPXbKo1xHMZeiZpxh9/full?limit=50"
АПИ Сайфера достаточно простое с одной лишь загвоздкой, по запросу на кошелек – выдает транзакции с максимум в 20 input/output чанков, если их больше, то необходимо делать дополнительный АПИ запрос на хеш транзакции, чтобы собрать общую сумму транзакции. Поэтому на и нужен chainso, а так же, можно поставить лимит на кол-во транзакций по АПИ. Вот так устроен блокчейн, вы возможно видели нечто подобное:
Поэтому, чтобы собрать сумму перевода, необходимо пройтись по всем инпутами и аутпутам и просуммировать value, если в адресах есть необходимый нам кошелек. Намного проще это можно объяснить с помощью кода:
Python:
r = requests.get(url)
data = r.json()
txs = data['txs']
for tx in txs:
val = 0
for out in tx['outputs']:
if wallet in out['addresses']:
val = out['value'] + val
for inp in tx['inputs']:
if wallet in inp['addresses']:
val = inp['output_value'] * -1 + val
if 'next_outputs' in tx:
nxt = tx['next_outputs']
url = nxt.replace('limit=20', 'limit=999999')
r = requests.get(url)
data = r.json()
for out in data['outputs']:
if wallet in out['addresses']:
val = out['value'] + val
for inp in data['inputs']:
if wallet in inp['addresses']:
val = inp['output_value'] * -1 + val
if type(val) == int:
val = val / pow(10, 8)
tx = [hash, wallet, ticker, val, dt, confirms]
В input собираем исходящую транзакцию, в output собираем входящую, которая нам и необходима для сверки с плательщиком
Безопасность
Но как нам понять, кто именно из пользователей сделал перевод, если кошелек для всех один общий? В случае QIWI или Yoomoney – можно написать примечание, а в случае криптовалюты – нельзя (ну кроме эфира). В таком случаем мы можем ориентировать только на сумму перевода.
Восьмизначное число исчесляемое сатошами, в случае Bitcoin, довольно уникально, но вдруг, у вас тысячи пользователей которые могут платить одновременно и это число совпадет двоих и больше пользователей? Можем начислить им всем по мере подтверждения транзакций,но кому первому и опять, вдруга, кто из них, случайно или умышленно, мог указать слишком маленькую комиссию и транзакция не прошла, но была ему зачислена вместо более добросовестного покупателя?
Это редкий случай и он просто решается добавлением 1 сатоши к общей сумме ожидаемой транзакции. Вообщем, сумма транзакции должна быть всегда уникальна.
Итог
Имеем простую приемку платажей, которая будет работать на сервере и с 128 Mbit RAM, которая не хранит ни приватных ключей ни каких-либо данных, ей нет оснований не доверять или ожидать подлог и довольно надежная из-за несколких источников данных, достаточно добавить столько необходимых резервных функций с парсилкой любого публичного блокчейна, чтобы приобрести ощущение стабильности, в моем случае 4-ех сервисов хватило.