cemehbl4

@cemehbl4

Восстанавливаем поврежденный wallet.dat
25.10.2022 21:41
Post earned 0.00 UFO

Условия задачи:

  • wallet.dat не зашифрован (не был установлен пароль)
  • Вы не ищете средства на z-адресах zcash и его форках (бабло на t-aдресах данным способом восстанавливается)
  • Юзаем линукс, ибо в нем всё необходимое уже есть из коробки

wallet.dat может быть поврежден кучей способов - виноват хдд или флешка, баг самого клиента, файл был случайно удален и восстановлен частично. В этом случае при запуске клиента поврежденный файл будет переименован с расширением .bak и создан пустой новый кошелек.

Итак, в wallet.dat все приватные ключи хранятся в hex-формате, при этом совершенно непонятно, какой ключ какому адресу принадлежит. Наша задача состоит в том, чтобы hex преобразовать в WIF (wallet import format), после чего импортировать его в новый кошелек, таким образом получив доступ к балансу. Если кошелек использовался активно, то ключей там может быть ОЧЕНЬ много, даже в только что созданном wallet.dat может быть больше ста ключей.

Сначала объясню на кошках на примере одного единственного приватного ключа BTC или ZEC.

Итак, у нас есть ключ вида:

0C28FCA386C7A227600B2FE50B7CAE11EC86D3BF1FBE471BE89827E19D72AA1D

Добавляем в начало префикс 80:

800C28FCA386C7A227600B2FE50B7CAE11EC86D3BF1FBE471BE89827E19D72AA1D

Префикс берется из исходного кода нужной монеты из файла src/chainparams.cpp

base58Prefixes[SECRET_KEY] = std::vector<unsigned char>(1,128);

Число 128 переводим из десятичной системы в шестнадцатеричную, получаем 80.

keyConstants.base58Prefixes[SECRET_KEY] = {0x80};

Здесь это число сразу в шестнадцатеричной системе, берем как есть.

base58Prefixes[SECRET_KEY] = std::vector<unsigned char>(1,176);

Число 176 переводим из десятичной системы в шестнадцатеричную, получаем B0.

Точно так же для любой монеты.

Добавляем в конец суффикс 01:

800C28FCA386C7A227600B2FE50B7CAE11EC86D3BF1FBE471BE89827E19D72AA1D01

Добавив этот суффикс, мы получим приватные ключи в сжатом (compressed) формате, они начинаются на K или L. Если нужны ключи, которые начинаются на 5 (uncompressed), то суффикс не добавляем.

Берем утилиту Bitcoin Explorer, Скачать готовый запускаемый файл можно здесь https://github.com/libbitcoin/libbitcoin-explorer/wiki/Download-BX

Вычисляем sha256 из нашего числа:

echo 800C28FCA386C7A227600B2FE50B7CAE11EC86D3BF1FBE471BE89827E19D72AA1D01 | ./bx-linux-x64-qrcode sha256

Получаем:

b504a81b66924482a289ce571a614c37b122f40cefb0abba0227e143154c2153

Вычисляем sha256 уже из полученного числа:

echo b504a81b66924482a289ce571a614c37b122f40cefb0abba0227e143154c2153 | ./bx-linux-x64-qrcode sha256

Результат:

a62019d20340a1de1b5f254f07f2f6c96ad5165218459ab4f3c8f5a7c0e12183

Первые восемь знаков a62019d2 - это контрольная сумма, которую мы должны добавить в конец нашего ключа после суффикса:

800C28FCA386C7A227600B2FE50B7CAE11EC86D3BF1FBE471BE89827E19D72AA1D01a62019d2

И наконец получаем приватный ключ, который можно импортировать в кошелек (WIF), с помощью base58-encode:

echo 800C28FCA386C7A227600B2FE50B7CAE11EC86D3BF1FBE471BE89827E19D72AA1D01a62019d2 | ./bx-linux-x64-qrcode base58-encode

Искомый ключ:

