Как программно обнаруживать и принимать депозиты ETH и ERC20

Я хочу воспроизвести функциональность, предоставляемую криптовалютными биржами, такими как Kraken и Poloniex, когда дело доходит до депонирования ETH и токенов. А именно:

  • Пользователи могут генерировать и отправлять средства на один или несколько депозитных адресов для ETH, EOS, OMG и других токенов.
  • Баланс соответствующего пользователя обновляется при обнаружении депозита для данного токена или актива.
  • Отправленные средства хранятся на счетах, контролируемых биржей

Каков наилучший способ добиться этого?


У меня есть несколько идей с использованием web3, но я не уверен, что они являются наиболее эффективными или масштабируемыми решениями:

Эфириум

  • Для каждого пользователя, который хочет внести депозит, сгенерируйте адрес ETH и закрытый ключ, используя web3.eth.accounts.create(). Сопоставьте сгенерированный адрес с пользователем и сохраните закрытый ключ.
  • Используйте web3.eth.filterдля мониторинга последнего блока в блокчейне ETH. Сопоставьте транзакции в блоке с сохраненными адресами пользователей и при необходимости обновите балансы пользователей.

Проблемы с этим подходом : мониторинг каждого блока и сопоставление с сохраненными адресами требует больших вычислительных ресурсов, особенно если количество отслеживаемых адресов становится большим (сотни тысяч). Как это может масштабироваться?

Токены ERC20

  • Для каждого пользователя, который хочет внести депозит, сгенерируйте адрес ETH и закрытый ключ, используя web3.eth.accounts.create(). Сопоставьте сгенерированный адрес с пользователем и соответствующим токеном и сохраните закрытый ключ.
  • Контракты ERC20 генерируют Transferсобытия, когда в контракте происходит транзакция. Отслеживайте это событие с помощью web3.eth.filter. Когда происходит Transferсобытие для адреса, который существует в нашей базе данных, обновите баланс соответствующего пользователя на бирже с переведенной суммой.

Проблемы с этим подходом : как настроить фильтр web3 для обнаружения Transferсобытий только из рассматриваемого токена, а не всей сети? Должен ли я установить 1 фильтр для каждого адреса или 1 фильтр для всех адресов пользователей? Сколько адресов может отслеживать фильтр web3 одновременно? Что, если отслеживаемые адреса станут очень большими (сотни тысяч)?


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

Интересно, как другие крупные сайты масштабируют Ethereum. Я собираюсь создать масштабируемый платежный процессор для внутреннего платежного модуля службы, но у меня такие же проблемы, как у вас.
Стоит посмотреть, как это делает EtherDelta: github.com/etherdelta (или, может быть, даже просто создать другой интерфейс поверх своих контрактов?) Они также потребляют около 15-20% всего газа в сети, поэтому высокое использование газа по-прежнему является реальной проблемой.

Ответы (3)

Вероятно, это будет примерно так:

  1. Пользователь хочет внести токен на вашу биржу

    1. Если это первый раз, когда пользователь вносит этот токен, происходит следующее:

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

  2. Пользователь вносит токен на депозитный адрес

    1. На вашем сервере есть рабочий, который прослушивает все события блокчейна ethereum. Проверьте адрес «кому» транзакции и сравните его с адресами депозитов, которые вы сохранили. Когда есть совпадение, отправьте пользователю уведомление о событии депозита
  3. Вызовите метод balanceOf контрактов токенов, передав ему адрес депозита, который вы сгенерировали, привязанный к пользователю, чтобы отобразить баланс токенов пользователей на бирже. Вы показываете только этот конкретный баланс токенов и ничего больше для этого адреса.

  4. Пользователь хочет вывести свой токен

    1. У вашей биржи будет резервный пул ликвидности. Вам нужно будет перевести некоторое количество ETH из вашего пула ликвидности на депозитный адрес пользователя, чтобы оплатить стоимость газа. Вы включаете эту стоимость как часть комиссии за снятие средств. У вас уже есть зашифрованное приватное хранилище, поэтому вы расшифровываете его с помощью секрета/соли, подписываете транзакцию передачи и транслируете ее в сеть ethereum.

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

Для баланса эфира вы вызовете web3.eth.getBalanceпередачу адреса, чтобы проверить значение, когда пользователь заходит на страницу, и установите таймер javascript для выполнения вызова, например, каждые 15 секунд.

И то же самое, что касается вашего вопроса о балансе Ether баланса токенов ERC20: « Как вы настроили фильтр web3 для обнаружения событий Transfer только из рассматриваемого токена, а не всей сети? ». Я думаю, что лучший способ — вызвать смарт-контракт токена ERC20, чтобы узнать баланс каждого токена. Это делается путем вызова метода: function balanceOf(address _owner)для каждого токена после входа пользователя на страницу. И вы можете установить таймер javascript для обновления значений, например, каждые 15 секунд.

Я думаю, что именно это делает Кракен, например, поскольку содержимое страницы перезагружается каждые пару секунд.

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

Как вы рекомендуете называть function balanceOf(address _owner) это не web3функцией
function balanceOf(address _owner)— это метод внутри любого токена ERC20. Таким образом, вы можете вызвать этот метод web3для любого токена ERC20.
Я думаю, это хорошая идея. Потому что это чрезвычайно эффективно. На самом деле это сводит меня с ума. Потому что я думаю, что единственный способ решить эту проблему, как в вопросе. Большое спасибо.

Вам нужен кошелек HD (Hierarchical Determenistic). Ознакомьтесь с пакетом npm для HD-кошелька Truffle. Эта ссылка может помочь: https://www.npmjs.com/package/@truffle/hdwallet-provider

ссылка не работает
HD означает иерархический детерминированный кошелек.