Advertisement
joric

Importing private keys into wallet.dat (pywallet.py 1.0)

Jul 12th, 2011
1,538
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 19.47 KB | None | 0 0
  1. #!/usr/bin/env python
  2. #
  3. # pywallet.py 1.0
  4. #
  5. # based on http://github.com/gavinandresen/bitcointools
  6. #
  7. # Usage: pywallet.py [options]
  8. #
  9. # Options:
  10. #   --version            show program's version number and exit
  11. #   -h, --help           show this help message and exit
  12. #   --dumpwallet         dump wallet in json format
  13. #   --importprivkey=KEY  import private key from vanitygen
  14. #   --datadir=DATADIR    wallet directory (defaults to bitcoin default)
  15.  
  16. from bsddb.db import *
  17. import os, sys, time
  18. import json
  19. import logging
  20. import struct
  21. import StringIO
  22. import traceback
  23. import socket
  24. import types
  25. import string
  26. import exceptions
  27. import hashlib
  28. from ctypes import *
  29.  
  30. max_version = 32400
  31. addrtype = 0
  32. json_db = {}
  33. private_keys = []
  34.  
  35. def determine_db_dir():
  36.     import os
  37.     import os.path
  38.     import platform
  39.     if platform.system() == "Darwin":
  40.         return os.path.expanduser("~/Library/Application Support/Bitcoin/")
  41.     elif platform.system() == "Windows":
  42.         return os.path.join(os.environ['APPDATA'], "Bitcoin")
  43.     return os.path.expanduser("~/.bitcoin")
  44.  
  45. dlls = list()
  46. if 'win' in sys.platform:
  47.     for d in ('libeay32.dll', 'libssl32.dll', 'ssleay32.dll'):
  48.         try:
  49.             dlls.append( cdll.LoadLibrary(d) )
  50.         except:
  51.             pass
  52. else:
  53.     dlls.append( cdll.LoadLibrary('libssl.so') )
  54.            
  55. class BIGNUM_Struct (Structure):
  56.     _fields_ = [("d",c_void_p),("top",c_int),("dmax",c_int),("neg",c_int),("flags",c_int)]
  57.                
  58. class BN_CTX_Struct (Structure):
  59.     _fields_ = [ ("_", c_byte) ]
  60.  
  61. BIGNUM = POINTER( BIGNUM_Struct )
  62. BN_CTX = POINTER( BN_CTX_Struct )
  63.  
  64. def load_func( name, args, returns = c_int):
  65.     d = sys.modules[ __name__ ].__dict__
  66.     f = None
  67.    
  68.     for dll in dlls:
  69.         try:
  70.             f = getattr(dll, name)
  71.             f.argtypes = args
  72.             f.restype  = returns
  73.             d[ name ] = f
  74.             return
  75.         except:
  76.             pass
  77.     raise ImportError('Unable to load required functions from SSL dlls')
  78.    
  79. load_func( 'BN_new', [], BIGNUM )
  80. load_func( 'BN_CTX_new', [], BN_CTX )
  81. load_func( 'BN_CTX_free', [BN_CTX], None   )
  82. load_func( 'BN_num_bits', [BIGNUM], c_int )
  83. load_func( 'BN_bn2bin',  [BIGNUM, c_char_p] )
  84. load_func( 'BN_bin2bn',  [c_char_p, c_int, BIGNUM], BIGNUM )
  85. load_func( 'EC_KEY_new_by_curve_name', [c_int], c_void_p )
  86. load_func( 'EC_KEY_get0_group', [c_void_p], c_void_p)
  87. load_func( 'EC_KEY_get0_private_key', [c_void_p], BIGNUM)
  88. load_func( 'EC_POINT_new', [c_void_p], c_void_p)
  89. load_func( 'EC_POINT_free', [c_void_p])
  90. load_func( 'EC_POINT_mul', [c_void_p, c_void_p, BIGNUM, c_void_p, BIGNUM, BN_CTX], c_int)
  91. load_func( 'EC_KEY_set_private_key', [c_void_p, BIGNUM], c_void_p)
  92. load_func( 'EC_KEY_set_public_key', [c_void_p, c_void_p], c_void_p)
  93. load_func( 'i2d_ECPrivateKey', [ c_void_p, POINTER(POINTER(c_char))], c_int )
  94. load_func( 'i2o_ECPublicKey', [ c_void_p, POINTER(POINTER(c_char))], c_int )
  95.  
  96. def BN_num_bytes(a):
  97.     return ((BN_num_bits(a)+7)/8)
  98.  
  99. NID_secp256k1 = 714
  100.  
  101. pkey = 0
  102.  
  103. def EC_KEY_regenerate_key(eckey, priv_key):
  104.     group = EC_KEY_get0_group(eckey)
  105.     ctx = BN_CTX_new()
  106.     pub_key = EC_POINT_new(group)
  107.     EC_POINT_mul(group, pub_key, priv_key, None, None, ctx)
  108.     EC_KEY_set_private_key(eckey, priv_key)
  109.     EC_KEY_set_public_key(eckey, pub_key)
  110.     EC_POINT_free(pub_key)
  111.     BN_CTX_free(ctx)
  112.  
  113. def GetSecret(pkey):
  114.     bn = EC_KEY_get0_private_key(pkey)
  115.     nSize = BN_num_bytes(bn)
  116.     b = create_string_buffer(nSize)
  117.     BN_bn2bin(bn, b)
  118.     return b.raw
  119.    
  120. def GetPrivKey(pkey):
  121.     nSize = i2d_ECPrivateKey(pkey, None)
  122.     p = create_string_buffer(nSize)
  123.     i2d_ECPrivateKey(pkey, byref(cast(p, POINTER(c_char))))
  124.     return p.raw
  125.  
  126. def GetPubKey(pkey):
  127.     nSize = i2o_ECPublicKey(pkey, None)
  128.     p = create_string_buffer(nSize)
  129.     i2o_ECPublicKey(pkey, byref(cast(p, POINTER(c_char))))
  130.     return p.raw
  131.  
  132. def Hash(data):
  133.     s1 = hashlib.sha256()
  134.     s1.update(data)
  135.     h1 = s1.digest()
  136.     s2 = hashlib.sha256()
  137.     s2.update(h1)
  138.     h2 = s2.digest()
  139.     return h2
  140.  
  141. def EncodeBase58Check(vchIn):
  142.     hash = Hash(vchIn)
  143.     return b58encode(vchIn + hash[0:4])
  144.  
  145. def DecodeBase58Check(psz):
  146.     vchRet = b58decode(psz, None)
  147.     key = vchRet[0:-4]
  148.     csum = vchRet[-4:]
  149.     hash = Hash(key)
  150.     cs32 = hash[0:4]
  151.     if cs32 != csum:
  152.         return None
  153.     else:
  154.         return key
  155.  
  156. def SecretToASecret(privkey):
  157.     vchSecret = privkey[9:9+32]
  158.     # add 1-byte version number
  159.     vchIn = "\x80" + vchSecret
  160.     return EncodeBase58Check(vchIn)
  161.  
  162. def ASecretToSecret(key):
  163.     vch = DecodeBase58Check(key)
  164.     if vch:
  165.         return vch[1:]
  166.     else:
  167.         return False
  168.  
  169. def importprivkey(db, key):
  170.     vchSecret = ASecretToSecret(key)
  171.  
  172.     if not vchSecret:
  173.         return False
  174.  
  175.     pkey = EC_KEY_new_by_curve_name(NID_secp256k1)
  176.     bn = BN_bin2bn(vchSecret, 32, BN_new())
  177.     EC_KEY_regenerate_key(pkey, bn)
  178.  
  179.     secret = GetSecret(pkey)
  180.     private_key = GetPrivKey(pkey)
  181.     public_key = GetPubKey(pkey)
  182.     addr = public_key_to_bc_address(public_key)
  183.  
  184.     print "Address: %s" % addr
  185.     print "Privkey: %s" % SecretToASecret(private_key)
  186.  
  187.     update_wallet(db, 'key', { 'public_key' : public_key, 'private_key' : private_key })
  188.     update_wallet(db, 'name', { 'hash' : addr, 'name' : '' })
  189.  
  190.     return True
  191.  
  192. __b58chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
  193. __b58base = len(__b58chars)
  194.  
  195. def b58encode(v):
  196.     """ encode v, which is a string of bytes, to base58.       
  197.     """
  198.  
  199.     long_value = 0L
  200.     for (i, c) in enumerate(v[::-1]):
  201.         long_value += (256**i) * ord(c)
  202.  
  203.     result = ''
  204.     while long_value >= __b58base:
  205.         div, mod = divmod(long_value, __b58base)
  206.         result = __b58chars[mod] + result
  207.         long_value = div
  208.     result = __b58chars[long_value] + result
  209.  
  210.     # Bitcoin does a little leading-zero-compression:
  211.     # leading 0-bytes in the input become leading-1s
  212.     nPad = 0
  213.     for c in v:
  214.         if c == '\0': nPad += 1
  215.         else: break
  216.  
  217.     return (__b58chars[0]*nPad) + result
  218.  
  219. def b58decode(v, length):
  220.     """ decode v into a string of len bytes
  221.     """
  222.     long_value = 0L
  223.     for (i, c) in enumerate(v[::-1]):
  224.         long_value += __b58chars.find(c) * (__b58base**i)
  225.  
  226.     result = ''
  227.     while long_value >= 256:
  228.         div, mod = divmod(long_value, 256)
  229.         result = chr(mod) + result
  230.         long_value = div
  231.     result = chr(long_value) + result
  232.  
  233.     nPad = 0
  234.     for c in v:
  235.         if c == __b58chars[0]: nPad += 1
  236.         else: break
  237.  
  238.     result = chr(0)*nPad + result
  239.     if length is not None and len(result) != length:
  240.         return None
  241.  
  242.     return result
  243.  
  244. def hash_160(public_key):
  245.     s1 = hashlib.sha256()
  246.     s1.update(public_key)
  247.     h1 = s1.digest()
  248.     s2 = hashlib.new('ripemd160')
  249.     s2.update(h1)
  250.     h2 = s2.digest()
  251.     return h2
  252.  
  253. def public_key_to_bc_address(public_key):
  254.     h160 = hash_160(public_key)
  255.     return hash_160_to_bc_address(h160)
  256.  
  257. def hash_160_to_bc_address(h160):
  258.     vh160 = chr(addrtype) + h160
  259.     h3 = Hash(vh160)
  260.     addr = vh160 + h3[0:4]
  261.     return b58encode(addr)
  262.  
  263. def bc_address_to_hash_160(addr):
  264.     bytes = b58decode(addr, 25)
  265.     return bytes[1:21]
  266.  
  267. def long_hex(bytes):
  268.     return bytes.encode('hex_codec')
  269.  
  270. def short_hex(bytes):
  271.     t = bytes.encode('hex_codec')
  272.     if len(t) < 32:
  273.         return t
  274.     return t[0:32]+"..."+t[-32:]
  275.  
  276. def create_env(db_dir=None):
  277.     if db_dir is None:
  278.         db_dir = determine_db_dir()
  279.     db_env = DBEnv(0)
  280.     r = db_env.open(db_dir, (DB_CREATE|DB_INIT_LOCK|DB_INIT_LOG|DB_INIT_MPOOL|DB_INIT_TXN|DB_THREAD|DB_RECOVER))
  281.     return db_env
  282.  
  283. def parse_CAddress(vds):
  284.     d = {'ip':'0.0.0.0','port':0,'nTime': 0}
  285.     try:
  286.         d['nVersion'] = vds.read_int32()
  287.         d['nTime'] = vds.read_uint32()
  288.         d['nServices'] = vds.read_uint64()
  289.         d['pchReserved'] = vds.read_bytes(12)
  290.         d['ip'] = socket.inet_ntoa(vds.read_bytes(4))
  291.         d['port'] = vds.read_uint16()
  292.     except:
  293.         pass
  294.     return d
  295.  
  296. def deserialize_CAddress(d):
  297.     return d['ip']+":"+str(d['port'])#+" (lastseen: %s)"%(time.ctime(d['nTime']),)
  298.  
  299. def parse_setting(setting, vds):
  300.     if setting[0] == "f":   # flag (boolean) settings
  301.         return str(vds.read_boolean())
  302.     elif setting[0:4] == "addr": # CAddress
  303.         d = parse_CAddress(vds)
  304.         return deserialize_CAddress(d)
  305.     elif setting == "nTransactionFee":
  306.         return vds.read_int64()
  307.     elif setting == "nLimitProcessors":
  308.         return vds.read_int32()
  309.     return 'unknown setting'
  310.  
  311. class SerializationError(Exception):
  312.     """ Thrown when there's a problem deserializing or serializing """
  313.  
  314. class BCDataStream(object):
  315.     def __init__(self):
  316.         self.input = None
  317.         self.read_cursor = 0
  318.  
  319.     def clear(self):
  320.         self.input = None
  321.         self.read_cursor = 0
  322.  
  323.     def write(self, bytes): # Initialize with string of bytes
  324.         if self.input is None:
  325.             self.input = bytes
  326.         else:
  327.             self.input += bytes
  328.  
  329.     def map_file(self, file, start):    # Initialize with bytes from file
  330.         self.input = mmap.mmap(file.fileno(), 0, access=mmap.ACCESS_READ)
  331.         self.read_cursor = start
  332.     def seek_file(self, position):
  333.         self.read_cursor = position
  334.     def close_file(self):
  335.         self.input.close()
  336.  
  337.     def read_string(self):
  338.         # Strings are encoded depending on length:
  339.         # 0 to 252 :    1-byte-length followed by bytes (if any)
  340.         # 253 to 65,535 : byte'253' 2-byte-length followed by bytes
  341.         # 65,536 to 4,294,967,295 : byte '254' 4-byte-length followed by bytes
  342.         # ... and the Bitcoin client is coded to understand:
  343.         # greater than 4,294,967,295 : byte '255' 8-byte-length followed by bytes of string
  344.         # ... but I don't think it actually handles any strings that big.
  345.         if self.input is None:
  346.             raise SerializationError("call write(bytes) before trying to deserialize")
  347.  
  348.         try:
  349.             length = self.read_compact_size()
  350.         except IndexError:
  351.             raise SerializationError("attempt to read past end of buffer")
  352.  
  353.         return self.read_bytes(length)
  354.  
  355.     def write_string(self, string):
  356.         # Length-encoded as with read-string
  357.         self.write_compact_size(len(string))
  358.         self.write(string)
  359.  
  360.     def read_bytes(self, length):
  361.         try:
  362.             result = self.input[self.read_cursor:self.read_cursor+length]
  363.             self.read_cursor += length
  364.             return result
  365.         except IndexError:
  366.             raise SerializationError("attempt to read past end of buffer")
  367.  
  368.         return ''
  369.  
  370.     def read_boolean(self): return self.read_bytes(1)[0] != chr(0)
  371.     def read_int16(self): return self._read_num('<h')
  372.     def read_uint16(self): return self._read_num('<H')
  373.     def read_int32(self): return self._read_num('<i')
  374.     def read_uint32(self): return self._read_num('<I')
  375.     def read_int64(self): return self._read_num('<q')
  376.     def read_uint64(self): return self._read_num('<Q')
  377.  
  378.     def write_boolean(self, val): return self.write(chr(1) if val else chr(0))
  379.     def write_int16(self, val): return self._write_num('<h', val)
  380.     def write_uint16(self, val): return self._write_num('<H', val)
  381.     def write_int32(self, val): return self._write_num('<i', val)
  382.     def write_uint32(self, val): return self._write_num('<I', val)
  383.     def write_int64(self, val): return self._write_num('<q', val)
  384.     def write_uint64(self, val): return self._write_num('<Q', val)
  385.  
  386.     def read_compact_size(self):
  387.         size = ord(self.input[self.read_cursor])
  388.         self.read_cursor += 1
  389.         if size == 253:
  390.             size = self._read_num('<H')
  391.         elif size == 254:
  392.             size = self._read_num('<I')
  393.         elif size == 255:
  394.             size = self._read_num('<Q')
  395.         return size
  396.  
  397.     def write_compact_size(self, size):
  398.         if size < 0:
  399.             raise SerializationError("attempt to write size < 0")
  400.         elif size < 253:
  401.              self.write(chr(size))
  402.         elif size < 2**16:
  403.             self.write('\xfd')
  404.             self._write_num('<H', size)
  405.         elif size < 2**32:
  406.             self.write('\xfe')
  407.             self._write_num('<I', size)
  408.         elif size < 2**64:
  409.             self.write('\xff')
  410.             self._write_num('<Q', size)
  411.  
  412.     def _read_num(self, format):
  413.         (i,) = struct.unpack_from(format, self.input, self.read_cursor)
  414.         self.read_cursor += struct.calcsize(format)
  415.         return i
  416.  
  417.     def _write_num(self, format, num):
  418.         s = struct.pack(format, num)
  419.         self.write(s)
  420.  
  421. def open_wallet(db_env, writable=False):
  422.     db = DB(db_env)
  423.     flags = DB_THREAD | (DB_CREATE if writable else DB_RDONLY)
  424.     try:
  425.         r = db.open("wallet.dat", "main", DB_BTREE, flags)
  426.     except DBError:
  427.         r = True
  428.  
  429.     if r is not None:
  430.         logging.error("Couldn't open wallet.dat/main. Try quitting Bitcoin and running this again.")
  431.         sys.exit(1)
  432.    
  433.     return db
  434.  
  435. def parse_wallet(db, item_callback):
  436.     kds = BCDataStream()
  437.     vds = BCDataStream()
  438.  
  439.     for (key, value) in db.items():
  440.         d = { }
  441.  
  442.         kds.clear(); kds.write(key)
  443.         vds.clear(); vds.write(value)
  444.  
  445.         type = kds.read_string()
  446.  
  447.         d["__key__"] = key
  448.         d["__value__"] = value
  449.         d["__type__"] = type
  450.  
  451.         try:
  452.             if type == "tx":
  453.                 d["tx_id"] = kds.read_bytes(32)
  454.                 #d.update(parse_WalletTx(vds))
  455.             elif type == "name":
  456.                 d['hash'] = kds.read_string()
  457.                 d['name'] = vds.read_string()
  458.             elif type == "version":
  459.                 d['version'] = vds.read_uint32()
  460.             elif type == "setting":
  461.                 d['setting'] = kds.read_string()
  462.                 d['value'] = parse_setting(d['setting'], vds)
  463.             elif type == "key":
  464.                 d['public_key'] = kds.read_bytes(kds.read_compact_size())
  465.                 d['private_key'] = vds.read_bytes(vds.read_compact_size())
  466.             elif type == "wkey":
  467.                 d['public_key'] = kds.read_bytes(kds.read_compact_size())
  468.                 d['private_key'] = vds.read_bytes(vds.read_compact_size())
  469.                 d['created'] = vds.read_int64()
  470.                 d['expires'] = vds.read_int64()
  471.                 d['comment'] = vds.read_string()
  472.             elif type == "defaultkey":
  473.                 d['key'] = vds.read_bytes(vds.read_compact_size())
  474.             elif type == "pool":
  475.                 d['n'] = kds.read_int64()
  476.                 d['nVersion'] = vds.read_int32()
  477.                 d['nTime'] = vds.read_int64()
  478.                 d['public_key'] = vds.read_bytes(vds.read_compact_size())
  479.             elif type == "acc":
  480.                 d['account'] = kds.read_string()
  481.                 d['nVersion'] = vds.read_int32()
  482.                 d['public_key'] = vds.read_bytes(vds.read_compact_size())
  483.             elif type == "acentry":
  484.                 d['account'] = kds.read_string()
  485.                 d['n'] = kds.read_uint64()
  486.                 d['nVersion'] = vds.read_int32()
  487.                 d['nCreditDebit'] = vds.read_int64()
  488.                 d['nTime'] = vds.read_int64()
  489.                 d['otherAccount'] = vds.read_string()
  490.                 d['comment'] = vds.read_string()
  491.            
  492.             item_callback(type, d)
  493.  
  494.         except Exception, e:
  495.             traceback.print_exc()
  496.             print("ERROR parsing wallet.dat, type %s" % type)
  497.             print("key data in hex: %s"%key.encode('hex_codec'))
  498.             print("value data in hex: %s"%value.encode('hex_codec'))
  499.             sys.exit(1)
  500.    
  501. def update_wallet(db, type, data):
  502.     """Write a single item to the wallet.
  503.     db must be open with writable=True.
  504.     type and data are the type code and data dictionary as parse_wallet would
  505.     give to item_callback.
  506.     data's __key__, __value__ and __type__ are ignored; only the primary data
  507.     fields are used.
  508.     """
  509.     d = data
  510.     kds = BCDataStream()
  511.     vds = BCDataStream()
  512.  
  513.     # Write the type code to the key
  514.     kds.write_string(type)
  515.     vds.write("")                        # Ensure there is something
  516.  
  517.     try:
  518.         if type == "tx":
  519.             raise NotImplementedError("Writing items of type 'tx'")
  520.             kds.write(d['tx_id'])
  521.             #d.update(parse_WalletTx(vds))
  522.         elif type == "name":
  523.             kds.write_string(d['hash'])
  524.             vds.write_string(d['name'])
  525.         elif type == "version":
  526.             vds.write_uint32(d['version'])
  527.         elif type == "setting":
  528.             raise NotImplementedError("Writing items of type 'setting'")
  529.             kds.write_string(d['setting'])
  530.             #d['value'] = parse_setting(d['setting'], vds)
  531.         elif type == "key":
  532.             kds.write_string(d['public_key'])
  533.             vds.write_string(d['private_key'])
  534.         elif type == "wkey":
  535.             kds.write_string(d['public_key'])
  536.             vds.write_string(d['private_key'])
  537.             vds.write_int64(d['created'])
  538.             vds.write_int64(d['expires'])
  539.             vds.write_string(d['comment'])
  540.         elif type == "defaultkey":
  541.             vds.write_string(d['key'])
  542.         elif type == "pool":
  543.             kds.write_int64(d['n'])
  544.             vds.write_int32(d['nVersion'])
  545.             vds.write_int64(d['nTime'])
  546.             vds.write_string(d['public_key'])
  547.         elif type == "acc":
  548.             kds.write_string(d['account'])
  549.             vds.write_int32(d['nVersion'])
  550.             vds.write_string(d['public_key'])
  551.         elif type == "acentry":
  552.             kds.write_string(d['account'])
  553.             kds.write_uint64(d['n'])
  554.             vds.write_int32(d['nVersion'])
  555.             vds.write_int64(d['nCreditDebit'])
  556.             vds.write_int64(d['nTime'])
  557.             vds.write_string(d['otherAccount'])
  558.             vds.write_string(d['comment'])
  559.         else:
  560.             print "Unknown key type: "+type
  561.  
  562.         # Write the key/value pair to the database
  563.         db.put(kds.input, vds.input)
  564.  
  565.     except Exception, e:
  566.         print("ERROR writing to wallet.dat, type %s"%type)
  567.         print("data dictionary: %r"%data)
  568.         traceback.print_exc()
  569.  
  570. def rewrite_wallet(db_env, destFileName, pre_put_callback=None):
  571.     db = open_wallet(db_env)
  572.  
  573.     db_out = DB(db_env)
  574.     try:
  575.         r = db_out.open(destFileName, "main", DB_BTREE, DB_CREATE)
  576.     except DBError:
  577.         r = True
  578.  
  579.     if r is not None:
  580.         logging.error("Couldn't open %s."%destFileName)
  581.         sys.exit(1)
  582.  
  583.     def item_callback(type, d):
  584.         if (pre_put_callback is None or pre_put_callback(type, d)):
  585.             db_out.put(d["__key__"], d["__value__"])
  586.  
  587.     parse_wallet(db, item_callback)
  588.     db_out.close()
  589.     db.close()
  590.  
  591. def read_wallet(json_db, db_env, print_wallet, print_wallet_transactions, transaction_filter):
  592.     db = open_wallet(db_env)
  593.  
  594.     json_db['keys'] = []
  595.     json_db['pool'] = []
  596.     json_db['names'] = {}
  597.  
  598.     def item_callback(type, d):
  599.  
  600.         if type == "name":
  601.             json_db['names'][d['hash']] = d['name']
  602.  
  603.         elif type == "version":
  604.             json_db['version'] = d['version']
  605.  
  606.         elif type == "setting":
  607.             if not json_db.has_key('settings'): json_db['settings'] = {}
  608.             json_db["settings"][d['setting']] = d['value']
  609.  
  610.         elif type == "defaultkey":
  611.             json_db['defaultkey'] = public_key_to_bc_address(d['key'])
  612.  
  613.         elif type == "key":
  614.             addr = public_key_to_bc_address(d['public_key'])
  615.             sec = SecretToASecret(d['private_key'])
  616.             private_keys.append(sec)
  617.             json_db['keys'].append({'addr' : addr, 'sec' : sec})
  618.  
  619.         elif type == "wkey":
  620.             if not json_db.has_key('wkey'): json_db['wkey'] = []
  621.             json_db['wkey']['created'] = d['created']
  622.  
  623.         elif type == "pool":
  624.             json_db['pool'].append( {'n': d['n'], 'addr': public_key_to_bc_address(d['public_key']), 'nTime' : d['nTime'] } )
  625.  
  626.         elif type == "acc":
  627.             json_db['acc'] = d['account']
  628.             print("Account %s (current key: %s)"%(d['account'], public_key_to_bc_address(d['public_key'])))
  629.  
  630.         elif type == "acentry":
  631.             json_db['acentry'] = (d['account'], d['nCreditDebit'], d['otherAccount'], time.ctime(d['nTime']), d['n'], d['comment'])
  632.  
  633.         else:
  634.             json_db[type] = 'unsupported'
  635.  
  636.  
  637.     parse_wallet(db, item_callback)
  638.  
  639.     db.close()
  640.  
  641.     for k in json_db['keys']:
  642.         addr = k['addr']
  643.         if (addr in json_db['names'].keys()):
  644.             k["label"] = json_db['names'][addr]
  645.         else:
  646.             k["reserve"] = 1
  647.    
  648.     del(json_db['pool'])
  649.     del(json_db['names'])
  650.  
  651. from optparse import OptionParser
  652.  
  653. def main():
  654.     parser = OptionParser(usage="%prog [options]", version="%prog 1.0")
  655.  
  656.     parser.add_option("--dumpwallet", dest="dump", action="store_true",
  657.         help="dump wallet in json format")
  658.  
  659.     parser.add_option("--importprivkey", dest="key",
  660.         help="import private key from vanitygen")
  661.  
  662.     parser.add_option("--datadir", dest="datadir",
  663.         help="wallet directory (defaults to bitcoin default)")
  664.  
  665.     (options, args) = parser.parse_args()
  666.  
  667.     if options.dump is None and options.key is None:
  668.         print "A mandatory option is missing\n"
  669.         parser.print_help()
  670.         exit(0)
  671.  
  672.     if options.datadir is None:
  673.         db_dir = determine_db_dir()
  674.     else:
  675.         db_dir = options.datadir
  676.  
  677.     db_env = create_env(db_dir)
  678.  
  679.     read_wallet(json_db, db_env, True, True, "")
  680.  
  681.     if options.dump:       
  682.         print json.dumps(json_db, sort_keys=True, indent=4)
  683.  
  684.     elif options.key:
  685.         if json_db['version'] > max_version:
  686.             print "Version mismatch (must be <= %d)" % max_version
  687.         elif options.key in private_keys:
  688.             print "Already exists"
  689.         else:  
  690.             db = open_wallet(db_env, writable=True)
  691.  
  692.             if importprivkey(db, options.key):
  693.                 print "Imported successfully"
  694.             else:
  695.                 print "Bad private key"
  696.  
  697.             db.close()
  698.  
  699. if __name__ == '__main__':
  700.     main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement