Как я восстановил wallet.dat который выдавал ошибку чтения

Предисловие. Я не программист, не системный администратор, мои познания о базах данных минимальны, но я смог восстановить свой поломанный wallet.dat. И поэтому опишу здесь порядок действий простыми словами, которые сможет понять рядовой пользователь.

Я искал решение около 3-х дней, перечитал множество статей на форумах, многочисленные ветки на github о работе zcashd. Узнал, что такое база данных Berkeley DB и многое другое. Но тем не менее, я не нашёл ни одной инструкции по восстановлению кошелька, а переписки на форумах в поисках решений, которые я встретил, заканчивались ничем.

Разработчик ZecWallet в переписке сообщил мне, что при тех ошибках, которые я получал, это сделать в принципе невозможно. Но логика подталкивала искать.

Я очень мало спал, но очень рад что у меня всё получилось. Надеюсь, мой опыт поможет кому-то в подобной неприятной ситуации.

:warning:Внимание! В первую очередь сделайте несколько резервных копий вашего wallet.dat (или переименованного wallet.000000.bak) – как его найти, написал ниже. Скопируйте его в резервные каталоги или на флэшку. Без этого файла ничего не получится. Прочитайте весь текст до конца и уже потом производите любые манипуляции с кошельком. :warning:

1. В начале определимся о какой ошибке идёт речь, как я её получил и как понять, что у вас именно она.

Как я её получил. Те, кто использует кошелёк ZecWallet FullNode возможно сталкивались с ситуацией, когда обновление блоков по каким-то причинам останавливается и что бы вы не делали кошелёк будет выдавать ошибку соединения до тех пор, пока вы не сделаете переиндексацию.

Я использую ZecWallet FullNode на MAC OS и после версии 9.1 обратил внимание, что из самой программы сделать реиндекс стало невозможно, поскольку соответствующую вкладку с данной функцией убрали после версии 8.3.

Я держал версию 8.3 чтобы при необходимости сделать переиндексацию из неё, в понятном графическом интерфейсе (ещё неделю назад я даже не знал как запустить zcashd вручную с атрибутами из терминала MAC OS).

После очередной проблемной ситуации (возможно мой macbook разрядился и погас с включённым кошельком), мне следовало вновь провести реиндексацию, но этот процесс настолько длителен (у меня он занимает точно более 14 часов), что я решил просто заменить папки blocks и chainstate в директории: ~/Library/Application Support/Zcash/

У меня всегда открыта полная нода на ПК под управлением Windows и я ранее делал такой финт, который решал проблему соединения – но в этот раз что то пошло не так…

Версия FullNode 8.3 (старый графический интерфейс) – выдавала ошибку:
«zcashd said: Error: wallet.dat corrupt, salvage failed»

Версия FullNode 9.1 и выше (новый графический интерфейс) – выдавала ошибку:
«Failed to start zcashd. Giving up! Please file an issue with Zecwallet»

Перезапуск кошелька происходил как ни в чём небывало, но совершенно с новыми пустыми адресами.

Я описал первичную визуальную симптоматику, теперь о том что при этом происходит внутри папки /Zcash/ которая находится в:
• Windows: %HOMEPATH%\AppData\Roaming\Zcash\debug.log
• macOS: ~/Library/Application Support/Zcash/debug.log
• Linux: ~/.zcash/debug.log

В ней будет находиться ваш повреждённый файл wallet.0000000.bak (цифры любые), который сохраняется с расширением .bak и создаётся новый wallet.dat

Файлы с логами (находятся здесь же) будут содержать следующие записи:

debug.log

020-04-26 05:25:14 Renamed wallet.dat to wallet.1587878714.bak
2020-04-26 05:25:14 CDBEnv::Salvage: Database salvage found errors, all data may not be recoverable.
2020-04-26 05:25:14 Salvage(aggressive) found no records in wallet.1587878714.bak.

db.log

BDB2506 file unknown has LSN 448/450072, past end of log at 1/204362
BDB2507 Commonly caused by moving a database from one database environment
BDB2508 to another without clearing the database LSNs, or by removing all of
BDB2509 the log files from a database environment
BDB0522 Page 0: metadata page corrupted
BDB0523 Page 0: could not check metadata page
wallet.dat: BDB0090 DB_VERIFY_BAD: Database verification failed
BDB2506 file unknown has LSN 448/450072, past end of log at 1/205410
BDB2507 Commonly caused by moving a database from one database environment
BDB2508 to another without clearing the database LSNs, or by removing all of
BDB2509 the log files from a database environment
wallet.1587877729.bak: BDB0090 DB_VERIFY_BAD: Database verification failed