KwdMAjGmerYanjeui5SHS7JkmpZvVipYvB2LJGU1ZxJwYvP98617

Запускаем bitcoind и импортируем ключ:

./bitcoin-cli importprivkey KwdMAjGmerYanjeui5SHS7JkmpZvVipYvB2LJGU1ZxJwYvP98617

Проверяем баланс:

./bitcoin-cli getbalance

Теперь перейдем к работе с файлом кошелька.

Пусть это будет zcash. Качаем и скидываем в одну директорию:

  • поврежденный wallet.dat
  • bx-linux-x64-qrcode
  • zcashd
  • zcash-cli

Сначала нужно файл кошелька преобразовать в текстовый формат:

xxd -p wallet.dat | tr -d '\n' > plainhex.dump

Далее полученный файл нужно препарировать так, чтобы в нем остались только ключи. В wallet.dat ключи находятся между значениями f70001d63081d30201010420 и a08185308182020101302c06072a8648ce3d0101022100 - они могут слегка варьироваться, рекомендуется покопать структуру файла hex-редактором.

cat plainhex.dump | sed "s/f70001d63081d30201010420/f70001d63081d30201010420\n/g" | sed "s/a08185308182020101302c06072a8648ce3d0101022100/\na08185308182020101302c06072a8648ce3d0101022100/g" | sed '/f70001d63081d30201010420/d' | sed '/a08185308182020101302c06072a8648ce3d0101022100/d' > keys.temp

Эту конструкцию сложно понять без бутылки, поэтому попытаюсь объяснить.

Первый sed вставляет знак перевода строки после каждого значения f70001d63081d30201010420.

Второй sed вставляет знак перевода строки перед каждым значением a08185308182020101302c06072a8648ce3d0101022100.

Третий sed удаляет все строки со значением f70001d63081d30201010420

Четвертый sed удаляет все строки со значением a08185308182020101302c06072a8648ce3d0101022100

На выходе получаем файл keys.temp со всеми ключами, найденными в wallet.dat. Ключи будут расположены построчно.

Удаляем повторы и добавляем нужные префикс и суффикс:

sort keys.temp | uniq -u | awk '{print "80"$0"01"}' > keys

Если нужны uncompressed ключи (5), то 01 просто удаляем.

Вычисляем два раза sha256 из каждой строки в файле keys:

cat keys | while read line; do echo $line | ./bx-linux-x64-qrcode sha256 | ./bx-linux-x64-qrcode sha256; done > checksum.temp

Теперь каждую строку в полученном файле checksum.temp нужно обрезать, оставив только первые восемь символов (контрольная сумма):

rev checksum.temp | cut -c 57- | rev > checksum

"Cклеиваем" построчно файлы keys и checksum:

paste keys checksum | sed s/'\t'//g > wif.temp

Получаем файл с приватными ключами, которые уже можно импортировать в кошелек:

cat wif.temp | while read line; do echo $line | ./bx-linux-x64-qrcode base58-encode; done > wif

Отключаем интернет. Запускаем клиент:


mkdir $HOME/zcash_temp/
touch $HOME/zcash_temp/zcash.conf
./zcashd -daemon -datadir=$HOME/zcash_temp/

Почему так? Дело в том, что если у вас уже скачан блокчейн, то импорт ключей займет очень много времени. То есть мы запускаем в данном случае "чистый" клиент без интернета.

Импортируем ключи:


cat wif | while read line; do ./zcash-cli -datadir=$HOME/zcash_temp/ importprivkey $line; done

./zcash-cli -datadir=$HOME/zcash_temp/ stop

Новый wallet.dat будет находиться по пути /home/ЮЗЕРНЕЙМ/zcash_temp/

Осталось лишь положить wallet.dat на штатное место (в линуксе это скрытые папки в хоуме .zcash, .bitcoin, .litecoin и т.д.) и запустить qt-кошелек с параметром -rescan.

Post earned 0.00 UFO

Post earned 0.00 UFO

Комментарии

Comments: