Я пытаюсь разработать нечто подобное bitcoin-abe
, например, импортировать всю цепочку блоков в базу данных.
Для базы данных я сейчас использую Redis — я знаю, что это займет много оперативной памяти, но давайте предположим, что это нормально.
Другими возможностями могут быть MySQL, Postgress или даже файл CSV.
У меня есть bitcoind
и я импортирую блок за блоком.
Для каждой транзакции мне нужно искать вывод транзакций, которые «финансируют» текущую транзакцию — надеюсь, вы понимаете, что я имею в виду.
В настоящее время я проверяю блоки с 2017 года. Большинство блоков имеют более 2000 транзакций. Если мы предположим, что каждая транзакция имеет один вход, это означает, что мне нужно просмотреть еще 2000 транзакций.
На данный момент эти 2000 поисковых запросов выполняются обратно в bitcoind
, потому что выходная база данных может быть CSV-файлом.
Я могу сделать все это "ленивым" способом, но тогда я не смогу найти, если какой-то адрес израсходован.
Есть ли более быстрый способ импорта?
Я использую PHP, и один блок из 2017 года импортируется примерно за 1 минуту.
вывод тратится (например, если в "vin" фигурирует какая-то другая транзакция), сохраняю индикатор.
Теперь одиночный блок обрабатывается 1-2 сек.
Следствием этого является то,
что если вы хотите проверить баланс адреса, вам нужно будет проверить каждый «вход» и составить список неизрасходованных входов.
Все еще не уверен, что это лучший путь.
Наконец-то я загружаю программное обеспечение на github здесь:
https://github.com/nmmmnu/BlockchainWalker.
Вот как выглядят ключи, если мы хотим найти баланс для адреса «1EoMoJK3FJPHg4EwrP31zPVu4iLqmCtQ6»:
127.0.0.1:2000> HGETALL a:1EoMoJK3FJPHg4EwrP31zPVu4iLqmCtQ6
1) "a:1EoMoJK3FJPHg4EwrP31zPVu4iLqmCtQ6:28c76c9d89f23c1b1f5435d8f4bb5cc66e6cb9d0798f1f0f4293faaac88fb7d0.0"
2) "0.01270199"
Это транзакция финансирования:
Это значение:
Затем нам нужно проверить, потрачено ли это, поэтому мы проверяем каждый ввод следующим образом:
127.0.0.1:2000> get t:28c76c9d89f23c1b1f5435d8f4bb5cc66e6cb9d0798f1f0f4293faaac88fb7d0.0:s
"055bd8148143c5b05bc2808ccafe54be43b292381449d41cc23462d02d3f85d8"
Транзакция 055bd8148143c5b05bc2808ccafe54be43b292381449d41cc23462d02d3f85d8 — это транзакция, на которую расходуется этот вывод.
Поскольку каждый вывод израсходован, это означает, что адрес 1EoMoJK3FJPHg4EwrP31zPVu4iLqmCtQ6 имеет нулевой баланс.
Если мы хотим проверить/перечислить транзакцию «055bd8148143c5b05bc2808ccafe54be43b292381449d41cc23462d02d3f85d8», мы можем сделать:
127.0.0.1:2000> HGETALL t:055bd8148143c5b05bc2808ccafe54be43b292381449d41cc23462d02d3f85d8
1) "t:055bd8148143c5b05bc2808ccafe54be43b292381449d41cc23462d02d3f85d8.-:i:28c76c9d89f23c1b1f5435d8f4bb5cc66e6cb9d0798f1f0f4293faaac88fb7d0.0"
2) "1"
3) "t:055bd8148143c5b05bc2808ccafe54be43b292381449d41cc23462d02d3f85d8.-:i:39edb8741b701b6da2dbc4e02290e8e78cba244bdbad96da203e41ee2704c525.0"
4) "1"
5) "t:055bd8148143c5b05bc2808ccafe54be43b292381449d41cc23462d02d3f85d8.0:o"
6) "1Kj76Sxe8c3UK85RAQwwdqScAxaBwAY2eb:0.00500000"
7) "t:055bd8148143c5b05bc2808ccafe54be43b292381449d41cc23462d02d3f85d8.0:s"
8) "49f8bd582439a3b2351f92e0fdb5fcb1032acd42e3ab469c16d805627889ce14"
9) "t:055bd8148143c5b05bc2808ccafe54be43b292381449d41cc23462d02d3f85d8.1:o"
10) "14yAJga4ZkULbaMz4LUW5vj8GhQYyzCPoW:0.01118727"
11) "t:055bd8148143c5b05bc2808ccafe54be43b292381449d41cc23462d02d3f85d8.1:s"
12) "edf55ace1396229c7a91a4b21cd63293c631ae2ddcc5987402b04ed540b9e5d8"
Эти «t:xxxxx.-:i:xxxx» являются входными данными.
Эти "t:xxxxx.N:o" являются выводами
Эти "t:xxxxx.N:s" являются индикаторами того, потрачен ли вывод или нет.
Обратите внимание, что это не Redis, это база данных, которую я разрабатываю с интерфейсом Redis. Вы можете проверить это здесь:
Я использую RocksDB и node.js. Моя база данных оптимизирована для отслеживания балансов адресов и истории платежей. Требуется около 143 ГБ памяти, 4 дня для загрузки. Текущие блоки импортируются менее чем за 2 секунды.
Я очень старался добиться этого с помощью PostgreSQL. Это выполнимо, но требует большого количества взломов и создания индекса после импорта. Я пробовал levelDB, но он примерно в 4 раза медленнее, чем rockDB на SSD-накопителе.
Я использую пользовательскую библиотеку синтаксического анализа блоков и недоработанную реализацию полного узла.
Якуб Федичак
Ник
Ник