2. Осознание проблемы

Вообще до этого момента ситуация меня не тревожила. Я предполагал, что walled.dat мог подвергнутся какой-то неудачной операции, которая его повредила, но у меня на этот случай был бэкап wallet.dat давностью 1 месяц, который содержал все мои активные адреса. Я создал его через стандартную функцию в графическом интерфейсе FullNode 8.3 и записал на диск.

Я скопировал свой бэкап в папку \Zcash простой заменой, заранее сохранив поломанную версию. Забегая вперёд, я напишу, что смог восстановить и поломанную версию тоже - его сохраняем обязательно, ведь бэкапа у вас может и не быть.

После перезапуска ZecWallet ошибка никуда не ушла. Мой бэкап точно также не принимался кошельком и внутренний обработчик zcashd записывал в логи все те же ошибки.

Логичным действием было переименовать папку Zcash во временную, деинсталлировать все кошельки, стереть все папки с внутренними данными кошелька, переустановить всё заново, загрузить бэкап по новой и переиндексировать всю базу.

Я так и поступил – никакого результата, оба мои wallet.dat и «повреждённый» и бэкап не принимались zcashd и вновь и вновь выдавали ошибку: Salvage: Database salvage found errors, all data may not be recoverable. :fearful:

3. Возможные причины

Я обратил внимание, что оба мои файла wallet.dat имели необычно большой вес для подобных файлов, не то чтобы у меня было много транзакций на моих адресах, но мой Z-адрес был указан в списках на сервисе zecpages.com и поэтому я регулярно получал рассылку с большим объёмом зашифрованной информации в memo-полях.

Поскольку wallet.dat содержит в себе всю информацию о всех произведённых транзакциях на адресах, а также информацию, полученную в memo-полях, то его объём значительно прирастал с каждым днём. Сервис zecpages.com был запущен в феврале. Так вот, мой бэкап на 22 марта wallet.dat весил 15,6 Мб, а повреждённая версия от 23 апреля составляла уже 36 Мб. И это, как мне кажется, повод задуматься. Справедливости ради отмечу, что поток инфы в рассылках был большим: 5-8 нагруженных информацией сообщений ежедневно в виде z2z-транзакций.

Я не могу назвать это в качестве причины, по крайней мере мой текущий восстановленный wallet.dat также имеет вес более 36 Мб и это не мешает ему подгружаться на вновь установленный кошелёк. Тем не менее это подтолкнуло меня на мысль, что резервные копии wallet.dat не являются надёжным способом резервирования. Об этом я напишу в PS.

4. Стандартные методы восстановления.

Итак, с симптоматикой разобрались, теперь опишу стандартные рекомендуемые методы восстановления, которые мне никак не помогли.

Существует документация, которая описывает различные атрибуты и команды для исполнительных файлов – клиентов, позволяющих ноде взаимодействовать с сетью (блокчейном), получать и отправлять команды и производить операции с базами данных.

Информация с условно актуальной документацией находится здесь –

https://zcash.readthedocs.io/en/latest/rtd_pages/wallet_backup.html

Почему «условно актуально»? Потому что некоторые из текущих версий ZecWallet FullNode могут не содержать отдельных исполнительных файлов:
Zcashd.exe
zcash-cli.exe

Кроме того, не всегда вы сможете найти документацию для вашей операционной системы, поскольку она написана в первую очередь для людей понимающих архитектуру взаимодействия. И как правило средой разработки является Linux – не самая популярная операционная система среди рядовых юзеров, согласитесь. Также это связано с тем, что официальный кошелёк долгое время существовал только под линукс.

Я не буду дублировать документацию. Напишу лишь, что попытки восстановления должны начинаться с простых команд в командной строке с исполняющим клиентом zcashd, документация здесь - Troubleshooting Issues - ZecWallet Docs

Команды:

zcashd -rescan
zcashd -reindex
zcashd -salvage

Как запускаются:

Windows

cmd /C ““C:\Program Files (x86)\zecwallet\zcashd.exe” -rescan”

MacOS

