Guest User

Untitled

a guest
Dec 16th, 2017
117
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.57 KB | None | 0 0
  1. #!/usr/bin/env python
  2.  
  3. from __future__ import print_function
  4.  
  5. import argparse, sys, atexit, hashlib, base64, itertools, struct
  6. from os import path
  7. from btcrecover.addressset import AddressSet, varint
  8.  
  9. def add(self, address):
  10. pos = self._find(address)
  11. if pos is True:
  12. return False
  13. bytes_to_add = address[ -(self._bytes_per_addr+self._hash_bytes) : -self._hash_bytes]
  14. if bytes_to_add.endswith(self._null_addr):
  15. return False # ignore these invalid addresses
  16. if self._len >= self._max_len:
  17. raise ValueError("addition to AddressSet exceeds load factor")
  18. self._data[pos : pos+self._bytes_per_addr] = bytes_to_add
  19. self._len += 1
  20. return True
  21.  
  22. dec_digit_to_base58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
  23. def bytes_to_base58(bytes_rep):
  24. int_rep = long(base64.b16encode(bytes_rep), 16)
  25. base58_rep = ''
  26. while int_rep:
  27. int_rep, remainder = divmod(int_rep, 58)
  28. base58_rep = dec_digit_to_base58[remainder] + base58_rep
  29. return base58_rep
  30.  
  31. def hash160_to_base58check(hash160_bytes, version_byte):
  32. assert len(hash160_bytes) == 20
  33. assert len(version_byte) == 1
  34. all_bytes = str(version_byte + hash160_bytes)
  35. all_bytes += hashlib.sha256(hashlib.sha256(all_bytes).digest()).digest()[:4]
  36. base58_rep = bytes_to_base58(all_bytes)
  37. zero_count = next(zeros for zeros,byte in enumerate(all_bytes) if byte != '\0')
  38. return '1' * zero_count + base58_rep
  39.  
  40. parser = argparse.ArgumentParser()
  41. parser.add_argument("--datadir", metavar="DIRECTORY", help="the Bitcoin data directory (default: auto)")
  42. parser.add_argument("--force", action="store_true", help="overwrite any existing addresses file")
  43. parser.add_argument("--no-pause", action="store_true", default=len(sys.argv)>1, help="never pause before exiting (default: auto)")
  44. parser.add_argument("--no-progress",action="store_true", default=not sys.stdout.isatty(), help="disable the progress bar (shows cur. blockfile instead)")
  45. parser.add_argument("addrfilename", nargs="?", default="addresses.txt", help="the name of the addresses file (default: addresses.txt)")
  46. args = parser.parse_args()
  47.  
  48. if not args.no_pause:
  49. atexit.register(lambda: raw_input("\nPress Enter to exit ..."))
  50.  
  51. if not args.force and path.exists(args.addrfilename):
  52. sys.exit("Addresses file already exists (use --force to overwrite)")
  53.  
  54. if args.datadir:
  55. blockdir = args.datadir
  56. elif sys.platform == "win32":
  57. blockdir = path.expandvars(r"%APPDATA%\Bitcoin")
  58. elif sys.platform.startswith("linux"):
  59. blockdir = path.expanduser("~/.bitcoin")
  60. elif sys.platform == "darwin":
  61. blockdir = path.expanduser("~/Library/Application Support/Bitcoin")
  62. else:
  63. sys.exit("Can't automatically determine Bitcoin data directory (use --datadir)")
  64. blockdir = path.join(blockdir, "blocks")
  65.  
  66. if not path.isfile(path.join(blockdir, "blk00000.dat")):
  67. raise ValueError("first block file 'blk00000.dat' doesn't exist in blocks directory '{}'".format(blockdir))
  68.  
  69. address_set = AddressSet(1 << 29)
  70. with open(args.addrfilename, "w") as addrfile:
  71.  
  72. if args.no_progress:
  73. progress_bar = None
  74. else:
  75. try:
  76. import progressbar
  77. print("Parsing block files ...")
  78. for filenum in itertools.count(0):
  79. filename = path.join(blockdir, "blk{:05}.dat".format(filenum))
  80. if not path.isfile(filename):
  81. break
  82. progress_label = progressbar.FormatLabel(" {:11,} addrs. %(elapsed)s, ".format(len(address_set)))
  83. progress_bar = progressbar.ProgressBar(maxval=filenum, widgets=[
  84. progressbar.SimpleProgress(), " ",
  85. progressbar.Bar(left="[", fill="-", right="]"),
  86. progress_label,
  87. progressbar.ETA()
  88. ])
  89. progress_bar.start()
  90. except ImportError:
  91. progress_bar = None
  92.  
  93. if not progress_bar:
  94. print("Block file Address count")
  95. print("------------ -------------")
  96. # e.g. blk00943.dat 255,212,706
  97.  
  98. for filenum in itertools.count(0):
  99. filename = path.join(blockdir, "blk{:05}.dat".format(filenum))
  100. if not path.isfile(filename):
  101. break
  102. address_set.last_filenum = filenum
  103.  
  104. with open(filename, "rb") as blockfile:
  105. if not progress_bar:
  106. print(path.basename(filename), end=" ")
  107.  
  108. header = blockfile.read(8) # read in the magic and remaining (after these 8 bytes) block length
  109. while len(header) == 8 and header[4:] != b"\0\0\0\0":
  110. assert header[:4] == b"\xf9\xbe\xb4\xd9" # magic
  111.  
  112. block = blockfile.read(struct.unpack_from("<I", header, 4)[0]) # read in the rest of the block
  113. tx_count, offset = varint(block, 80) # skips 80 bytes of header
  114. for tx_num in xrange(tx_count):
  115. offset += 4 # skips 4-byte tx version
  116. is_bip144 = block[offset] == b"\0" # bip-144 marker
  117. if is_bip144:
  118. offset += 2 # skips 1-byte marker & 1-byte flag
  119. txin_count, offset = varint(block, offset)
  120. for txin_num in xrange(txin_count):
  121. sigscript_len, offset = varint(block, offset + 36) # skips 32-byte tx id & 4-byte tx index
  122. offset += sigscript_len + 4 # skips sequence number & sigscript
  123. txout_count, offset = varint(block, offset)
  124. for txout_num in xrange(txout_count):
  125. pkscript_len, offset = varint(block, offset + 8) # skips 8-byte satoshi count
  126.  
  127. # If this is a P2PKH script (OP_DUP OP_HASH160 PUSH(20) <20 address bytes> OP_EQUALVERIFY OP_CHECKSIG)
  128. if pkscript_len == 25 and block[offset:offset+3] == b"\x76\xa9\x14" and block[offset+23:offset+25] == b"\x88\xac":
  129. # Add the discovered address to the address set and print it if it's new
  130. if add(address_set, block[offset+3:offset+23]):
  131. print(hash160_to_base58check(block[offset+3:offset+23], '\0'), file=addrfile)
  132.  
  133. offset += pkscript_len # advances past the pubkey script
  134. if is_bip144:
  135. for txin_num in xrange(txin_count):
  136. stackitem_count, offset = varint(block, offset)
  137. for stackitem_num in xrange(stackitem_count):
  138. stackitem_len, offset = varint(block, offset)
  139. offset += stackitem_len # skips this stack item
  140. offset += 4 # skips the 4-byte locktime
  141. header = blockfile.read(8) # read in the next magic and remaining block length
  142.  
  143. if progress_bar:
  144. progress_label.format = " {:11,} addrs. %(elapsed)s, ".format(len(address_set)) # updates address count
  145. nextval = progress_bar.currval + 1
  146. if nextval > progress_bar.maxval: # can happen if the bitcoin client is left running
  147. progress_bar.maxval = nextval
  148. progress_bar.update(nextval)
  149. else:
  150. print("{:13,}".format(len(address_set)))
  151.  
  152. if progress_bar:
  153. progress_bar.widgets.pop() # remove the ETA
  154. progress_bar.finish()
  155.  
  156. print("\nDone.")
Add Comment
Please, Sign In to add comment