Как HD-кошельки отслеживают все учетные записи?

Например, если HD-кошелек генерирует 1000 учетных записей.

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

Я предполагаю, что хранение всех учетных записей будет неэффективным, и запросы к блокчейну или API для всех 1000 также не будут эффективными.

Использование изолированного варианта использования:

Если кошелек API HD генерирует 1000 адресов, он не может запрашивать все 1000 каждый раз, когда пользователь запускает телефон, и он не может делать это периодически, потому что, когда все обращаются к одной и той же конечной точке, это будет узким местом.

Я помню, что blockchain.info позволял вам запрашивать ваш расширенный открытый ключ, я полагаю, что они перебирают учетные записи таким же образом, используя ограничение пробела.

Можете ли вы уточнить, что вы подразумеваете под API HD Wallet (это не часто используемый термин). Вы имеете в виду кошелек SPV, такой как Электрум?
@darkknight Кошелек, который использует службы API, такие как blockchain.info, для получения баланса и отправки транзакций, а не SPV.

Ответы (1)

Как правило, HD-кошельки используют следующую логику для определения того, сколько адресов запрашивать и когда остановиться:

  1. Начните с учетной записи 0, сгенерируйте gap limitколичество адресов (обычно 20)
  2. Проверьте наличие транзакций по этим адресам.
  3. Если транзакций нет, остановить поиск новых адресов и счетов
  4. Если есть транзакции, генерировать gap limitбольше из индекса последнего адреса с транзакциями на нем. Кроме того, также выполните этот процесс для учетной записи 1 (вы проверяете учетные записи n+1, только если учетная запись n имеет транзакции

Общая идея состоит в том, что никакие учетные записи не будут существовать, если предыдущая учетная запись не используется, и что никакие адреса в учетной записи не будут использоваться после одного последовательного блока gap limitколичества неиспользуемых адресов.

Такие компании, как BitGo, которые предлагают услуги HD-кошелька для бирж и т. д., где вы можете легко иметь тысячи неиспользуемых адресов подряд, а затем адреса с транзакциями, обычно игнорируют лимит пропусков. Вместо этого они ведут список всех сгенерированных адресов и индексируют их как отдельные адреса, а не как HD-кошелек.

Что касается API, кошельки обычно стараются поддерживать работающий индекс. Они будут поддерживать кеш известных транзакций и продолжать добавлять к нему. Таким образом, когда вы запускаете его, он сканирует транзакции только в новых блоках с момента последнего сканирования. Это позволяет даже легким клиентам, таким как кошельки Electrum или Ledger/Trezor, обслуживать тысячи пользователей всего с несколькими узлами, поскольку каждый кошелек не будет запрашивать предыдущие транзакции, о которых он уже знает.

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

В дополнение к этому, HD-кошельки часто полагаются на полный узел (например, Bitcoin Core) или систему, такую ​​как ElectrumX или Insight. Все они способны поддерживать полный индекс. Bitcoin Core поддерживает только текущий индекс по известным адресам (поэтому вам нужно повторно сканировать, когда вы импортируете адрес). ElectrumX и Insight поддерживают расширенный индекс, который отслеживает все транзакции и может быстро возвращать данные для любого заданного адреса.

HD-кошельки продолжают проверять транзакции по всем используемым адресам. Они просто не сканируют всю цепочку каждый раз. Но для каждого нового блока каждая транзакция в этом блоке будет проверяться для каждого адреса в кошельке HD. Эту проверку можно быстро выполнить с помощью фильтров Блума или предварительно проиндексированных данных, таких как Electrum или Insight, не достигая узкого места.

Теоретически я понимаю, как работают HD-кошельки, спасибо за разъяснение. Мой вопрос касается того, как это работает на практике. Как HD-кошелек будет проверять, были ли средства отправлены на какой-либо из ранее сгенерированных адресов? Если бы у них было 1000, это было бы узким местом для кошелька API.
@KyleGraham Большинство кошельков справляются с этим, поддерживая список известных транзакций и запрашивая транзакции только в новых блоках, вместо того, чтобы каждый раз сканировать всю цепочку для каждого адреса. Я отредактировал ответ, чтобы включить это.
То есть, если кошелек поддерживает 1000 учетных записей, он все равно будет сканировать блокчейн для каждой учетной записи, но будет искать новые блоки? Если это так, то это не кажется эффективным, поскольку у пользователей потенциально могут быть тысячи учетных записей. С каждой учетной записью, имеющей возможность отправки средств на них.
Сканирование новых транзакций имеет одинаковую стоимость независимо от того, сканируете ли вы 1 адрес или 10000. Большинство реализаций используют какой-то фильтр Блума для ускорения. После того, как фильтр построен, проверка каждого tx, чтобы убедиться, что он для вашего адреса, тривиальна.
Да, точно. Было бы расточительно сканировать все 1000 адресов (пропускать использованные адреса) каждый раз, когда пользователь открывает HD Wallet. Если мы не проверим, отправил ли кто-то средства на ранее использовавшийся адрес, HD Wallet покажет неверный баланс. Мой вопрос: как с этим справляются HD-кошельки (мобильные)?
Я еще немного отредактировал ответ. Короче говоря, кошелек также проверяет каждый используемый адрес. Просто есть способы сделать это эффективно до такой степени, что в большинстве случаев это не является узким местом.
@RaghavSood Как сделать 1000+ HTTP-запросов каждый раз, когда вы запускаете приложение, не является узким местом?
Любое место, имеющее дело со значительным количеством адресов, поддерживает постоянно обновляемое состояние для каждого адреса, сканируя мемпул и каждый новый блок. Приложения, использующие баланс адресов, транзакции и т. д., затем запрашивают приложения мониторинга, которые оптимизированы, чтобы не требовать 1000 запросов.
@RaghavSood Как мобильный кошелек, использующий SPV или ElectrumX, может постоянно сканировать мемпул и новые блоки, когда он не в сети? Разве не нужно будет запрашивать у сервера все адреса каждый раз, когда он подключается к сети?
Использование фильтров bloomf позволяет запрашивать достаточно большие пакеты адресов за раз — большинство кошельков Electrum, которые использовались какое-то время, уже сканируют тысячи адресов за считанные минуты. Это работает достаточно хорошо для личных кошельков. На уровне биржи у вас есть специальные системы, предназначенные для работы с миллионами адресов.
Я внедряю мобильный кошелек прямо сейчас, и я хотел бы узнать, как это сделать, но я не вижу никаких методов ElectrumX, позволяющих выполнять пакетные запросы . Я также использую Esplora, и я не вижу там таких пакетных запросов github.com/Blockstream/esplora/blob/master/API.md