В Finder открываете программы, находите ZecWallet FullNode, правой кнопкой вызываете контекстное меню, «Показать содержимое пакета», внутри заходите в “Contnets”, и там в “Mac OS”. Открываете окно терминала, перетаскиваете туда zcashd, добавляете атрибут команды, например, -reindex

Кстати, если вы его не найдёте в текущей версии ZecWallet FullNode, то качайте специальные версии, в котором он точно есть, два варианта:

Zecwallet Special Build (master branch zcashd) - https://www.zecwallet.co/masterzcashd.html
ZecWallet FullNode v.0.8.3 - Release zcashd update · ZcashFoundation/zecwallet · GitHub

Также рекомендуется удалить папку с параметрами, для того чтобы в случае выхода этих баз данных из строя, кошелёк смог установить заново:
• Windows: %HOMEPATH%\AppData\Roaming\ZcashParams
• macOS: ~/Library/Application Support/ZcashParams/
• Linux: ~/.zcash-params/

Удаляйте целиком папку, не стесняйтесь, её вам восстановит кошелёк автоматически при следующем запуске ZecWallet.

Собственно, на этом весь стандартизированный арсенал средств заканчивается.

Но будьте уверены, в случае если ваш wallet.dat повреждён, то в логах будет одна и та же формулировка «CDBEnv::Salvage: Database salvage found errors, all data may not be recoverable.» и все манипуляции будут производится с вновь созданным wallet.dat, а ваш wallet.dat будет переименован с расширением *.bak (а в некоторых случаях он попросту удаляется в случае неудачного бэкапа поэтому всегда делайте резервную копию).

5. Нестандартный метод восстановления

Я добрался до самого интересного места, ради которого и написал этот длинный пост.
Даже прочитав безнадёжные прогнозы, моя логика говорила мне: Ок, даже если мой текущий файл был нарушен, то бэкап? Почему не подгружается бэкап? :thinking:

  • я создавал бэкап в здравом рассудке и трезвой памяти;
  • я отчётливо помню, как я это делал;
  • я делал его стандартным функционалом ZecWallet FullNode v.0.8.3;
  • нода была полностью синхронизирована;
  • бинарная копия этого файла успешно продолжала работать после бэкапа – просто потому, что операция бэкапа это банальный копи-паст wallet.dat с новым именем.

Почему же сейчас zcashd его выплёвывает?

Начал я с банального просмотра текстовым редактором своего резервного wallet.dat
Проматывая туда-сюда этот бессмысленный набор символов, я обнаружил что у файла присутствует чёткая структура. То есть скорее всего он является базой данных.
А поскольку FullNode не поддерживает функцию шифрования - это к тому же незашифрованная база данных.

Не имея понятия как там всё устроено, я предположил, что wallet.dat не всегда является самостоятельной базой данных, где хранятся ключи и транзакции, а взаимодействует именно с той структурой блоков, которая была в момент его актуальности (то есть по состоянию и на дату бэкапа) и в случае если какой-либо процесс незавершён, она сохраняется в некотором «открытом» положении, что в дальнейшем мешает ей выступать в качестве резервной копии.

Таким образом, я подумал, что мне нужно точно узнать момент бэкапа и увидеть в логах какой это был блок, чтобы каким-то образом отмотать на него – впрочем я быстро понял, что это анриал и оставил эту попытку, но благодаря этому я более внимательно изучил все имеющиеся логи.

Среди прочего в логах я увидел строчку
Using BerkeleyDB version Berkeley DB 6.2.23: (March 28, 2016).
И это была зацепка. :smirk:

Итак, первое что нужно сделать это скачать исходники для работы в среде для баз данных Berkeley, они лежат тут - Oracle Berkeley DB Downloads

Я выбрал ближайший релиз к версии Berkeley DB 6.2.23, это 12cR1 Releases
Berkeley DB 12cR1 (12.1.6.2.38) - https://download.oracle.com/otn/berkeley-db/db-6.2.38_64.msi ссылка для версии Windows 64. Кстати, для скачивания придётся пройти регистрацию на сайте Oracle.

Не буду утомлять рассказом обо всех безуспешных попытках, напишу конкретно команды, которые помогли мне, и я надеюсь помогут и вам.

Их всего три:

После установки пакета Berkeley DB, находится эта радость в папке C:\Program Files\Oracle\Berkeley DB 12cR1 6.2.38\bin

Открываете в этой папке PowerShell (в окне папки Windows в контекстном меню правой кнопкой мыши с прижатым Shift).

