0% found this document useful (0 votes)
31 views16 pages

Bitcoin 2 Johnhashscript

Uploaded by

Greg Long
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
31 views16 pages

Bitcoin 2 Johnhashscript

Uploaded by

Greg Long
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 16

1#!

/usr/bin/env python
2
3# jackjack's pywallet.py
4# https://github.com/jackjack-jj/pywallet
5# forked from Joric's pywallet.py
6
7missing_dep = []
8
9try:
10 from bsddb.db import *
11except:
12 from bsddb3.db import *
13 # missing_dep.append('bsddb')
14
15import os, sys, time
16pyw_filename = sys.argv[0].split('/')[len(sys.argv[0].split('/')) - 1]
17pyw_path = os.getcwd()
18
19try:
20 import json
21except:
22 try:
23 import simplejson as json
24 except:
25 sys.stdout.write("json or simplejson package is needed")
26
27import logging
28import struct
29import traceback
30import types
31import string
32import hashlib
33import random
34import math
35import binascii
36
37max_version = 81000
38addrtype = 0
39json_db = {}
40private_keys = []
41private_hex_keys = []
42passphrase = ""
43global_merging_message = ["", ""]
44
45wallet_dir = ""
46wallet_name = ""
47
48ko = 1e3
49kio = 1024
50Mo = 1e6
51Mio = 1024 ** 2
52Go = 1e9
53Gio = 1024 ** 3
54To = 1e12
55Tio = 1024 ** 4
56
57prekeys = [binascii.unhexlify("308201130201010420"),
binascii.unhexlify("308201120201010420")]
58postkeys = [binascii.unhexlify("a081a530"), binascii.unhexlify("81a530")]
59
60def hash_160(public_key):
61 md = hashlib.new('ripemd160')
62 md.update(hashlib.sha256(public_key).digest())
63 return md.digest()
64
65def public_key_to_bc_address(public_key):
66 h160 = hash_160(public_key)
67 return hash_160_to_bc_address(h160)
68
69def hash_160_to_bc_address(h160):
70 vh160 = chr(addrtype) + h160
71 h = Hash(vh160)
72 addr = vh160 + h[0:4]
73 return b58encode(addr)
74
75def bc_address_to_hash_160(addr):
76 bytes = b58decode(addr, 25)
77 return bytes[1:21]
78
79__b58chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
80__b58base = len(__b58chars)
81
82def b58encode(v):
83 """ encode v, which is a string of bytes, to base58.
84 """
85
86 long_value = 0
87 for (i, c) in enumerate(v[::-1]):
88 long_value += (256 ** i) * ord(c)
89
90 result = ''
91 while long_value >= __b58base:
92 div, mod = divmod(long_value, __b58base)
93 result = __b58chars[mod] + result
94 long_value = div
95 result = __b58chars[long_value] + result
96
97 # Bitcoin does a little leading-zero-compression:
98 # leading 0-bytes in the input become leading-1s
99 nPad = 0
100 for c in v:
101 if c == '\0': nPad += 1
102 else: break
103
104 return (__b58chars[0] * nPad) + result
105
106def b58decode(v, length):
107 """ decode v into a string of len bytes
108 """
109 long_value = 0
110 for (i, c) in enumerate(v[::-1]):
111 long_value += __b58chars.find(c) * (__b58base ** i)
112
113 result = ''
114 while long_value >= 256:
115 div, mod = divmod(long_value, 256)
116 result = chr(mod) + result
117 long_value = div
118 result = chr(long_value) + result
119
120 nPad = 0
121 for c in v:
122 if c == __b58chars[0]: nPad += 1
123 else: break
124
125 result = chr(0) * nPad + result
126 if length is not None and len(result) != length:
127 return None
128
129 return result
130
131# end of bitcointools base58 implementation
132
133def Hash(data):
134 return hashlib.sha256(hashlib.sha256(data).digest()).digest()
135
136# bitcointools wallet.dat handling code
137
138def create_env(db_dir):
139 db_env = DBEnv(0)
140 r = db_env.open(db_dir, (DB_CREATE | DB_INIT_LOCK | DB_INIT_LOG |
DB_INIT_MPOOL | DB_INIT_TXN | DB_THREAD | DB_RECOVER))
141 return db_env
142
143def parse_CAddress(vds):
144 d = {'ip':'0.0.0.0', 'port':0, 'nTime': 0}
145 try:
146 d['nVersion'] = vds.read_int32()
147 d['nTime'] = vds.read_uint32()
148 d['nServices'] = vds.read_uint64()
149 d['pchReserved'] = vds.read_bytes(12)
150 d['ip'] = socket.inet_ntoa(vds.read_bytes(4))
151 d['port'] = vds.read_uint16()
152 except:
153 pass
154 return d
155
156def deserialize_CAddress(d):
157 return d['ip'] + ":" + str(d['port'])
158
159def parse_BlockLocator(vds):
160 d = { 'hashes' : [] }
161 nHashes = vds.read_compact_size()
162 for i in xrange(nHashes):
163 d['hashes'].append(vds.read_bytes(32))
164 return d
165
166def deserialize_BlockLocator(d):
167 result = "Block Locator top: " + d['hashes'][0][::-1].encode('hex_codec')
168 return result
169
170def parse_setting(setting, vds):
171 if setting[0] == "f": # flag (boolean) settings
172 return str(vds.read_boolean())
173 elif setting[0:4] == "addr": # CAddress
174 d = parse_CAddress(vds)
175 return deserialize_CAddress(d)
176 elif setting == "nTransactionFee":
177 return vds.read_int64()
178 elif setting == "nLimitProcessors":
179 return vds.read_int32()
180 return 'unknown setting'
181
182class SerializationError(Exception):
183 """ Thrown when there's a problem deserializing or serializing """
184
185def ts():
186 return int(time.mktime(datetime.now().timetuple()))
187
188def check_postkeys(key, postkeys):
189 for i in postkeys:
190 if key[:len(i)] == i:
191 return True
192 return False
193
194def one_element_in(a, string):
195 for i in a:
196 if i in string:
197 return True
198 return False
199
200def first_read(device, size, prekeys, inc=10000):
201 t0 = ts() - 1
202 try:
203 fd = os.open (device, os.O_RDONLY)
204 except:
205 sys.stdout.write("Can't open %s, check the path or try as root"
% device)
206 exit(0)
207 prekey = prekeys[0]
208 data = ""
209 i = 0
210 data = os.read (fd, i)
211 before_contained_key = False
212 contains_key = False
213 ranges = []
214
215 while i < int(size):
216 if i % (10 * Mio) > 0 and i % (10 * Mio) <= inc:
217 sys.stdout.write("\n%.2f/%.2f Go" % (i / 1e9, size /
1e9))
218 t = ts()
219 speed = i / (t - t0)
220 ETAts = size / speed + t0
221 d = datetime.fromtimestamp(ETAts)
222 sys.stdout.write(d.strftime(" ETA: %H:%M:%S"))
223
224 try:
225 data = os.read (fd, inc)
226 except Exception as exc:
227 os.lseek(fd, inc, os.SEEK_CUR)
228 sys.stdout.write(str(exc))
229 i += inc
230 continue
231
232 contains_key = one_element_in(prekeys, data)
233
234 if not before_contained_key and contains_key:
235 ranges.append(i)
236
237 if before_contained_key and not contains_key:
238 ranges.append(i)
239
240 before_contained_key = contains_key
241
242 i += inc
243
244 os.close (fd)
245 return ranges
246
247def shrink_intervals(device, ranges, prekeys, inc=1000):
248 prekey = prekeys[0]
249 nranges = []
250 fd = os.open (device, os.O_RDONLY)
251 for j in range(len(ranges) / 2):
252 before_contained_key = False
253 contains_key = False
254 bi = ranges[2 * j]
255 bf = ranges[2 * j + 1]
256
257 mini_blocks = []
258 k = bi
259 while k <= bf + len(prekey) + 1:
260 mini_blocks.append(k)
261 k += inc
262 mini_blocks.append(k)
263
264 for k in range(len(mini_blocks) / 2):
265 mini_blocks[2 * k] -= len(prekey) + 1
266 mini_blocks[2 * k + 1] += len(prekey) + 1
267
268
269 bi = mini_blocks[2 * k]
270 bf = mini_blocks[2 * k + 1]
271
272 os.lseek(fd, bi, 0)
273
274 data = os.read(fd, bf - bi + 1)
275 contains_key = one_element_in(prekeys, data)
276
277 if not before_contained_key and contains_key:
278 nranges.append(bi)
279
280 if before_contained_key and not contains_key:
281 nranges.append(bi + len(prekey) + 1 +
len(prekey) + 1)
282
283 before_contained_key = contains_key
284
285 os.close (fd)
286
287 return nranges
288
289def find_offsets(device, ranges, prekeys):
290 prekey = prekeys[0]
291 list_offsets = []
292 to_read = 0
293 fd = os.open (device, os.O_RDONLY)
294 for i in range(len(ranges) / 2):
295 bi = ranges[2 * i] - len(prekey) - 1
296 os.lseek(fd, bi, 0)
297 bf = ranges[2 * i + 1] + len(prekey) + 1
298 to_read += bf - bi + 1
299 buf = ""
300 for j in range(len(prekey)):
301 buf += "\x00"
302 curs = bi
303
304 while curs <= bf:
305 data = os.read(fd, 1)
306 buf = buf[1:] + data
307 if buf in prekeys:
308 list_offsets.append(curs)
309 curs += 1
310
311 os.close (fd)
312
313 return [to_read, list_offsets]
314
315def read_keys(device, list_offsets):
316 found_hexkeys = []
317 fd = os.open (device, os.O_RDONLY)
318 for offset in list_offsets:
319 os.lseek(fd, offset + 1, 0)
320 data = os.read(fd, 40)
321 hexkey = data[1:33].encode('hex')
322 after_key = data[33:39].encode('hex')
323 if hexkey not in found_hexkeys and
check_postkeys(after_key.decode('hex'), postkeys):
324 found_hexkeys.append(hexkey)
325
326 os.close (fd)
327
328 return found_hexkeys
329
330
331def md5_2(a):
332 return hashlib.md5(a).digest()
333
334def md5_file(nf):
335 fichier = file(nf, 'r').read()
336 return md5_2(fichier)
337
338
339class KEY:
340
341 def __init__ (self):
342 self.prikey = None
343 self.pubkey = None
344
345 def generate (self, secret=None):
346 if secret:
347 exp = int ('0x' + secret.encode ('hex'), 16)
348 self.prikey =
ecdsa.SigningKey.from_secret_exponent (exp, curve=secp256k1)
349 else:
350 self.prikey = ecdsa.SigningKey.generate
(curve=secp256k1)
351 self.pubkey = self.prikey.get_verifying_key()
352 return self.prikey.to_der()
353
354 def set_privkey (self, key):
355 if len(key) == 279:
356 seq1, rest = der.remove_sequence (key)
357 integer, rest = der.remove_integer (seq1)
358 octet_str, rest = der.remove_octet_string (rest)
359 tag1, cons1, rest, = der.remove_constructed
(rest)
360 tag2, cons2, rest, = der.remove_constructed
(rest)
361 point_str, rest = der.remove_bitstring (cons2)
362 self.prikey =
ecdsa.SigningKey.from_string(octet_str, curve=secp256k1)
363 else:
364 self.prikey = ecdsa.SigningKey.from_der (key)
365
366 def set_pubkey (self, key):
367 key = key[1:]
368 self.pubkey = ecdsa.VerifyingKey.from_string (key,
curve=secp256k1)
369
370 def get_privkey (self):
371 _p = self.prikey.curve.curve.p ()
372 _r = self.prikey.curve.generator.order ()
373 _Gx = self.prikey.curve.generator.x ()
374 _Gy = self.prikey.curve.generator.y ()
375 encoded_oid2 = der.encode_oid (*(1, 2, 840, 10045, 1, 1))
376 encoded_gxgy = "\x04" + ("%64x" % _Gx).decode('hex') + ("%64x"
% _Gy).decode('hex')
377 param_sequence = der.encode_sequence (
378 ecdsa.der.encode_integer(1),
379 der.encode_sequence (
380 encoded_oid2,
381 der.encode_integer (_p),
382 ),
383 der.encode_sequence (
384 der.encode_octet_string("\x00"),
385 der.encode_octet_string("\x07"),
386 ),
387 der.encode_octet_string (encoded_gxgy),
388 der.encode_integer (_r),
389 der.encode_integer (1),
390 );
391 encoded_vk = "\x00\x04" + self.pubkey.to_string ()
392 return der.encode_sequence (
393 der.encode_integer (1),
394 der.encode_octet_string (self.prikey.to_string
()),
395 der.encode_constructed (0, param_sequence),
396 der.encode_constructed (1, der.encode_bitstring
(encoded_vk)),
397 )
398
399 def get_pubkey (self):
400 return "\x04" + self.pubkey.to_string()
401
402 def sign (self, hash):
403 sig = self.prikey.sign_digest (hash,
sigencode=ecdsa.util.sigencode_der)
404 return sig.encode('hex')
405
406 def verify (self, hash, sig):
407 return self.pubkey.verify_digest (sig, hash,
sigdecode=ecdsa.util.sigdecode_der)
408
409def bool_to_int(b):
410 if b:
411 return 1
412 return 0
413
414class BCDataStream(object):
415 def __init__(self):
416 self.input = None
417 self.read_cursor = 0
418
419 def clear(self):
420 self.input = None
421 self.read_cursor = 0
422
423 def write(self, bytes): # Initialize with string of bytes
424 if self.input is None:
425 self.input = bytes
426 else:
427 self.input += bytes
428
429 def map_file(self, file, start): # Initialize with bytes from file
430 self.input = mmap.mmap(file.fileno(), 0,
access=mmap.ACCESS_READ)
431 self.read_cursor = start
432 def seek_file(self, position):
433 self.read_cursor = position
434 def close_file(self):
435 self.input.close()
436
437 def read_string(self):
438 # Strings are encoded depending on length:
439 # 0 to 252 : 1-byte-length followed by bytes (if any)
440 # 253 to 65,535 : byte'253' 2-byte-length followed by bytes
441 # 65,536 to 4,294,967,295 : byte '254' 4-byte-length followed by
bytes
442 # ... and the Bitcoin client is coded to understand:
443 # greater than 4,294,967,295 : byte '255' 8-byte-length followed
by bytes of string
444 # ... but I don't think it actually handles any strings that
big.
445 if self.input is None:
446 raise SerializationError("call write(bytes) before
trying to deserialize")
447
448 try:
449 length = self.read_compact_size()
450 except IndexError:
451 raise SerializationError("attempt to read past end of
buffer")
452
453 return self.read_bytes(length)
454
455 def write_string(self, string):
456 # Length-encoded as with read-string
457 self.write_compact_size(len(string))
458 self.write(string)
459
460 def read_bytes(self, length):
461 try:
462 result = self.input[self.read_cursor:self.read_cursor +
length]
463 self.read_cursor += length
464 return result
465 except IndexError:
466 raise SerializationError("attempt to read past end of
buffer")
467
468 return ''
469
470 def read_boolean(self): return self.read_bytes(1)[0] != chr(0)
471 def read_int16(self): return self._read_num('<h')
472 def read_uint16(self): return self._read_num('<H')
473 def read_int32(self): return self._read_num('<i')
474 def read_uint32(self): return self._read_num('<I')
475 def read_int64(self): return self._read_num('<q')
476 def read_uint64(self): return self._read_num('<Q')
477
478 def write_boolean(self, val): return self.write(chr(bool_to_int(val)))
479 def write_int16(self, val): return self._write_num('<h', val)
480 def write_uint16(self, val): return self._write_num('<H', val)
481 def write_int32(self, val): return self._write_num('<i', val)
482 def write_uint32(self, val): return self._write_num('<I', val)
483 def write_int64(self, val): return self._write_num('<q', val)
484 def write_uint64(self, val): return self._write_num('<Q', val)
485
486 def read_compact_size(self):
487 size = self.input[self.read_cursor]
488 if isinstance(size, str):
489 size = ord(self.input[self.read_cursor])
490 self.read_cursor += 1
491 if size == 253:
492 size = self._read_num('<H')
493 elif size == 254:
494 size = self._read_num('<I')
495 elif size == 255:
496 size = self._read_num('<Q')
497 return size
498
499 def write_compact_size(self, size):
500 if size < 0:
501 raise SerializationError("attempt to write size < 0")
502 elif size < 253:
503 self.write(chr(size))
504 elif size < 2 ** 16:
505 self.write('\xfd')
506 self._write_num('<H', size)
507 elif size < 2 ** 32:
508 self.write('\xfe')
509 self._write_num('<I', size)
510 elif size < 2 ** 64:
511 self.write('\xff')
512 self._write_num('<Q', size)
513
514 def _read_num(self, format):
515 (i,) = struct.unpack_from(format, self.input, self.read_cursor)
516 self.read_cursor += struct.calcsize(format)
517 return i
518
519 def _write_num(self, format, num):
520 s = struct.pack(format, num)
521 self.write(s)
522
523def open_wallet(walletfile, writable=False):
524 db = DB()
525 DB_TYPEOPEN = DB_RDONLY
526 flags = DB_THREAD | DB_TYPEOPEN
527 try:
528 r = db.open(walletfile, "main", DB_BTREE, flags)
529 except DBError:
530 r = True
531
532 if r is not None:
533 logging.error("Couldn't open wallet.dat/main. Try quitting
Bitcoin and running this again.")
534 sys.exit(1)
535
536 return db
537
538def inversetxid(txid):
539 if len(txid) is not 64:
540 sys.stdout.write("Bad txid")
541 return "CORRUPTEDTXID:" + txid
542 new_txid = ""
543 for i in range(32):
544 new_txid += txid[62 - 2 * i];
545 new_txid += txid[62 - 2 * i + 1];
546 return new_txid
547
548def parse_wallet(db, item_callback):
549 kds = BCDataStream()
550 vds = BCDataStream()
551
552
553 def parse_TxIn(vds):
554 d = {}
555 d['prevout_hash'] = vds.read_bytes(32).encode('hex')
556 d['prevout_n'] = vds.read_uint32()
557 d['scriptSig'] =
vds.read_bytes(vds.read_compact_size()).encode('hex')
558 d['sequence'] = vds.read_uint32()
559 return d
560
561
562 def parse_TxOut(vds):
563 d = {}
564 d['value'] = vds.read_int64() / 1e8
565 d['scriptPubKey'] =
vds.read_bytes(vds.read_compact_size()).encode('hex')
566 return d
567
568
569 for (key, value) in db.items():
570 d = { }
571
572 kds.clear(); kds.write(key)
573 vds.clear(); vds.write(value)
574
575 type = kds.read_string()
576
577 d["__key__"] = key
578 d["__value__"] = value
579 d["__type__"] = type
580
581 try:
582 if type == "tx":
583 d["tx_id"] =
inversetxid(kds.read_bytes(32).encode('hex_codec'))
584 start = vds.read_cursor
585 d['version'] = vds.read_int32()
586 n_vin = vds.read_compact_size()
587 d['txIn'] = []
588 for i in xrange(n_vin):
589 d['txIn'].append(parse_TxIn(vds))
590 n_vout = vds.read_compact_size()
591 d['txOut'] = []
592 for i in xrange(n_vout):
593 d['txOut'].append(parse_TxOut(vds))
594 d['lockTime'] = vds.read_uint32()
595 d['tx'] =
vds.input[start:vds.read_cursor].encode('hex_codec')
596 d['txv'] = value.encode('hex_codec')
597 d['txk'] = key.encode('hex_codec')
598 elif type == "name":
599 d['hash'] = kds.read_string()
600 d['name'] = vds.read_string()
601 elif type == "version":
602 d['version'] = vds.read_uint32()
603 elif type == "minversion":
604 d['minversion'] = vds.read_uint32()
605 elif type == "setting":
606 d['setting'] = kds.read_string()
607 d['value'] = parse_setting(d['setting'], vds)
608 elif type == "key":
609 d['public_key'] =
kds.read_bytes(kds.read_compact_size())
610 d['private_key'] =
vds.read_bytes(vds.read_compact_size())
611 elif type == "wkey":
612 d['public_key'] =
kds.read_bytes(kds.read_compact_size())
613 d['private_key'] =
vds.read_bytes(vds.read_compact_size())
614 d['created'] = vds.read_int64()
615 d['expires'] = vds.read_int64()
616 d['comment'] = vds.read_string()
617 elif type == "defaultkey":
618 d['key'] =
vds.read_bytes(vds.read_compact_size())
619 elif type == "pool":
620 d['n'] = kds.read_int64()
621 d['nVersion'] = vds.read_int32()
622 d['nTime'] = vds.read_int64()
623 d['public_key'] =
vds.read_bytes(vds.read_compact_size())
624 elif type == "acc":
625 d['account'] = kds.read_string()
626 d['nVersion'] = vds.read_int32()
627 d['public_key'] =
vds.read_bytes(vds.read_compact_size())
628 elif type == "acentry":
629 d['account'] = kds.read_string()
630 d['n'] = kds.read_uint64()
631 d['nVersion'] = vds.read_int32()
632 d['nCreditDebit'] = vds.read_int64()
633 d['nTime'] = vds.read_int64()
634 d['otherAccount'] = vds.read_string()
635 d['comment'] = vds.read_string()
636 elif type == "bestblock":
637 d['nVersion'] = vds.read_int32()
638 d.update(parse_BlockLocator(vds))
639 elif type == "ckey":
640 d['public_key'] =
kds.read_bytes(kds.read_compact_size())
641 d['encrypted_private_key'] =
vds.read_bytes(vds.read_compact_size())
642 elif type == "mkey":
643 d['nID'] = kds.read_uint32()
644 d['encrypted_key'] = vds.read_string()
645 d['salt'] = vds.read_string()
646 d['nDerivationMethod'] = vds.read_uint32()
647 d['nDerivationIterations'] = vds.read_uint32()
648 d['otherParams'] = vds.read_string()
649
650 item_callback(type, d)
651
652 except Exception:
653 traceback.print_exc()
654 sys.stdout.write("ERROR parsing wallet.dat, type %s" %
type)
655 sys.stdout.write("key data: %s" % key)
656 sys.stdout.write("key data in hex: %s" %
key.encode('hex_codec'))
657 sys.stdout.write("value data in hex: %s" %
value.encode('hex_codec'))
658 sys.exit(1)
659
660
661# end of bitcointools wallet.dat handling code
662
663# wallet.dat reader / writer
664
665def read_wallet(json_db, walletfile, print_wallet, print_wallet_transactions,
transaction_filter, include_balance, vers= -1, FillPool=False):
666 global passphrase
667 crypted = False
668
669 private_keys = []
670 private_hex_keys = []
671
672 if vers > -1:
673 global addrtype
674 oldaddrtype = addrtype
675 addrtype = vers
676
677 db = open_wallet(walletfile, writable=FillPool)
678
679 json_db['keys'] = []
680 json_db['pool'] = []
681 json_db['tx'] = []
682 json_db['names'] = {}
683 json_db['ckey'] = []
684 json_db['mkey'] = {}
685
686 def item_callback(type, d):
687 if type == "tx":
688 json_db['tx'].append({"tx_id" : d['tx_id'], "txin" :
d['txIn'], "txout" : d['txOut'], "tx_v" : d['txv'], "tx_k" : d['txk']})
689
690 elif type == "name":
691 json_db['names'][d['hash']] = d['name']
692
693 elif type == "version":
694 json_db['version'] = d['version']
695
696 elif type == "minversion":
697 json_db['minversion'] = d['minversion']
698
699 elif type == "setting":
700 if not json_db.has_key('settings'): json_db['settings']
= {}
701 json_db["settings"][d['setting']] = d['value']
702
703 elif type == "defaultkey":
704 json_db['defaultkey'] =
public_key_to_bc_address(d['key'])
705
706 elif type == "key":
707 addr = public_key_to_bc_address(d['public_key'])
708 compressed = d['public_key'][0] != '\04'
709 sec = SecretToASecret(PrivKeyToSecret(d['private_key']),
compressed)
710 hexsec = ASecretToSecret(sec).encode('hex')
711 private_keys.append(sec)
712 json_db['keys'].append({'addr' : addr, 'sec' : sec,
'hexsec' : hexsec, 'secret' : hexsec, 'pubkey':d['public_key'].encode('hex'),
'compressed':compressed, 'private':d['private_key'].encode('hex')})
713
714 elif type == "wkey":
715 if not json_db.has_key('wkey'): json_db['wkey'] = []
716 json_db['wkey']['created'] = d['created']
717
718 elif type == "pool":
719 """ d['n'] = kds.read_int64()
720 d['nVersion'] = vds.read_int32()
721 d['nTime'] = vds.read_int64()
722 d['public_key'] =
vds.read_bytes(vds.read_compact_size())"""
723 try:
724 json_db['pool'].append({'n': d['n'], 'addr':
public_key_to_bc_address(d['public_key']), 'addr2':
public_key_to_bc_address(d['public_key'].decode('hex')), 'addr3':
public_key_to_bc_address(d['public_key'].encode('hex')), 'nTime' : d['nTime'],
'nVersion' : d['nVersion'], 'public_key_hex' : d['public_key'] })
725 except:
726 json_db['pool'].append({'n': d['n'], 'addr':
public_key_to_bc_address(d['public_key']), 'nTime' : d['nTime'], 'nVersion' :
d['nVersion'], 'public_key_hex' : d['public_key'].encode('hex') })
727
728 elif type == "acc":
729 json_db['acc'] = d['account']
730 sys.stdout.write("Account %s (current key: %s)" %
(d['account'], public_key_to_bc_address(d['public_key'])))
731
732 elif type == "acentry":
733 json_db['acentry'] = (d['account'], d['nCreditDebit'],
d['otherAccount'], time.ctime(d['nTime']), d['n'], d['comment'])
734
735 elif type == "bestblock":
736 json_db['bestblock'] = d['hashes'][0][::-
1].encode('hex_codec')
737
738 elif type == "ckey":
739 crypted = True
740 compressed = d['public_key'][0] != '\04'
741 json_db['keys'].append({ 'pubkey':
d['public_key'].encode('hex'), 'addr': public_key_to_bc_address(d['public_key']),
'encrypted_privkey': d['encrypted_private_key'].encode('hex_codec'),
'compressed':compressed})
742
743 elif type == "mkey":
744 json_db['mkey']['nID'] = d['nID']
745 json_db['mkey']['encrypted_key'] =
d['encrypted_key'].encode('hex_codec')
746 json_db['mkey']['salt'] = d['salt'].encode('hex_codec')
747 json_db['mkey']['nDerivationMethod'] =
d['nDerivationMethod']
748 json_db['mkey']['nDerivationIterations'] =
d['nDerivationIterations']
749 json_db['mkey']['otherParams'] = d['otherParams']
750
751 if passphrase:
752 res = crypter.SetKeyFromPassphrase(passphrase,
d['salt'], d['nDerivationIterations'], d['nDerivationMethod'])
753 if res == 0:
754 logging.error("Unsupported derivation
method")
755 sys.exit(1)
756 masterkey = crypter.Decrypt(d['encrypted_key'])
757 crypter.SetKey(masterkey)
758
759 else:
760 json_db[type] = 'unsupported'
761
762 parse_wallet(db, item_callback)
763
764
765 nkeys = len(json_db['keys'])
766 i = 0
767 for k in json_db['keys']:
768 i += 1
769 addr = k['addr']
770 if addr in json_db['names'].keys():
771 k["label"] = json_db['names'][addr]
772 k["reserve"] = 0
773
774 db.close()
775
776 crypted = 'salt' in json_db['mkey']
777
778 if not crypted:
779 sys.stdout.write("%s : this wallet is not encrypted!" %
walletfile)
780 return -1
781
782 for k in json_db['keys']:
783 if k['compressed'] and 'secret' in k:
784 k['secret'] += "01"
785
786 if vers > -1:
787 addrtype = oldaddrtype
788
789 return {'crypted':crypted}
790
791
792from optparse import OptionParser
793
794if __name__ == '__main__':
795
796 parser = OptionParser(usage="%prog [bitcoin wallet files]")
797
798 (options, args) = parser.parse_args()
799
800 if len(args) < 1:
801 print >> sys.stderr, "Usage: %s [bitcon wallet files]" % sys.argv[0]
802 sys.exit(-1)
803
804 for i in range(0, len(args)):
805 filename = args[i]
806 if read_wallet(json_db, filename, True, True, "", False) == -1:
807 continue
808
809 cry_master = json_db['mkey']['encrypted_key'].decode('hex')
810 cry_salt = json_db['mkey']['salt'].decode('hex')
811 cry_rounds = json_db['mkey']['nDerivationIterations']
812 cry_method = json_db['mkey']['nDerivationMethod']
813
814 crypted = 'salt' in json_db['mkey']
815
816 if not crypted:
817 print >> sys.stderr, "%s : this wallet is not encrypted" %
os.path.basename(filename)
818 continue
819
820 for k in json_db['keys']:
821 pass # dirty hack but it works!
822
823 ckey = k['encrypted_privkey']
824 public_key = k['pubkey']
825 cry_master = json_db['mkey']['encrypted_key']
826 cry_salt = json_db['mkey']['salt']
827
828 sys.stdout.write("$bitcoin$%s$%s$%s$%s$%s$%s$%s$%s$%s\n" %
829 (len(cry_master), cry_master, len(cry_salt),
830 cry_salt, cry_rounds, len(ckey), ckey, len(public_key),
831 public_key))
832
833
834
835
836

You might also like