Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate from bsddb3 to berkeleydb #19

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 61 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,68 @@
walletool ~ a tool for reading wallet.dat files
===============================================
# Walletool - Read wallet.dat files

Installation
------------
## Access [Bitcoin-Core](https://bitcoin.org/en/bitcoin-core/) and [Litecoin-Core](https://litecoin.org/) wallets __addresses__ and __private keys__

* Install Python 3.x.
* Install the `bsddb3` module (if you're on Windows, use Gohlke's site).
-----------------------------------------------------------

## Requirements

* Install python 3.6+
* Install `requirements.py` by running:
* `$pip install -r requirements.txt`
* Your wallet must be __UNENCRYPTED__!

## Installation

### _Linux - Install BerkeleyDB_

#### [Berkeley source installation](https://www.linuxfromscratch.org/blfs/view/svn/server/db.html)

1. [Download Berkely to compile](https://anduin.linuxfromscratch.org/BLFS/bdb/db-5.3.28.tar.gz)

2. First apply a fix so that this will compile with current versions of g++:

`$ sed -i 's/\(__atomic_compare_exchange\)/\1_db/' src/dbinc/atomic.h`

3. Install Berkeley DB by running the following commands:

`cd build_unix &&
../dist/configure --prefix=/usr \
--enable-compat185 \
--enable-dbm \
--disable-static \
--enable-cxx &&
make`

4. Now, as the __root__ user:

`make docdir=/usr/share/doc/db-5.3.28 install &&
chown -v -R root:root \
/usr/bin/db_* \
/usr/include/db{,_185,_cxx}.h \
/usr/lib/libdb*.{so,la} \
/usr/share/doc/db-5.3.28`

## Wallet location

### _Linux_

* `~/.bitcoin/wallets/[WALLET_NAME]/wallet.dat`

Extracting private keys from Bitcoin-QT/Litecoin-QT wallets
-----------------------------------------------------------

* Have your `wallet.dat` handy.
* For Bitcoin, run `python wt_extract_keys.py -d wallet.dat -v 0`
* For Litecoin, run `python wt_extract_keys.py -d wallet.dat -v 48`
### Types / CoinType

* For Bitcoin, run `python3 main.py -d WALLET_NAME.dat -v 0`
* For Litecoin, run `python3 main.py -d WALLET_NAME.dat -v 48`

-----------------------------------------------------------

### _Output_

Print / Log - Wallet addresses and private keys

A list of addresses / private keys is printed.
<!-- Install berkely DB
https://www.linuxfromscratch.org/blfs/view/svn/server/db.html

YMMV :)
Alt:
`$ sudo apt install libdb-dev && pip install bsddb3` -->
4 changes: 3 additions & 1 deletion check_bchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

var_re = re.compile('var (.+?) = (.+?);')


def main():
ap = argparse.ArgumentParser()
ap.add_argument('file', help='address file; one address per line')
Expand All @@ -30,5 +31,6 @@ def main():
continue
print(vs)


if __name__ == '__main__':
main()
main()
5 changes: 4 additions & 1 deletion check_dogechain.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import sys
import time


def main():
ap = argparse.ArgumentParser()
ap.add_argument('file', help='address file; one address per line')
Expand All @@ -12,7 +13,8 @@ def main():
for line in open(args.file):
line = line.strip()
while True:
r = requests.get('https://dogechain.info/api/v1/address/balance/%s' % line)
r = requests.get(
'https://dogechain.info/api/v1/address/balance/%s' % line)
if r.status_code == 429: # Too Many Requests
print('Throttled, hold on...', file=sys.stderr)
time.sleep(60)
Expand All @@ -26,5 +28,6 @@ def main():
print(r)
time.sleep(0.5)


if __name__ == '__main__':
main()
54 changes: 54 additions & 0 deletions main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import argparse
from walletool.wallet_files import read_wallet_dat
from walletool.wallet_items import parse_wallet_dict, KeyWalletItem
from walletool.consts import addressTypes


def main():

# Parser Arguments
ap = argparse.ArgumentParser()
ap.add_argument('-d', '--dat', help='wallet.dat path',
required=True, dest='wallet')
ap.add_argument('-t', '--type',
help='address version, as integer, 0xHEX, or any of the following known coins:\n[%s]' % ', '.join(sorted(addressTypes)), required=True)
args = ap.parse_args()

# Parser Logic - Checking for hex
if args.type.startswith('0x'):
coinType = int(args.type[2:], 16)
elif args.type.isdigit(): # Else: Use set addressTypes
coinType = int(args.type)
else:
if args.type not in addressTypes:
raise ValueError('invalid type (see --help)')
version = addressTypes[args.type]

# Start reading wallet information
wallet_data = read_wallet_dat(args.wallet)
addr_list = ['', '']
for item in parse_wallet_dict(wallet_data):
if isinstance(item, KeyWalletItem):
address = item.get_address(version=coinType)
privkey = item.get_private_key(version=coinType)
addr_list[0] += address
addr_list[1] += privkey

# Log address and private key
log = input("Save log of Output? (Y/n): ")
if (log.lower() == "n"):
print(f'\nAddress:\n{addr_list[0]} \n\nPrivate-Key: \n{addr_list[1]}')
elif (log.lower() == "y"):
file_output = open('wallet-output.txt', "w")
file_output.write(f'Address:\n{addr_list[0]} \n\nPrivate-Key: \n{addr_list[1]}')
print(f'\nAddress:\n{addr_list[0]} \n\nPrivate-Key: \n{addr_list[1]}')
print('\n>> Output saved as {wallet-output.txt}. <<')
else:
file_output = open('wallet-output.txt', "w")
file_output.write(f'Address:\n{addr_list[0]} \n\nPrivate-Key: \n{addr_list[1]}')
print('\n>> Output saved as {wallet-output.txt}. <<')



if __name__ == '__main__':
main()
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
berkeleydb==18.1.5
requests==2.27.1
3 changes: 1 addition & 2 deletions walletool/bc_data_stream.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
# -- encoding: UTF-8 --
import struct
import sys

assert sys.version_info[0] == 3 # TODO: Use six for 2/3 compat

# From Joric's pywallet.

import struct


class SerializationError(Exception):
pass
Expand Down
2 changes: 1 addition & 1 deletion walletool/consts.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
addrtypes = {
addressTypes = {
'bitcoin': 0,
'litecoin': 48,
'namecoin': 52,
Expand Down
2 changes: 1 addition & 1 deletion walletool/wallet_files.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@


def read_wallet_dat(filename):
from bsddb3 import db
from berkeleydb import db
filename = os.path.realpath(filename)
env = db.DBEnv()
env.set_lk_detect(db.DB_LOCK_DEFAULT)
Expand Down
3 changes: 2 additions & 1 deletion walletool/wallet_items.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,8 @@ def parse(cls, key, value):
data.update(parse_BlockLocator(vds))
elif type == 'ckey':
data['public_key'] = kds.read_bytes(kds.read_compact_size())
data['encrypted_private_key'] = vds.read_bytes(vds.read_compact_size())
data['encrypted_private_key'] = vds.read_bytes(
vds.read_compact_size())
elif type == 'mkey':
data['nID'] = kds.read_uint32()
data['encrypted_key'] = vds.read_string()
Expand Down
31 changes: 0 additions & 31 deletions wt_extract_keys.py

This file was deleted.