Допустим ваш файл называется wallet.bak – переместите его в эту папку \bin где находятся все эти exe-шники, тогда команды с атрибутами будут такие (в терминале PowerShell, будьте внимательнее с расширениями):

db_verify wallet.bak

И если ответ звучит: «BDB5105 Verification of wallet.bak succeeded» - уже можете посылать кого-нибудь за вином :champagne:

db_dump -f 1.txt wallet.bak
что означает декомпилировать ваш wallet.bak в файл 1.txt
Кстати, открыв его в просмотре вы можете насладится чёткой структурой записей.

db_load -f 1.txt wallet.dat
что означает обратная компиляция wallet.dat из 1.txt

Полученный файл копируйте обратно в папку Zcash (там где у нас хранится структура блоков и логи).

Стартуйте кошелёк, если увидите знакомые адреса, но естественно будет нулевой баланс (поскольку у вас сейчас новая структура файлов), то вы на финишной прямой - делайте реиндекс из командной строки (или терминала MAC OS):
zcashd -reindex

После реиндексации вы увидите свои балансы :wink:

Вот такая, действительно не хитрая операция каким то образом поправляет структуру wallet.dat, который в результате замечательно читается zcashd и даже немного теряет в весе.

:no_entry: Если db_verify не выдаст успешный результат, это значит что ваш кошелёк действительно серьёзно повреждён. В таком случае попробуйте команду db_recover man page - libdb-utils - General Commands
На форумах программистов 1С (1С, Карл - я даже там был) я прочитал, что эта команда помогает поправить таблицы.

6. Заключение.

После длительных мытарств и восстановления своего кошелька я смог испытать очень приятные чувства облегчения и радости.

И если вы тоже их почувствуете, можете дать мне знать об этом:

zs1f2hlu6vzl65256mr0k2nh3n49wtrtj2vvalathwvzxt9asn6v0xtda2nfwgukvaaeuvcq3gpzqv
Спасибо!

PS чтобы не сталкиваться со всем этим головняком,

  1. Рекомендую для транзакций использовать ZecWallet Lite - Zecwallet Lite - Fully featured Zcash wallet
    потому что в отличие от FullNode:
    • Он имеет seed-фразу восстановления, по которой вы восстановите все свои созданные адреса, а не только те, которые у вас были на момент бэкапа кошелька;
    • не заставит вас проводить многочасовую переиндексацию в случае неправильного завершения работы;
    • позволяет зашифровать ваш wallet.dat

  2. Всегда вытягивайте приватные ключи из FullNode, если всё-таки хотите иметь его.

3 Likes

thx
5244c2c1b90b2093b82464c017265aa9b8d0c3e4a4cdcfe6206c649587ca9222

1 Like

:pray:t2:Thank You!

Привет. Мой вопрос может показаться вам глупый , но все же . Подходит описанный вами способ что бы восстановить wallet. dat litecoin?

1 Like

Здравствуйте Сергей!
Я приверженец тезиса: не бывает глупых вопросов :slight_smile:
Я предполагаю, что данный способ подходит для любого QT-кошелька, который строился на кодовой базе биткоина. Litecoin один из них.

Но успех будет зависеть от двух составляющих:

  1. Было ли включено шифрование на кошельке.
    То есть в таскбаре кошелька Litecoin QT c полной нодой был пункт “encryption” (я точно это помню потому что использовал его когда-то) . Там был чекбокс - галочка, при установке которого предлагалось ввести пароль для шифрования wallet.dat
    Если кошелёк был зашифрован то переходим к пункту 2.
    А если нет - то успех скорее всего следует ожидать.

  2. Известен ли вам пароль шифрования wallet.dat
    Если да, то для зашифрованной базы данных Berkeley DB будет возможность указать пароль. Вы просто его введёте при выполнении команд и далее та же самая процедура.

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

Отмечу, что в ZecWallet Full node шифрование wallet.dat отключено по умолчанию, потому что он не рекомендуется для хранения активов, а скорее создан для тестировщиков и держателей нод. Если бы он был зашифрован, то это стало бы дополнительным препятствием для разбора возможных проблем при добавлении новой технологии. На сайте кошелька есть предупреждение об этом.

Я не знаю, сталкивался ли кто-нибудь с ошибкой чтения wallet.dat в иных блокчейнах. Я просто не искал информацию об этом.

1 Like

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

Скажите пожалуйста, что тут происходит )))))

Да я сам не программист ))
Так… лезу во всё подряд, что интересно.

Команда имеет такой вид: db_verify [-NoqV] [-h home ] [-P password ] file

то есть
db_verify -p <пароль> wallet.bak

Описание здесь:

https://docs.oracle.com/database/bdb181/html/api_reference/C/db_verify.html

Из того что вижу: пишет что верификация БД закончилась неудачно. И сообщает где есть ошибки. Ок. Допустим есть ошибки, но wallet.dat хранит всю инфу о транзакциях, так что возможно эти строки не так важны. Главное это чтобы приватные ключи были без ошибок.

Попробуйте восстановить файл командой:

db_recover [-cefVv] [-h home ] [-P password ] [-t [[CC]YY]MMDDhhmm[.SS]]]

Описание: db_recover command man page - libdb-utils | ManKier

С этой функцией надо поэксперементировать, потому что я ей не пользовался, но судя по описанию, она может отфильтровать из БД выборку транзакций по периоду времени. Поскольку нам вообще не нужна информация о транзакциях (все транзакции восстановятся из блокчейна при запуске реиндексации в самом кошельке), а только приватные ключи, то можно указать минимально маленький период и очистить таким образом БД от плохих строк.

Попробуйте такую комбинацию для последней даты транзакции, которую мы включаем в БД, например, 01-01-2017:

db_recover -p <пароль> -t 201701010000.00 wallet.bak

ещё вариант с ключом -с (в описании указано как “катастрофическое восстановление”)

db_recover -с -p <пароль> -t 201701010000.00 wallet.bak

[

Статус выхода

](db_recover command man page - libdb-utils | ManKier)

db_recover Утилита выходит 0 в случае успеха и > 0 в случае ошибки.

1 Like

Огромное Вам спасибо, что так подробно отвечаете . Пока ничего не выходит . Программа пока показывает примеры парильного написания. Буду пытаться . Расскажу Вам свою ситуацию может когда нибудь с таким сталкивались : я перевел себе монеты с одного своего кошелька на другой используя систему mimblwimbl вы наверное знаете это неотслеживаемые транзакции . Когда монеты пришли я сделал резервную копию и удали свой кошелек с пк . Через некоторое время я вновь восстановил кошелек использовал копию . Когда открыл был очень удивлен сумме она была огромная , потом на моих глазах она перерасчиталась , но все равно оставалась большой . В итоге у меня на балансе сумма двойная , но при попытке отправить она становится ноль .проверить где они на самом деле не могу так как транзакция была неотслеживаемая Подтверждения транзакций есть . Доставал приватный ключи вставлял в новый кошелек и ничего вообще даже транзакций нет . Вот я и предположил , что они могли уйти обратно . Вот я и пытаюсь восстановить свой старый кошелек , кошелек . Вот такая история . Если в итоге у меня все получится я о Вас не забуду . Спасибо Вам за вашу помощь

1 Like

Добавлю ещё некоторые дополнения. С Litecoin я давно не взаимодействовал. Последний раз в году 2018. Поэтому опыта работы с новыми кошельками у меня нет. То что Вы описали про изменение балансов - это нормальное явление при синхронизации кошелька с блокчейном. После того как синхронизация выполнена на 100% по идее должен быть правильный остаток, который должен соответствовать тому, что отображает обозреватель блоков. Проверить адрес на наличие монет также можно в проводнике, например в этом: Litecoin Explorer — Blockchair

MimbleWimble ведь не скрывает адреса в обозревателе, так что если помните свои адреса, то обозреватель - это надёжный способ узнать фактические остатки.

С MimbleWimble я знакомился в начале запуска Grin и Beam. UX мне не понравился. А после того, как Иван Богатый опубликовал своё исследование, в ту сторону больше не смотрел.

1 Like

Обозреватель по этому адресу вообще ничего не показывает (. У меня есть вопрос : вот я делаю db_verify wallet.dat он дает мне информацию , но когда я хочу сделать dump он пишет ( requested page not found . Спасибо

“запрошенная страница не найдена”
вот не подскажу уже, о чём это он. Вроде бы в функции на конкретную страницу нет ссылки.

Попробуйте различные префиксы из описания: db_dump command man page - libdb-utils | ManKier

вроде при использовании -r и -R как написано должно быть “агрессивное восстановление”

2 Likes