Sammey19

PyWallet 2.1.7 by jackjack

Dec 31st, 2013
119
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 342.11 KB | None | 0 0
  1. #!/usr/bin/env python
  2. #-*- coding: utf-8 -*-
  3. pywversion="2.1.7"
  4. never_update=False
  5.  
  6. #
  7. # jackjack's pywallet.py
  8. # https://github.com/jackjack-jj/pywallet
  9. # forked from Joric's pywallet.py
  10. #
  11.  
  12.  
  13.  
  14.  
  15. beta_version =  ('a' in pywversion.split('-')[0]) or ('b' in pywversion.split('-')[0])
  16.  
  17. missing_dep = []
  18.  
  19. try:
  20.     from bsddb.db import *
  21. except:
  22.     missing_dep.append('bsddb')
  23.  
  24. import os, sys, time, re
  25. pyw_filename = os.path.basename(__file__)
  26. pyw_path = os.path.dirname(os.path.realpath(__file__))
  27.  
  28. try:
  29.     for i in os.listdir('/usr/lib/python2.5/site-packages'):
  30.         if 'Twisted' in i:
  31.             sys.path.append('/usr/lib/python2.5/site-packages/'+i)
  32. except:
  33.     ''
  34.  
  35. try:
  36.     import json
  37. except:
  38.     try:
  39.          import simplejson as json
  40.     except:
  41.          print("Json or simplejson package is needed")
  42.  
  43. import logging
  44. import struct
  45. import StringIO
  46. import traceback
  47. import socket
  48. import types
  49. import string
  50. import exceptions
  51. import hashlib
  52. import random
  53. import urllib
  54. import math
  55.  
  56. try:
  57.     from twisted.internet import reactor
  58.     from twisted.web import server, resource
  59.     from twisted.web.static import File
  60.     from twisted.python import log
  61. except:
  62.     missing_dep.append('twisted')
  63.  
  64. from datetime import datetime
  65. from subprocess import *
  66.  
  67. import os
  68. import os.path
  69. import platform
  70.  
  71. max_version = 81000
  72. addrtype = 0
  73. json_db = {}
  74. private_keys = []
  75. private_hex_keys = []
  76. passphrase = ""
  77. global_merging_message = ["",""]
  78.  
  79. balance_site = 'http://jackjack.alwaysdata.net/balance/index.php?address'
  80. aversions = {};
  81. for i in range(256):
  82.     aversions[i] = "version %d" % i;
  83. aversions[0] = 'Bitcoin';
  84. aversions[48] = 'Litecoin';
  85. aversions[52] = 'Namecoin';
  86. aversions[111] = 'Testnet';
  87.  
  88. wallet_dir = ""
  89. wallet_name = ""
  90.  
  91. ko = 1e3
  92. kio = 1024
  93. Mo = 1e6
  94. Mio = 1024 ** 2
  95. Go = 1e9
  96. Gio = 1024 ** 3
  97. To = 1e12
  98. Tio = 1024 ** 4
  99.  
  100. prekeys = ["308201130201010420".decode('hex'), "308201120201010420".decode('hex')]
  101. postkeys = ["a081a530".decode('hex'), "81a530".decode('hex')]
  102.  
  103. def iais(a):
  104.     if a>= 2:
  105.         return 's'
  106.     else:
  107.         return ''
  108.  
  109. def systype():
  110.     if platform.system() == "Darwin":
  111.         return 'Mac'
  112.     elif platform.system() == "Windows":
  113.         return 'Win'
  114.     return 'Linux'
  115.  
  116. def determine_db_dir():
  117.     if wallet_dir in "":
  118.         if platform.system() == "Darwin":
  119.             return os.path.expanduser("~/Library/Application Support/Bitcoin/")
  120.         elif platform.system() == "Windows":
  121.             return os.path.join(os.environ['APPDATA'], "Bitcoin")
  122.         return os.path.expanduser("~/.bitcoin")
  123.     else:
  124.         return wallet_dir
  125.  
  126. def determine_db_name():
  127.     if wallet_name in "":
  128.         return "wallet.dat"
  129.     else:
  130.         return wallet_name
  131.  
  132. ########################
  133. # begin of aes.py code #
  134. ########################
  135.  
  136. # from the SlowAES project, http://code.google.com/p/slowaes (aes.py)
  137.  
  138. def append_PKCS7_padding(s):
  139.     """return s padded to a multiple of 16-bytes by PKCS7 padding"""
  140.     numpads = 16 - (len(s)%16)
  141.     return s + numpads*chr(numpads)
  142.  
  143. def strip_PKCS7_padding(s):
  144.     """return s stripped of PKCS7 padding"""
  145.     if len(s)%16 or not s:
  146.         raise ValueError("String of len %d can't be PCKS7-padded" % len(s))
  147.     numpads = ord(s[-1])
  148.     if numpads > 16:
  149.         raise ValueError("String ending with %r can't be PCKS7-padded" % s[-1])
  150.     return s[:-numpads]
  151.  
  152. class AES(object):
  153.     # valid key sizes
  154.     keySize = dict(SIZE_128=16, SIZE_192=24, SIZE_256=32)
  155.  
  156.     # Rijndael S-box
  157.     sbox =  [0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67,
  158.             0x2b, 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59,
  159.             0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7,
  160.             0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1,
  161.             0x71, 0xd8, 0x31, 0x15, 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05,
  162.             0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83,
  163.             0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29,
  164.             0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
  165.             0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, 0xd0, 0xef, 0xaa,
  166.             0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c,
  167.             0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc,
  168.             0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c, 0x13, 0xec,
  169.             0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19,
  170.             0x73, 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee,
  171.             0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49,
  172.             0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
  173.             0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4,
  174.             0xea, 0x65, 0x7a, 0xae, 0x08, 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6,
  175.             0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, 0x70,
  176.             0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9,
  177.             0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e,
  178.             0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 0x8c, 0xa1,
  179.             0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0,
  180.             0x54, 0xbb, 0x16]
  181.  
  182.     # Rijndael Inverted S-box
  183.     rsbox = [0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3,
  184.             0x9e, 0x81, 0xf3, 0xd7, 0xfb , 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f,
  185.             0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb , 0x54,
  186.             0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b,
  187.             0x42, 0xfa, 0xc3, 0x4e , 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24,
  188.             0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25 , 0x72, 0xf8,
  189.             0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d,
  190.             0x65, 0xb6, 0x92 , 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda,
  191.             0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84 , 0x90, 0xd8, 0xab,
  192.             0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3,
  193.             0x45, 0x06 , 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1,
  194.             0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b , 0x3a, 0x91, 0x11, 0x41,
  195.             0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6,
  196.             0x73 , 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9,
  197.             0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e , 0x47, 0xf1, 0x1a, 0x71, 0x1d,
  198.             0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b ,
  199.             0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0,
  200.             0xfe, 0x78, 0xcd, 0x5a, 0xf4 , 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07,
  201.             0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f , 0x60,
  202.             0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f,
  203.             0x93, 0xc9, 0x9c, 0xef , 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5,
  204.             0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61 , 0x17, 0x2b,
  205.             0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55,
  206.             0x21, 0x0c, 0x7d]
  207.  
  208.     def getSBoxValue(self,num):
  209.         """Retrieves a given S-Box Value"""
  210.         return self.sbox[num]
  211.  
  212.     def getSBoxInvert(self,num):
  213.         """Retrieves a given Inverted S-Box Value"""
  214.         return self.rsbox[num]
  215.  
  216.     def rotate(self, word):
  217.         """ Rijndael's key schedule rotate operation.
  218.  
  219.         Rotate a word eight bits to the left: eg, rotate(1d2c3a4f) == 2c3a4f1d
  220.         Word is an char list of size 4 (32 bits overall).
  221.         """
  222.         return word[1:] + word[:1]
  223.  
  224.     # Rijndael Rcon
  225.     Rcon = [0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36,
  226.             0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97,
  227.             0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72,
  228.             0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66,
  229.             0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04,
  230.             0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d,
  231.             0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3,
  232.             0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61,
  233.             0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a,
  234.             0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40,
  235.             0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc,
  236.             0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5,
  237.             0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a,
  238.             0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d,
  239.             0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c,
  240.             0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35,
  241.             0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4,
  242.             0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc,
  243.             0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08,
  244.             0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a,
  245.             0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d,
  246.             0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2,
  247.             0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74,
  248.             0xe8, 0xcb ]
  249.  
  250.     def getRconValue(self, num):
  251.         """Retrieves a given Rcon Value"""
  252.         return self.Rcon[num]
  253.  
  254.     def core(self, word, iteration):
  255.         """Key schedule core."""
  256.         # rotate the 32-bit word 8 bits to the left
  257.         word = self.rotate(word)
  258.         # apply S-Box substitution on all 4 parts of the 32-bit word
  259.         for i in range(4):
  260.             word[i] = self.getSBoxValue(word[i])
  261.         # XOR the output of the rcon operation with i to the first part
  262.         # (leftmost) only
  263.         word[0] = word[0] ^ self.getRconValue(iteration)
  264.         return word
  265.  
  266.     def expandKey(self, key, size, expandedKeySize):
  267.         """Rijndael's key expansion.
  268.  
  269.         Expands an 128,192,256 key into an 176,208,240 bytes key
  270.  
  271.         expandedKey is a char list of large enough size,
  272.         key is the non-expanded key.
  273.         """
  274.         # current expanded keySize, in bytes
  275.         currentSize = 0
  276.         rconIteration = 1
  277.         expandedKey = [0] * expandedKeySize
  278.  
  279.         # set the 16, 24, 32 bytes of the expanded key to the input key
  280.         for j in range(size):
  281.             expandedKey[j] = key[j]
  282.         currentSize += size
  283.  
  284.         while currentSize < expandedKeySize:
  285.             # assign the previous 4 bytes to the temporary value t
  286.             t = expandedKey[currentSize-4:currentSize]
  287.  
  288.             # every 16,24,32 bytes we apply the core schedule to t
  289.             # and increment rconIteration afterwards
  290.             if currentSize % size == 0:
  291.                 t = self.core(t, rconIteration)
  292.                 rconIteration += 1
  293.             # For 256-bit keys, we add an extra sbox to the calculation
  294.             if size == self.keySize["SIZE_256"] and ((currentSize % size) == 16):
  295.                 for l in range(4): t[l] = self.getSBoxValue(t[l])
  296.  
  297.             # We XOR t with the four-byte block 16,24,32 bytes before the new
  298.             # expanded key.  This becomes the next four bytes in the expanded
  299.             # key.
  300.             for m in range(4):
  301.                 expandedKey[currentSize] = expandedKey[currentSize - size] ^ \
  302.                         t[m]
  303.                 currentSize += 1
  304.  
  305.         return expandedKey
  306.  
  307.     def addRoundKey(self, state, roundKey):
  308.         """Adds (XORs) the round key to the state."""
  309.         for i in range(16):
  310.             state[i] ^= roundKey[i]
  311.         return state
  312.  
  313.     def createRoundKey(self, expandedKey, roundKeyPointer):
  314.         """Create a round key.
  315.         Creates a round key from the given expanded key and the
  316.         position within the expanded key.
  317.         """
  318.         roundKey = [0] * 16
  319.         for i in range(4):
  320.             for j in range(4):
  321.                 roundKey[j*4+i] = expandedKey[roundKeyPointer + i*4 + j]
  322.         return roundKey
  323.  
  324.     def galois_multiplication(self, a, b):
  325.         """Galois multiplication of 8 bit characters a and b."""
  326.         p = 0
  327.         for counter in range(8):
  328.             if b & 1: p ^= a
  329.             hi_bit_set = a & 0x80
  330.             a <<= 1
  331.             # keep a 8 bit
  332.             a &= 0xFF
  333.             if hi_bit_set:
  334.                 a ^= 0x1b
  335.             b >>= 1
  336.         return p
  337.  
  338.     #
  339.     # substitute all the values from the state with the value in the SBox
  340.     # using the state value as index for the SBox
  341.     #
  342.     def subBytes(self, state, isInv):
  343.         if isInv: getter = self.getSBoxInvert
  344.         else: getter = self.getSBoxValue
  345.         for i in range(16): state[i] = getter(state[i])
  346.         return state
  347.  
  348.     # iterate over the 4 rows and call shiftRow() with that row
  349.     def shiftRows(self, state, isInv):
  350.         for i in range(4):
  351.             state = self.shiftRow(state, i*4, i, isInv)
  352.         return state
  353.  
  354.     # each iteration shifts the row to the left by 1
  355.     def shiftRow(self, state, statePointer, nbr, isInv):
  356.         for i in range(nbr):
  357.             if isInv:
  358.                 state[statePointer:statePointer+4] = \
  359.                         state[statePointer+3:statePointer+4] + \
  360.                         state[statePointer:statePointer+3]
  361.             else:
  362.                 state[statePointer:statePointer+4] = \
  363.                         state[statePointer+1:statePointer+4] + \
  364.                         state[statePointer:statePointer+1]
  365.         return state
  366.  
  367.     # galois multiplication of the 4x4 matrix
  368.     def mixColumns(self, state, isInv):
  369.         # iterate over the 4 columns
  370.         for i in range(4):
  371.             # construct one column by slicing over the 4 rows
  372.             column = state[i:i+16:4]
  373.             # apply the mixColumn on one column
  374.             column = self.mixColumn(column, isInv)
  375.             # put the values back into the state
  376.             state[i:i+16:4] = column
  377.  
  378.         return state
  379.  
  380.     # galois multiplication of 1 column of the 4x4 matrix
  381.     def mixColumn(self, column, isInv):
  382.         if isInv: mult = [14, 9, 13, 11]
  383.         else: mult = [2, 1, 1, 3]
  384.         cpy = list(column)
  385.         g = self.galois_multiplication
  386.  
  387.         column[0] = g(cpy[0], mult[0]) ^ g(cpy[3], mult[1]) ^ \
  388.                     g(cpy[2], mult[2]) ^ g(cpy[1], mult[3])
  389.         column[1] = g(cpy[1], mult[0]) ^ g(cpy[0], mult[1]) ^ \
  390.                     g(cpy[3], mult[2]) ^ g(cpy[2], mult[3])
  391.         column[2] = g(cpy[2], mult[0]) ^ g(cpy[1], mult[1]) ^ \
  392.                     g(cpy[0], mult[2]) ^ g(cpy[3], mult[3])
  393.         column[3] = g(cpy[3], mult[0]) ^ g(cpy[2], mult[1]) ^ \
  394.                     g(cpy[1], mult[2]) ^ g(cpy[0], mult[3])
  395.         return column
  396.  
  397.     # applies the 4 operations of the forward round in sequence
  398.     def aes_round(self, state, roundKey):
  399.         state = self.subBytes(state, False)
  400.         state = self.shiftRows(state, False)
  401.         state = self.mixColumns(state, False)
  402.         state = self.addRoundKey(state, roundKey)
  403.         return state
  404.  
  405.     # applies the 4 operations of the inverse round in sequence
  406.     def aes_invRound(self, state, roundKey):
  407.         state = self.shiftRows(state, True)
  408.         state = self.subBytes(state, True)
  409.         state = self.addRoundKey(state, roundKey)
  410.         state = self.mixColumns(state, True)
  411.         return state
  412.  
  413.     # Perform the initial operations, the standard round, and the final
  414.     # operations of the forward aes, creating a round key for each round
  415.     def aes_main(self, state, expandedKey, nbrRounds):
  416.         state = self.addRoundKey(state, self.createRoundKey(expandedKey, 0))
  417.         i = 1
  418.         while i < nbrRounds:
  419.             state = self.aes_round(state,
  420.                                    self.createRoundKey(expandedKey, 16*i))
  421.             i += 1
  422.         state = self.subBytes(state, False)
  423.         state = self.shiftRows(state, False)
  424.         state = self.addRoundKey(state,
  425.                                  self.createRoundKey(expandedKey, 16*nbrRounds))
  426.         return state
  427.  
  428.     # Perform the initial operations, the standard round, and the final
  429.     # operations of the inverse aes, creating a round key for each round
  430.     def aes_invMain(self, state, expandedKey, nbrRounds):
  431.         state = self.addRoundKey(state,
  432.                                  self.createRoundKey(expandedKey, 16*nbrRounds))
  433.         i = nbrRounds - 1
  434.         while i > 0:
  435.             state = self.aes_invRound(state,
  436.                                       self.createRoundKey(expandedKey, 16*i))
  437.             i -= 1
  438.         state = self.shiftRows(state, True)
  439.         state = self.subBytes(state, True)
  440.         state = self.addRoundKey(state, self.createRoundKey(expandedKey, 0))
  441.         return state
  442.  
  443.     # encrypts a 128 bit input block against the given key of size specified
  444.     def encrypt(self, iput, key, size):
  445.         output = [0] * 16
  446.         # the number of rounds
  447.         nbrRounds = 0
  448.         # the 128 bit block to encode
  449.         block = [0] * 16
  450.         # set the number of rounds
  451.         if size == self.keySize["SIZE_128"]: nbrRounds = 10
  452.         elif size == self.keySize["SIZE_192"]: nbrRounds = 12
  453.         elif size == self.keySize["SIZE_256"]: nbrRounds = 14
  454.         else: return None
  455.  
  456.         # the expanded keySize
  457.         expandedKeySize = 16*(nbrRounds+1)
  458.  
  459.         # Set the block values, for the block:
  460.         # a0,0 a0,1 a0,2 a0,3
  461.         # a1,0 a1,1 a1,2 a1,3
  462.         # a2,0 a2,1 a2,2 a2,3
  463.         # a3,0 a3,1 a3,2 a3,3
  464.         # the mapping order is a0,0 a1,0 a2,0 a3,0 a0,1 a1,1 ... a2,3 a3,3
  465.         #
  466.         # iterate over the columns
  467.         for i in range(4):
  468.             # iterate over the rows
  469.             for j in range(4):
  470.                 block[(i+(j*4))] = iput[(i*4)+j]
  471.  
  472.         # expand the key into an 176, 208, 240 bytes key
  473.         # the expanded key
  474.         expandedKey = self.expandKey(key, size, expandedKeySize)
  475.  
  476.         # encrypt the block using the expandedKey
  477.         block = self.aes_main(block, expandedKey, nbrRounds)
  478.  
  479.         # unmap the block again into the output
  480.         for k in range(4):
  481.             # iterate over the rows
  482.             for l in range(4):
  483.                 output[(k*4)+l] = block[(k+(l*4))]
  484.         return output
  485.  
  486.     # decrypts a 128 bit input block against the given key of size specified
  487.     def decrypt(self, iput, key, size):
  488.         output = [0] * 16
  489.         # the number of rounds
  490.         nbrRounds = 0
  491.         # the 128 bit block to decode
  492.         block = [0] * 16
  493.         # set the number of rounds
  494.         if size == self.keySize["SIZE_128"]: nbrRounds = 10
  495.         elif size == self.keySize["SIZE_192"]: nbrRounds = 12
  496.         elif size == self.keySize["SIZE_256"]: nbrRounds = 14
  497.         else: return None
  498.  
  499.         # the expanded keySize
  500.         expandedKeySize = 16*(nbrRounds+1)
  501.  
  502.         # Set the block values, for the block:
  503.         # a0,0 a0,1 a0,2 a0,3
  504.         # a1,0 a1,1 a1,2 a1,3
  505.         # a2,0 a2,1 a2,2 a2,3
  506.         # a3,0 a3,1 a3,2 a3,3
  507.         # the mapping order is a0,0 a1,0 a2,0 a3,0 a0,1 a1,1 ... a2,3 a3,3
  508.  
  509.         # iterate over the columns
  510.         for i in range(4):
  511.             # iterate over the rows
  512.             for j in range(4):
  513.                 block[(i+(j*4))] = iput[(i*4)+j]
  514.         # expand the key into an 176, 208, 240 bytes key
  515.         expandedKey = self.expandKey(key, size, expandedKeySize)
  516.         # decrypt the block using the expandedKey
  517.         block = self.aes_invMain(block, expandedKey, nbrRounds)
  518.         # unmap the block again into the output
  519.         for k in range(4):
  520.             # iterate over the rows
  521.             for l in range(4):
  522.                 output[(k*4)+l] = block[(k+(l*4))]
  523.         return output
  524.  
  525. class AESModeOfOperation(object):
  526.  
  527.     aes = AES()
  528.  
  529.     # structure of supported modes of operation
  530.     modeOfOperation = dict(OFB=0, CFB=1, CBC=2)
  531.  
  532.     # converts a 16 character string into a number array
  533.     def convertString(self, string, start, end, mode):
  534.         if end - start > 16: end = start + 16
  535.         if mode == self.modeOfOperation["CBC"]: ar = [0] * 16
  536.         else: ar = []
  537.  
  538.         i = start
  539.         j = 0
  540.         while len(ar) < end - start:
  541.             ar.append(0)
  542.         while i < end:
  543.             ar[j] = ord(string[i])
  544.             j += 1
  545.             i += 1
  546.         return ar
  547.  
  548.     # Mode of Operation Encryption
  549.     # stringIn - Input String
  550.     # mode - mode of type modeOfOperation
  551.     # hexKey - a hex key of the bit length size
  552.     # size - the bit length of the key
  553.     # hexIV - the 128 bit hex Initilization Vector
  554.     def encrypt(self, stringIn, mode, key, size, IV):
  555.         if len(key) % size:
  556.             return None
  557.         if len(IV) % 16:
  558.             return None
  559.         # the AES input/output
  560.         plaintext = []
  561.         iput = [0] * 16
  562.         output = []
  563.         ciphertext = [0] * 16
  564.         # the output cipher string
  565.         cipherOut = []
  566.         # char firstRound
  567.         firstRound = True
  568.         if stringIn != None:
  569.             for j in range(int(math.ceil(float(len(stringIn))/16))):
  570.                 start = j*16
  571.                 end = j*16+16
  572.                 if  end > len(stringIn):
  573.                     end = len(stringIn)
  574.                 plaintext = self.convertString(stringIn, start, end, mode)
  575.                 # print 'PT@%s:%s' % (j, plaintext)
  576.                 if mode == self.modeOfOperation["CFB"]:
  577.                     if firstRound:
  578.                         output = self.aes.encrypt(IV, key, size)
  579.                         firstRound = False
  580.                     else:
  581.                         output = self.aes.encrypt(iput, key, size)
  582.                     for i in range(16):
  583.                         if len(plaintext)-1 < i:
  584.                             ciphertext[i] = 0 ^ output[i]
  585.                         elif len(output)-1 < i:
  586.                             ciphertext[i] = plaintext[i] ^ 0
  587.                         elif len(plaintext)-1 < i and len(output) < i:
  588.                             ciphertext[i] = 0 ^ 0
  589.                         else:
  590.                             ciphertext[i] = plaintext[i] ^ output[i]
  591.                     for k in range(end-start):
  592.                         cipherOut.append(ciphertext[k])
  593.                     iput = ciphertext
  594.                 elif mode == self.modeOfOperation["OFB"]:
  595.                     if firstRound:
  596.                         output = self.aes.encrypt(IV, key, size)
  597.                         firstRound = False
  598.                     else:
  599.                         output = self.aes.encrypt(iput, key, size)
  600.                     for i in range(16):
  601.                         if len(plaintext)-1 < i:
  602.                             ciphertext[i] = 0 ^ output[i]
  603.                         elif len(output)-1 < i:
  604.                             ciphertext[i] = plaintext[i] ^ 0
  605.                         elif len(plaintext)-1 < i and len(output) < i:
  606.                             ciphertext[i] = 0 ^ 0
  607.                         else:
  608.                             ciphertext[i] = plaintext[i] ^ output[i]
  609.                     for k in range(end-start):
  610.                         cipherOut.append(ciphertext[k])
  611.                     iput = output
  612.                 elif mode == self.modeOfOperation["CBC"]:
  613.                     for i in range(16):
  614.                         if firstRound:
  615.                             iput[i] =  plaintext[i] ^ IV[i]
  616.                         else:
  617.                             iput[i] =  plaintext[i] ^ ciphertext[i]
  618.                     # print 'IP@%s:%s' % (j, iput)
  619.                     firstRound = False
  620.                     ciphertext = self.aes.encrypt(iput, key, size)
  621.                     # always 16 bytes because of the padding for CBC
  622.                     for k in range(16):
  623.                         cipherOut.append(ciphertext[k])
  624.         return mode, len(stringIn), cipherOut
  625.  
  626.     # Mode of Operation Decryption
  627.     # cipherIn - Encrypted String
  628.     # originalsize - The unencrypted string length - required for CBC
  629.     # mode - mode of type modeOfOperation
  630.     # key - a number array of the bit length size
  631.     # size - the bit length of the key
  632.     # IV - the 128 bit number array Initilization Vector
  633.     def decrypt(self, cipherIn, originalsize, mode, key, size, IV):
  634.         # cipherIn = unescCtrlChars(cipherIn)
  635.         if len(key) % size:
  636.             return None
  637.         if len(IV) % 16:
  638.             return None
  639.         # the AES input/output
  640.         ciphertext = []
  641.         iput = []
  642.         output = []
  643.         plaintext = [0] * 16
  644.         # the output plain text string
  645.         stringOut = ''
  646.         # char firstRound
  647.         firstRound = True
  648.         if cipherIn != None:
  649.             for j in range(int(math.ceil(float(len(cipherIn))/16))):
  650.                 start = j*16
  651.                 end = j*16+16
  652.                 if j*16+16 > len(cipherIn):
  653.                     end = len(cipherIn)
  654.                 ciphertext = cipherIn[start:end]
  655.                 if mode == self.modeOfOperation["CFB"]:
  656.                     if firstRound:
  657.                         output = self.aes.encrypt(IV, key, size)
  658.                         firstRound = False
  659.                     else:
  660.                         output = self.aes.encrypt(iput, key, size)
  661.                     for i in range(16):
  662.                         if len(output)-1 < i:
  663.                             plaintext[i] = 0 ^ ciphertext[i]
  664.                         elif len(ciphertext)-1 < i:
  665.                             plaintext[i] = output[i] ^ 0
  666.                         elif len(output)-1 < i and len(ciphertext) < i:
  667.                             plaintext[i] = 0 ^ 0
  668.                         else:
  669.                             plaintext[i] = output[i] ^ ciphertext[i]
  670.                     for k in range(end-start):
  671.                         stringOut += chr(plaintext[k])
  672.                     iput = ciphertext
  673.                 elif mode == self.modeOfOperation["OFB"]:
  674.                     if firstRound:
  675.                         output = self.aes.encrypt(IV, key, size)
  676.                         firstRound = False
  677.                     else:
  678.                         output = self.aes.encrypt(iput, key, size)
  679.                     for i in range(16):
  680.                         if len(output)-1 < i:
  681.                             plaintext[i] = 0 ^ ciphertext[i]
  682.                         elif len(ciphertext)-1 < i:
  683.                             plaintext[i] = output[i] ^ 0
  684.                         elif len(output)-1 < i and len(ciphertext) < i:
  685.                             plaintext[i] = 0 ^ 0
  686.                         else:
  687.                             plaintext[i] = output[i] ^ ciphertext[i]
  688.                     for k in range(end-start):
  689.                         stringOut += chr(plaintext[k])
  690.                     iput = output
  691.                 elif mode == self.modeOfOperation["CBC"]:
  692.                     output = self.aes.decrypt(ciphertext, key, size)
  693.                     for i in range(16):
  694.                         if firstRound:
  695.                             plaintext[i] = IV[i] ^ output[i]
  696.                         else:
  697.                             plaintext[i] = iput[i] ^ output[i]
  698.                     firstRound = False
  699.                     if originalsize is not None and originalsize < end:
  700.                         for k in range(originalsize-start):
  701.                             stringOut += chr(plaintext[k])
  702.                     else:
  703.                         for k in range(end-start):
  704.                             stringOut += chr(plaintext[k])
  705.                     iput = ciphertext
  706.         return stringOut
  707.  
  708. ######################
  709. # end of aes.py code #
  710. ######################
  711.  
  712. ###################################
  713. # pywallet crypter implementation #
  714. ###################################
  715.  
  716. crypter = None
  717.  
  718. try:
  719.     from Crypto.Cipher import AES
  720.     crypter = 'pycrypto'
  721. except:
  722.     pass
  723.  
  724. class Crypter_pycrypto( object ):
  725.     def SetKeyFromPassphrase(self, vKeyData, vSalt, nDerivIterations, nDerivationMethod):
  726.         if nDerivationMethod != 0:
  727.             return 0
  728.         data = vKeyData + vSalt
  729.         for i in xrange(nDerivIterations):
  730.             data = hashlib.sha512(data).digest()
  731.         self.SetKey(data[0:32])
  732.         self.SetIV(data[32:32+16])
  733.         return len(data)
  734.  
  735.     def SetKey(self, key):
  736.         self.chKey = key
  737.  
  738.     def SetIV(self, iv):
  739.         self.chIV = iv[0:16]
  740.  
  741.     def Encrypt(self, data):
  742.         return AES.new(self.chKey,AES.MODE_CBC,self.chIV).encrypt(data)[0:32]
  743.  
  744.     def Decrypt(self, data):
  745.         return AES.new(self.chKey,AES.MODE_CBC,self.chIV).decrypt(data)[0:32]
  746.  
  747. try:
  748.     if not crypter:
  749.         import ctypes
  750.         import ctypes.util
  751.         ssl = ctypes.cdll.LoadLibrary (ctypes.util.find_library ('ssl') or 'libeay32')
  752.         crypter = 'ssl'
  753. except:
  754.     pass
  755.  
  756. class Crypter_ssl(object):
  757.     def __init__(self):
  758.         self.chKey = ctypes.create_string_buffer (32)
  759.         self.chIV = ctypes.create_string_buffer (16)
  760.  
  761.     def SetKeyFromPassphrase(self, vKeyData, vSalt, nDerivIterations, nDerivationMethod):
  762.         if nDerivationMethod != 0:
  763.             return 0
  764.         strKeyData = ctypes.create_string_buffer (vKeyData)
  765.         chSalt = ctypes.create_string_buffer (vSalt)
  766.         return ssl.EVP_BytesToKey(ssl.EVP_aes_256_cbc(), ssl.EVP_sha512(), chSalt, strKeyData,
  767.             len(vKeyData), nDerivIterations, ctypes.byref(self.chKey), ctypes.byref(self.chIV))
  768.  
  769.     def SetKey(self, key):
  770.         self.chKey = ctypes.create_string_buffer(key)
  771.  
  772.     def SetIV(self, iv):
  773.         self.chIV = ctypes.create_string_buffer(iv)
  774.  
  775.     def Encrypt(self, data):
  776.         buf = ctypes.create_string_buffer(len(data) + 16)
  777.         written = ctypes.c_int(0)
  778.         final = ctypes.c_int(0)
  779.         ctx = ssl.EVP_CIPHER_CTX_new()
  780.         ssl.EVP_CIPHER_CTX_init(ctx)
  781.         ssl.EVP_EncryptInit_ex(ctx, ssl.EVP_aes_256_cbc(), None, self.chKey, self.chIV)
  782.         ssl.EVP_EncryptUpdate(ctx, buf, ctypes.byref(written), data, len(data))
  783.         output = buf.raw[:written.value]
  784.         ssl.EVP_EncryptFinal_ex(ctx, buf, ctypes.byref(final))
  785.         output += buf.raw[:final.value]
  786.         return output
  787.  
  788.     def Decrypt(self, data):
  789.         buf = ctypes.create_string_buffer(len(data) + 16)
  790.         written = ctypes.c_int(0)
  791.         final = ctypes.c_int(0)
  792.         ctx = ssl.EVP_CIPHER_CTX_new()
  793.         ssl.EVP_CIPHER_CTX_init(ctx)
  794.         ssl.EVP_DecryptInit_ex(ctx, ssl.EVP_aes_256_cbc(), None, self.chKey, self.chIV)
  795.         ssl.EVP_DecryptUpdate(ctx, buf, ctypes.byref(written), data, len(data))
  796.         output = buf.raw[:written.value]
  797.         ssl.EVP_DecryptFinal_ex(ctx, buf, ctypes.byref(final))
  798.         output += buf.raw[:final.value]
  799.         return output
  800.  
  801. class Crypter_pure(object):
  802.     def __init__(self):
  803.         self.m = AESModeOfOperation()
  804.         self.cbc = self.m.modeOfOperation["CBC"]
  805.         self.sz = self.m.aes.keySize["SIZE_256"]
  806.  
  807.     def SetKeyFromPassphrase(self, vKeyData, vSalt, nDerivIterations, nDerivationMethod):
  808.         if nDerivationMethod != 0:
  809.             return 0
  810.         data = vKeyData + vSalt
  811.         for i in xrange(nDerivIterations):
  812.             data = hashlib.sha512(data).digest()
  813.         self.SetKey(data[0:32])
  814.         self.SetIV(data[32:32+16])
  815.         return len(data)
  816.  
  817.     def SetKey(self, key):
  818.         self.chKey = [ord(i) for i in key]
  819.  
  820.     def SetIV(self, iv):
  821.         self.chIV = [ord(i) for i in iv]
  822.  
  823.     def Encrypt(self, data):
  824.         mode, size, cypher = self.m.encrypt(data, self.cbc, self.chKey, self.sz, self.chIV)
  825.         return ''.join(map(chr, cypher))
  826.  
  827.     def Decrypt(self, data):
  828.         chData = [ord(i) for i in data]
  829.         return self.m.decrypt(chData, self.sz, self.cbc, self.chKey, self.sz, self.chIV)
  830.  
  831. if crypter == 'pycrypto':
  832.     crypter = Crypter_pycrypto()
  833. #   print "Crypter: pycrypto"
  834. elif crypter == 'ssl':
  835.     crypter = Crypter_ssl()
  836. #   print "Crypter: ssl"
  837. else:
  838.     crypter = Crypter_pure()
  839. #   print "Crypter: pure"
  840.     logging.warning("pycrypto or libssl not found, decryption may be slow")
  841.  
  842. ##########################################
  843. # end of pywallet crypter implementation #
  844. ##########################################
  845.  
  846. # secp256k1
  847.  
  848. try:
  849.     _p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2FL
  850. except:
  851.     print "Python 3 is not supported, you need Python 2.7.x"
  852.     exit(1)
  853. _r = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141L
  854. _b = 0x0000000000000000000000000000000000000000000000000000000000000007L
  855. _a = 0x0000000000000000000000000000000000000000000000000000000000000000L
  856. _Gx = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798L
  857. _Gy = 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8L
  858.  
  859. try:
  860.     import ecdsa
  861.     from ecdsa import der
  862.     curve_secp256k1 = ecdsa.ellipticcurve.CurveFp (_p, _a, _b)
  863.     generator_secp256k1 = g = ecdsa.ellipticcurve.Point (curve_secp256k1, _Gx, _Gy, _r)
  864.     randrange = random.SystemRandom().randrange
  865.     secp256k1 = ecdsa.curves.Curve ( "secp256k1", curve_secp256k1, generator_secp256k1, (1, 3, 132, 0, 10) )
  866.     ecdsa.curves.curves.append (secp256k1)
  867. except:
  868.     missing_dep.append('ecdsa')
  869.  
  870. # python-ecdsa code (EC_KEY implementation)
  871.  
  872. class CurveFp( object ):
  873.     def __init__( self, p, a, b ):
  874.         self.__p = p
  875.         self.__a = a
  876.         self.__b = b
  877.  
  878.     def p( self ):
  879.         return self.__p
  880.  
  881.     def a( self ):
  882.         return self.__a
  883.  
  884.     def b( self ):
  885.         return self.__b
  886.  
  887.     def contains_point( self, x, y ):
  888.         return ( y * y - ( x * x * x + self.__a * x + self.__b ) ) % self.__p == 0
  889.  
  890. class Point( object ):
  891.     def __init__( self, curve, x, y, order = None ):
  892.         self.__curve = curve
  893.         self.__x = x
  894.         self.__y = y
  895.         self.__order = order
  896.         if self.__curve: assert self.__curve.contains_point( x, y )
  897.         if order: assert self * order == INFINITY
  898.  
  899.     def __add__( self, other ):
  900.         if other == INFINITY: return self
  901.         if self == INFINITY: return other
  902.         assert self.__curve == other.__curve
  903.         if self.__x == other.__x:
  904.             if ( self.__y + other.__y ) % self.__curve.p() == 0:
  905.                 return INFINITY
  906.             else:
  907.                 return self.double()
  908.  
  909.         p = self.__curve.p()
  910.         l = ( ( other.__y - self.__y ) * \
  911.                     inverse_mod( other.__x - self.__x, p ) ) % p
  912.         x3 = ( l * l - self.__x - other.__x ) % p
  913.         y3 = ( l * ( self.__x - x3 ) - self.__y ) % p
  914.         return Point( self.__curve, x3, y3 )
  915.  
  916.     def __mul__( self, other ):
  917.         def leftmost_bit( x ):
  918.             assert x > 0
  919.             result = 1L
  920.             while result <= x: result = 2 * result
  921.             return result / 2
  922.  
  923.         e = other
  924.         if self.__order: e = e % self.__order
  925.         if e == 0: return INFINITY
  926.         if self == INFINITY: return INFINITY
  927.         assert e > 0
  928.         e3 = 3 * e
  929.         negative_self = Point( self.__curve, self.__x, -self.__y, self.__order )
  930.         i = leftmost_bit( e3 ) / 2
  931.         result = self
  932.         while i > 1:
  933.             result = result.double()
  934.             if ( e3 & i ) != 0 and ( e & i ) == 0: result = result + self
  935.             if ( e3 & i ) == 0 and ( e & i ) != 0: result = result + negative_self
  936.             i = i / 2
  937.         return result
  938.  
  939.     def __rmul__( self, other ):
  940.         return self * other
  941.  
  942.     def __str__( self ):
  943.         if self == INFINITY: return "infinity"
  944.         return "(%d,%d)" % ( self.__x, self.__y )
  945.  
  946.     def double( self ):
  947.         if self == INFINITY:
  948.             return INFINITY
  949.  
  950.         p = self.__curve.p()
  951.         a = self.__curve.a()
  952.         l = ( ( 3 * self.__x * self.__x + a ) * \
  953.                     inverse_mod( 2 * self.__y, p ) ) % p
  954.         x3 = ( l * l - 2 * self.__x ) % p
  955.         y3 = ( l * ( self.__x - x3 ) - self.__y ) % p
  956.         return Point( self.__curve, x3, y3 )
  957.  
  958.     def x( self ):
  959.         return self.__x
  960.  
  961.     def y( self ):
  962.         return self.__y
  963.  
  964.     def curve( self ):
  965.         return self.__curve
  966.  
  967.     def order( self ):
  968.         return self.__order
  969.  
  970. INFINITY = Point( None, None, None )
  971.  
  972. def inverse_mod( a, m ):
  973.     if a < 0 or m <= a: a = a % m
  974.     c, d = a, m
  975.     uc, vc, ud, vd = 1, 0, 0, 1
  976.     while c != 0:
  977.         q, c, d = divmod( d, c ) + ( c, )
  978.         uc, vc, ud, vd = ud - q*uc, vd - q*vc, uc, vc
  979.     assert d == 1
  980.     if ud > 0: return ud
  981.     else: return ud + m
  982.  
  983. class Signature( object ):
  984.     def __init__( self, r, s ):
  985.         self.r = r
  986.         self.s = s
  987.  
  988. class Public_key( object ):
  989.     def __init__( self, generator, point, c=None ):
  990.         self.curve = generator.curve()
  991.         self.generator = generator
  992.         self.point = point
  993.         self.compressed = c
  994.         n = generator.order()
  995.         if not n:
  996.             raise RuntimeError, "Generator point must have order."
  997.         if not n * point == INFINITY:
  998.             raise RuntimeError, "Generator point order is bad."
  999.         if point.x() < 0 or n <= point.x() or point.y() < 0 or n <= point.y():
  1000.             raise RuntimeError, "Generator point has x or y out of range."
  1001.  
  1002.     def verifies( self, hash, signature ):
  1003.         G = self.generator
  1004.         n = G.order()
  1005.         r = signature.r
  1006.         s = signature.s
  1007.         if r < 1 or r > n-1: return False
  1008.         if s < 1 or s > n-1: return False
  1009.         c = inverse_mod( s, n )
  1010.         u1 = ( hash * c ) % n
  1011.         u2 = ( r * c ) % n
  1012.         xy = u1 * G + u2 * self.point
  1013.         v = xy.x() % n
  1014.         return v == r
  1015.  
  1016.     def ser(self):
  1017.         if self.compressed:
  1018.             pk=('%02x'%(2+(self.point.y()&1))) + '%064x' % self.point.x()
  1019.         else:
  1020.             pk='04%064x%064x' % (self.point.x(), self.point.y())
  1021.  
  1022.         return pk.decode('hex')
  1023.  
  1024.     def get_addr(self, v=0):
  1025.         return public_key_to_bc_address(self.ser(), v)
  1026.  
  1027. class Private_key( object ):
  1028.     def __init__( self, public_key, secret_multiplier ):
  1029.         self.public_key = public_key
  1030.         self.secret_multiplier = secret_multiplier
  1031.  
  1032.     def der( self ):
  1033.         hex_der_key = '06052b8104000a30740201010420' + \
  1034.             '%064x' % self.secret_multiplier + \
  1035.             'a00706052b8104000aa14403420004' + \
  1036.             '%064x' % self.public_key.point.x() + \
  1037.             '%064x' % self.public_key.point.y()
  1038.         return hex_der_key.decode('hex')
  1039.  
  1040.     def sign( self, hash, random_k ):
  1041.         G = self.public_key.generator
  1042.         n = G.order()
  1043.         k = random_k % n
  1044.         p1 = k * G
  1045.         r = p1.x()
  1046.         if r == 0: raise RuntimeError, "amazingly unlucky random number r"
  1047.         s = ( inverse_mod( k, n ) * \
  1048.                     ( hash + ( self.secret_multiplier * r ) % n ) ) % n
  1049.         if s == 0: raise RuntimeError, "amazingly unlucky random number s"
  1050.         return Signature( r, s )
  1051.  
  1052. class EC_KEY(object):
  1053.     def __init__( self, secret ):
  1054.         curve = CurveFp( _p, _a, _b )
  1055.         generator = Point( curve, _Gx, _Gy, _r )
  1056.         self.pubkey = Public_key( generator, generator * secret )
  1057.         self.privkey = Private_key( self.pubkey, secret )
  1058.         self.secret = secret
  1059.  
  1060. # end of python-ecdsa code
  1061.  
  1062. # pywallet openssl private key implementation
  1063.  
  1064. def i2d_ECPrivateKey(pkey, compressed=False):#, crypted=True):
  1065.     part3='a081a53081a2020101302c06072a8648ce3d0101022100'  # for uncompressed keys
  1066.     if compressed:
  1067.         if True:#not crypted:  ## Bitcoin accepts both part3's for crypted wallets...
  1068.             part3='a08185308182020101302c06072a8648ce3d0101022100'  # for compressed keys
  1069.         key = '3081d30201010420' + \
  1070.             '%064x' % pkey.secret + \
  1071.             part3 + \
  1072.             '%064x' % _p + \
  1073.             '3006040100040107042102' + \
  1074.             '%064x' % _Gx + \
  1075.             '022100' + \
  1076.             '%064x' % _r + \
  1077.             '020101a124032200'
  1078.     else:
  1079.         key = '308201130201010420' + \
  1080.             '%064x' % pkey.secret + \
  1081.             part3 + \
  1082.             '%064x' % _p + \
  1083.             '3006040100040107044104' + \
  1084.             '%064x' % _Gx + \
  1085.             '%064x' % _Gy + \
  1086.             '022100' + \
  1087.             '%064x' % _r + \
  1088.             '020101a144034200'
  1089.  
  1090.     return key.decode('hex') + i2o_ECPublicKey(pkey, compressed)
  1091.  
  1092. def i2o_ECPublicKey(pkey, compressed=False):
  1093.     # public keys are 65 bytes long (520 bits)
  1094.     # 0x04 + 32-byte X-coordinate + 32-byte Y-coordinate
  1095.     # 0x00 = point at infinity, 0x02 and 0x03 = compressed, 0x04 = uncompressed
  1096.     # compressed keys: <sign> <x> where <sign> is 0x02 if y is even and 0x03 if y is odd
  1097.     if compressed:
  1098.         if pkey.pubkey.point.y() & 1:
  1099.             key = '03' + '%064x' % pkey.pubkey.point.x()
  1100.         else:
  1101.             key = '02' + '%064x' % pkey.pubkey.point.x()
  1102.     else:
  1103.         key = '04' + \
  1104.             '%064x' % pkey.pubkey.point.x() + \
  1105.             '%064x' % pkey.pubkey.point.y()
  1106.  
  1107.     return key.decode('hex')
  1108.  
  1109. # bitcointools hashes and base58 implementation
  1110.  
  1111. def hash_160(public_key):
  1112.     md = hashlib.new('ripemd160')
  1113.     md.update(hashlib.sha256(public_key).digest())
  1114.     return md.digest()
  1115.  
  1116. def public_key_to_bc_address(public_key, v=None):
  1117.     if v==None:
  1118.         v=addrtype
  1119.     h160 = hash_160(public_key)
  1120.     return hash_160_to_bc_address(h160, v)
  1121.  
  1122. def hash_160_to_bc_address(h160, v=None):
  1123.     if v==None:
  1124.         v=addrtype
  1125.     vh160 = chr(v) + h160
  1126.     h = Hash(vh160)
  1127.     addr = vh160 + h[0:4]
  1128.     return b58encode(addr)
  1129.  
  1130. def bc_address_to_hash_160(addr):
  1131.     bytes = b58decode(addr, 25)
  1132.     return bytes[1:21]
  1133.  
  1134. __b58chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
  1135. __b58base = len(__b58chars)
  1136.  
  1137. def b58encode(v):
  1138.     """ encode v, which is a string of bytes, to base58.
  1139.     """
  1140.  
  1141.     long_value = 0L
  1142.     for (i, c) in enumerate(v[::-1]):
  1143.         long_value += (256**i) * ord(c)
  1144.  
  1145.     result = ''
  1146.     while long_value >= __b58base:
  1147.         div, mod = divmod(long_value, __b58base)
  1148.         result = __b58chars[mod] + result
  1149.         long_value = div
  1150.     result = __b58chars[long_value] + result
  1151.  
  1152.     # Bitcoin does a little leading-zero-compression:
  1153.     # leading 0-bytes in the input become leading-1s
  1154.     nPad = 0
  1155.     for c in v:
  1156.         if c == '\0': nPad += 1
  1157.         else: break
  1158.  
  1159.     return (__b58chars[0]*nPad) + result
  1160.  
  1161. def b58decode(v, length):
  1162.     """ decode v into a string of len bytes
  1163.     """
  1164.     long_value = 0L
  1165.     for (i, c) in enumerate(v[::-1]):
  1166.         long_value += __b58chars.find(c) * (__b58base**i)
  1167.  
  1168.     result = ''
  1169.     while long_value >= 256:
  1170.         div, mod = divmod(long_value, 256)
  1171.         result = chr(mod) + result
  1172.         long_value = div
  1173.     result = chr(long_value) + result
  1174.  
  1175.     nPad = 0
  1176.     for c in v:
  1177.         if c == __b58chars[0]: nPad += 1
  1178.         else: break
  1179.  
  1180.     result = chr(0)*nPad + result
  1181.     if length is not None and len(result) != length:
  1182.         return None
  1183.  
  1184.     return result
  1185.  
  1186. # end of bitcointools base58 implementation
  1187.  
  1188. # address handling code
  1189.  
  1190. def long_hex(bytes):
  1191.     return bytes.encode('hex_codec')
  1192.  
  1193. def Hash(data):
  1194.     return hashlib.sha256(hashlib.sha256(data).digest()).digest()
  1195.  
  1196. def EncodeBase58Check(secret):
  1197.     hash = Hash(secret)
  1198.     return b58encode(secret + hash[0:4])
  1199.  
  1200. def DecodeBase58Check(sec):
  1201.     vchRet = b58decode(sec, None)
  1202.     secret = vchRet[0:-4]
  1203.     csum = vchRet[-4:]
  1204.     hash = Hash(secret)
  1205.     cs32 = hash[0:4]
  1206.     if cs32 != csum:
  1207.         return None
  1208.     else:
  1209.         return secret
  1210.  
  1211. def str_to_long(b):
  1212.     res = 0
  1213.     pos = 1
  1214.     for a in reversed(b):
  1215.         res += ord(a) * pos
  1216.         pos *= 256
  1217.     return res
  1218.  
  1219. def PrivKeyToSecret(privkey):
  1220.     if len(privkey) == 279:
  1221.         return privkey[9:9+32]
  1222.     else:
  1223.         return privkey[8:8+32]
  1224.  
  1225. def SecretToASecret(secret, compressed=False):
  1226.     prefix = chr((addrtype+128)&255)
  1227.     if addrtype==48:  #assuming Litecoin
  1228.         prefix = chr(128)
  1229.     vchIn = prefix + secret
  1230.     if compressed: vchIn += '\01'
  1231.     return EncodeBase58Check(vchIn)
  1232.  
  1233. def ASecretToSecret(sec):
  1234.     vch = DecodeBase58Check(sec)
  1235.     if not vch:
  1236.         return False
  1237.     if vch[0] != chr((addrtype+128)&255):
  1238.         print 'Warning: adress prefix seems bad (%d vs %d)'%(ord(vch[0]), (addrtype+128)&255)
  1239.     return vch[1:]
  1240.  
  1241. def regenerate_key(sec):
  1242.     b = ASecretToSecret(sec)
  1243.     if not b:
  1244.         return False
  1245.     b = b[0:32]
  1246.     secret = int('0x' + b.encode('hex'), 16)
  1247.     return EC_KEY(secret)
  1248.  
  1249. def GetPubKey(pkey, compressed=False):
  1250.     return i2o_ECPublicKey(pkey, compressed)
  1251.  
  1252. def GetPrivKey(pkey, compressed=False):
  1253.     return i2d_ECPrivateKey(pkey, compressed)
  1254.  
  1255. def GetSecret(pkey):
  1256.     return ('%064x' % pkey.secret).decode('hex')
  1257.  
  1258. def is_compressed(sec):
  1259.     b = ASecretToSecret(sec)
  1260.     return len(b) == 33
  1261.  
  1262. # bitcointools wallet.dat handling code
  1263.  
  1264. def create_env(db_dir):
  1265.     db_env = DBEnv(0)
  1266.     r = db_env.open(db_dir, (DB_CREATE|DB_INIT_LOCK|DB_INIT_LOG|DB_INIT_MPOOL|DB_INIT_TXN|DB_THREAD|DB_RECOVER))
  1267.     return db_env
  1268.  
  1269. def parse_CAddress(vds):
  1270.     d = {'ip':'0.0.0.0','port':0,'nTime': 0}
  1271.     try:
  1272.         d['nVersion'] = vds.read_int32()
  1273.         d['nTime'] = vds.read_uint32()
  1274.         d['nServices'] = vds.read_uint64()
  1275.         d['pchReserved'] = vds.read_bytes(12)
  1276.         d['ip'] = socket.inet_ntoa(vds.read_bytes(4))
  1277.         d['port'] = vds.read_uint16()
  1278.     except:
  1279.         pass
  1280.     return d
  1281.  
  1282. def deserialize_CAddress(d):
  1283.     return d['ip']+":"+str(d['port'])
  1284.  
  1285. def parse_BlockLocator(vds):
  1286.     d = { 'hashes' : [] }
  1287.     nHashes = vds.read_compact_size()
  1288.     for i in xrange(nHashes):
  1289.         d['hashes'].append(vds.read_bytes(32))
  1290.         return d
  1291.  
  1292. def deserialize_BlockLocator(d):
  1293.   result = "Block Locator top: "+d['hashes'][0][::-1].encode('hex_codec')
  1294.   return result
  1295.  
  1296. def parse_setting(setting, vds):
  1297.     if setting[0] == "f":   # flag (boolean) settings
  1298.         return str(vds.read_boolean())
  1299.     elif setting[0:4] == "addr": # CAddress
  1300.         d = parse_CAddress(vds)
  1301.         return deserialize_CAddress(d)
  1302.     elif setting == "nTransactionFee":
  1303.         return vds.read_int64()
  1304.     elif setting == "nLimitProcessors":
  1305.         return vds.read_int32()
  1306.     return 'unknown setting'
  1307.  
  1308. class SerializationError(Exception):
  1309.     """ Thrown when there's a problem deserializing or serializing """
  1310.  
  1311.  
  1312. def search_patterns_on_disk(device, size, inc, patternlist):   # inc must be higher than 1k
  1313.     try:
  1314.         otype=os.O_RDONLY|os.O_BINARY
  1315.     except:
  1316.         otype=os.O_RDONLY
  1317.     try:
  1318.         fd = os.open(device, otype)
  1319.     except Exception as e:
  1320.         print "Can't open %s, check the path or try as root"%device
  1321.         print "  Error:", e.args
  1322.         exit(0)
  1323.  
  1324.     i = 0
  1325.     data=''
  1326.  
  1327.     tzero=time.time()
  1328.     sizetokeep=0
  1329.     BlocksToInspect=dict(map(lambda x:[x,[]], patternlist))
  1330.     syst=systype()
  1331.     lendataloaded=None
  1332.     writeProgressEvery=100*Mo
  1333.     while i < int(size) and (lendataloaded!=0 or lendataloaded==None):
  1334.         if int(i/writeProgressEvery)!=int((i+inc)/writeProgressEvery):
  1335.             print "%.2f Go read"%(i/1e9)
  1336.         try:
  1337.             datakept=data[-sizetokeep:]
  1338.             data = datakept+os.read(fd, inc)
  1339.             lendataloaded = len(data)-len(datakept)   #should be inc
  1340.             for text in patternlist:
  1341.                 if text in data:
  1342.                     BlocksToInspect[text].append([i-len(datakept), data, len(datakept)])
  1343.                     pass
  1344.             sizetokeep=20   # 20 because all the patterns have a len<20. Could be higher.
  1345.             i += lendataloaded
  1346.         except Exception as exc:
  1347.             if lendataloaded%512>0:
  1348.                 raise Exception("SPOD error 1: %d, %d"%(lendataloaded, i-len(datakept)))
  1349.             os.lseek(fd, lendataloaded, os.SEEK_CUR)
  1350.             print str(exc)
  1351.             i += lendataloaded
  1352.             continue
  1353.     os.close(fd)
  1354.  
  1355.     AllOffsets=dict(map(lambda x:[x,[]], patternlist))
  1356.     for text,blocks in BlocksToInspect.items():
  1357.         for offset,data,ldk in blocks:  #ldk = len(datakept)
  1358.             offsetslist=[offset+m.start() for m in re.finditer(text, data)]
  1359.             AllOffsets[text].extend(offsetslist)
  1360.  
  1361.     AllOffsets['PRFdevice']=device
  1362.     AllOffsets['PRFdt']=time.time()-tzero
  1363.     AllOffsets['PRFsize']=i
  1364.     return AllOffsets
  1365.  
  1366. def multiextract(s, ll):
  1367.     r=[]
  1368.     cursor=0
  1369.     for length in ll:
  1370.         r.append(s[cursor:cursor+length])
  1371.         cursor+=length
  1372.     if s[cursor:]!='':
  1373.         r.append(s[cursor:])
  1374.     return r
  1375.  
  1376. class RecovCkey(object):
  1377.     def __init__(self, epk, pk):
  1378.         self.encrypted_pk=epk
  1379.         self.public_key=pk
  1380.         self.mkey=None
  1381.         self.privkey=None
  1382.  
  1383.  
  1384. class RecovMkey(object):
  1385.     def __init__(self, ekey, salt, nditer, ndmethod, nid):
  1386.         self.encrypted_key=ekey
  1387.         self.salt=salt
  1388.         self.iterations=nditer
  1389.         self.method=ndmethod
  1390.         self.id=nid
  1391.  
  1392. def readpartfile(fd, offset, length):   #make everything 512*n because of windows...
  1393.     rest=offset%512
  1394.     new_offset=offset-rest
  1395.     big_length=512*(int((length+rest-1)/512)+1)
  1396.     os.lseek(fd, new_offset, os.SEEK_SET)
  1397.     d=os.read(fd, big_length)
  1398.     return d[rest:rest+length]
  1399.  
  1400. def recov_ckey(fd, offset):
  1401.     d=readpartfile(fd, offset-49, 122)
  1402.     me=multiextract(d, [1,48,4,4,1])
  1403.  
  1404.     checks=[]
  1405.     checks.append([0, '30'])
  1406.     checks.append([3, '636b6579'])
  1407.     if sum(map(lambda x:int(me[x[0]]!=x[1].decode('hex')), checks)):  #number of false statements
  1408.         return None
  1409.  
  1410.     return me
  1411.  
  1412. def recov_mkey(fd, offset):
  1413.     d=readpartfile(fd, offset-72, 84)
  1414.     me=multiextract(d, [4,48,1,8,4,4,1,2,8,4])
  1415.  
  1416.     checks=[]
  1417.     checks.append([0, '43000130'])
  1418.     checks.append([2, '08'])
  1419.     checks.append([6, '00'])
  1420.     checks.append([8, '090001046d6b6579'])
  1421.     if sum(map(lambda x:int(me[x[0]]!=x[1].decode('hex')), checks)):  #number of false statements
  1422.         return None
  1423.  
  1424.     return me
  1425.  
  1426. def recov_uckey(fd, offset):
  1427.     checks=[]
  1428.  
  1429.     d=readpartfile(fd, offset-217, 223)
  1430.     if d[-7]=='\x26':
  1431.         me=multiextract(d, [2,1,4,1,32,141,33,2,1,6])
  1432.  
  1433.         checks.append([0, '3081'])
  1434.         checks.append([2, '02010104'])
  1435.     elif d[-7]=='\x46':
  1436.         d=readpartfile(fd, offset-282, 286)
  1437.  
  1438.         me=multiextract(d, [2,1,4,1,32,173,65,1,2,5])
  1439.  
  1440.         checks.append([0, '8201'])
  1441.         checks.append([2, '02010104'])
  1442.         checks.append([-1, '460001036b'])
  1443.     else:
  1444.         return None
  1445.  
  1446.  
  1447.     if sum(map(lambda x:int(me[x[0]]!=x[1].decode('hex')), checks)):  #number of false statements
  1448.         return None
  1449.  
  1450.     return me
  1451.  
  1452. def starts_with(s, b):
  1453.     return len(s)>=len(b) and s[:len(b)]==b
  1454.  
  1455.  
  1456. def recov(device, passes, size=102400, inc=10240, outputdir='.'):
  1457.     if inc%512>0:
  1458.         inc-=inc%512   #inc must be 512*n on Windows... Don't ask me why...
  1459.  
  1460.     nameToDBName={'mkey':'\x09\x00\x01\x04mkey','ckey':'\x27\x00\x01\x04ckey','key':'\x00\x01\x03key',}
  1461.  
  1462.  
  1463.     if not starts_with(device, 'PartialRecoveryFile:'):
  1464.         r=search_patterns_on_disk(device, size, inc, map(lambda x:nameToDBName[x], ['mkey', 'ckey', 'key']))
  1465.         f=open(outputdir+'/pywallet_partial_recovery_%d.dat'%ts(), 'w')
  1466.         f.write(str(r))
  1467.         f.close()
  1468.         print "\nRead %.1f Go in %.1f minutes\n"%(r['PRFsize']/1e9, r['PRFdt']/60.0)
  1469.     else:
  1470.         prf=device[20:]
  1471.         f=open(prf, 'r')
  1472.         content=f.read()
  1473.         f.close()
  1474.         cmd=("z = "+content+"")
  1475.         exec cmd in locals()
  1476.         r=z
  1477.         device=r['PRFdevice']
  1478.         print "\nLoaded %.1f Go from %s\n"%(r['PRFsize']/1e9, device)
  1479.  
  1480.  
  1481.     try:
  1482.         otype=os.O_RDONLY|os.O_BINARY
  1483.     except:
  1484.         otype=os.O_RDONLY
  1485.     fd = os.open(device, otype)
  1486.  
  1487.  
  1488.     mkeys=[]
  1489.     crypters=[]
  1490.     syst=systype()
  1491.     for offset in r[nameToDBName['mkey']]:
  1492.         s=recov_mkey(fd, offset)
  1493.         if s==None:
  1494.             continue
  1495.         newmkey=RecovMkey(s[1],s[3],int(s[5][::-1].encode('hex'), 16),int(s[4][::-1].encode('hex'), 16),int(s[-1][::-1].encode('hex'), 16))
  1496.         mkeys.append([offset,newmkey])
  1497.  
  1498.     print "Found", len(mkeys), 'possible wallets'
  1499.  
  1500.  
  1501.  
  1502.  
  1503.     ckeys=[]
  1504.     for offset in r[nameToDBName['ckey']]:
  1505.         s=recov_ckey(fd, offset)
  1506.         if s==None:
  1507.             continue
  1508.         newckey=RecovCkey(s[1], s[5][:int(s[4].encode('hex'),16)])
  1509.         ckeys.append([offset,newckey])
  1510.     print "Found", len(ckeys), 'possible encrypted keys'
  1511.  
  1512.  
  1513.     uckeys=[]
  1514.     for offset in r[nameToDBName['key']]:
  1515.         s=recov_uckey(fd, offset)
  1516.         if s==None:
  1517.             continue
  1518.         uckeys.append(s[4])
  1519.     print "Found", len(uckeys), 'possible unencrypted keys'
  1520.  
  1521.  
  1522.     os.close(fd)
  1523.  
  1524.  
  1525.     list_of_possible_keys_per_master_key=dict(map(lambda x:[x[1],[]], mkeys))
  1526.     for cko,ck in ckeys:
  1527.         tl=map(lambda x:[abs(x[0]-cko)]+x, mkeys)
  1528.         tl=sorted(tl, key=lambda x:x[0])
  1529.         list_of_possible_keys_per_master_key[tl[0][2]].append(ck)
  1530.  
  1531.     cpt=0
  1532.     mki=1
  1533.     tzero=time.time()
  1534.     if len(passes)==0:
  1535.         if len(ckeys)>0:
  1536.             print "Can't decrypt them as you didn't provide any passphrase."
  1537.     else:
  1538.         for mko,mk in mkeys:
  1539.             list_of_possible_keys=list_of_possible_keys_per_master_key[mk]
  1540.             sys.stdout.write( "\nPossible wallet #"+str(mki))
  1541.             sys.stdout.flush()
  1542.             for ppi,pp in enumerate(passes):
  1543.                 sys.stdout.write( "\n    with passphrase #"+str(ppi+1)+"  ")
  1544.                 sys.stdout.flush()
  1545.                 failures_in_a_row=0
  1546. #               print "SKFP params:", pp, mk.salt, mk.iterations, mk.method
  1547.                 res = crypter.SetKeyFromPassphrase(pp, mk.salt, mk.iterations, mk.method)
  1548.                 if res == 0:
  1549.                     print "Unsupported derivation method"
  1550.                     sys.exit(1)
  1551.                 masterkey = crypter.Decrypt(mk.encrypted_key)
  1552.                 crypter.SetKey(masterkey)
  1553.                 for ck in list_of_possible_keys:
  1554.                     if cpt%10==9 and failures_in_a_row==0:
  1555.                         sys.stdout.write('.')
  1556.                         sys.stdout.flush()
  1557.                     if failures_in_a_row>5:
  1558.                         break
  1559.                     crypter.SetIV(Hash(ck.public_key))
  1560.                     secret = crypter.Decrypt(ck.encrypted_pk)
  1561.                     compressed = ck.public_key[0] != '\04'
  1562.  
  1563.  
  1564.                     pkey = EC_KEY(int('0x' + secret.encode('hex'), 16))
  1565.                     if ck.public_key != GetPubKey(pkey, compressed):
  1566.                         failures_in_a_row+=1
  1567.                     else:
  1568.                         failures_in_a_row=0
  1569.                         ck.mkey=mk
  1570.                         ck.privkey=secret
  1571.                     cpt+=1
  1572.             mki+=1
  1573.         print "\n"
  1574.         tone=time.time()
  1575.         try:
  1576.             calcspeed=1.0*cpt/(tone-tzero)*60  #calc/min
  1577.         except:
  1578.             calcspeed=1.0
  1579.         if calcspeed==0:
  1580.             calcspeed=1.0
  1581.  
  1582.         ckeys_not_decrypted=filter(lambda x:x[1].privkey==None, ckeys)
  1583.         refused_to_test_all_pps=True
  1584.         if len(ckeys_not_decrypted)==0:
  1585.             print "All the found encrypted private keys have been decrypted."
  1586.             return map(lambda x:x[1].privkey, ckeys)
  1587.         else:
  1588.             print "Private keys not decrypted: %d"%len(ckeys_not_decrypted)
  1589.             print "Trying all the remaining possibilities (%d) might take up to %d minutes."%(len(ckeys_not_decrypted)*len(passes)*len(mkeys),int(len(ckeys_not_decrypted)*len(passes)*len(mkeys)/calcspeed))
  1590.             cont=raw_input("Do you want to test them? (y/n): ")
  1591.             while len(cont)==0:
  1592.                                 cont=raw_input("Do you want to test them? (y/n): ")
  1593.                         if cont[0]=='y':
  1594.                                 refused_to_test_all_pps=False
  1595.                                 cpt=0
  1596.                                 for dist,mko,mk in tl:
  1597.                                         for ppi,pp in enumerate(passes):
  1598.                                                 res = crypter.SetKeyFromPassphrase(pp, mk.salt, mk.iterations, mk.method)
  1599.                                                 if res == 0:
  1600.                                                         logging.error("Unsupported derivation method")
  1601.                                                         sys.exit(1)
  1602.                                                 masterkey = crypter.Decrypt(mk.encrypted_key)
  1603.                                                 crypter.SetKey(masterkey)
  1604.                                                 for cko,ck in ckeys_not_decrypted:
  1605.                                                         tl=map(lambda x:[abs(x[0]-cko)]+x, mkeys)
  1606.                                                         tl=sorted(tl, key=lambda x:x[0])
  1607.                                                         if mk==tl[0][2]:
  1608.                                                                 continue         #because already tested
  1609.                                                         crypter.SetIV(Hash(ck.public_key))
  1610.                                                         secret = crypter.Decrypt(ck.encrypted_pk)
  1611.                                                         compressed = ck.public_key[0] != '\04'
  1612.  
  1613.  
  1614.                                                         pkey = EC_KEY(int('0x' + secret.encode('hex'), 16))
  1615.                                                         if ck.public_key == GetPubKey(pkey, compressed):
  1616.                                                                 ck.mkey=mk
  1617.                                                                 ck.privkey=secret
  1618.                                                         cpt+=1
  1619.  
  1620.         print
  1621.         ckeys_not_decrypted=filter(lambda x:x[1].privkey==None, ckeys)
  1622.         if len(ckeys_not_decrypted)==0:
  1623.             print "All the found encrypted private keys have been finally decrypted."
  1624.         elif not refused_to_test_all_pps:
  1625.             print "Private keys not decrypted: %d"%len(ckeys_not_decrypted)
  1626.             print "Try another password, check the size of your partition or seek help"
  1627.  
  1628.  
  1629.     uncrypted_ckeys=filter(lambda x:x!=None, map(lambda x:x[1].privkey, ckeys))
  1630.     uckeys.extend(uncrypted_ckeys)
  1631.  
  1632.     return uckeys
  1633.  
  1634.  
  1635.  
  1636.  
  1637. def ts():
  1638.     return int(time.mktime(datetime.now().timetuple()))
  1639.  
  1640. def check_postkeys(key, postkeys):
  1641.     for i in postkeys:
  1642.         if key[:len(i)] == i:
  1643.             return True
  1644.     return False
  1645.  
  1646. def one_element_in(a, string):
  1647.     for i in a:
  1648.         if i in string:
  1649.             return True
  1650.     return False
  1651.  
  1652. def first_read(device, size, prekeys, inc=10000):
  1653.     t0 = ts()-1
  1654.     try:
  1655.         fd = os.open (device, os.O_RDONLY)
  1656.     except:
  1657.         print("Can't open %s, check the path or try as root"%device)
  1658.         exit(0)
  1659.     prekey = prekeys[0]
  1660.     data = ""
  1661.     i = 0
  1662.     data = os.read (fd, i)
  1663.     before_contained_key = False
  1664.     contains_key = False
  1665.     ranges = []
  1666.  
  1667.     while i < int(size):
  1668.         if i%(10*Mio) > 0 and i%(10*Mio) <= inc:
  1669.             print("\n%.2f/%.2f Go"%(i/1e9, size/1e9))
  1670.             t = ts()
  1671.             speed = i/(t-t0)
  1672.             ETAts = size/speed + t0
  1673.             d = datetime.fromtimestamp(ETAts)
  1674.             print(d.strftime("   ETA: %H:%M:%S"))
  1675.  
  1676.         try:
  1677.             data = os.read (fd, inc)
  1678.         except Exception as exc:
  1679.             os.lseek(fd, inc, os.SEEK_CUR)
  1680.             print str(exc)
  1681.             i += inc
  1682.             continue
  1683.  
  1684.         contains_key = one_element_in(prekeys, data)
  1685.  
  1686.         if not before_contained_key and contains_key:
  1687.             ranges.append(i)
  1688.  
  1689.         if before_contained_key and not contains_key:
  1690.             ranges.append(i)
  1691.  
  1692.         before_contained_key = contains_key
  1693.  
  1694.         i += inc
  1695.  
  1696.     os.close (fd)
  1697.     return ranges
  1698.  
  1699. def shrink_intervals(device, ranges, prekeys, inc=1000):
  1700.     prekey = prekeys[0]
  1701.     nranges = []
  1702.     fd = os.open (device, os.O_RDONLY)
  1703.     for j in range(len(ranges)/2):
  1704.         before_contained_key = False
  1705.         contains_key = False
  1706.         bi = ranges[2*j]
  1707.         bf = ranges[2*j+1]
  1708.  
  1709.         mini_blocks = []
  1710.         k = bi
  1711.         while k <= bf + len(prekey) + 1:
  1712.             mini_blocks.append(k)
  1713.             k += inc
  1714.             mini_blocks.append(k)
  1715.  
  1716.         for k in range(len(mini_blocks)/2):
  1717.             mini_blocks[2*k] -= len(prekey) +1
  1718.             mini_blocks[2*k+1] += len(prekey) +1
  1719.  
  1720.  
  1721.             bi = mini_blocks[2*k]
  1722.             bf = mini_blocks[2*k+1]
  1723.  
  1724.             os.lseek(fd, bi, 0)
  1725.  
  1726.             data = os.read(fd, bf-bi+1)
  1727.             contains_key = one_element_in(prekeys, data)
  1728.  
  1729.             if not before_contained_key and contains_key:
  1730.                 nranges.append(bi)
  1731.  
  1732.             if before_contained_key and not contains_key:
  1733.                 nranges.append(bi+len(prekey) +1+len(prekey) +1)
  1734.  
  1735.             before_contained_key = contains_key
  1736.  
  1737.     os.close (fd)
  1738.  
  1739.     return nranges
  1740.  
  1741. def find_offsets(device, ranges, prekeys):
  1742.     prekey = prekeys[0]
  1743.     list_offsets = []
  1744.     to_read = 0
  1745.     fd = os.open (device, os.O_RDONLY)
  1746.     for i in range(len(ranges)/2):
  1747.         bi = ranges[2*i]-len(prekey)-1
  1748.         os.lseek(fd, bi, 0)
  1749.         bf = ranges[2*i+1]+len(prekey)+1
  1750.         to_read += bf-bi+1
  1751.         buf = ""
  1752.         for j in range(len(prekey)):
  1753.             buf += "\x00"
  1754.         curs = bi
  1755.  
  1756.         while curs <= bf:
  1757.             data = os.read(fd, 1)
  1758.             buf = buf[1:] + data
  1759.             if buf in prekeys:
  1760.                 list_offsets.append(curs)
  1761.             curs += 1
  1762.  
  1763.     os.close (fd)
  1764.  
  1765.     return [to_read, list_offsets]
  1766.  
  1767. def read_keys(device, list_offsets):
  1768.     found_hexkeys = []
  1769.     fd = os.open (device, os.O_RDONLY)
  1770.     for offset in list_offsets:
  1771.         os.lseek(fd, offset+1, 0)
  1772.         data = os.read(fd, 40)
  1773.         hexkey = data[1:33].encode('hex')
  1774.         after_key = data[33:39].encode('hex')
  1775.         if hexkey not in found_hexkeys and check_postkeys(after_key.decode('hex'), postkeys):
  1776.             found_hexkeys.append(hexkey)
  1777.  
  1778.     os.close (fd)
  1779.  
  1780.     return found_hexkeys
  1781.  
  1782. def read_device_size(size):
  1783.     if size[-2] == 'i':
  1784.         unit = size[-3:]
  1785.         value = float(size[:-3])
  1786.     else:
  1787.         unit = size[-2:]
  1788.         value = float(size[:-2])
  1789.     exec 'unit = %s' % unit
  1790.     return int(value * unit)
  1791.  
  1792. def md5_2(a):
  1793.     return hashlib.md5(a).digest()
  1794.  
  1795. def md5_file(nf):
  1796.   try:
  1797.     fichier = file(nf, 'r').read()
  1798.     return md5_2(fichier)
  1799.   except:
  1800.     return 'zz'
  1801.  
  1802. def md5_onlinefile(add):
  1803.     page = urllib.urlopen(add).read()
  1804.     return md5_2(page)
  1805.  
  1806.  
  1807. class KEY:
  1808.  
  1809.      def __init__ (self):
  1810.           self.prikey = None
  1811.           self.pubkey = None
  1812.  
  1813.      def generate (self, secret=None):
  1814.           if secret:
  1815.                 exp = int ('0x' + secret.encode ('hex'), 16)
  1816.                 self.prikey = ecdsa.SigningKey.from_secret_exponent (exp, curve=secp256k1)
  1817.           else:
  1818.                 self.prikey = ecdsa.SigningKey.generate (curve=secp256k1)
  1819.           self.pubkey = self.prikey.get_verifying_key()
  1820.           return self.prikey.to_der()
  1821.  
  1822.      def set_privkey (self, key):
  1823.           if len(key) == 279:
  1824.                 seq1, rest = der.remove_sequence (key)
  1825.                 integer, rest = der.remove_integer (seq1)
  1826.                 octet_str, rest = der.remove_octet_string (rest)
  1827.                 tag1, cons1, rest, = der.remove_constructed (rest)
  1828.                 tag2, cons2, rest, = der.remove_constructed (rest)
  1829.                 point_str, rest = der.remove_bitstring (cons2)
  1830.                 self.prikey = ecdsa.SigningKey.from_string(octet_str, curve=secp256k1)
  1831.           else:
  1832.                 self.prikey = ecdsa.SigningKey.from_der (key)
  1833.  
  1834.      def set_pubkey (self, key):
  1835.           key = key[1:]
  1836.           self.pubkey = ecdsa.VerifyingKey.from_string (key, curve=secp256k1)
  1837.  
  1838.      def get_privkey (self):
  1839.           _p = self.prikey.curve.curve.p ()
  1840.           _r = self.prikey.curve.generator.order ()
  1841.           _Gx = self.prikey.curve.generator.x ()
  1842.           _Gy = self.prikey.curve.generator.y ()
  1843.           encoded_oid2 = der.encode_oid (*(1, 2, 840, 10045, 1, 1))
  1844.           encoded_gxgy = "\x04" + ("%64x" % _Gx).decode('hex') + ("%64x" % _Gy).decode('hex')
  1845.           param_sequence = der.encode_sequence (
  1846.                 ecdsa.der.encode_integer(1),
  1847.                     der.encode_sequence (
  1848.                     encoded_oid2,
  1849.                     der.encode_integer (_p),
  1850.                 ),
  1851.                 der.encode_sequence (
  1852.                     der.encode_octet_string("\x00"),
  1853.                     der.encode_octet_string("\x07"),
  1854.                 ),
  1855.                 der.encode_octet_string (encoded_gxgy),
  1856.                 der.encode_integer (_r),
  1857.                 der.encode_integer (1),
  1858.           );
  1859.           encoded_vk = "\x00\x04" + self.pubkey.to_string ()
  1860.           return der.encode_sequence (
  1861.                 der.encode_integer (1),
  1862.                 der.encode_octet_string (self.prikey.to_string ()),
  1863.                 der.encode_constructed (0, param_sequence),
  1864.                 der.encode_constructed (1, der.encode_bitstring (encoded_vk)),
  1865.           )
  1866.  
  1867.      def get_pubkey (self):
  1868.           return "\x04" + self.pubkey.to_string()
  1869.  
  1870.      def sign (self, hash):
  1871.           sig = self.prikey.sign_digest (hash, sigencode=ecdsa.util.sigencode_der)
  1872.           return sig.encode('hex')
  1873.  
  1874.      def verify (self, hash, sig):
  1875.           return self.pubkey.verify_digest (sig, hash, sigdecode=ecdsa.util.sigdecode_der)
  1876.  
  1877. def bool_to_int(b):
  1878.     if b:
  1879.         return 1
  1880.     return 0
  1881.  
  1882. class BCDataStream(object):
  1883.     def __init__(self):
  1884.         self.input = None
  1885.         self.read_cursor = 0
  1886.  
  1887.     def clear(self):
  1888.         self.input = None
  1889.         self.read_cursor = 0
  1890.  
  1891.     def write(self, bytes): # Initialize with string of bytes
  1892.         if self.input is None:
  1893.             self.input = bytes
  1894.         else:
  1895.             self.input += bytes
  1896.  
  1897.     def map_file(self, file, start):    # Initialize with bytes from file
  1898.         self.input = mmap.mmap(file.fileno(), 0, access=mmap.ACCESS_READ)
  1899.         self.read_cursor = start
  1900.     def seek_file(self, position):
  1901.         self.read_cursor = position
  1902.     def close_file(self):
  1903.         self.input.close()
  1904.  
  1905.     def read_string(self):
  1906.         # Strings are encoded depending on length:
  1907.         # 0 to 252 :    1-byte-length followed by bytes (if any)
  1908.         # 253 to 65,535 : byte'253' 2-byte-length followed by bytes
  1909.         # 65,536 to 4,294,967,295 : byte '254' 4-byte-length followed by bytes
  1910.         # ... and the Bitcoin client is coded to understand:
  1911.         # greater than 4,294,967,295 : byte '255' 8-byte-length followed by bytes of string
  1912.         # ... but I don't think it actually handles any strings that big.
  1913.         if self.input is None:
  1914.             raise SerializationError("call write(bytes) before trying to deserialize")
  1915.  
  1916.         try:
  1917.             length = self.read_compact_size()
  1918.         except IndexError:
  1919.             raise SerializationError("attempt to read past end of buffer")
  1920.  
  1921.         return self.read_bytes(length)
  1922.  
  1923.     def write_string(self, string):
  1924.         # Length-encoded as with read-string
  1925.         self.write_compact_size(len(string))
  1926.         self.write(string)
  1927.  
  1928.     def read_bytes(self, length):
  1929.         try:
  1930.             result = self.input[self.read_cursor:self.read_cursor+length]
  1931.             self.read_cursor += length
  1932.             return result
  1933.         except IndexError:
  1934.             raise SerializationError("attempt to read past end of buffer")
  1935.  
  1936.         return ''
  1937.  
  1938.     def read_boolean(self): return self.read_bytes(1)[0] != chr(0)
  1939.     def read_int16(self): return self._read_num('<h')
  1940.     def read_uint16(self): return self._read_num('<H')
  1941.     def read_int32(self): return self._read_num('<i')
  1942.     def read_uint32(self): return self._read_num('<I')
  1943.     def read_int64(self): return self._read_num('<q')
  1944.     def read_uint64(self): return self._read_num('<Q')
  1945.  
  1946.     def write_boolean(self, val): return self.write(chr(bool_to_int(val)))
  1947.     def write_int16(self, val): return self._write_num('<h', val)
  1948.     def write_uint16(self, val): return self._write_num('<H', val)
  1949.     def write_int32(self, val): return self._write_num('<i', val)
  1950.     def write_uint32(self, val): return self._write_num('<I', val)
  1951.     def write_int64(self, val): return self._write_num('<q', val)
  1952.     def write_uint64(self, val): return self._write_num('<Q', val)
  1953.  
  1954.     def read_compact_size(self):
  1955.         size = ord(self.input[self.read_cursor])
  1956.         self.read_cursor += 1
  1957.         if size == 253:
  1958.             size = self._read_num('<H')
  1959.         elif size == 254:
  1960.             size = self._read_num('<I')
  1961.         elif size == 255:
  1962.             size = self._read_num('<Q')
  1963.         return size
  1964.  
  1965.     def write_compact_size(self, size):
  1966.         if size < 0:
  1967.             raise SerializationError("attempt to write size < 0")
  1968.         elif size < 253:
  1969.              self.write(chr(size))
  1970.         elif size < 2**16:
  1971.             self.write('\xfd')
  1972.             self._write_num('<H', size)
  1973.         elif size < 2**32:
  1974.             self.write('\xfe')
  1975.             self._write_num('<I', size)
  1976.         elif size < 2**64:
  1977.             self.write('\xff')
  1978.             self._write_num('<Q', size)
  1979.  
  1980.     def _read_num(self, format):
  1981.         (i,) = struct.unpack_from(format, self.input, self.read_cursor)
  1982.         self.read_cursor += struct.calcsize(format)
  1983.         return i
  1984.  
  1985.     def _write_num(self, format, num):
  1986.         s = struct.pack(format, num)
  1987.         self.write(s)
  1988.  
  1989. def open_wallet(db_env, walletfile, writable=False):
  1990.     db = DB(db_env)
  1991.     if writable:
  1992.         DB_TYPEOPEN = DB_CREATE
  1993.     else:
  1994.         DB_TYPEOPEN = DB_RDONLY
  1995.     flags = DB_THREAD | DB_TYPEOPEN
  1996.     try:
  1997.         r = db.open(walletfile, "main", DB_BTREE, flags)
  1998.     except DBError:
  1999.         r = True
  2000.  
  2001.     if r is not None:
  2002.         logging.error("Couldn't open wallet.dat/main. Try quitting Bitcoin and running this again.")
  2003.         sys.exit(1)
  2004.  
  2005.     return db
  2006.  
  2007. def inversetxid(txid):
  2008.     if len(txid) is not 64:
  2009.         print("Bad txid")
  2010.         return "CORRUPTEDTXID:"+txid
  2011. #       exit(0)
  2012.     new_txid = ""
  2013.     for i in range(32):
  2014.         new_txid += txid[62-2*i];
  2015.         new_txid += txid[62-2*i+1];
  2016.     return new_txid
  2017.  
  2018. def parse_wallet(db, item_callback):
  2019.     kds = BCDataStream()
  2020.     vds = BCDataStream()
  2021.  
  2022.  
  2023.     def parse_TxIn(vds):
  2024.         d = {}
  2025.         d['prevout_hash'] = vds.read_bytes(32).encode('hex')
  2026.         d['prevout_n'] = vds.read_uint32()
  2027.         d['scriptSig'] = vds.read_bytes(vds.read_compact_size()).encode('hex')
  2028.         d['sequence'] = vds.read_uint32()
  2029.         return d
  2030.  
  2031.  
  2032.     def parse_TxOut(vds):
  2033.         d = {}
  2034.         d['value'] = vds.read_int64()/1e8
  2035.         d['scriptPubKey'] = vds.read_bytes(vds.read_compact_size()).encode('hex')
  2036.         return d
  2037.  
  2038.  
  2039.     for (key, value) in db.items():
  2040.         d = { }
  2041.  
  2042.         kds.clear(); kds.write(key)
  2043.         vds.clear(); vds.write(value)
  2044.  
  2045.         type = kds.read_string()
  2046.  
  2047.         d["__key__"] = key
  2048.         d["__value__"] = value
  2049.         d["__type__"] = type
  2050.  
  2051.         try:
  2052.             if type == "tx":
  2053.                 d["tx_id"] = inversetxid(kds.read_bytes(32).encode('hex_codec'))
  2054.                 start = vds.read_cursor
  2055.                 d['version'] = vds.read_int32()
  2056.                 n_vin = vds.read_compact_size()
  2057.                 d['txIn'] = []
  2058.                 for i in xrange(n_vin):
  2059.                     d['txIn'].append(parse_TxIn(vds))
  2060.                 n_vout = vds.read_compact_size()
  2061.                 d['txOut'] = []
  2062.                 for i in xrange(n_vout):
  2063.                     d['txOut'].append(parse_TxOut(vds))
  2064.                 d['lockTime'] = vds.read_uint32()
  2065.                 d['tx'] = vds.input[start:vds.read_cursor].encode('hex_codec')
  2066.                 d['txv'] = value.encode('hex_codec')
  2067.                 d['txk'] = key.encode('hex_codec')
  2068.             elif type == "name":
  2069.                 d['hash'] = kds.read_string()
  2070.                 d['name'] = vds.read_string()
  2071.             elif type == "version":
  2072.                 d['version'] = vds.read_uint32()
  2073.             elif type == "minversion":
  2074.                 d['minversion'] = vds.read_uint32()
  2075.             elif type == "setting":
  2076.                 d['setting'] = kds.read_string()
  2077.                 d['value'] = parse_setting(d['setting'], vds)
  2078.             elif type == "key":
  2079.                 d['public_key'] = kds.read_bytes(kds.read_compact_size())
  2080.                 d['private_key'] = vds.read_bytes(vds.read_compact_size())
  2081.             elif type == "wkey":
  2082.                 d['public_key'] = kds.read_bytes(kds.read_compact_size())
  2083.                 d['private_key'] = vds.read_bytes(vds.read_compact_size())
  2084.                 d['created'] = vds.read_int64()
  2085.                 d['expires'] = vds.read_int64()
  2086.                 d['comment'] = vds.read_string()
  2087.             elif type == "defaultkey":
  2088.                 d['key'] = vds.read_bytes(vds.read_compact_size())
  2089.             elif type == "pool":
  2090.                 d['n'] = kds.read_int64()
  2091.                 d['nVersion'] = vds.read_int32()
  2092.                 d['nTime'] = vds.read_int64()
  2093.                 d['public_key'] = vds.read_bytes(vds.read_compact_size())
  2094.             elif type == "acc":
  2095.                 d['account'] = kds.read_string()
  2096.                 d['nVersion'] = vds.read_int32()
  2097.                 d['public_key'] = vds.read_bytes(vds.read_compact_size())
  2098.             elif type == "acentry":
  2099.                 d['account'] = kds.read_string()
  2100.                 d['n'] = kds.read_uint64()
  2101.                 d['nVersion'] = vds.read_int32()
  2102.                 d['nCreditDebit'] = vds.read_int64()
  2103.                 d['nTime'] = vds.read_int64()
  2104.                 d['otherAccount'] = vds.read_string()
  2105.                 d['comment'] = vds.read_string()
  2106.             elif type == "bestblock":
  2107.                 d['nVersion'] = vds.read_int32()
  2108.                 d.update(parse_BlockLocator(vds))
  2109.             elif type == "ckey":
  2110.                 d['public_key'] = kds.read_bytes(kds.read_compact_size())
  2111.                 d['encrypted_private_key'] = vds.read_bytes(vds.read_compact_size())
  2112.             elif type == "mkey":
  2113.                 d['nID'] = kds.read_uint32()
  2114.                 d['encrypted_key'] = vds.read_string()
  2115.                 d['salt'] = vds.read_string()
  2116.                 d['nDerivationMethod'] = vds.read_uint32()
  2117.                 d['nDerivationIterations'] = vds.read_uint32()
  2118.                 d['otherParams'] = vds.read_string()
  2119.  
  2120.             item_callback(type, d)
  2121.  
  2122.         except Exception, e:
  2123.             traceback.print_exc()
  2124.             print("ERROR parsing wallet.dat, type %s" % type)
  2125.             print("key data: %s"%key)
  2126.             print("key data in hex: %s"%key.encode('hex_codec'))
  2127.             print("value data in hex: %s"%value.encode('hex_codec'))
  2128.             sys.exit(1)
  2129.  
  2130. def delete_from_wallet(db_env, walletfile, typedel, kd):
  2131.     db = open_wallet(db_env, walletfile, True)
  2132.     kds = BCDataStream()
  2133.     vds = BCDataStream()
  2134.  
  2135.     deleted_items = 0
  2136.  
  2137.     if not isinstance(kd, list):
  2138.         kd=[kd]
  2139.  
  2140.     if typedel=='tx' and kd!=['all']:
  2141.         for keydel in kd:
  2142.             db.delete('\x02\x74\x78'+keydel.decode('hex')[::-1])
  2143.             deleted_items+=1
  2144.  
  2145.     else:
  2146.         for i,keydel in enumerate(kd):
  2147.             for (key, value) in db.items():
  2148.                 kds.clear(); kds.write(key)
  2149.                 vds.clear(); vds.write(value)
  2150.                 type = kds.read_string()
  2151.  
  2152.                 if typedel == "tx" and type == "tx":
  2153.                     db.delete(key)
  2154.                     deleted_items+=1
  2155.                 elif typedel == "key":
  2156.                     if type == "key" or type == "ckey":
  2157.                         if keydel == public_key_to_bc_address(kds.read_bytes(kds.read_compact_size())):
  2158.                             db.delete(key)
  2159.                             deleted_items+=1
  2160.                     elif type == "pool":
  2161.                         vds.read_int32()
  2162.                         vds.read_int64()
  2163.                         if keydel == public_key_to_bc_address(vds.read_bytes(vds.read_compact_size())):
  2164.                             db.delete(key)
  2165.                             deleted_items+=1
  2166.                     elif type == "name":
  2167.                         if keydel == kds.read_string():
  2168.                             db.delete(key)
  2169.                             deleted_items+=1
  2170.  
  2171.  
  2172.     db.close()
  2173.     return deleted_items
  2174.  
  2175. def merge_keys_lists(la, lb):
  2176.     lr={}
  2177.     llr=[]
  2178.     for k in la:
  2179.         lr[k[0]]=k[1]
  2180.  
  2181.     for k in lb:
  2182.         if k[0] in lr.keys():
  2183.             lr[k[0]]=lr[k[0]]+" / "+k[1]
  2184.         else:
  2185.             lr[k[0]]=k[1]
  2186.  
  2187.     for k,j in lr.items():
  2188.         llr.append([k,j])
  2189.  
  2190.     return llr
  2191.  
  2192. def merge_wallets(wadir, wa, wbdir, wb, wrdir, wr, passphrase_a, passphrase_b, passphrase_r):
  2193.     global passphrase
  2194.     passphrase_LAST=passphrase
  2195.  
  2196.     #Read Wallet 1
  2197.     passphrase=passphrase_a
  2198.     dba_env = create_env(wadir)
  2199.     crypted_a = read_wallet(json_db, dba_env, wa, True, True, "", None)['crypted']
  2200.  
  2201.     list_keys_a=[]
  2202.     for i in json_db['keys']:
  2203.         try:
  2204.             label=i['label']
  2205.         except:
  2206.             label="#Reserve"
  2207.         try:
  2208.             list_keys_a.append([i['secret'], label])
  2209.         except:
  2210.             pass
  2211.  
  2212.     if len(list_keys_a)==0:
  2213.         return [False, "Something went wrong with the first wallet."]
  2214.  
  2215.  
  2216.     #Read Wallet 2
  2217.     passphrase=passphrase_b
  2218.     dbb_env = create_env(wbdir)
  2219.     crypted_b = read_wallet(json_db, dbb_env, wb, True, True, "", None)['crypted']
  2220.  
  2221.     list_keys_b=[]
  2222.     for i in json_db['keys']:
  2223.         try:
  2224.             label=i['label']
  2225.         except:
  2226.             label="#Reserve"
  2227.         try:
  2228.             list_keys_b.append([i['secret'], label])
  2229.         except:
  2230.             pass
  2231.     if len(list_keys_b)==0:
  2232.         return [False, "Something went wrong with the second wallet."]
  2233.  
  2234.     m=merge_keys_lists(list_keys_a,list_keys_b)
  2235.  
  2236.  
  2237.     #Create new wallet
  2238.     dbr_env = create_env(wrdir)
  2239.     create_new_wallet(dbr_env, wr, 80100)
  2240.  
  2241.     dbr = open_wallet(dbr_env, wr, True)
  2242.     update_wallet(dbr, 'minversion', { 'minversion' : 60000})
  2243.  
  2244.  
  2245.     if len(passphrase_r)>0:
  2246.         NPP_salt=random_string(16).decode('hex')
  2247.         NPP_rounds=int(50000+random.random()*20000)
  2248.         NPP_method=0
  2249.         NPP_MK=random_string(64).decode('hex')
  2250.  
  2251.         crypter.SetKeyFromPassphrase(passphrase_r, NPP_salt, NPP_rounds, NPP_method)
  2252.         NPP_EMK = crypter.Encrypt(NPP_MK)
  2253.  
  2254.         update_wallet(dbr, 'mkey', {
  2255.             "encrypted_key": NPP_EMK,
  2256.             'nDerivationIterations' : NPP_rounds,
  2257.             'nDerivationMethod' : NPP_method,
  2258.             'nID' : 1,
  2259.             'otherParams' : ''.decode('hex'),
  2260.             "salt": NPP_salt
  2261.         })
  2262.  
  2263.  
  2264.     dbr.close()
  2265.  
  2266.     t='\n'.join(map(lambda x:';'.join(x), m))
  2267.     passphrase=passphrase_r
  2268.  
  2269.     global global_merging_message
  2270.  
  2271.     global_merging_message=["Merging...","Merging..."]
  2272.     thread.start_new_thread(import_csv_keys, ("\x00"+t, wrdir, wr,))
  2273.     t=""
  2274.  
  2275.     passphrase=passphrase_LAST
  2276.  
  2277.     return [True]
  2278.  
  2279. def random_string(l, alph="0123456789abcdef"):
  2280.     r=""
  2281.     la=len(alph)
  2282.     for i in range(l):
  2283.         r+=alph[int(la*(random.random()))]
  2284.     return r
  2285.  
  2286. def update_wallet(db, types, datas, paramsAreLists=False):
  2287.     """Write a single item to the wallet.
  2288.     db must be open with writable=True.
  2289.     type and data are the type code and data dictionary as parse_wallet would
  2290.     give to item_callback.
  2291.     data's __key__, __value__ and __type__ are ignored; only the primary data
  2292.     fields are used.
  2293.     """
  2294.  
  2295.     if not paramsAreLists:
  2296.         types=[types]
  2297.         datas=[datas]
  2298.  
  2299.     if len(types)!=len(datas):
  2300.         raise Exception("UpdateWallet: sizes are different")
  2301.  
  2302.     for it,type in enumerate(types):
  2303.         data=datas[it]
  2304.  
  2305.         d = data
  2306.         kds = BCDataStream()
  2307.         vds = BCDataStream()
  2308.  
  2309.         # Write the type code to the key
  2310.         kds.write_string(type)
  2311.         vds.write("")                        # Ensure there is something
  2312.  
  2313.         try:
  2314.             if type == "tx":
  2315.     #           raise NotImplementedError("Writing items of type 'tx'")
  2316.                 kds.write(d['txi'][6:].decode('hex_codec'))
  2317.                 vds.write(d['txv'].decode('hex_codec'))
  2318.             elif type == "name":
  2319.                 kds.write_string(d['hash'])
  2320.                 vds.write_string(d['name'])
  2321.             elif type == "version":
  2322.                 vds.write_uint32(d['version'])
  2323.             elif type == "minversion":
  2324.                 vds.write_uint32(d['minversion'])
  2325.             elif type == "setting":
  2326.                 raise NotImplementedError("Writing items of type 'setting'")
  2327.                 kds.write_string(d['setting'])
  2328.                 #d['value'] = parse_setting(d['setting'], vds)
  2329.             elif type == "key":
  2330.                 kds.write_string(d['public_key'])
  2331.                 vds.write_string(d['private_key'])
  2332.             elif type == "wkey":
  2333.                 kds.write_string(d['public_key'])
  2334.                 vds.write_string(d['private_key'])
  2335.                 vds.write_int64(d['created'])
  2336.                 vds.write_int64(d['expires'])
  2337.                 vds.write_string(d['comment'])
  2338.             elif type == "defaultkey":
  2339.                 vds.write_string(d['key'])
  2340.             elif type == "pool":
  2341.                 kds.write_int64(d['n'])
  2342.                 vds.write_int32(d['nVersion'])
  2343.                 vds.write_int64(d['nTime'])
  2344.                 vds.write_string(d['public_key'])
  2345.             elif type == "acc":
  2346.                 kds.write_string(d['account'])
  2347.                 vds.write_int32(d['nVersion'])
  2348.                 vds.write_string(d['public_key'])
  2349.             elif type == "acentry":
  2350.                 kds.write_string(d['account'])
  2351.                 kds.write_uint64(d['n'])
  2352.                 vds.write_int32(d['nVersion'])
  2353.                 vds.write_int64(d['nCreditDebit'])
  2354.                 vds.write_int64(d['nTime'])
  2355.                 vds.write_string(d['otherAccount'])
  2356.                 vds.write_string(d['comment'])
  2357.             elif type == "bestblock":
  2358.                 vds.write_int32(d['nVersion'])
  2359.                 vds.write_compact_size(len(d['hashes']))
  2360.                 for h in d['hashes']:
  2361.                     vds.write(h)
  2362.             elif type == "ckey":
  2363.                 kds.write_string(d['public_key'])
  2364.                 vds.write_string(d['encrypted_private_key'])
  2365.             elif type == "mkey":
  2366.                 kds.write_uint32(d['nID'])
  2367.                 vds.write_string(d['encrypted_key'])
  2368.                 vds.write_string(d['salt'])
  2369.                 vds.write_uint32(d['nDerivationMethod'])
  2370.                 vds.write_uint32(d['nDerivationIterations'])
  2371.                 vds.write_string(d['otherParams'])
  2372.  
  2373.             else:
  2374.                 print "Unknown key type: "+type
  2375.  
  2376.             # Write the key/value pair to the database
  2377.             db.put(kds.input, vds.input)
  2378.  
  2379.         except Exception, e:
  2380.             print("ERROR writing to wallet.dat, type %s"%type)
  2381.             print("data dictionary: %r"%data)
  2382.             traceback.print_exc()
  2383.  
  2384. def create_new_wallet(db_env, walletfile, version):
  2385.     db_out = DB(db_env)
  2386.  
  2387.     try:
  2388.         r = db_out.open(walletfile, "main", DB_BTREE, DB_CREATE)
  2389.     except DBError:
  2390.         r = True
  2391.  
  2392.     if r is not None:
  2393.         logging.error("Couldn't open %s."%walletfile)
  2394.         sys.exit(1)
  2395.  
  2396.     db_out.put("0776657273696f6e".decode('hex'), ("%08x"%version).decode('hex')[::-1])
  2397.  
  2398.     db_out.close()
  2399.  
  2400.  
  2401. def rewrite_wallet(db_env, walletfile, destFileName, pre_put_callback=None):
  2402.     db = open_wallet(db_env, walletfile)
  2403.  
  2404.     db_out = DB(db_env)
  2405.     try:
  2406.         r = db_out.open(destFileName, "main", DB_BTREE, DB_CREATE)
  2407.     except DBError:
  2408.         r = True
  2409.  
  2410.     if r is not None:
  2411.         logging.error("Couldn't open %s."%destFileName)
  2412.         sys.exit(1)
  2413.  
  2414.     def item_callback(type, d):
  2415.         if (pre_put_callback is None or pre_put_callback(type, d)):
  2416.             db_out.put(d["__key__"], d["__value__"])
  2417.  
  2418.     parse_wallet(db, item_callback)
  2419.     db_out.close()
  2420.     db.close()
  2421.  
  2422. # end of bitcointools wallet.dat handling code
  2423.  
  2424. # wallet.dat reader / writer
  2425.  
  2426. addr_to_keys={}
  2427. def read_wallet(json_db, db_env, walletfile, print_wallet, print_wallet_transactions, transaction_filter, include_balance, vers=-1, FillPool=False):
  2428.     global passphrase, addr_to_keys
  2429.     crypted=False
  2430.  
  2431.     private_keys = []
  2432.     private_hex_keys = []
  2433.  
  2434.     if vers > -1:
  2435.         global addrtype
  2436.         oldaddrtype = addrtype
  2437.         addrtype = vers
  2438.  
  2439.     db = open_wallet(db_env, walletfile, writable=FillPool)
  2440.  
  2441.     json_db['keys'] = []
  2442.     json_db['pool'] = []
  2443.     json_db['tx'] = []
  2444.     json_db['names'] = {}
  2445.     json_db['ckey'] = []
  2446.     json_db['mkey'] = {}
  2447.  
  2448.     def item_callback(type, d):
  2449.         if type == "tx":
  2450.             json_db['tx'].append({"tx_id" : d['tx_id'], "txin" : d['txIn'], "txout" : d['txOut'], "tx_v" : d['txv'], "tx_k" : d['txk']})
  2451.  
  2452.         elif type == "name":
  2453.             json_db['names'][d['hash']] = d['name']
  2454.  
  2455.         elif type == "version":
  2456.             json_db['version'] = d['version']
  2457.  
  2458.         elif type == "minversion":
  2459.             json_db['minversion'] = d['minversion']
  2460.  
  2461.         elif type == "setting":
  2462.             if not json_db.has_key('settings'): json_db['settings'] = {}
  2463.             json_db["settings"][d['setting']] = d['value']
  2464.  
  2465.         elif type == "defaultkey":
  2466.             json_db['defaultkey'] = public_key_to_bc_address(d['key'])
  2467.  
  2468.         elif type == "key":
  2469.             addr = public_key_to_bc_address(d['public_key'])
  2470.             compressed = d['public_key'][0] != '\04'
  2471.             sec = SecretToASecret(PrivKeyToSecret(d['private_key']), compressed)
  2472.             hexsec = ASecretToSecret(sec).encode('hex')[:32]
  2473.             private_keys.append(sec)
  2474.             addr_to_keys[addr]=[hexsec, d['public_key'].encode('hex')]
  2475.             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')})
  2476.  
  2477.         elif type == "wkey":
  2478.             if not json_db.has_key('wkey'): json_db['wkey'] = []
  2479.             json_db['wkey']['created'] = d['created']
  2480.  
  2481.         elif type == "pool":
  2482.             """ d['n'] = kds.read_int64()
  2483.                 d['nVersion'] = vds.read_int32()
  2484.                 d['nTime'] = vds.read_int64()
  2485.                 d['public_key'] = vds.read_bytes(vds.read_compact_size())"""
  2486.             try:
  2487.                 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'] } )
  2488.             except:
  2489.                 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') } )
  2490.  
  2491.         elif type == "acc":
  2492.             json_db['acc'] = d['account']
  2493.             print("Account %s (current key: %s)"%(d['account'], public_key_to_bc_address(d['public_key'])))
  2494.  
  2495.         elif type == "acentry":
  2496.             json_db['acentry'] = (d['account'], d['nCreditDebit'], d['otherAccount'], time.ctime(d['nTime']), d['n'], d['comment'])
  2497.  
  2498.         elif type == "bestblock":
  2499.             json_db['bestblock'] = d['hashes'][0][::-1].encode('hex_codec')
  2500.  
  2501.         elif type == "ckey":
  2502.             crypted=True
  2503.             compressed = d['public_key'][0] != '\04'
  2504.             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})
  2505.  
  2506.         elif type == "mkey":
  2507.             json_db['mkey']['nID'] = d['nID']
  2508.             json_db['mkey']['encrypted_key'] = d['encrypted_key'].encode('hex_codec')
  2509.             json_db['mkey']['salt'] = d['salt'].encode('hex_codec')
  2510.             json_db['mkey']['nDerivationMethod'] = d['nDerivationMethod']
  2511.             json_db['mkey']['nDerivationIterations'] = d['nDerivationIterations']
  2512.             json_db['mkey']['otherParams'] = d['otherParams']
  2513.  
  2514.             if passphrase:
  2515.                 res = crypter.SetKeyFromPassphrase(passphrase, d['salt'], d['nDerivationIterations'], d['nDerivationMethod'])
  2516.                 if res == 0:
  2517.                     logging.error("Unsupported derivation method")
  2518.                     sys.exit(1)
  2519.                 masterkey = crypter.Decrypt(d['encrypted_key'])
  2520.                 crypter.SetKey(masterkey)
  2521.  
  2522.         else:
  2523.             json_db[type] = 'unsupported'
  2524.             print "Wallet data not recognized: "+str(d)
  2525.  
  2526.     list_of_reserve_not_in_pool=[]
  2527.     parse_wallet(db, item_callback)
  2528.  
  2529.  
  2530.     nkeys = len(json_db['keys'])
  2531.     i = 0
  2532.     for k in json_db['keys']:
  2533.         i+=1
  2534.         addr = k['addr']
  2535.         if include_balance:
  2536. #           print("%3d/%d  %s  %s" % (i, nkeys, k["addr"], k["balance"]))
  2537.             k["balance"] = balance(balance_site, k["addr"])
  2538. #           print("  %s" % (i, nkeys, k["addr"], k["balance"]))
  2539.  
  2540.         if addr in json_db['names'].keys():
  2541.             k["label"] = json_db['names'][addr]
  2542.             k["reserve"] = 0
  2543.         else:
  2544.             k["reserve"] = 1
  2545.             list_of_reserve_not_in_pool.append(k['pubkey'])
  2546.  
  2547.  
  2548.     def rnip_callback(a):
  2549.         list_of_reserve_not_in_pool.remove(a['public_key_hex'])
  2550.  
  2551.     if FillPool:
  2552.         map(rnip_callback, json_db['pool'])
  2553.  
  2554.         cpt=1
  2555.         for p in list_of_reserve_not_in_pool:
  2556.             update_wallet(db, 'pool', { 'public_key' : p.decode('hex'), 'n' : cpt, 'nTime' : ts(), 'nVersion':80100 })
  2557.             cpt+=1
  2558.  
  2559.  
  2560.  
  2561.     db.close()
  2562.  
  2563.     crypted = 'salt' in json_db['mkey']
  2564.  
  2565.     if not crypted:
  2566.         print "The wallet is not encrypted"
  2567.  
  2568.     if crypted and not passphrase:
  2569.         print "The wallet is encrypted but no passphrase is used"
  2570.  
  2571.     if crypted and passphrase:
  2572.         check = True
  2573.         ppcorrect=True
  2574.         for k in json_db['keys']:
  2575.           if 'encrypted_privkey' in k:
  2576.             ckey = k['encrypted_privkey'].decode('hex')
  2577.             public_key = k['pubkey'].decode('hex')
  2578.             crypter.SetIV(Hash(public_key))
  2579.             secret = crypter.Decrypt(ckey)
  2580.             compressed = public_key[0] != '\04'
  2581.  
  2582.  
  2583.             if check:
  2584.                 check = False
  2585.                 pkey = EC_KEY(int('0x' + secret.encode('hex'), 16))
  2586.                 if public_key != GetPubKey(pkey, compressed):
  2587.                     print "The wallet is encrypted and the passphrase is incorrect"
  2588.                     ppcorrect=False
  2589.                     break
  2590.  
  2591.             sec = SecretToASecret(secret, compressed)
  2592.             k['sec'] = sec
  2593.             k['hexsec'] = secret[:32].encode('hex')
  2594.             k['secret'] = secret.encode('hex')
  2595.             k['compressed'] = compressed
  2596.             addr_to_keys[k['addr']]=[sec, k['pubkey']]
  2597. #           del(k['ckey'])
  2598. #           del(k['secret'])
  2599. #           del(k['pubkey'])
  2600.             private_keys.append(sec)
  2601.         if ppcorrect:
  2602.             print "The wallet is encrypted and the passphrase is correct"
  2603.  
  2604.     for k in json_db['keys']:
  2605.         if k['compressed'] and 'secret' in k:
  2606.             k['secret']+="01"
  2607.  
  2608. #   del(json_db['pool'])
  2609. #   del(json_db['names'])
  2610.     if vers > -1:
  2611.         addrtype = oldaddrtype
  2612.  
  2613.     return {'crypted':crypted}
  2614.  
  2615.  
  2616.  
  2617. def importprivkey(db, sec, label, reserve, keyishex, verbose=True, addrv=addrtype):
  2618.     if keyishex is None:
  2619.         pkey = regenerate_key(sec)
  2620.         compressed = is_compressed(sec)
  2621.     elif len(sec) == 64:
  2622.         pkey = EC_KEY(str_to_long(sec.decode('hex')))
  2623.         compressed = False
  2624.     elif len(sec) == 66:
  2625.         pkey = EC_KEY(str_to_long(sec[:-2].decode('hex')))
  2626.         compressed = True
  2627.     else:
  2628.         print("Hexadecimal private keys must be 64 or 66 characters long (specified one is "+str(len(sec))+" characters long)")
  2629.         return False
  2630.  
  2631.     if not pkey:
  2632.         return False
  2633.  
  2634.     secret = GetSecret(pkey)
  2635.     private_key = GetPrivKey(pkey, compressed)
  2636.     public_key = GetPubKey(pkey, compressed)
  2637.     addr = public_key_to_bc_address(public_key, addrv)
  2638.  
  2639.     if verbose:
  2640.         print "Address (%s): %s"%(aversions[addrv], addr)
  2641.         print "Privkey (%s): %s"%(aversions[addrv], SecretToASecret(secret, compressed))
  2642.         print "Hexprivkey: %s"%(secret.encode('hex'))
  2643.         print "Hash160: %s"%(bc_address_to_hash_160(addr).encode('hex'))
  2644.         if not compressed:
  2645.             print "Pubkey: 04%.64x%.64x"%(pkey.pubkey.point.x(), pkey.pubkey.point.y())
  2646.         else:
  2647.             print "Pubkey: 0%d%.64x"%(2+(pkey.pubkey.point.y()&1), pkey.pubkey.point.x())
  2648.         if int(secret.encode('hex'), 16)>_r:
  2649.             print 'Beware, 0x%s is equivalent to 0x%.33x</b>'%(secret.encode('hex'), int(secret.encode('hex'), 16)-_r)
  2650.  
  2651.  
  2652.  
  2653.     global crypter, passphrase, json_db
  2654.     crypted = False
  2655.     if 'mkey' in json_db.keys() and 'salt' in json_db['mkey']:
  2656.         crypted = True
  2657.     if crypted:
  2658.         if passphrase:
  2659.             cry_master = json_db['mkey']['encrypted_key'].decode('hex')
  2660.             cry_salt   = json_db['mkey']['salt'].decode('hex')
  2661.             cry_rounds = json_db['mkey']['nDerivationIterations']
  2662.             cry_method = json_db['mkey']['nDerivationMethod']
  2663.  
  2664.             crypter.SetKeyFromPassphrase(passphrase, cry_salt, cry_rounds, cry_method)
  2665. #           if verbose:
  2666. #               print "Import with", passphrase, "", cry_master.encode('hex'), "", cry_salt.encode('hex')
  2667.             masterkey = crypter.Decrypt(cry_master)
  2668.             crypter.SetKey(masterkey)
  2669.             crypter.SetIV(Hash(public_key))
  2670.             e = crypter.Encrypt(secret)
  2671.             ck_epk=e
  2672.  
  2673.             update_wallet(db, 'ckey', { 'public_key' : public_key, 'encrypted_private_key' : ck_epk })
  2674.     else:
  2675.         update_wallet(db, 'key', { 'public_key' : public_key, 'private_key' : private_key })
  2676.  
  2677.     if not reserve:
  2678.         update_wallet(db, 'name', { 'hash' : addr, 'name' : label })
  2679.  
  2680.  
  2681.     return True
  2682.  
  2683. def balance(site, address):
  2684.     page=urllib.urlopen("%s=%s" % (site, address))
  2685.     json_acc = json.loads(page.read().split("<end>")[0])
  2686.     if json_acc['0'] == 0:
  2687.         return "Invalid address"
  2688.     elif json_acc['0'] == 2:
  2689.         return "Never used"
  2690.     else:
  2691.         return json_acc['balance']
  2692.  
  2693. def read_jsonfile(filename):
  2694.     filin = open(filename, 'r')
  2695.     txdump = filin.read()
  2696.     filin.close()
  2697.     return json.loads(txdump)
  2698.  
  2699. def write_jsonfile(filename, array):
  2700.     filout = open(filename, 'w')
  2701.     filout.write(json.dumps(array, sort_keys=True, indent=0))
  2702.     filout.close()
  2703.  
  2704. def keyinfo(sec, keyishex):
  2705.     if keyishex is None:
  2706.         pkey = regenerate_key(sec)
  2707.         compressed = is_compressed(sec)
  2708.     elif len(sec) == 64:
  2709.         pkey = EC_KEY(str_to_long(sec.decode('hex')))
  2710.         compressed = False
  2711.     elif len(sec) == 66:
  2712.         pkey = EC_KEY(str_to_long(sec[:-2].decode('hex')))
  2713.         compressed = True
  2714.     else:
  2715.         print("Hexadecimal private keys must be 64 or 66 characters long (specified one is "+str(len(sec))+" characters long)")
  2716.         exit(0)
  2717.  
  2718.     if not pkey:
  2719.         return False
  2720.  
  2721.     secret = GetSecret(pkey)
  2722.     private_key = GetPrivKey(pkey, compressed)
  2723.     public_key = GetPubKey(pkey, compressed)
  2724.     addr = public_key_to_bc_address(public_key)
  2725.  
  2726.     print "Address (%s): %s" % ( aversions[addrtype], addr )
  2727.     print "Privkey (%s): %s" % ( aversions[addrtype], SecretToASecret(secret, compressed) )
  2728.     print "Hexprivkey:   %s" % secret.encode('hex')
  2729.     print "Hash160:      %s"%(bc_address_to_hash_160(addr).encode('hex'))
  2730.  
  2731.     return True
  2732.  
  2733. def css_wui():
  2734.     return """html, body {
  2735.  height: 100%;
  2736.  width: 100%;
  2737.  padding: 0;
  2738.  margin: 0;
  2739. }
  2740.  
  2741. body {
  2742.     margin: 0px;
  2743.     padding: 0px;
  2744.     background: url(data:image/jpeg;base64,/9j/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP/sABFEdWNreQABAAQAAABLAAD/4QMpaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/PiA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjAtYzA2MSA2NC4xNDA5NDksIDIwMTAvMTIvMDctMTA6NTc6MDEgICAgICAgICI+IDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDUzUgV2luZG93cyIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDozRjJGNUI0ODZBN0YxMUUyQkZGRUNDQzgwNjYxQkJENCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDozRjJGNUI0OTZBN0YxMUUyQkZGRUNDQzgwNjYxQkJENCI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjNGMkY1QjQ2NkE3RjExRTJCRkZFQ0NDODA2NjFCQkQ0IiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjNGMkY1QjQ3NkE3RjExRTJCRkZFQ0NDODA2NjFCQkQ0Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+/+4ADkFkb2JlAGTAAAAAAf/bAIQAAwICAgICAwICAwUDAwMFBQQDAwQF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%3D%3D) repeat;
  2745.     font-family: 'Open Sans', sans-serif;
  2746.     font-size: 10pt;
  2747.     color: #B0B0B0;
  2748. }
  2749.  
  2750.  
  2751. h1, h2, h3 {
  2752.     margin: 0;
  2753.     padding: 0;
  2754. }
  2755.  
  2756. h2
  2757. {
  2758.     font-weight: 400;
  2759.     font-family: 'Archivo Narrow', sans-serif;
  2760.     font-size: 2.50em;
  2761. }
  2762.  
  2763. p, ol, ul {
  2764.     margin-top: 0px;
  2765. }
  2766.  
  2767. p {
  2768.     line-height: 180%;
  2769. }
  2770.  
  2771. strong {
  2772. }
  2773.  
  2774. a {
  2775.     color: #1492C4;
  2776. }
  2777.  
  2778. a:hover {
  2779.     text-decoration: none;
  2780. }
  2781.  
  2782. a img {
  2783.     border: none;
  2784. }
  2785.  
  2786. img.border {
  2787.     border: 10px solid rgba(255,255,255,.10);
  2788. }
  2789.  
  2790. img.alignleft {
  2791.     float: left;
  2792.     margin-right: 30px;
  2793. }
  2794.  
  2795. img.alignright {
  2796.     float: right;
  2797. }
  2798.  
  2799. img.aligncenter {
  2800.     margin: 0px auto;
  2801. }
  2802.  
  2803. hr {
  2804.     display: none;
  2805. }
  2806.  
  2807. #retour-pyw{
  2808. overflow: auto;
  2809. }
  2810.  
  2811. #uptodate{
  2812.     position:absolute;
  2813.     top:0px;
  2814.     right:0px;
  2815.     background: rgba(0,0,0,0.70);
  2816.     padding:10px;
  2817. }
  2818.  
  2819. #full-screen-background-image {
  2820.  z-index: -999;
  2821.  min-height: 100%;
  2822.  min-width: 1024px;
  2823.  width: 100%;
  2824.  height: auto;
  2825.  position: fixed;
  2826.  top: 0;
  2827.  left: 0;
  2828. }
  2829.  
  2830. #wrapper {
  2831.  position: relative;
  2832.  width: 100%;
  2833.  min-height: 400px;
  2834.  #margin: 30px auto;
  2835.     margin-top:10px;  #decalage p/r haut
  2836. }
  2837.  
  2838. #wrapper {
  2839.     overflow: hidden;
  2840. }
  2841.  
  2842. .container {
  2843.     width: 1000px;
  2844.     margin: 0px auto;
  2845. }
  2846.  
  2847. .clearfix {
  2848.     clear: both;
  2849. }
  2850.  
  2851. /** HEADER */
  2852.  
  2853. #header-wrapper-title
  2854. {
  2855.     overflow: hidden;
  2856.     height: 80px;
  2857.     margin-bottom: 10px;
  2858.     background: rgba(0,0,0,0);
  2859. }
  2860.  
  2861. #header-wrapper
  2862. {
  2863.     overflow: hidden;
  2864.     height: 50px;
  2865.     margin-bottom: 20px;
  2866.     background: rgba(0,0,0,0.70);
  2867. }
  2868.  
  2869. #header {
  2870.     overflow: hidden;
  2871. }
  2872.  
  2873. /** LOGO */
  2874.  
  2875. #logo {
  2876.     float: left;
  2877.     #width: 300px;
  2878.     height: 50px;
  2879.  
  2880. }
  2881.  
  2882. #logo h1, #logo p {
  2883.     margin: 0px;
  2884.     line-height: normal;
  2885. }
  2886.  
  2887. #logo h1 a {
  2888.     padding-left: 00px;
  2889.     text-decoration: none;
  2890.     font-size: 2.50em;
  2891.     font-weight: 400;
  2892.     font-family: 'Archivo Narrow', sans-serif;
  2893.     color: #FFFFFF;
  2894. }
  2895.  
  2896. /** MENU */
  2897.  
  2898. #menu {
  2899.     float: left;
  2900.     height: 50px;
  2901. }
  2902.  
  2903. #menu ul {
  2904.     margin: 0px;
  2905.     padding: 0px;
  2906.     list-style: none;
  2907.     line-height: normal;
  2908. }
  2909.  
  2910. #menu li {
  2911.     float: left;
  2912.     margin-right: 10px;
  2913.     padding: 0px 5px 0px 5px;
  2914. }
  2915.  
  2916. #menu a {
  2917.     display: block;
  2918.     height: 50px;
  2919.     padding: 0px 10px;
  2920.     line-height: 50px;
  2921.     text-decoration: none;
  2922.     text-transform: uppercase;
  2923.     color: #FFFFFF;
  2924. }
  2925.  
  2926. #menu a:hover {
  2927.     text-decoration: none;
  2928.     background: rgba(0,0,0,0.70);
  2929. }
  2930.  
  2931. #menu .active
  2932. {
  2933.     background: rgba(0,0,0,0.70);
  2934. }
  2935.  
  2936. /** PAGE */
  2937.  
  2938. #page {
  2939.     overflow: hidden;
  2940.     margin-bottom: 20px;
  2941. }
  2942.  
  2943. /** CONTENT */
  2944.  
  2945. #content {
  2946.     float: left;
  2947.     width: 950px;
  2948.     padding: 40px;
  2949.     background: rgba(0,0,0,0.70);
  2950. }
  2951.  
  2952. #content h2 a
  2953. {
  2954.     display: block;
  2955.     padding: 0px 0px 20px 0px;
  2956.     text-decoration: none;
  2957.     color: #FFFFFF;
  2958. }
  2959.  
  2960. #content #box1
  2961. {
  2962.     margin-bottom: 0px;
  2963. }
  2964.  
  2965. /** SIDEBAR */
  2966.  
  2967. #sidebar {
  2968.     float: right;
  2969.     width: 350px;
  2970.     padding: 20px;
  2971.     background: rgba(0,0,0,0.70);
  2972. }
  2973.  
  2974. #sidebar h2
  2975. {
  2976.     padding: 0px 0px 00px 0px;
  2977.     color: #FFFFFF;
  2978. }
  2979.  
  2980. /* Footer */
  2981.  
  2982. #footer {
  2983.     overflow: hidden;
  2984.     margin: 00px auto 0px auto;
  2985.     padding: 10px 0px;
  2986.     background: rgba(0,0,0,0.70);
  2987. }
  2988.  
  2989. #footer p {
  2990.     text-align: center;
  2991.     font-size: 12px;
  2992. }
  2993.  
  2994. #footer a {
  2995. }
  2996.  
  2997. /** LIST STYLE 1 */
  2998.  
  2999. ul.style1 {
  3000.     margin: 0px;
  3001.     padding: 10px 0px 0px 0px;
  3002.     list-style: none;
  3003. }
  3004.  
  3005. ul.style1 li {
  3006.     clear: both;
  3007.     margin-bottom: 25px;
  3008.     padding: 30px 0px 40px 0px;
  3009.     border-top: 1px solid #000000;
  3010.     box-shadow: inset 0 1px 0 rgba(255,255,255,.10);
  3011. }
  3012.  
  3013. ul.style1 h3 {
  3014.     padding-bottom: 5px;
  3015.     font-size: 14px;
  3016.     color: #FFFFFF;
  3017. }
  3018.  
  3019. ul.style1 p {
  3020.     line-height: 150%;
  3021. }
  3022.  
  3023. ul.style1 .button-style {
  3024.     float: left;
  3025.     margin-top: 0px;
  3026. }
  3027.  
  3028. ul.style1 .first {
  3029.     padding-top: 0px;
  3030.     border-top: none;
  3031.     box-shadow: none;
  3032. }
  3033.  
  3034. /** LIST STYLE 3 */
  3035.  
  3036. ul.style3 {
  3037.     margin: 0px;
  3038.     padding: 0px;
  3039.     list-style: none;
  3040. }
  3041.  
  3042. ul.style3 li {
  3043.     padding: 10px 0px 10px 0px;
  3044.     border-top: 1px solid #000000;
  3045.     box-shadow: inset 0 1px 0 rgba(255,255,255,.10);
  3046. }
  3047.  
  3048. ul.style3 a {
  3049.     text-decoration: none;
  3050.     color: #949494;
  3051. }
  3052.  
  3053. ul.style3 a:hover {
  3054.     text-decoration: underline;
  3055. }
  3056.  
  3057. ul.style3 .first {
  3058.     padding-top: 0px;
  3059.     border-top: none;
  3060.     box-shadow: none;
  3061. }
  3062.  
  3063. ul.style3 .date {
  3064.     width: 87px;
  3065.     background-color: #1F768D;
  3066.     margin-top: 20px;
  3067.     height: 24px;
  3068.     line-height: 24px;
  3069.     text-align: center;
  3070.     font-size: 12px;
  3071.     color: #FFFFFF;
  3072. }
  3073.  
  3074. ul.style3 .first .date
  3075. {
  3076.     margin-top: 0px;
  3077. }
  3078.  
  3079. .button-style
  3080. {
  3081.     display: inline-block;
  3082.     background-color: #1F768D;
  3083.     margin-top: 0px;
  3084.     padding: 5px 30px;
  3085.     height: 24px;
  3086.     line-height: 24px;
  3087.     text-decoration: none;
  3088.     text-align: center;
  3089.     color: #FFFFFF;
  3090. }
  3091.  
  3092. .button-style-red
  3093. {
  3094.     color: #ffffff;
  3095.     display: inline-block;
  3096.     background-color: #a12323;
  3097.     margin-top: 20px;
  3098.     padding: 5px 30px;
  3099.     height: 24px;
  3100.     line-height: 24px;
  3101.     text-decoration: none;
  3102.     text-align: center;
  3103. }
  3104.  
  3105. .entry
  3106. {
  3107.     margin-bottom: 30px;
  3108. }
  3109. """
  3110.  
  3111. def onclick_on_tab(page):
  3112.     list=['DumpPage','ImportPage','DeletePage','InfoPage','AboutPage','PassphrasePage','TxPage']
  3113.     r=''
  3114.     for p in list:
  3115.         if p!=page:
  3116.             r+="document.getElementById('"+p+"').style.display='none';"
  3117.             r+="document.getElementById('"+p+"Button').className='';"
  3118.     r+="document.getElementById('"+page+"').style.display='block';"
  3119.     r+="document.getElementById('"+page+"Button').className='active';"
  3120.     return r
  3121.  
  3122. def html_wui(listcontent,uptodate_text):
  3123.     global pywversion
  3124.     return """<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  3125. <html xmlns="http://www.w3.org/1999/xhtml">
  3126. <head>
  3127. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  3128. <title>Pywallet Web Interface - Pywallet """+pywversion+"""</title>
  3129. <!--link href='http://fonts.googleapis.com/css?family=Archivo+Narrow:400,700|Open+Sans:400,600,700' rel='stylesheet' type='text/css'-->
  3130. <!--link href="default.css" rel="stylesheet" type="text/css" media="all" /-->
  3131. <style type="text/css">
  3132. @font-face {
  3133.  font-family: 'Archivo Narrow';
  3134.  font-style: normal;
  3135.  font-weight: 400;
  3136.  src: local('Archivo Narrow Regular'), local('ArchivoNarrow-Regular'), url('data:application/x-font-woff;base64,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') format('woff');
  3137. }
  3138. @font-face {
  3139.  font-family: 'Archivo Narrow';
  3140.  font-style: normal;
  3141.  font-weight: 700;
  3142.  src: local('Archivo Narrow Bold'), local('ArchivoNarrow-Bold'), url('data:application/x-font-woff;base64,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') format('woff');
  3143. }
  3144. @font-face {
  3145.  font-family: 'Open Sans';
  3146.  font-style: normal;
  3147.  font-weight: 400;
  3148.  src: local('Open Sans'), local('OpenSans'), url('data:application/x-font-woff;base64,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') format('woff');
  3149. }
  3150. @font-face {
  3151.  font-family: 'Open Sans';
  3152.  font-style: normal;
  3153.  font-weight: 600;
  3154.  src: local('Open Sans Semibold'), local('OpenSans-Semibold'), url('data:application/x-font-woff;base64,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') format('woff');
  3155. }
  3156. @font-face {
  3157.  font-family: 'Open Sans';
  3158.  font-style: normal;
  3159.  font-weight: 700;
  3160.  src: local('Open Sans Bold'), local('OpenSans-Bold'), url('data:application/x-font-woff;base64,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') format('woff');
  3161. }
  3162.  
  3163. """+css_wui()+"""
  3164. </style>
  3165. </head>
  3166. <body>
  3167. <div id="wrapper">
  3168.     <div id="header-wrapper-title">
  3169.         <div id="header" class="container">
  3170.             <div id="logo" style="height: 150px;">
  3171.                 <h1><a href="#">Pywallet """+str(pywversion)+"""</a></h1>
  3172.             </div>
  3173.         </div>
  3174.     </div>
  3175.     <div id="header-wrapper">
  3176.             <div style="width:300px;float: left;">&nbsp;</div>
  3177.             <div id="menu">
  3178.                 <ul>
  3179.                     <li id="DumpPageButton" class="active"><a href="#" accesskey="1" title="" onclick=" """+onclick_on_tab('DumpPage')+""" " >Dump</a></li>
  3180.                     <li id="ImportPageButton"><a href="#" accesskey="2" title="" onclick=" """+onclick_on_tab('ImportPage')+""" " >Import</a></li>
  3181.                     <li id="InfoPageButton"><a href="#" accesskey="3" title="" onclick=" """+onclick_on_tab('InfoPage')+""" " >Info</a></li>
  3182.                     <li id="DeletePageButton"><a href="#" accesskey="4" title="" onclick=" """+onclick_on_tab('DeletePage')+""" " >Delete</a></li>
  3183.                     <li id="PassphrasePageButton"><a href="#" accesskey="5" title="" onclick=" """+onclick_on_tab('PassphrasePage')+""" " >Passphrase</a></li>
  3184.                     <li id="TxPageButton"><a href="#" accesskey="6" title="" onclick=" """+onclick_on_tab('TxPage')+""" " >Transaction</a></li>
  3185.                     <li id="AboutPageButton"><a href="#" accesskey="7" title="" onclick=" """+onclick_on_tab('AboutPage')+""" " >About</a></li>
  3186.                     <li id="QuitPageButton"><a href="quit">Stop</a></li>
  3187.                 </ul>
  3188.             </div>
  3189.     </div>
  3190.     <div id="page" class="container">
  3191.         <div id="content">
  3192.             """+listcontent+"""
  3193.         </div>
  3194.         <div id="sidebar" style="display:none;">
  3195.             <a href="#" class="button-style-red" style="float:right;position:relative;top:-15px;" onclick="document.getElementById('content').style.width='950px';document.getElementById('content').style.display='block';document.getElementById('sidebar').style.display='none';document.getElementById('sidebar').style.width='350px';">Close</a>
  3196.             <a href="#" class="button-style" style="float:right;position:relative;top:5px;left:-10px;" onclick="
  3197.             if(document.getElementById('content').style.display=='none'){
  3198.                 document.getElementById('sidebar').style.width='350px';
  3199.                 document.getElementById('content').style.width='500px';
  3200.                 document.getElementById('content').style.display='block';
  3201.                 this.innerHTML='Full page';
  3202.             }else{
  3203.                 document.getElementById('sidebar').style.width='970px';
  3204.                 document.getElementById('content').style.display='none';
  3205.                 this.innerHTML='Reduce';
  3206.             }
  3207.             document.getElementById('sidebar').style.display='block';
  3208.             ">Full page</a>
  3209.             <h2 style="positive:relative;top:-20px;">Data</h2>
  3210.             <br />
  3211.             <br />
  3212.             <p id="retour-pyw">
  3213.             </p>
  3214.         </div>
  3215.     </div>
  3216.     <div id="footer">
  3217.         <p><a href="http://pywallet.tk">Instructions to use Pywallet</a></p>
  3218.     </div>
  3219. </div>
  3220. <div id="uptodate">"""+uptodate_text+"""</div>
  3221. </body>
  3222. </html>
  3223. """
  3224.  
  3225. def WI_FormInit(title, action, divname):
  3226.     return "<li><h3>%s</h3>"%title
  3227.     return '<style>#h'+divname+':hover{color:red;}</style><h3 id="h'+divname+'" onClick="document.getElementById(\''+divname+'\').style.display=(document.getElementById(\''+divname+'\').style.display==\'none\')?\'block\':\'none\';document.getElementById(\'iconOF_'+divname+'\').innerHTML=image_showdiv(\''+divname+'\');"><span style="width:21px;" id="iconOF_'+divname+'"><img src="http://creation-entreprise.comprendrechoisir.com/img/puce_tab_down.png" /></span>&nbsp;&nbsp;'+title+'</h3><div id="'+divname+'"><form style="margin-left:15px;" action="'+action+'" method=get>'
  3228.  
  3229. def WI_InputText(label, name, id, value, size=30):
  3230.     return '%s<input type=text name="%s" id="%s" value="%s" size=%s /><br />'%(label, name, id, value, size)
  3231.  
  3232. def WI_InputPassword(label, name, id, value, size=30):
  3233.     return '%s<input type=password name="%s" id="%s" value="%s" size=%s /><br />'%(label, name, id, value, size)
  3234.  
  3235. def WI_Submit(value, local_block, local_button, function):
  3236.     return """<br /><a href="#" class="button-style"  onClick="document.getElementById('content').style.width='500px';document.getElementById('sidebar').style.display='block';%s();return false;">%s</a>"""%(function,value)
  3237.  
  3238. def WI_CloseButton(local_block, local_button):
  3239.     return '<input type=button value="Close" onClick="document.getElementById(\'%s\').style.display=\'none\';document.getElementById(\'%s\').style.display=\'none\';" id="%s" style="display:none;" />'%(local_block, local_button, local_button)
  3240.  
  3241. def WI_ReturnDiv(local_block):
  3242.     return '<div id="%s" style="display:none;margin:10px 3%% 10px;padding:10px;overflow:auto;width:90%%;max-height:600px;background-color:#fff8dd;"></div>'%(local_block)
  3243.  
  3244. def WI_FormEnd():
  3245.     return "</li>"
  3246.  
  3247. def WI_RadioButton(name, value, id, checked, label):
  3248.     return '&nbsp;&nbsp;&nbsp;<input type="radio" name="%s" value="%s" id="%s" %s >%s<br>'%(name, value, id, checked, label)
  3249.  
  3250. def WI_Checkbox(name, value, id, other, label):
  3251.     return '<input type="checkbox" name="%s" value="%s" id="%s" %s />%s'%(name, value, id, other, label)
  3252.  
  3253. def WI_Endiv(t,name,title, desc,hidden=False):
  3254.     return '<div id="'+name+'" style="display:'+X_if_else('none',hidden,'block')+';"><div id="box1"><h2 class="title"><a href="#">'+title+'</a></h2>'+X_if_else('<p>'+desc+'</p>',desc!='','')+'</div><div ><ul class="style1">'+t+'</ul></div></div>'
  3255.  
  3256. def WI_AjaxFunction(name, command_when_ready, query_string, command_until_ready):
  3257.     return '\n\
  3258. function ajax%s(){\n\
  3259.     var ajaxRequest;\n\
  3260.     try{\n\
  3261.         ajaxRequest = new XMLHttpRequest();\n\
  3262.     } catch (e){\n\
  3263.         try{\n\
  3264.             ajaxRequest = new ActiveXObject("Msxml2.XMLHTTP");\n\
  3265.         } catch (e) {\n\
  3266.             try{\n\
  3267.                 ajaxRequest = new ActiveXObject("Microsoft.XMLHTTP");\n\
  3268.             } catch (e){\n\
  3269.                 alert("Your browser broke!");\n\
  3270.                 return false;\n\
  3271.             }\n\
  3272.         }\n\
  3273.     }\n\
  3274.     ajaxRequest.onreadystatechange = function(){\n\
  3275.         if(ajaxRequest.readyState == 4){\n\
  3276.             %s\n\
  3277.         }\n\
  3278.     };\n\
  3279.     var queryString = %s;\n\
  3280.     ajaxRequest.open("GET", queryString, true);\n\
  3281.     %s\n\
  3282.     ajaxRequest.send(null);\n\
  3283. }\n\
  3284. \n\
  3285. '%(name, command_when_ready, query_string, command_until_ready)
  3286.  
  3287. def X_if_else(iftrue, cond, iffalse):
  3288.     if cond:
  3289.         return iftrue
  3290.     return iffalse
  3291.  
  3292. def export_all_keys(db, ks, filename):
  3293.     txt=";".join(ks)+"\n"
  3294.     for i in db['keys']:
  3295.       try:
  3296.         j=i.copy()
  3297.         if 'label' not in j:
  3298.             j['label']='#Reserve'
  3299.         t=";".join([str(j[k]) for k in ks])
  3300.         txt+=t+"\n"
  3301.       except:
  3302.         return False
  3303.  
  3304.     try:
  3305.         myFile = open(filename, 'w')
  3306.         myFile.write(txt)
  3307.         myFile.close()
  3308.         return True
  3309.     except:
  3310.         return False
  3311.  
  3312. def import_csv_keys(filename, wdir, wname, nbremax=9999999):
  3313.     global global_merging_message
  3314.     if filename[0]=="\x00":    #yeah, dirty workaround
  3315.         content=filename[1:]
  3316.     else:
  3317.         filen = open(filename, "r")
  3318.         content = filen.read()
  3319.         filen.close()
  3320.  
  3321.     db_env = create_env(wdir)
  3322.     read_wallet(json_db, db_env, wname, True, True, "", None)
  3323.     db = open_wallet(db_env, wname, writable=True)
  3324.  
  3325.     content=content.split('\n')
  3326.     content=content[:min(nbremax, len(content))]
  3327.     for i in range(len(content)):
  3328.       c=content[i]
  3329.       global_merging_message = ["Merging: "+str(round(100.0*(i+1)/len(content),1))+"%" for j in range(2)]
  3330.       if ';' in c and len(c)>0 and c[0]!="#":
  3331.         cs=c.split(';')
  3332.         sec,label=cs[0:2]
  3333.         v=addrtype
  3334.         if len(cs)>2:
  3335.             v=int(cs[2])
  3336.         reserve=False
  3337.         if label=="#Reserve":
  3338.             reserve=True
  3339.         keyishex=None
  3340.         if abs(len(sec)-65)==1:
  3341.             keyishex=True
  3342.         importprivkey(db, sec, label, reserve, keyishex, verbose=False, addrv=v)
  3343.  
  3344.     global_merging_message = ["Merging done.", ""]
  3345.  
  3346.     db.close()
  3347.  
  3348.     read_wallet(json_db, db_env, wname, True, True, "", None, -1, True)  #Fill the pool if empty
  3349.  
  3350.     return True
  3351.  
  3352. def dep_text_aboutpage(val):
  3353.     if val:
  3354.         return "<span style='color:#bb0000;'>Not found</span>"
  3355.     else:
  3356.         return "<span style='color:#00bb00;'>Found</span>"
  3357.  
  3358. CTX_adds=''
  3359.  
  3360. if 'twisted' not in missing_dep:
  3361.     class WIRoot(resource.Resource):
  3362.  
  3363.          def render_GET(self, request):
  3364.                 try:
  3365.                     request.args['update'][0]
  3366.                     return update_pyw()
  3367.                 except:
  3368.                     True
  3369.  
  3370.                 uptodate=md5_last_pywallet[1]==md5_pywallet
  3371.                 checking_finished=bool(md5_last_pywallet[0])
  3372.  
  3373.                 color="#DDDDFF"
  3374.                 if checking_finished:
  3375.                     if uptodate:
  3376.                         color="#DDFFDD"
  3377.                     else:
  3378.                         color="#FFDDDD"
  3379.  
  3380.                 check_version_text = \
  3381.  X_if_else(
  3382.     X_if_else(
  3383.         'Pywallet is up-to-date',
  3384.         uptodate,
  3385.         'Pywallet is <span style="color:red;font-weight:none;">not</span> up-to-date<br /><a href="#" onclick="ajaxUpdatePyw();return false;">Click to update</a>'),
  3386.     checking_finished,
  3387.     'Checking version...'
  3388.  )
  3389.  
  3390.                 if beta_version:
  3391.                     check_version_text="You are using a beta version<br />Thank you for your help"
  3392.                     color="#DDDDDD"
  3393.  
  3394.                 global pywversion
  3395.                 header = '<h1 title="'+pyw_filename+' in '+pyw_path+'">Pywallet Web Interface v'+pywversion+'</h1><h3>CLOSE BITCOIN BEFORE USE!</h3><div style="position:fixed;top:5px;right:5px;border:solid 1px black;padding:15px;background-color:'+color+';font-weight:bold;text-align:center;">' + check_version_text + '</div><br /><br />'
  3396.  
  3397.                 CPPForm = WI_FormInit('Change passphrase:', 'ChangePP', 'divformcpp') + \
  3398.                             WI_InputPassword('', 'pp', 'cppf-pp', '') + \
  3399.                             WI_Submit('Change', 'CPPDiv', 'cppf-close', 'ajaxCPP') + \
  3400.                             WI_CloseButton('CPPDiv', 'cppf-close') + \
  3401.                             WI_ReturnDiv('CPPDiv') + \
  3402.                             WI_FormEnd()
  3403.  
  3404.                 DWForm = WI_FormInit('Dump your wallet:', 'DumpWallet', 'divformdw') + \
  3405.                             WI_InputText('Wallet Directory: ', 'dir', 'dwf-dir', determine_db_dir()) + \
  3406.                             WI_InputText('Wallet Filename: ', 'name', 'dwf-name', determine_db_name(), 20) + \
  3407.                             WI_InputText('<span style="border: 0 dashed;border-bottom-width:1px;" title="0 for Bitcoin, 52 for Namecoin, 111 for testnets">Version</span>:', 'vers', 'dwf-vers', '0', 1) + \
  3408.                             WI_Checkbox('bal', 'y', 'dwf-bal', '', ' Dump with balance (can take minutes)') + "<br />" + \
  3409.                             WI_Submit('Dump wallet', 'DWDiv', 'dwf-close', 'ajaxDW') + \
  3410.                             WI_CloseButton('DWDiv', 'dwf-close') + \
  3411.                             WI_ReturnDiv('DWDiv') + \
  3412.                             WI_FormEnd()
  3413.  
  3414.                 MWForm = WI_FormInit('Merge two wallets:', 'MergeWallets', 'divformmw') + \
  3415.                             WI_InputText('Wallet 1 Directory: ', 'dir1', 'mwf-dir1', determine_db_dir()) + \
  3416.                             WI_InputText('Wallet 1 Filename: ', 'name1', 'mwf-name1', determine_db_name(), 20) + \
  3417.                             WI_InputPassword('<span style="border: 0 dashed;border-bottom-width:1px;" title="empty if none">Wallet 1 Passphrase: </span>', 'pass1', 'mwf-pass1', '') + "<br />" + \
  3418.                             WI_InputText('Wallet 2 Directory: ', 'dir2', 'mwf-dir2', determine_db_dir()) + \
  3419.                             WI_InputText('Wallet 2 Filename: ', 'name2', 'mwf-name2', "", 20) + \
  3420.                             WI_InputPassword('<span style="border: 0 dashed;border-bottom-width:1px;" title="empty if none">Wallet 2 Passphrase: </span>', 'pass2', 'mwf-pass2', '') + "<br />" + \
  3421.                             WI_InputText('Merged Wallet Directory: ', 'dirm', 'mwf-dirm', determine_db_dir()) + \
  3422.                             WI_InputText('Merged Wallet Filename: ', 'namem', 'mwf-namem', "", 20) + \
  3423.                             WI_InputPassword('<span style="border: 0 dashed;border-bottom-width:1px;" title="empty if none">Merged Wallet Passphrase: </span>', 'passm1', 'mwf-passm1', '') + \
  3424.                             WI_InputPassword('Repeat Wallet Passphrase: ', 'passm2', 'mwf-passm2', '') + \
  3425.                             WI_Submit('Merge wallets', 'MWDiv', 'mwf-close', 'ajaxMW') + \
  3426.                             WI_CloseButton('MWDiv', 'mwf-close') + \
  3427.                             WI_ReturnDiv('MWDiv') + \
  3428.                             WI_FormEnd()
  3429.  
  3430.                 DKForm = WI_FormInit('Dump your keys:', 'DumpKeys', 'divformdk') + \
  3431.                             WI_InputText('Wallet Directory: ', 'dir', 'dkf-dir', determine_db_dir()) + \
  3432.                             WI_InputText('Wallet Filename: ', 'name', 'dkf-name', determine_db_name(), 20) + \
  3433.                             WI_InputText('<span style="border: 0 dashed;border-bottom-width:1px;" title="0 for Bitcoin, 52 for Namecoin, 111 for testnets">Version</span>:', 'vers', 'dkf-vers', '0', 1) + \
  3434.                             WI_InputText('Output file: ', 'file', 'dkf-file', '', 60) + \
  3435.                             WI_InputText('<span style="border: 0 dashed;border-bottom-width:1px;" title="to be chosen from the ones in wallet dump, separated with \',\', e.g. \'addr,secret\'">Data to print: </span>', 'keys', 'dkf-keys', '') + \
  3436.                             WI_Checkbox('bal', 'y', 'dkf-bal', '', ' Dump with balance (can take minutes)') + "<br />" + \
  3437.                             WI_Submit('Dump keys', 'DKDiv', 'dkf-close', 'ajaxDK') + \
  3438.                             WI_CloseButton('DKDiv', 'dkf-close') + \
  3439.                             WI_ReturnDiv('DKDiv') + \
  3440.                             WI_FormEnd()
  3441.  
  3442.                 IKForm = WI_FormInit('Import keys:', 'ImportKeys', 'divformik') + \
  3443. "The CSV file must have the following format: '5PrivateKey;Label'<br />" + \
  3444.                             WI_InputText('Wallet Directory: ', 'dir', 'ikf-dir', determine_db_dir()) + \
  3445.                             WI_InputText('Wallet Filename: ', 'name', 'ikf-name', determine_db_name(), 20) + \
  3446.                             WI_InputText('<span style="border: 0 dashed;border-bottom-width:1px;" title="Format: \'privkey;label\', label=\'#Reserve\' to make the key a pool one">CSV file path</span>: ', 'file', 'ikf-file', '', 60) + \
  3447.                             WI_Submit('Import keys', 'IKDiv', 'ikf-close', 'ajaxIK') + \
  3448.                             WI_CloseButton('IKDiv', 'ikf-close') + \
  3449.                             WI_ReturnDiv('IKDiv') + \
  3450.                             WI_FormEnd()
  3451.  
  3452.                 DTxForm = WI_FormInit('Dump your transactions to a file:', 'DumpTx', 'divformdtx') + \
  3453.                             WI_InputText('Wallet Directory: ', 'dir', 'dt-dir', determine_db_dir()) + \
  3454.                             WI_InputText('Wallet Filename: ', 'name', 'dt-name', determine_db_name(), 20) + \
  3455.                             WI_InputText('Output file: ', 'file', 'dt-file', '') + \
  3456.                             WI_Submit('Dump tx\'s', 'DTxDiv', 'dt-close', 'ajaxDTx') + \
  3457.                             WI_CloseButton('DTxDiv', 'dt-close') + \
  3458.                             WI_ReturnDiv('DTxDiv') + \
  3459.                             WI_FormEnd()
  3460.  
  3461.                 prehide_ecdsa=""
  3462.                 posthide_ecdsa=""
  3463.                 if 'ecdsa' in missing_dep:
  3464.                     prehide_ecdsa="<span style='display:none;'>"
  3465.                     posthide_ecdsa="</span>"
  3466.                 InfoForm = WI_FormInit('Get some info about one key'+X_if_else(' and sign/verify messages', 'ecdsa' not in missing_dep,'')+':', 'Info', 'divforminfo') + \
  3467.                             WI_InputText('Key: ', 'key', 'if-key', '', 60) + \
  3468.                             prehide_ecdsa + WI_InputText('Message: ', 'msg', 'if-msg', '', 30) + posthide_ecdsa + \
  3469.                             prehide_ecdsa + WI_InputText('Signature: ', 'sig', 'if-sig', '', 30) + posthide_ecdsa + \
  3470.                             prehide_ecdsa + WI_InputText('Pubkey: ', 'pubkey', 'if-pubkey', '', 30) + posthide_ecdsa + \
  3471.                             WI_InputText('<span style="border: 0 dashed;border-bottom-width:1px;" title="0 for Bitcoin, 52 for Namecoin, 111 for testnets">Version</span>:', 'vers', 'if-vers', '0', 1) + \
  3472.                             "Format:<br />" + \
  3473.                             WI_RadioButton('format', 'reg', 'if-reg', 'CHECKED', ' Regular, base 58') + \
  3474.                             WI_RadioButton('format', 'hex', 'if-hex', '', ' Hexadecimal, 64 characters long') + \
  3475.                             "You want:<br />" + \
  3476.                             WI_RadioButton('i-need', '1', 'if-n-info', 'CHECKED', ' Info') + \
  3477.                             prehide_ecdsa + WI_RadioButton('i-need', '2', 'if-n-sv', '', ' Sign and verify') + posthide_ecdsa +\
  3478.                             prehide_ecdsa + WI_RadioButton('i-need', '3', 'if-n-both', '', ' Both') + posthide_ecdsa + \
  3479.                             WI_Submit('Get info', 'InfoDiv', 'if-close', 'ajaxInfo') + \
  3480.                             WI_CloseButton('InfoDiv', 'if-close') + \
  3481.                             WI_ReturnDiv('InfoDiv') + \
  3482.                             WI_FormEnd()
  3483.  
  3484.  
  3485.                 ImportForm = WI_FormInit('Import a key into your wallet:', 'Import', 'divformimport') + \
  3486.                             WI_InputText('Wallet Directory: ', 'dir', 'impf-dir', determine_db_dir(), 30) + \
  3487.                             WI_InputText('Wallet Filename:', 'name', 'impf-name', determine_db_name(), 20) + \
  3488.                             WI_InputText('Key:', 'key', 'impf-key', '', 65) + \
  3489.                             WI_InputText('Label:', 'label', 'impf-label', '') + \
  3490.                             WI_Checkbox('reserve', 'true', 'impf-reserve', 'onClick="document.getElementById(\'impf-label\').disabled=document.getElementById(\'impf-reserve\').checked"', ' Reserve') + "<br />" + \
  3491.                             WI_InputText('<span style="border: 0 dashed;border-bottom-width:1px;" title="0 for Bitcoin, 52 for Namecoin, 111 for testnets">Version</span>:', 'vers', 'impf-vers', '0', 1) + \
  3492.                             "Format:<br />" + \
  3493.                             WI_Checkbox('format', 'hex', 'impf-hex', '', ' Hexadecimal, instead of base58') + "<br />" + \
  3494.                             WI_Checkbox('format', 'cry', 'impf-cry', 'hidden=true', '<!-- Crypt-->') + \
  3495.                             WI_Checkbox('format', 'com', 'impf-com', 'hidden=true', '<!--Compressed key-->') + \
  3496.                             WI_Submit('Import key', 'ImportDiv', 'impf-close', 'ajaxImport') + \
  3497.                             WI_CloseButton('ImportDiv', 'impf-close') + \
  3498.                             WI_ReturnDiv('ImportDiv') + \
  3499.                             WI_FormEnd()
  3500. #                           WI_RadioButton('format', 'reg', 'impf-reg', 'CHECKED', ' Regular, base 58') + \
  3501. #                           WI_RadioButton('format', 'hex', 'impf-hex', '', ' Hexadecimal, 64 characters long') + \
  3502.  
  3503.  
  3504.                 ImportROForm = WI_FormInit('Import a read-only address (encrypted wallets only):', 'Import', 'divformimportro') + \
  3505.                             WI_InputText('Wallet Directory: ', 'dir', 'irof-dir', determine_db_dir(), 30) + \
  3506.                             WI_InputText('Wallet Filename:', 'name', 'irof-name', determine_db_name(), 20) + \
  3507.                             WI_InputText('Public key (starting with 04): ', 'pub', 'irof-pub', '', 40) + \
  3508.                             WI_InputText('Label: ', 'label', 'irof-label', '') + \
  3509.                             WI_Submit('Import address', 'ImportDiv', 'irof-close', 'ajaxImportRO') + \
  3510.                             WI_CloseButton('ImportRODiv', 'irof-close') + \
  3511.                             WI_ReturnDiv('ImportRODiv') + \
  3512.                             WI_FormEnd()
  3513.  
  3514.                 DeleteForm = WI_FormInit('Delete keys from your wallet:', 'Delete', 'divformdelete') + \
  3515.                             WI_InputText('Wallet Directory: ', 'dir', 'd-dir', determine_db_dir(), 40) + \
  3516.                             WI_InputText('Wallet Filename:', 'name', 'd-name', determine_db_name()) + \
  3517.                             WI_InputText('<span style="border: 0 dashed;border-bottom-width:1px;" title="divided by \'-\'">Keys</span>:', 'key', 'd-key', '', 65) + \
  3518.                             "Type:<br />" + \
  3519.                             WI_RadioButton('d-type', 'tx', 'd-r-tx', 'CHECKED', ' Transaction (type "all" in "Keys" to delete them all)') + \
  3520.                             WI_RadioButton('d-type', 'key', 'd-r-key', '', ' Bitcoin address') + \
  3521.                             WI_Submit('Delete', 'DeleteDiv', 'd-close', 'ajaxDelete') + \
  3522.                             WI_CloseButton('DeleteDiv', 'd-close') + \
  3523.                             WI_ReturnDiv('DeleteDiv') + \
  3524.                             WI_FormEnd()
  3525.  
  3526.                 ImportTxForm = WI_FormInit('Import a transaction into your wallet:', 'ImportTx', 'divformimporttx') + \
  3527.                             WI_InputText('Wallet Directory: ', 'dir', 'it-dir', determine_db_dir(), 40) + \
  3528.                             WI_InputText('Wallet Filename:', 'name', 'it-name', determine_db_name()) + \
  3529.                             WI_InputText('Txk:', 'key', 'it-txk', '', 65) + \
  3530.                             WI_InputText('Txv:', 'label', 'it-txv', '', 65) + \
  3531.                             WI_Submit('Import', 'ImportTxDiv', 'it-close', 'ajaxImportTx') + \
  3532.                             WI_CloseButton('ImportTxDiv', 'it-close') + \
  3533.                             WI_ReturnDiv('ImportTxDiv') + \
  3534.                             WI_FormEnd()
  3535.  
  3536.                 BalanceForm = WI_FormInit('Print the balance of a Bitcoin address:', 'Balance', 'divformbalance') + \
  3537.                             WI_InputText('Key:', 'key', 'bf-key', '', 35) + \
  3538.                             WI_Submit('Get balance', 'BalanceDiv', 'gb-close', 'ajaxBalance') + \
  3539.                             WI_CloseButton('BalanceDiv', 'gb-close') + \
  3540.                             WI_ReturnDiv('BalanceDiv') + \
  3541.                             WI_FormEnd()
  3542.  
  3543.                 global CTX_adds, addr_to_keys
  3544.                 CTX_adds2=CTX_adds.split('|')+addr_to_keys.keys()
  3545.  
  3546.  
  3547.                 CreateTxForm = WI_FormInit('Create transaction', 'CTX', 'divformctx') + \
  3548.                             X_if_else("Additional addresses used: " + ', '.join(CTX_adds.split('|'))+"<br /><br />",len(CTX_adds)>0,"No additional addresses used<br /><br />") + \
  3549.                             listtx_txt(CTX_adds) + \
  3550.                             WI_FormEnd()
  3551.  
  3552.                 CreateTxForm2 = WI_FormInit('Check addresses funds', 'ListTransactions', 'divformctx') + \
  3553.                             WI_InputText('<span style="border: 0 dashed;border-bottom-width:1px;" title="Divided by a |">Addresses</span>: ', 'adds', 'ctx-adds', '', 35) + \
  3554.                             WI_Submit('Check ', '', '', 'ajaxCTx') + \
  3555.                             WI_FormEnd()
  3556.  
  3557.                 Misc = ''
  3558.  
  3559.                 Javascript = '<script language="javascript" type="text/javascript">interv1=0;\
  3560.                     totalin=0;\
  3561.                     totalout=0;\
  3562.                     \
  3563.                     function majfee(){\
  3564.                         document.getElementById("tot_in").innerHTML=(totalin)/100000000;\
  3565.                         document.getElementById("tot_out").innerHTML=(totalout)/100000000;\
  3566.                         document.getElementById("tot_fee").innerHTML=(totalin-totalout)/100000000;\
  3567.                     }\
  3568.                     \
  3569.                     function image_showdiv(a){\
  3570.                         if(document.getElementById(a).style.display!="none")r="http://creation-entreprise.comprendrechoisir.com/img/puce_tab_down.png";\
  3571.                         else{\
  3572.                         r="http://creation-entreprise.comprendrechoisir.com/img/puce_tab.png";}\
  3573.                         \
  3574.                         return "<img src=\'"+r+"\' />";\
  3575.                         \
  3576.                     }\
  3577.                     function get_radio_value(radioform){\
  3578.                         var rad_val;\
  3579.                         for (var i=0; i < radioform.length; i++){\
  3580.                             if (radioform[i].checked){\
  3581.                                 rad_val = radioform[i].value;\
  3582.                             }\
  3583.                         }\
  3584.                         return rad_val;\
  3585.                     }' + \
  3586.                 WI_AjaxFunction('UpdatePyw', 'document.getElementById("uptodate").innerHTML = ajaxRequest.responseText;setTimeout(function() {window.location.reload();}, 2000);', '"/?update=1"', 'document.getElementById("uptodate").innerHTML = "Updating...";') + \
  3587.                 WI_AjaxFunction('CTx', 'document.getElementById("retour-pyw").innerHTML = ajaxRequest.responseText;', '"/ListTransactions?addresses="+document.getElementById("ctx-adds").value', 'document.getElementById("retour-pyw").innerHTML = "Loading...";') + \
  3588.                 WI_AjaxFunction('CPP', 'document.getElementById("retour-pyw").innerHTML = ajaxRequest.responseText;', '"/ChangePP?pp="+document.getElementById("cppf-pp").value', 'document.getElementById("retour-pyw").innerHTML = "Loading...";') + \
  3589.                 WI_AjaxFunction('DW', 'document.getElementById("retour-pyw").innerHTML = ajaxRequest.responseText;', '"/DumpWallet?dir="+document.getElementById("dwf-dir").value+"&name="+document.getElementById("dwf-name").value+"&bal="+document.getElementById("dwf-bal").checked+"&version="+document.getElementById("dwf-vers").value', 'document.getElementById("retour-pyw").innerHTML = "Loading...";') + \
  3590.                 WI_AjaxFunction('MW', 'document.getElementById("retour-pyw").innerHTML = ajaxRequest.responseText;', '"/MergeWallets?dir1="+document.getElementById("mwf-dir1").value+"&name1="+document.getElementById("mwf-name1").value+"&pass1="+encodeURIComponent(document.getElementById("mwf-pass1").value)+"&dir2="+document.getElementById("mwf-dir2").value+"&name2="+document.getElementById("mwf-name2").value+"&pass2="+encodeURIComponent(document.getElementById("mwf-pass2").value)+"&dirm="+document.getElementById("mwf-dirm").value+"&namem="+document.getElementById("mwf-namem").value+"&passm1="+encodeURIComponent(document.getElementById("mwf-passm1").value)+"&passm2="+encodeURIComponent(document.getElementById("mwf-passm2").value)+""', 'document.getElementById("retour-pyw").innerHTML = "Merging wallets... This may take a few minutes.";interv1=setInterval(ajaxUpdateMW,300);') + \
  3591.                 WI_AjaxFunction('UpdateMW', 'if(ajaxRequest.responseText.length>0){document.getElementById("retour-pyw").innerHTML = ajaxRequest.responseText;}else{clearInterval(interv1);}', '"/Others?action=update_mwdiv"', '') + \
  3592.                 WI_AjaxFunction('DK', 'document.getElementById("retour-pyw").innerHTML = ajaxRequest.responseText;', '"/DumpWallet?dir="+document.getElementById("dkf-dir").value+"&filetw="+document.getElementById("dkf-file").value+"&keys="+document.getElementById("dkf-keys").value+"&bal="+document.getElementById("dkf-bal").checked+"&name="+document.getElementById("dkf-name").value+"&version="+document.getElementById("dkf-vers").value', 'document.getElementById("retour-pyw").innerHTML = "Loading...";') + \
  3593.                 WI_AjaxFunction('IK', 'document.getElementById("retour-pyw").innerHTML = ajaxRequest.responseText;', '"/Import?dir="+document.getElementById("ikf-dir").value+"&file="+document.getElementById("ikf-file").value+"&name="+document.getElementById("ikf-name").value', 'document.getElementById("retour-pyw").innerHTML = "Loading...";') + \
  3594.                 WI_AjaxFunction('DTx', 'document.getElementById("retour-pyw").innerHTML = ajaxRequest.responseText;', '"/DumpTx?dir="+document.getElementById("dt-dir").value+"&name="+document.getElementById("dt-name").value+"&file="+document.getElementById("dt-file").value', 'document.getElementById("retour-pyw").innerHTML = "Loading...";') + \
  3595.                 WI_AjaxFunction('Info', 'document.getElementById("retour-pyw").innerHTML = ajaxRequest.responseText;', '"/Info?key="+document.getElementById("if-key").value+"&msg="+document.getElementById("if-msg").value+"&pubkey="+document.getElementById("if-pubkey").value+"&sig="+document.getElementById("if-sig").value+"&vers="+document.getElementById("if-vers").value+"&format="+(document.getElementById("if-hex").checked?"hex":"reg")+"&need="+get_radio_value(document.getElementsByName("i-need"))', 'document.getElementById("retour-pyw").innerHTML = "Loading...";') + \
  3596.                 WI_AjaxFunction('Import', 'document.getElementById("retour-pyw").innerHTML = ajaxRequest.responseText;', '"/Import?dir="+document.getElementById("impf-dir").value+"&name="+document.getElementById("impf-name").value+"&key="+document.getElementById("impf-key").value+"&label="+document.getElementById("impf-label").value+"&vers="+document.getElementById("impf-vers").value+"&com="+document.getElementById("impf-com").checked+"&cry="+document.getElementById("impf-cry").checked+"&format="+document.getElementById("impf-hex").checked+(document.getElementById("impf-reserve").checked?"&reserve=1":"")', 'document.getElementById("retour-pyw").innerHTML = "Loading...";') + \
  3597.                 WI_AjaxFunction('ImportRO', 'document.getElementById("retour-pyw").innerHTML = ajaxRequest.responseText;', '"/Import?dir="+document.getElementById("irof-dir").value+"&name="+document.getElementById("irof-name").value+"&pub="+document.getElementById("irof-pub").value+"&label="+document.getElementById("irof-label").value', 'document.getElementById("retour-pyw").innerHTML = "Loading...";') + \
  3598.                 WI_AjaxFunction('Balance', 'document.getElementById("retour-pyw").innerHTML = "Balance of " + document.getElementById("bf-key").value + ": " + ajaxRequest.responseText;', '"/Balance?key="+document.getElementById("bf-key").value', 'document.getElementById("retour-pyw").innerHTML = "Loading...";') + \
  3599.                 WI_AjaxFunction('Delete', 'document.getElementById("retour-pyw").innerHTML = ajaxRequest.responseText;', '"/Delete?dir="+document.getElementById("d-dir").value+"&name="+document.getElementById("d-name").value+"&keydel="+document.getElementById("d-key").value+"&typedel="+get_radio_value(document.getElementsByName("d-type"))', 'document.getElementById("retour-pyw").innerHTML = "Loading...";') + \
  3600.                 WI_AjaxFunction('ImportTx', 'document.getElementById("retour-pyw").innerHTML = ajaxRequest.responseText;', '"/ImportTx?dir="+document.getElementById("it-dir").value+"&name="+document.getElementById("it-name").value+"&txk="+document.getElementById("it-txk").value+"&txv="+document.getElementById("it-txv").value', 'document.getElementById("retour-pyw").innerHTML = "Loading...";') + \
  3601.                 '</script>'
  3602.  
  3603. #               WI_AjaxFunction('Import', 'document.getElementById("ImportDiv").innerHTML = ajaxRequest.responseText;', '"/Import?dir="+document.getElementById("impf-dir").value+"&name="+document.getElementById("impf-name").value+"&key="+document.getElementById("impf-key").value+"&label="+document.getElementById("impf-label").value+"&vers="+document.getElementById("impf-vers").value+"&format="+(document.getElementById("impf-hex").checked?"hex":"reg")+(document.getElementById("impf-reserve").checked?"&reserve=1":"")', 'document.getElementById("ImportDiv").innerHTML = "Loading...";') + \
  3604.  
  3605.  
  3606.                 page = '<html><head><title>Pywallet Web Interface</title></head><body>' + header + Javascript + CPPForm + DWForm + MWForm + DKForm + IKForm + DTxForm + InfoForm + ImportForm + ImportTxForm + DeleteForm + BalanceForm + Misc + '</body></html>'
  3607.  
  3608.                 AboutPage="\
  3609. Pywallet is a tool to manage wallet files, developped by jackjack. <a href='https://bitcointalk.org/index.php?topic=34028'>Support thread</a> is on bitcointalk.<br />\
  3610. <br />\
  3611. To support pywallet's development or if you think it's worth something, you can send anything you want to 1AQDfx22pKGgXnUZFL1e4UKos3QqvRzNh5.\
  3612. \
  3613. <br /><br /><br /><br /><b>Dependencies:</b><br />\
  3614.                 \
  3615.                 &nbsp;&nbsp;&nbsp;ecdsa: "+dep_text_aboutpage('ecdsa' in missing_dep)+"\
  3616.                 \
  3617. <br /><br /><b>Pywallet path:</b>&nbsp;&nbsp;&nbsp;"+pyw_path+"/"+pyw_filename+"\
  3618.                 "
  3619.  
  3620.                 return html_wui(Javascript + \
  3621.                     WI_Endiv(DWForm+DKForm+DTxForm, 'DumpPage', 'Dump', '') + \
  3622.                     WI_Endiv(ImportForm+IKForm+MWForm+ImportTxForm+ImportROForm,'ImportPage', 'Import', "Don't forget to close Bitcoin when you modify your wallet", True) + \
  3623.                     WI_Endiv(DeleteForm,'DeletePage', 'Delete', "Don't forget to close Bitcoin when you modify your wallet", True) + \
  3624.                     WI_Endiv(CPPForm,'PassphrasePage', 'Change passphrase', '', True) + \
  3625.                     WI_Endiv(InfoForm+BalanceForm,'InfoPage', 'Info', '', True) + \
  3626.                     WI_Endiv(CreateTxForm2+CreateTxForm,'TxPage', 'Manage transactions', 'You can here create your own transactions. <br />By default, the unspent transactions from addresses previously dumped are shown, but you can add other addresses to check.<br />You can\'t create a transaction if you didn\'t dump the private keys of each input beforehand.', True) + \
  3627.                     WI_Endiv(AboutPage,'AboutPage','About','', True)
  3628.                 ,check_version_text
  3629.                 )
  3630.  
  3631.  
  3632.                 return page
  3633.  
  3634.          def getChild(self, name, request):
  3635.              if name == '':
  3636.                  return self
  3637.              else:
  3638.                  if name in VIEWS.keys():
  3639.                      return resource.Resource.getChild(self, name, request)
  3640.                  else:
  3641.                      return WI404()
  3642.  
  3643.     class WIDumpWallet(resource.Resource):
  3644.  
  3645.          def render_GET(self, request):
  3646.              try:
  3647.  
  3648.                     wdir=request.args['dir'][0]
  3649.                     wname=request.args['name'][0]
  3650.                     version = int(request.args['version'][0])
  3651.                     log.msg('Wallet Dir: %s' %(wdir))
  3652.                     log.msg('Wallet Name: %s' %(wname))
  3653.  
  3654.                     if not os.path.isfile(wdir+"/"+wname):
  3655.                         return '%s/%s doesn\'t exist'%(wdir, wname)
  3656.  
  3657.                     try:
  3658.                         bal=request.args['bal'][0]=='true'
  3659.                     except:
  3660.                         bal=false
  3661.                     read_wallet(json_db, create_env(wdir), wname, True, True, "", bal, version)
  3662.  
  3663. #                   print wdir
  3664. #                   print wname
  3665. #                   print json_db  #json.dumps(json_db, sort_keys=True, indent=4)
  3666.  
  3667.                     try:
  3668.                         kfile=request.args['filetw'][0]
  3669.                         kkeys=request.args['keys'][0]
  3670. #                       print kkeys.split(',')
  3671.                         reteak=export_all_keys(json_db, kkeys.split(','), kfile)
  3672.                         return 'File'+X_if_else("",reteak," not")+' written'
  3673.                     except:
  3674.                         return 'Wallet: %s/%s<br />Dump:<pre>%s</pre>'%(wdir, wname, json.dumps(json_db, sort_keys=True, indent=4))
  3675.              except:
  3676.                  log.err()
  3677.                  return 'Error in dump page'
  3678.  
  3679.              def render_POST(self, request):
  3680.                  return self.render_GET(request)
  3681.  
  3682.     class WIDumpTx(resource.Resource):
  3683.  
  3684.          def render_GET(self, request):
  3685.              try:
  3686.                     wdir=request.args['dir'][0]
  3687.                     wname=request.args['name'][0]
  3688.                     jsonfile=request.args['file'][0]
  3689.                     log.msg('Wallet Dir: %s' %(wdir))
  3690.                     log.msg('Wallet Name: %s' %(wname))
  3691.  
  3692.                     if not os.path.isfile(wdir+"/"+wname):
  3693.                         return '%s/%s doesn\'t exist'%(wdir, wname)
  3694.                     if os.path.isfile(jsonfile):
  3695.                         return '%s exists'%(jsonfile)
  3696.  
  3697.                     read_wallet(json_db, create_env(wdir), wname, True, True, "", None)
  3698.                     write_jsonfile(jsonfile, json_db['tx'])
  3699.                     return 'Wallet: %s/%s<br />Transations dumped in %s'%(wdir, wname, jsonfile)
  3700.              except:
  3701.                  log.err()
  3702.                  return 'Error in dumptx page'
  3703.  
  3704.              def render_POST(self, request):
  3705.                  return self.render_GET(request)
  3706.  
  3707.     class WIMergeWallets(resource.Resource):
  3708.  
  3709.          def render_GET(self, request):
  3710.              try:
  3711.                 dir1=request.args['dir1'][0]
  3712.                 name1=request.args['name1'][0]
  3713.                 pass1=request.args['pass1'][0]
  3714.                 dir2=request.args['dir2'][0]
  3715.                 name2=request.args['name2'][0]
  3716.                 pass2=request.args['pass2'][0]
  3717.                 dirm=request.args['dirm'][0]
  3718.                 namem=request.args['namem'][0]
  3719.                 passm1=request.args['passm1'][0]
  3720.                 passm2=request.args['passm2'][0]
  3721.                 if passm1!=passm2:
  3722.                     return 'The passphrases for the merged wallet don\'t match. Aborted.'
  3723.  
  3724.                 r=merge_wallets(dir1, name1, dir2, name2, dirm, namem, pass1, pass2, passm1)
  3725.                 if r[0]:
  3726.                     return "Merging in progress..."
  3727.                 else:
  3728.                     return r[1]
  3729.  
  3730.                 return ret
  3731.              except:
  3732.                  log.err()
  3733.                  return 'Error in mergewallets page'
  3734.  
  3735.              def render_POST(self, request):
  3736.                  return self.render_GET(request)
  3737.  
  3738.     class WIChangePP(resource.Resource):
  3739.  
  3740.          def render_GET(self, request):
  3741.              try:
  3742.                 global passphrase
  3743.                 passphrase=request.args['pp'][0]
  3744.                 return 'Done'
  3745.              except:
  3746.                 log.err()
  3747.                 return 'Error while changing passphrase'
  3748.  
  3749.              def render_POST(self, request):
  3750.                  return self.render_GET(request)
  3751.  
  3752.     class WIOthers(resource.Resource):
  3753.  
  3754.          def render_GET(self, request):
  3755.              try:
  3756.                 global passphrase
  3757.                 global global_merging_message
  3758.  
  3759.                 action=request.args['action'][0]
  3760.                 if action=="update_mwdiv":
  3761.                     ret=global_merging_message[0]
  3762.                     global_merging_message[0]=global_merging_message[1]
  3763.                     global_merging_message[1]=""
  3764.                     return ret
  3765.                 return 'Done'
  3766.              except:
  3767.                 log.err()
  3768.                 return 'Error while WIOthers'
  3769.  
  3770.              def render_POST(self, request):
  3771.                  return self.render_GET(request)
  3772.  
  3773.     class WIBalance(resource.Resource):
  3774.  
  3775.          def render_GET(self, request):
  3776.              try:
  3777.                     return "%s"%str(balance(balance_site, request.args['key'][0]).encode('utf-8'))
  3778.              except:
  3779.                  log.err()
  3780.                  return 'Error in balance page'
  3781.  
  3782.              def render_POST(self, request):
  3783.                  return self.render_GET(request)
  3784.  
  3785.     class WIDelete(resource.Resource):
  3786.  
  3787.          def render_GET(self, request):
  3788.              try:
  3789.                     wdir=request.args['dir'][0]
  3790.                     wname=request.args['name'][0]
  3791.                     keydel=request.args['keydel'][0]
  3792.                     typedel=request.args['typedel'][0]
  3793.                     db_env = create_env(wdir)
  3794.  
  3795.                     if not os.path.isfile(wdir+"/"+wname):
  3796.                         return '%s/%s doesn\'t exist'%(wdir, wname)
  3797.  
  3798.                     deleted_items = delete_from_wallet(db_env, wname, typedel, keydel.split('-'))
  3799.  
  3800.                     return "%s:%s has been successfully deleted from %s/%s, resulting in %d deleted item%s"%(typedel, keydel, wdir, wname, deleted_items, iais(deleted_items))
  3801.  
  3802.              except:
  3803.                  log.err()
  3804.                  return 'Error in delete page'
  3805.  
  3806.              def render_POST(self, request):
  3807.                  return self.render_GET(request)
  3808.  
  3809. def message_to_hash(msg, msgIsHex=False):
  3810.     str = ""
  3811. #   str += '04%064x%064x'%(pubkey.point.x(), pubkey.point.y())
  3812. #   str += "Padding text - "
  3813.     str += msg
  3814.     if msgIsHex:
  3815.         str = str.decode('hex')
  3816.     hash = Hash(str)
  3817.     return hash
  3818.  
  3819. def sign_message(secret, msg, msgIsHex=False):
  3820.     k = KEY()
  3821.     k.generate(secret)
  3822.     return k.sign(message_to_hash(msg, msgIsHex))
  3823.  
  3824. def verify_message_signature(pubkey, sign, msg, msgIsHex=False):
  3825.     k = KEY()
  3826.     k.set_pubkey(pubkey.decode('hex'))
  3827.     return k.verify(message_to_hash(msg, msgIsHex), sign.decode('hex'))
  3828.  
  3829.  
  3830. OP_DUP = 118;
  3831. OP_HASH160 = 169;
  3832. OP_EQUALVERIFY = 136;
  3833. OP_CHECKSIG = 172;
  3834.  
  3835. XOP_DUP = "%02x"%OP_DUP;
  3836. XOP_HASH160 = "%02x"%OP_HASH160;
  3837. XOP_EQUALVERIFY = "%02x"%OP_EQUALVERIFY;
  3838. XOP_CHECKSIG = "%02x"%OP_CHECKSIG;
  3839.  
  3840. BTC = 1e8
  3841.  
  3842. def ct(l_prevh, l_prevn, l_prevsig, l_prevpubkey, l_value_out, l_pubkey_out, is_msg_to_sign=-1, oldScriptPubkey=""):
  3843.     scriptSig = True
  3844.     if is_msg_to_sign is not -1:
  3845.         scriptSig = False
  3846.         index = is_msg_to_sign
  3847.  
  3848.     ret = ""
  3849.     ret += inverse_str("%08x"%1)
  3850.     nvin = len(l_prevh)
  3851.     ret += "%02x"%nvin
  3852.  
  3853.     for i in range(nvin):
  3854.         txin_ret = ""
  3855.         txin_ret2 = ""
  3856.  
  3857.         txin_ret += inverse_str(l_prevh[i])
  3858.         txin_ret += inverse_str("%08x"%l_prevn[i])
  3859.  
  3860.         if scriptSig:
  3861.             txin_ret2 += "%02x"%(1+len(l_prevsig[i])/2)
  3862.             txin_ret2 += l_prevsig[i]
  3863.             txin_ret2 += "01"
  3864.             txin_ret2 += "%02x"%(len(l_prevpubkey[i])/2)
  3865.             txin_ret2 += l_prevpubkey[i]
  3866.  
  3867.             txin_ret += "%02x"%(len(txin_ret2)/2)
  3868.             txin_ret += txin_ret2
  3869.  
  3870.         elif index == i:
  3871.             txin_ret += "%02x"%(len(oldScriptPubkey)/2)
  3872.             txin_ret += oldScriptPubkey
  3873.         else:
  3874.             txin_ret += "00"
  3875.  
  3876.         ret += txin_ret
  3877.         ret += "ffffffff"
  3878.  
  3879.  
  3880.     nvout = len(l_value_out)
  3881.     ret += "%02x"%nvout
  3882.     for i in range(nvout):
  3883.         txout_ret = ""
  3884.  
  3885.         txout_ret += inverse_str("%016x"%(l_value_out[i]))
  3886.         txout_ret += "%02x"%(len(l_pubkey_out[i])/2+5)
  3887.         txout_ret += "%02x"%OP_DUP
  3888.         txout_ret += "%02x"%OP_HASH160
  3889.         txout_ret += "%02x"%(len(l_pubkey_out[i])/2)
  3890.         txout_ret += l_pubkey_out[i]
  3891.         txout_ret += "%02x"%OP_EQUALVERIFY
  3892.         txout_ret += "%02x"%OP_CHECKSIG
  3893.         ret += txout_ret
  3894.  
  3895.     ret += "00000000"
  3896.     if not scriptSig:
  3897.         ret += "01000000"
  3898.     return ret
  3899.  
  3900. def create_transaction(secret_key, hashes_txin, indexes_txin, pubkey_txin, prevScriptPubKey, amounts_txout, scriptPubkey):
  3901.     li1 = len(secret_key)
  3902.     li2 = len(hashes_txin)
  3903.     li3 = len(indexes_txin)
  3904.     li4 = len(pubkey_txin)
  3905.     li5 = len(prevScriptPubKey)
  3906.  
  3907.     if li1 != li2 or li2 != li3 or li3 != li4 or li4 != li5:
  3908.         print("Error in the number of tx inputs")
  3909.         exit(0)
  3910.  
  3911.     lo1 = len(amounts_txout)
  3912.     lo2 = len(scriptPubkey)
  3913.  
  3914.     if lo1 != lo2:
  3915.         print("Error in the number of tx outputs")
  3916.         exit(0)
  3917.  
  3918.     sig_txin = []
  3919.     i=0
  3920.     for cpt in hashes_txin:
  3921.         sig_txin.append(sign_message(secret_key[i].decode('hex'), ct(hashes_txin, indexes_txin, sig_txin, pubkey_txin, amounts_txout, scriptPubkey, i, prevScriptPubKey[i]), True)+"01")
  3922.         i+=1
  3923.  
  3924.     tx = ct(hashes_txin, indexes_txin, sig_txin, pubkey_txin, amounts_txout, scriptPubkey)
  3925.     hashtx = Hash(tx.decode('hex')).encode('hex')
  3926.  
  3927.     for i in range(len(sig_txin)):
  3928.         try:
  3929.             verify_message_signature(pubkey_txin[i], sig_txin[i][:-2], ct(hashes_txin, indexes_txin, sig_txin, pubkey_txin, amounts_txout, scriptPubkey, i, prevScriptPubKey[i]), True)
  3930.             print("sig %2d: verif ok"%i)
  3931.         except:
  3932.             print("sig %2d: verif error"%i)
  3933.             exit(0)
  3934.  
  3935. #   tx += end_of_wallettx([], int(time.time()))
  3936. #   return [inverse_str(hashtx), "027478" + hashtx, tx]
  3937.     return [inverse_str(hashtx), "", tx]
  3938.  
  3939. def inverse_str(string):
  3940.     ret = ""
  3941.     for i in range(len(string)/2):
  3942.         ret += string[len(string)-2-2*i];
  3943.         ret += string[len(string)-2-2*i+1];
  3944.     return ret
  3945.  
  3946. def read_table(table, beg, end):
  3947.     rows = table.split(beg)
  3948.     for i in range(len(rows)):
  3949.         rows[i] = rows[i].split(end)[0]
  3950.     return rows
  3951.  
  3952. def read_blockexplorer_table(table):
  3953.     cell = []
  3954.     rows = read_table(table, '<tr>', '</tr>')
  3955.     for i in range(len(rows)):
  3956.         cell.append(read_table(rows[i], '<td>', '</td>'))
  3957.         del cell[i][0]
  3958.     del cell[0]
  3959.     del cell[0]
  3960.     return cell
  3961.  
  3962. txin_amounts = {}
  3963.  
  3964. def bc_address_to_available_tx(address, testnet=False):
  3965.     TN=""
  3966.     if testnet:
  3967.         TN="testnet"
  3968.  
  3969.     blockexplorer_url = "http://blockexplorer.com/"+TN+"/address/"
  3970.     ret = ""
  3971.     txin = []
  3972.     txin_no = {}
  3973.     global txin_amounts
  3974.     txout = []
  3975.     balance = 0
  3976.     txin_is_used = {}
  3977.  
  3978.     page = urllib.urlopen("%s/%s" % (blockexplorer_url, address))
  3979.     try:
  3980.         table = page.read().split('<table class="txtable">')[1]
  3981.         table = table.split("</table>")[0]
  3982.     except:
  3983.         return {address:[]}
  3984.  
  3985.     cell = read_blockexplorer_table(table)
  3986.  
  3987.     for i in range(len(cell)):
  3988.         txhash = read_table(cell[i][0], '/tx/', '#')[1]
  3989.         post_hash = read_table(cell[i][0], '#', '">')[1]
  3990.         io = post_hash[0]
  3991.         no_tx = post_hash[1:]
  3992.         if io in 'i':
  3993.             txout.append([txhash, post_hash])
  3994.         else:
  3995.             txin.append(txhash+no_tx)
  3996.             txin_no[txhash+no_tx] = post_hash[1:]
  3997.             txin_is_used[txhash+no_tx] = 0
  3998.  
  3999.         #hashblock = read_table(cell[i][1], '/block/', '">')[1]
  4000.         #blocknumber = read_table(cell[i][1], 'Block ', '</a>')[1]
  4001.  
  4002.         txin_amounts[txhash+no_tx] = round(float(cell[i][2]), 8)
  4003.  
  4004. #       if cell[i][3][:4] in 'Sent' and io in 'o':
  4005. #           print(cell[i][3][:4])
  4006. #           print(io)
  4007. #           return 'error'
  4008. #       if cell[i][3][:4] in 'Rece' and io in 'i':
  4009. #           print(cell[i][3][:4])
  4010. #           print(io)
  4011. #           return 'error'
  4012.  
  4013.         balance = round(float(cell[i][5]), 8)
  4014.  
  4015.  
  4016.     for tx in txout:
  4017.         pagetx = urllib.urlopen("http://blockexplorer.com/"+TN+"/tx/"+tx[0])
  4018.         table_in = pagetx.read().split('<a name="outputs">Outputs</a>')[0].split('<table class="txtable">')[1].split("</table>")[0]
  4019.  
  4020.         cell = read_blockexplorer_table(table_in)
  4021.         for i in range(len(cell)):
  4022.             txhash = read_table(cell[i][0], '/tx/', '#')[1]
  4023.             no_tx = read_table(cell[i][0], '#', '">')[1][1:]
  4024.  
  4025.             if txhash+no_tx in txin:
  4026.                 txin_is_used[txhash+no_tx] = 1
  4027.  
  4028.     ret = []
  4029.     for tx in txin:
  4030.         if not txin_is_used[tx]:
  4031.             ret.append([tx,txin_amounts[tx],txin_no[tx]])
  4032.  
  4033.     return {address : ret}
  4034.  
  4035. def write_avtx(list_avtx, testnet=False):
  4036.     TN=""
  4037.     if testnet:
  4038.         TN="testnet"
  4039.     gret = "<table border=1>"
  4040.     for add in list_avtx:
  4041.         notnull = False
  4042.         try:
  4043.             hexsec = " -> " + bc_address_to_sec[add]
  4044.         except:
  4045.             hexsec = ""
  4046.         ret = '<tr><td colspan=3 align="center" rowspan=1><a href="http://blockexplorer.com/'+TN+'/address/' +add + '">' + add + "</a>" + hexsec + '</td></tr>'
  4047.         a = list_avtx[add]
  4048.         for array in a:
  4049.             notnull = True
  4050.             no_tx = array[0][64:]
  4051.             array[0] = array[0][:64]
  4052.             link = "http://blockexplorer.com/"+TN+"/rawtx/"+array[0]
  4053.             pagetx = urllib.urlopen(link)
  4054.             ScriptPubkey = str(json.loads(pagetx.read())['out'][int(array[2])]['scriptPubKey'])
  4055. #           ret += '<a href="http://blockexplorer.com/tx/' +array[0] + '">' + array[0] + "#" + no_tx + "</a>: " + str(array[1]) + " & " + ScriptPubkey + "<br />"
  4056.             ret += '<tr><td><a href="http://blockexplorer.com/'+TN+'/tx/' +array[0] + '#' + no_tx + '">' + array[0] + "</a></td><td>" + str(array[1]) + "</td><td>" + ScriptPubkey + "</td></tr>"
  4057.         ret+="<tr><td colspan=3></td></tr>"
  4058. #       ret += "<br />" + "<br />"
  4059.         if notnull is False:
  4060.             ret = ""
  4061.         gret += ret
  4062.     gret=gret[:-len("<tr><td colspan=3></td></tr>")]
  4063.  
  4064.     return gret+"</table>"
  4065.  
  4066. ct_txin = []
  4067. ct_txout = []
  4068.  
  4069.  
  4070. empty_txin={'hash':'', 'index':'', 'sig':'##', 'pubkey':'', 'oldscript':'', 'addr':''}
  4071. empty_txout={'amount':'', 'script':''}
  4072.  
  4073. class tx():
  4074.     ins=[]
  4075.     outs=[]
  4076.     tosign=False
  4077.  
  4078.     def hashtypeone(index,script):
  4079.         global empty_txin
  4080.         for i in range(len(ins)):
  4081.             self.ins[i]=empty_txin
  4082.         self.ins[index]['pubkey']=""
  4083.         self.ins[index]['oldscript']=s
  4084.         self.tosign=True
  4085.  
  4086.     def copy():
  4087.         r=tx()
  4088.         r.ins=self.ins[:]
  4089.         r.outs=self.outs[:]
  4090.         return r
  4091.  
  4092.     def sign(n=-1):
  4093.         if n==-1:
  4094.             for i in range(len(ins)):
  4095.                 self.sign(i)
  4096.                 return "done"
  4097.  
  4098.         global json_db
  4099.         txcopy=self.copy()
  4100.         txcopy.hashtypeone(i, self.ins[n]['oldscript'])
  4101.  
  4102.         sec=''
  4103.         for k in json_db['keys']:
  4104.           if k['addr']==self.ins[n]['addr'] and 'hexsec' in k:
  4105.             sec=k['hexsec']
  4106.         if sec=='':
  4107.             print "priv key not found (addr:"+self.ins[n]['addr']+")"
  4108.             return ""
  4109.  
  4110.         self.ins[n]['sig']=sign_message(sec.decode('hex'), txcopy.get_tx(), True)
  4111.  
  4112.     def ser():
  4113.         r={}
  4114.         r['ins']=self.ins
  4115.         r['outs']=self.outs
  4116.         r['tosign']=self.tosign
  4117.         return json.dumps(r)
  4118.  
  4119.     def unser(r):
  4120.         s=json.loads(r)
  4121.         self.ins=s['ins']
  4122.         self.outs=s['outs']
  4123.         self.tosign=s['tosign']
  4124.  
  4125.     def get_tx():
  4126.         r=''
  4127.         ret += inverse_str("%08x"%1)
  4128.         ret += "%02x"%len(self.ins)
  4129.  
  4130.         for i in range(len(self.ins)):
  4131.             txin=self.ins[i]
  4132.             ret += inverse_str(txin['hash'])
  4133.             ret += inverse_str("%08x"%txin['index'])
  4134.  
  4135.             if txin['pubkey']!="":
  4136.                 tmp += "%02x"%(1+len(txin['sig'])/2)
  4137.                 tmp += txin['sig']
  4138.                 tmp += "01"
  4139.                 tmp += "%02x"%(len(txin['pubkey'])/2)
  4140.                 tmp += txin['pubkey']
  4141.  
  4142.                 ret += "%02x"%(len(tmp)/2)
  4143.                 ret += tmp
  4144.  
  4145.             elif txin['oldscript']!="":
  4146.                 ret += "%02x"%(len(txin['oldscript'])/2)
  4147.                 ret += txin['oldscript']
  4148.  
  4149.             else:
  4150.                 ret += "00"
  4151.  
  4152.             ret += "ffffffff"
  4153.  
  4154.         ret += "%02x"%len(self.outs)
  4155.  
  4156.         for i in range(len(self.outs)):
  4157.             txout=self.outs[i]
  4158.             ret += inverse_str("%016x"%(txout['amount']))
  4159.  
  4160.             if txout['script'][:2]=='s:':  #script
  4161.                 script=txout['script'][:2]
  4162.                 ret += "%02x"%(len(script)/2)
  4163.                 ret += script
  4164.             else:                         #address
  4165.                 ret += "%02x"%(len(txout['script'])/2+5)
  4166.                 ret += "%02x"%OP_DUP
  4167.                 ret += "%02x"%OP_HASH160
  4168.                 ret += "%02x"%(len(txout['script'])/2)
  4169.                 ret += txout['script']
  4170.                 ret += "%02x"%OP_EQUALVERIFY
  4171.                 ret += "%02x"%OP_CHECKSIG
  4172.  
  4173.         ret += "00000000"
  4174.         if not self.tosign:
  4175.             ret += "01000000"
  4176.         return ret
  4177.  
  4178.  
  4179. def listtx_txt(adds):
  4180.             untx_site="http://blockchain.info/unspent?active="
  4181.             ret=''
  4182.             table="""<form action='CT' method=post><table border=1>"""
  4183.             utx=untx_site+adds
  4184.             try:
  4185.                 utxs=json.loads(urllib.urlopen(utx).read())["unspent_outputs"]
  4186.             except:
  4187.                 return "No inputs"
  4188.  
  4189.             table+="<tr>\
  4190.                     <td>Use</td>\
  4191.                     <td>Tx hash</td>\
  4192.                     <td>Script</td>\
  4193.                     <td>Amount</td>\
  4194.                 </tr>"
  4195.             for tx in utxs:
  4196.                 txhash=str(tx["tx_hash"]).decode('hex')[::-1].encode('hex')
  4197.                 txn=int(tx["tx_output_n"])
  4198.                 txscript=str(tx["script"])
  4199.                 txvalue=int(tx["value"])
  4200.                 table+="<tr>"
  4201.                 table+="<td>\
  4202.                             <input type=checkbox onchange='totalin+=(this.checked?1:-1)*"+str(txvalue)+";majfee();' value='' defaultChecked=false name='txin_"+txhash+"_use_"+random_string(6)+"' >\
  4203.                             <input type=hidden name='txin_"+txhash+"_h' value='"+str(txhash)+"'>\
  4204.                             <input type=hidden name='txin_"+txhash+"_n' value='"+str(txn)+"'>\
  4205.                             <input type=hidden name='txin_"+txhash+"_script' value='"+txscript+"'>\
  4206. <input type=hidden name='txin_"+txhash+"_amin' value='"+str(txvalue)+"'>\
  4207.                         </td>"
  4208. #               table+="<td>"+a+"</td>"
  4209.                 table+="<td>"+txhash+"</td>"
  4210.                 table+="<!--td>"+str(txn)+"</td-->"
  4211.                 if txscript[:6]+txscript[-4:]=="76a91488ac":
  4212.                     table+="<td>Address "+hash_160_to_bc_address(txscript[6:-4].decode('hex'))+"</td>"
  4213.                     table+="<input type=hidden name='txin_"+txhash+"_add' value='"+hash_160_to_bc_address(txscript[6:-4].decode('hex'))+"'>"
  4214.                 else:
  4215.                     table+="<td>"+txscript+"</td>"
  4216.  
  4217.                 table+="<td>"+str(txvalue/1e8)+"</td>"
  4218.                 table+="</tr>\n"
  4219.             table+="</table>"
  4220.             ret+=table
  4221.  
  4222.             ret+="<span id='tot_in'>0</span> BTC (inputs) - <span id='tot_out'>0</span> BTC (outputs) = <span id='tot_fee'>0</span> BTC (fee)<br /><br />"
  4223.  
  4224.             txouts=""
  4225.             nbretxouts=30
  4226.             unserouts=["parseFloat(document.getElementById(\"txout_am_"+str(i)+"\").value)" for i in range(nbretxouts)]
  4227.             serouts="+".join(unserouts)
  4228.             for i in range(nbretxouts):
  4229.                 txouts+="<span id='txout_"+str(i)+"' style='display:"+X_if_else("inline",i<3,"none")+";' >\
  4230. Amount: <input value='0' onchange='totalout=Math.round(("+serouts+")*100000000);majfee();' name='txout_am_"+str(i)+"' id='txout_am_"+str(i)+"' />&nbsp;&nbsp;&nbsp;&nbsp;Script: <input name='txout_script_"+str(i)+"' />\
  4231. \
  4232. \
  4233. \
  4234. <br />"+X_if_else("<input type=button id='button_txout_"+str(i)+"' value='Add a txout' onclick='document.getElementById(\"txout_"+str(i+X_if_else(0,i==nbretxouts-1,1))+"\").style.display=\"block\";document.getElementById(\"button_txout_"+str(i)+"\").style.display=\"none\";' />",i>=2,"")+"</span>"
  4235.  
  4236.             ret+=txouts
  4237.             ret+="<input type=submit value='Create' /></form>"
  4238. #           ret+=WI_Submit('Create', '', '', 'ajaxCTX2')
  4239.  
  4240.             return ret
  4241.  
  4242. if 'twisted' not in missing_dep:
  4243.     class WIInfo(resource.Resource):
  4244.  
  4245.          def render_GET(self, request):
  4246.              global addrtype
  4247.              try:
  4248.                     sec = request.args['key'][0]
  4249.                     format = request.args['format'][0]
  4250.                     addrtype = int(request.args['vers'][0])
  4251.                     msgIsHex = False
  4252.                     msgIsFile = False
  4253.                     try:
  4254.                         msg = request.args['msg'][0]
  4255.                         if msg[0:4] == "Hex:":
  4256.                             msg = msg[4:]
  4257.                             msgIsHex = True
  4258.                         elif msg[0:5] == "File:":
  4259.                             msg = msg[5:]
  4260.                             if not os.path.isfile(msg):
  4261.                                 return '%s doesn\'t exist'%(msg)
  4262.                             filin = open(msg, 'r')
  4263.                             msg = filin.read()
  4264.                             filin.close()
  4265.                             msgIsFile = True
  4266.  
  4267.                         sig = request.args['sig'][0]
  4268.                         pubkey = request.args['pubkey'][0]
  4269.                         need = int(request.args['need'][0])
  4270.                     except:
  4271.                         need = 1
  4272.  
  4273.                     ret = ""
  4274.  
  4275.                     if sec is not '':
  4276.                         if format in 'reg':
  4277.                             pkey = regenerate_key(sec)
  4278.                             compressed = is_compressed(sec)
  4279.                         elif len(sec) == 64:
  4280.                             pkey = EC_KEY(str_to_long(sec.decode('hex')))
  4281.                             compressed = False
  4282.                         elif len(sec) == 66:
  4283.                             pkey = EC_KEY(str_to_long(sec[:-2].decode('hex')))
  4284.                             compressed = True
  4285.                         else:
  4286.                             return "Hexadecimal private keys must be 64 characters long"
  4287.  
  4288.                         if not pkey:
  4289.                             return "Bad private key"
  4290.  
  4291.  
  4292.                         secret = GetSecret(pkey)
  4293.                         private_key = GetPrivKey(pkey, compressed)
  4294.                         public_key = GetPubKey(pkey, compressed)
  4295.                         addr = public_key_to_bc_address(public_key)
  4296.  
  4297.                         if need & 1:
  4298.                             ret += "Address (%s): %s<br />"%(aversions[addrtype], addr)
  4299.                             ret += "Privkey (%s): %s<br />"%(aversions[addrtype], SecretToASecret(secret, compressed))
  4300.                             ret += "Hexprivkey: %s<br />"%(secret.encode('hex'))
  4301.                             ret += "Hash160: %s<br />"%(bc_address_to_hash_160(addr).encode('hex'))
  4302.     #                       ret += "Inverted hexprivkey: %s<br />"%(inversetxid(secret.encode('hex')))
  4303.                             ret += "Pubkey: <span style='font-size:60%%;'>04%.64x%.64x</span><br />"%(pkey.pubkey.point.x(), pkey.pubkey.point.y())
  4304.                             ret += X_if_else('<br /><br /><b>Beware, 0x%s is equivalent to 0x%.33x</b>'%(secret.encode('hex'), int(secret.encode('hex'), 16)-_r), (int(secret.encode('hex'), 16)>_r), '')
  4305.  
  4306.                     if 'ecdsa' not in missing_dep and need & 2:
  4307.                         if sec is not '' and msg is not '':
  4308.                             if need & 1:
  4309.                                 ret += "<br />"
  4310.                             ret += "Signature of '%s' by %s: <span style='font-size:60%%;'>%s</span><br />Pubkey: <span style='font-size:60%%;'>04%.64x%.64x</span><br />"%(X_if_else(msg, not msgIsFile, request.args['msg'][0]), addr, sign_message(secret, msg, msgIsHex), pkey.pubkey.point.x(), pkey.pubkey.point.y())
  4311.  
  4312.                         if sig is not '' and msg is not '' and pubkey is not '':
  4313.                             addr = public_key_to_bc_address(pubkey.decode('hex'))
  4314.                             try:
  4315.                                 verify_message_signature(pubkey, sig, msg, msgIsHex)
  4316.                                 ret += "<br /><span style='color:#005500;'>Signature of '%s' by %s is <span style='font-size:60%%;'>%s</span></span><br />"%(X_if_else(msg, not msgIsFile, request.args['msg'][0]), addr, sig)
  4317.                             except:
  4318.                                 ret += "<br /><span style='color:#990000;'>Signature of '%s' by %s is NOT <span style='font-size:60%%;'>%s</span></span><br />"%(X_if_else(msg, not msgIsFile, request.args['msg'][0]), addr, sig)
  4319.  
  4320.                     return ret
  4321.  
  4322.              except:
  4323.                  log.err()
  4324.                  return 'Error in info page'
  4325.  
  4326.              def render_POST(self, request):
  4327.                  return self.render_GET(request)
  4328.  
  4329.  
  4330.     class WIImportTx(resource.Resource):
  4331.  
  4332.          def render_GET(self, request):
  4333.              global addrtype
  4334.              try:
  4335.                     wdir=request.args['dir'][0]
  4336.                     wname=request.args['name'][0]
  4337.                     txk=request.args['txk'][0]
  4338.                     txv=request.args['txv'][0]
  4339.                     d = {}
  4340.  
  4341.                     if not os.path.isfile(wdir+"/"+wname):
  4342.                         return '%s/%s doesn\'t exist'%(wdir, wname)
  4343.  
  4344.                     if txk not in "file":
  4345.                         dd = [{'tx_k':txk, 'tx_v':txv}]
  4346.                     else:
  4347.                         if not os.path.isfile(txv):
  4348.                             return '%s doesn\'t exist'%(txv)
  4349.                         dd = read_jsonfile(txv)
  4350.  
  4351.  
  4352.                     db_env = create_env(wdir)
  4353.                     read_wallet(json_db, db_env, wname, True, True, "", None)
  4354.                     db = open_wallet(db_env, wname, writable=True)
  4355.  
  4356.                     i=0
  4357.                     for tx in dd:
  4358.                         d = {'txi':tx['tx_k'], 'txv':tx['tx_v']}
  4359.                         print(d)
  4360.                         update_wallet(db, "tx", d)
  4361.                         i+=1
  4362.  
  4363.                     db.close()
  4364.  
  4365.                     return "<pre>hash: %s\n%d transaction%s imported in %s/%s<pre>" % (inverse_str(txk[6:]), i, iais(i), wdir, wname)
  4366.  
  4367.              except:
  4368.                  log.err()
  4369.                  return 'Error in importtx page'
  4370.  
  4371.              def render_POST(self, request):
  4372.                  return self.render_GET(request)
  4373.  
  4374.     class WIQuit(resource.Resource):
  4375.         def render_GET(self, request):
  4376.             reactor.stop()
  4377.         def render_POST(self, request):
  4378.             return self.render_GET(request)
  4379.  
  4380.     class WICTListTx(resource.Resource):
  4381.         def render_GET(self, request):
  4382.             global CTX_adds
  4383.             try:
  4384.                 adds=request.args['addresses'][0]
  4385.                 CTX_adds=adds
  4386.             except:
  4387.                 return "You must provide at least one address to see the transaction you can spend. Divided by |"
  4388.  
  4389.             ret=""
  4390.             ret=listtx_txt(adds)
  4391.             return "Refresh to display available incoming transactions"
  4392.  
  4393.         def render_POST(self, request):
  4394.             return self.render_GET(request)
  4395.  
  4396.     class WICT(resource.Resource):
  4397.         def render_GET(self, request):
  4398.             #CT?sec=s&hashesin=h&indexes=1&pubkeys=p&prevspk=r&amounts=2453628&spk=spk#tbend
  4399.             global txin_amounts, json_db
  4400.             display = ""
  4401.  
  4402.  
  4403.  
  4404.             try:
  4405.                 testnet=request.args['testnet'][0]
  4406.                 TN="testnet"
  4407.             except:
  4408.                 TN=""
  4409.  
  4410.             try:
  4411.  
  4412.                 list_sec, list_hin, list_indexes, list_pubs, list_scriptin, list_outam, list_scriptout, list_amin = [[] for i in range(8)]
  4413.  
  4414.                 txin_to_use=[]
  4415.                 txouts_nos=[]
  4416.                 txouts_not_empty=[]
  4417.                 for i in request.args:
  4418.                     if i[:4]=='txin' and i[-10:-7]=='use':
  4419.                         txin_to_use.append(i.split('_')[1])
  4420.                     if i[:4]=='txou' and i.split('_')[2] not in txouts_nos:
  4421.                         p=i.split('_')[1]
  4422.                         no=i.split('_')[2]
  4423.                         txouts_nos.append(no)
  4424.  
  4425.                 for no in txouts_nos:
  4426.                   if request.args['txout_am_'+no][0]!='' and request.args['txout_am_'+no][0]!='0':
  4427.                     list_outam.append(request.args['txout_am_'+no][0])
  4428.                     list_scriptout.append(request.args['txout_script_'+no][0])
  4429.  
  4430.  
  4431.                 global addr_to_keys
  4432.                 for h in txin_to_use:
  4433.                     if request.args['txin_'+h+'_add'][0] not in addr_to_keys.keys():
  4434.                         return "<br />No private key for "+request.args['txin_'+h+'_add'][0]+", please dump a wallet containing this address<br /><br /><a href='http://localhost:"+str(webport)+"'>Return to Pywallet</a>"
  4435.  
  4436.                     list_hin.append(h)
  4437.                     list_indexes.append(request.args['txin_'+h+'_n'][0])
  4438.                     list_scriptin.append(request.args['txin_'+h+'_script'][0])
  4439.                     list_sec.append(addr_to_keys[request.args['txin_'+h+'_add'][0]][0])
  4440.                     list_pubs.append(addr_to_keys[request.args['txin_'+h+'_add'][0]][1])
  4441.                     list_amin.append(request.args['txin_'+h+'_amin'][0])
  4442.  
  4443.                 sec=",".join(list_sec)
  4444.                 hashesin=",".join(list_hin)
  4445.                 indexes=",".join(list_indexes)
  4446.                 pubkeys=",".join(list_pubs)
  4447.                 prevspk=",".join(list_scriptin)
  4448.                 amins=",".join(list_amin)
  4449.                 amounts=",".join(list_outam)
  4450.                 spk=",".join(list_scriptout)
  4451.  
  4452.  
  4453.             except:
  4454.                 display += "error"
  4455.                 return display
  4456.  
  4457.             secret_key = sec.split(',')
  4458.             hashes_txin = hashesin.split(',')
  4459.             indexes_txin = indexes.split(',')
  4460.             for i in range(len(indexes_txin)):
  4461.                 indexes_txin[i] = int(indexes_txin[i])
  4462.             pubkey_txin = pubkeys.split(',')
  4463.             am_txin = amins.split(',')
  4464.             prevScriptPubKey = prevspk.split(',')
  4465.  
  4466.             amounts_txout = amounts.split(',')
  4467.             for i in range(len(amounts_txout)):
  4468.                 amounts_txout[i] = int(1e8*float(amounts_txout[i]))
  4469.             spk_txout = spk.split(',')
  4470.  
  4471.             tx = create_transaction(secret_key, hashes_txin, indexes_txin, pubkey_txin, prevScriptPubKey, amounts_txout, spk_txout)
  4472.  
  4473.             display += "Inputs: (go to <a href='CTTest'>CTTest</a> before)<br />"
  4474.             sum_in = 0
  4475.             for i in range(len(hashes_txin)):
  4476.                 try:
  4477. #                   ain = txin_amounts[hashes_txin[i] + ("%d"%indexes_txin[i])]
  4478.                     ain=int(am_txin[i])/1e8
  4479.                     aaa = ", %.8f BTC"%ain
  4480.                     sum_in += ain
  4481.                 except:
  4482.                     aaa = ""
  4483.                 display += ('%d: <a href="http://blockexplorer.com/'+TN+'/tx/%s#o%d">%s #%d</a>%s<br />')%(i, hashes_txin[i], indexes_txin[i], hashes_txin[i], indexes_txin[i], aaa)
  4484.  
  4485.             display += "<br /><br />Outputs:<br />"
  4486.             sum_out = 0
  4487.             for i in range(len(spk_txout)):
  4488.                 sum_out += amounts_txout[i]/BTC
  4489.                 display += '%.8f BTC to %s<br />'%(amounts_txout[i]/BTC, hash_160_to_bc_address(spk_txout[i].decode('hex')))
  4490.  
  4491.             display += "<br />"
  4492.             display += "<br />"
  4493.             display += "In: %.8f BTC"%sum_in
  4494.             display += "<br />"
  4495.             display += "Out: %.8f BTC"%sum_out
  4496.             display += "<br />"
  4497.             display += "Fee: %.8f BTC"%(sum_in-sum_out)
  4498.             display += "<br />"
  4499.             display += "<br />"
  4500.             display += "<br />"
  4501.             display += ("<pre>Transaction hash: "+tx[0])
  4502.             display += "<br />"
  4503. #           display += ("tx_k:    "+tx[1])
  4504. #           display += "<br />"
  4505.             display += ("Raw transaction:       "+tx[2])
  4506.  
  4507.             display += "</pre><br />"
  4508.  
  4509.  
  4510.             return display
  4511.  
  4512.         def render_POST(self, request):
  4513.             return self.render_GET(request)
  4514.  
  4515.     class WICTTest(resource.Resource):
  4516.  
  4517.         def render_GET(self, request):
  4518.             try:
  4519.                 request.args['testnet'][0]
  4520.                 testnet=True
  4521.             except:
  4522.                 testnet=False
  4523.             list_avtx = {}
  4524.             i = 0
  4525.  
  4526.             try:
  4527.                 for add in request.args['addresses'][0].split(','):
  4528.                     print "Address %d: %s"%(i, add)
  4529.                     list_avtx[add] = bc_address_to_available_tx(add, testnet)[add]
  4530.                     i += 1
  4531.  
  4532.                 print(list_avtx)
  4533.  
  4534.                 display = ""
  4535.                 display += write_avtx(list_avtx, testnet)
  4536.             except:
  4537.                 display="You must provide at least one address to see the transaction you can spend.<br /><a href='CTTest?addresses=1BAdzvknPux2zqG2eNawvgitCW1aqwE4bb'>Like this</a>"
  4538.  
  4539.             return display
  4540.  
  4541.         def render_POST(self, request):
  4542.             return self.render_GET(request)
  4543.  
  4544.  
  4545.     class WIImport(resource.Resource):
  4546.  
  4547.          def render_GET(self, request):
  4548.              global addrtype
  4549.              try:
  4550.                                 pub=request.args['pub'][0]
  4551.                                 try:
  4552.                                         wdir=request.args['dir'][0]
  4553.                                         wname=request.args['name'][0]
  4554.                                         label=request.args['label'][0]
  4555.  
  4556.                                         db_env = create_env(wdir)
  4557.                                         db = open_wallet(db_env, wname, writable=True)
  4558.                                         update_wallet(db, 'ckey', { 'public_key' : pub.decode('hex'), 'encrypted_private_key' : random_string(96).decode('hex') })
  4559.                                         update_wallet(db, 'name', { 'hash' : public_key_to_bc_address(pub.decode('hex')), 'name' : "Read-only: "+label })
  4560.                                         db.close()
  4561.                                         return "Read-only address "+public_key_to_bc_address(pub.decode('hex'))+" imported"
  4562.                     except:
  4563.                                         return "Read-only address "+public_key_to_bc_address(pub.decode('hex'))+" not imported"
  4564.              except:
  4565.                                 pass
  4566.  
  4567.              try:
  4568.  
  4569.                     wdir=request.args['dir'][0]
  4570.                     wname=request.args['name'][0]
  4571.  
  4572.                     try:        #Import a single key
  4573.                         addrtype = int(request.args['vers'][0])
  4574.                         format = X_if_else('hex', request.args['format'][0]=='true', 'reg')
  4575.                         reserve=request.args.has_key('reserve')
  4576.                         label=request.args['label'][0]
  4577.                         compressed=request.args['com'][0]=='true'
  4578.                         tocrypt=request.args['cry'][0]=='true'
  4579.                         sec = request.args['key'][0]
  4580.                     except:     #Import csv file
  4581.                         ret=import_csv_keys(request.args['file'][0],wdir,wname)
  4582.                         return "File "+X_if_else("", ret, "not ")+"imported"
  4583.  
  4584.  
  4585.  
  4586.  
  4587.  
  4588.                     if format in 'reg':
  4589.                         pkey = regenerate_key(sec)
  4590.                         compressed = is_compressed(sec)
  4591.                     elif len(sec) == 64:
  4592.                         pkey = EC_KEY(str_to_long(sec.decode('hex')))
  4593.                         compressed = False
  4594.                     elif len(sec) == 66:
  4595.                         pkey = EC_KEY(str_to_long(sec[:-2].decode('hex')))
  4596.                         compressed = True
  4597.                     else:
  4598.                         return "Hexadecimal private keys must be 64 or 66 characters long"
  4599.  
  4600.                     if not pkey:
  4601.                         return "Bad private key"
  4602.  
  4603.                     if not os.path.isfile(wdir+"/"+wname):
  4604.                         return '%s/%s doesn\'t exist'%(wdir, wname)
  4605.  
  4606.  
  4607.                     db_env = create_env(wdir)
  4608.                     ret_read = read_wallet(json_db, db_env, wname, True, True, "", None)
  4609.                     tocrypt = ret_read['crypted']
  4610.                     db = open_wallet(db_env, wname, writable=True)
  4611.  
  4612.  
  4613.                     secret = GetSecret(pkey)
  4614.                     private_key = GetPrivKey(pkey, compressed)
  4615.                     public_key = GetPubKey(pkey, compressed)
  4616.                     addr = public_key_to_bc_address(public_key)
  4617.  
  4618.  
  4619.  
  4620.                     if (format in 'reg' and sec in private_keys) or (format not in 'reg' and sec in private_hex_keys):
  4621.                         return "Already exists"
  4622.  
  4623.                     if not tocrypt:
  4624.                         update_wallet(db, 'key', { 'public_key' : public_key, 'private_key' : private_key })
  4625.                     else:
  4626.                         cry_master = json_db['mkey']['encrypted_key'].decode('hex')
  4627.                         cry_salt   = json_db['mkey']['salt'].decode('hex')
  4628.                         cry_rounds = json_db['mkey']['nDerivationIterations']
  4629.                         cry_method = json_db['mkey']['nDerivationMethod']
  4630.  
  4631.                         crypter.SetKeyFromPassphrase(passphrase, cry_salt, cry_rounds, cry_method)
  4632.                         masterkey = crypter.Decrypt(cry_master)
  4633.                         crypter.SetKey(masterkey)
  4634.                         crypter.SetIV(Hash(public_key))
  4635.                         e = crypter.Encrypt(secret)
  4636.                         ck_epk=e
  4637.  
  4638.                         update_wallet(db, 'ckey', { 'public_key' : public_key, 'encrypted_private_key' : ck_epk })
  4639.  
  4640.                     if not reserve:
  4641.                         update_wallet(db, 'name', { 'hash' : addr, 'name' : label })
  4642.  
  4643.                     db.close()
  4644.  
  4645.                     return "<pre>Address: %s\nPrivkey: %s\nHexkey: %s\nKey (%scrypted, %scompressed) imported in %s/%s<pre>" % (addr, SecretToASecret(secret, compressed), secret.encode('hex'), X_if_else("",tocrypt,"un"), X_if_else("",compressed,"un"), wdir, wname)
  4646.  
  4647.              except:
  4648.                  log.err()
  4649.                  return 'Error in import page'
  4650.  
  4651.              def render_POST(self, request):
  4652.                  return self.render_GET(request)
  4653.  
  4654.     class WI404(resource.Resource):
  4655.  
  4656.          def render_GET(self, request):
  4657.              return 'Page Not Found'
  4658.  
  4659.  
  4660. def update_pyw():
  4661.     if md5_last_pywallet[0] and md5_last_pywallet[1] not in md5_pywallet:
  4662.         dl=urllib.urlopen('https://raw.github.com/jackjack-jj/pywallet/master/pywallet.py').read()
  4663.         if len(dl)>40 and md5_2(dl)==md5_last_pywallet[1]:
  4664.             filout = open(pyw_path+"/"+pyw_filename, 'w')
  4665.             filout.write(dl)
  4666.             filout.close()
  4667.             thread.start_new_thread(restart_pywallet, ())
  4668.             return "Updated, restarting..."
  4669.         else:
  4670.             return "Problem when downloading new version ("+md5_2(dl)+"/"+md5_last_pywallet[1]+")"
  4671.  
  4672. def restart_pywallet():
  4673.     thread.start_new_thread(start_pywallet, ())
  4674.     time.sleep(2)
  4675.     reactor.stop()
  4676.  
  4677. def start_pywallet():
  4678.     a=Popen("python "+pyw_path+"/"+pyw_filename+" --web --port "+str(webport)+" --wait 3", shell=True, bufsize=-1, stdout=PIPE).stdout
  4679.     a.close()
  4680.  
  4681. def clone_wallet(parentPath, clonePath):
  4682.     types,datas=[],[]
  4683.     parentdir,parentname=os.path.split(parentPath)
  4684.     wdir,wname=os.path.split(clonePath)
  4685.  
  4686.     db_env = create_env(parentdir)
  4687.     read_wallet(json_db, db_env, parentname, True, True, "", False)
  4688.  
  4689.     types.append('version')
  4690.     datas.append({'version':json_db['version']})
  4691.     types.append('defaultkey')
  4692.     datas.append({'key':json_db['defaultkey']})
  4693.     for k in json_db['keys']:
  4694.         types.append('ckey')
  4695.         datas.append({'public_key':k['pubkey'].decode('hex'),'encrypted_private_key':random_string(96).decode('hex')})
  4696.     for k in json_db['pool']:
  4697.         types.append('pool')
  4698.         datas.append({'n':k['n'],'nVersion':k['nVersion'],'nTime':k['nTime'],'public_key':k['public_key_hex'].decode('hex')})
  4699.     for addr,label in json_db['names'].items():
  4700.         types.append('name')
  4701.         datas.append({'hash':addr,'name':'Watch:'+label})
  4702.  
  4703.     db_env = create_env(wdir)
  4704.     create_new_wallet(db_env, wname, 60000)
  4705.  
  4706.     db = open_wallet(db_env, wname, True)
  4707.     NPP_salt=random_string(16).decode('hex')
  4708.     NPP_rounds=int(50000+random.random()*20000)
  4709.     NPP_method=0
  4710.     NPP_MK=random_string(64).decode('hex')
  4711.     crypter.SetKeyFromPassphrase(random_string(64), NPP_salt, NPP_rounds, NPP_method)
  4712.     NPP_EMK = crypter.Encrypt(NPP_MK)
  4713.     update_wallet(db, 'mkey', {
  4714.         "encrypted_key": NPP_EMK,
  4715.         'nDerivationIterations' : NPP_rounds,
  4716.         'nDerivationMethod' : NPP_method,
  4717.         'nID' : 1,
  4718.         'otherParams' : ''.decode('hex'),
  4719.         "salt": NPP_salt
  4720.     })
  4721.     db.close()
  4722.  
  4723.     read_wallet(json_db, db_env, wname, True, True, "", False)
  4724.  
  4725.     db = open_wallet(db_env, wname, writable=True)
  4726.     update_wallet(db, types, datas, True)
  4727.     db.close()
  4728.     print "Wallet successfully cloned to:\n   %s"%clonePath
  4729.  
  4730. import thread
  4731. md5_last_pywallet = [False, ""]
  4732.  
  4733. def retrieve_last_pywallet_md5():
  4734.     global md5_last_pywallet
  4735.     md5_last_pywallet = [True, md5_onlinefile('https://raw.github.com/jackjack-jj/pywallet/master/pywallet.py')]
  4736.  
  4737. from optparse import OptionParser
  4738.  
  4739. if __name__ == '__main__':
  4740.  
  4741.  
  4742.     parser = OptionParser(usage="%prog [options]", version="%prog 1.1")
  4743.  
  4744.     parser.add_option("--passphrase", dest="passphrase",
  4745.         help="passphrase for the encrypted wallet")
  4746.  
  4747.     parser.add_option("--dumpwallet", dest="dump", action="store_true",
  4748.         help="dump wallet in json format")
  4749.  
  4750.     parser.add_option("--dumpwithbalance", dest="dumpbalance", action="store_true",
  4751.         help="includes balance of each address in the json dump, takes about 2 minutes per 100 addresses")
  4752.  
  4753.     parser.add_option("--importprivkey", dest="key",
  4754.         help="import private key from vanitygen")
  4755.  
  4756.     parser.add_option("--importhex", dest="keyishex", action="store_true",
  4757.         help="KEY is in hexadecimal format")
  4758.  
  4759.     parser.add_option("--datadir", dest="datadir",
  4760.         help="wallet directory (defaults to bitcoin default)")
  4761.  
  4762.     parser.add_option("--wallet", dest="walletfile",
  4763.         help="wallet filename (defaults to wallet.dat)",
  4764.         default="wallet.dat")
  4765.  
  4766.     parser.add_option("--label", dest="label",
  4767.         help="label shown in the adress book (defaults to '')",
  4768.         default="")
  4769.  
  4770.     parser.add_option("--testnet", dest="testnet", action="store_true",
  4771.         help="use testnet subdirectory and address type")
  4772.  
  4773.     parser.add_option("--namecoin", dest="namecoin", action="store_true",
  4774.         help="use namecoin address type")
  4775.  
  4776.     parser.add_option("--otherversion", dest="otherversion",
  4777.         help="use other network address type, whose version is OTHERVERSION")
  4778.  
  4779.     parser.add_option("--info", dest="keyinfo", action="store_true",
  4780.         help="display pubkey, privkey (both depending on the network) and hexkey")
  4781.  
  4782.     parser.add_option("--reserve", dest="reserve", action="store_true",
  4783.         help="import as a reserve key, i.e. it won't show in the adress book")
  4784.  
  4785.     parser.add_option("--multidelete", dest="multidelete",
  4786.         help="deletes data in your wallet, according to the file provided")
  4787.  
  4788.     parser.add_option("--balance", dest="key_balance",
  4789.         help="prints balance of KEY_BALANCE")
  4790.  
  4791.     parser.add_option("--web", dest="web", action="store_true",
  4792.         help="run pywallet web interface")
  4793.  
  4794.     parser.add_option("--port", dest="port",
  4795.         help="port of web interface (defaults to 8989)")
  4796.  
  4797.     parser.add_option("--recover", dest="recover", action="store_true",
  4798.         help="recover your deleted keys, use with recov_size and recov_device")
  4799.  
  4800.     parser.add_option("--recov_device", dest="recov_device",
  4801.         help="device to read (e.g. /dev/sda1 or E: or a file)")
  4802.  
  4803.     parser.add_option("--recov_size", dest="recov_size",
  4804.         help="number of bytes to read (e.g. 20Mo or 50Gio)")
  4805.  
  4806.     parser.add_option("--recov_outputdir", dest="recov_outputdir",
  4807.         help="output directory where the recovered wallet will be put")
  4808.  
  4809.     parser.add_option("--clone_watchonly_from", dest="clone_watchonly_from",
  4810.         help="path of the original wallet")
  4811.  
  4812.     parser.add_option("--clone_watchonly_to", dest="clone_watchonly_to",
  4813.         help="path of the resulting watch-only wallet")
  4814.  
  4815.     parser.add_option("--dont_check_walletversion", dest="dcv", action="store_true",
  4816.         help="don't check if wallet version > %d before running (WARNING: this may break your wallet, be sure you know what you do)"%max_version)
  4817.  
  4818.     parser.add_option("--wait", dest="nseconds",
  4819.         help="wait NSECONDS seconds before launch")
  4820.  
  4821.  
  4822. #   parser.add_option("--forcerun", dest="forcerun",
  4823. #       action="store_true",
  4824. #       help="run even if pywallet detects bitcoin is running")
  4825.  
  4826.     (options, args) = parser.parse_args()
  4827.  
  4828. #   a=Popen("ps xa | grep ' bitcoin'", shell=True, bufsize=-1, stdout=PIPE).stdout
  4829. #   aread=a.read()
  4830. #   nl = aread.count("\n")
  4831. #   a.close()
  4832. #   if nl > 2:
  4833. #       print('Bitcoin seems to be running: \n"%s"'%(aread))
  4834. #       if options.forcerun is None:
  4835. #           exit(0)
  4836.  
  4837.     if options.nseconds:
  4838.         time.sleep(int(options.nseconds))
  4839.  
  4840.     if options.passphrase:
  4841.         passphrase = options.passphrase
  4842.  
  4843.     if options.clone_watchonly_from is not None and options.clone_watchonly_to:
  4844.         clone_wallet(options.clone_watchonly_from, options.clone_watchonly_to)
  4845.         exit(0)
  4846.  
  4847.  
  4848.     if options.recover:
  4849.         if options.recov_size is None or options.recov_device is None or options.recov_outputdir is None:
  4850.             print("You must provide the device, the number of bytes to read and the output directory")
  4851.             exit(0)
  4852.         device = options.recov_device
  4853.         if len(device) in [2,3] and device[1]==':':
  4854.             device="\\\\.\\"+device
  4855.         size = read_device_size(options.recov_size)
  4856.  
  4857.         passphraseRecov=''
  4858.         while passphraseRecov=='':
  4859.             passphraseRecov=raw_input("Enter the passphrase for the wallet that will contain all the recovered keys: ")
  4860.         passphrase=passphraseRecov
  4861.  
  4862.         passes=[]
  4863.         p=' '
  4864.         print '\nEnter the possible passphrases used in your deleted wallets.'
  4865.         print "Don't forget that more passphrases = more time to test the possibilities."
  4866.         print 'Write one passphrase per line and end with an empty line.'
  4867.         while p!='':
  4868.             p=raw_input("Possible passphrase: ")
  4869.             if p!='':
  4870.                 passes.append(p)
  4871.  
  4872.         print "\nStarting recovery."
  4873.         recoveredKeys=recov(device, passes, size, 10240, options.recov_outputdir)
  4874.         recoveredKeys=list(set(recoveredKeys))
  4875. #       print recoveredKeys[0:5]
  4876.  
  4877.  
  4878.         db_env = create_env(options.recov_outputdir)
  4879.         recov_wallet_name = "recovered_wallet_%s.dat"%ts()
  4880.  
  4881.         create_new_wallet(db_env, recov_wallet_name, 32500)
  4882.  
  4883.         if passphraseRecov!="I don't want to put a password on the recovered wallet and I know what can be the consequences.":
  4884.             db = open_wallet(db_env, recov_wallet_name, True)
  4885.  
  4886.             NPP_salt=random_string(16).decode('hex')
  4887.             NPP_rounds=int(50000+random.random()*20000)
  4888.             NPP_method=0
  4889.             NPP_MK=random_string(64).decode('hex')
  4890.             crypter.SetKeyFromPassphrase(passphraseRecov, NPP_salt, NPP_rounds, NPP_method)
  4891.             NPP_EMK = crypter.Encrypt(NPP_MK)
  4892.             update_wallet(db, 'mkey', {
  4893.                 "encrypted_key": NPP_EMK,
  4894.                 'nDerivationIterations' : NPP_rounds,
  4895.                 'nDerivationMethod' : NPP_method,
  4896.                 'nID' : 1,
  4897.                 'otherParams' : ''.decode('hex'),
  4898.                 "salt": NPP_salt
  4899.             })
  4900.             db.close()
  4901.  
  4902.         read_wallet(json_db, db_env, recov_wallet_name, True, True, "", False)
  4903.  
  4904.         db = open_wallet(db_env, recov_wallet_name, True)
  4905.  
  4906.         print "\n\nImporting:"
  4907.         for i,sec in enumerate(recoveredKeys):
  4908.             sec=sec.encode('hex')
  4909.             print("\nImporting key %4d/%d:"%(i+1, len(recoveredKeys)))
  4910.             importprivkey(db, sec, "recovered: %s"%sec, None, True)
  4911.             importprivkey(db, sec+'01', "recovered: %s"%sec, None, True)
  4912.         db.close()
  4913.  
  4914.         print("\n\nThe new wallet %s/%s contains the %d recovered key%s"%(options.recov_outputdir, recov_wallet_name, len(recoveredKeys), iais(len(recoveredKeys))))
  4915.  
  4916.         exit(0)
  4917.  
  4918.  
  4919.     if 'bsddb' in missing_dep:
  4920.         print("pywallet needs 'bsddb' package to run, please install it")
  4921.         exit(0)
  4922.  
  4923.     if 'twisted' in missing_dep and options.web is not None:
  4924.         print("'twisted' package is not installed, pywallet web interface can't be launched")
  4925.         exit(0)
  4926.  
  4927.     if 'ecdsa' in missing_dep:
  4928.         print("'ecdsa' package is not installed, pywallet won't be able to sign/verify messages")
  4929.  
  4930.     if 'twisted' not in missing_dep:
  4931.         VIEWS = {
  4932.              'DumpWallet': WIDumpWallet(),
  4933.              'MergeWallets': WIMergeWallets(),
  4934.              'Import': WIImport(),
  4935.              'ImportTx': WIImportTx(),
  4936.              'DumpTx': WIDumpTx(),
  4937.              'Info': WIInfo(),
  4938.              'Delete': WIDelete(),
  4939.              'Balance': WIBalance(),
  4940.              'ChangePP': WIChangePP(),
  4941.              'Others': WIOthers(),
  4942.              'LoadBalances': WICTTest(),
  4943.              'CTTest': WICTTest(),
  4944.              'ListTransactions': WICTListTx(),
  4945.              'CreateTransaction': WICT(),
  4946.              'CT': WICT(),
  4947.              'quit': WIQuit()
  4948.  
  4949.         }
  4950.  
  4951.     if options.dcv is not None:
  4952.         max_version = 10 ** 9
  4953.  
  4954.     if options.datadir is not None:
  4955.         wallet_dir = options.datadir
  4956.  
  4957.     if options.walletfile is not None:
  4958.         wallet_name = options.walletfile
  4959.  
  4960.     if 'twisted' not in missing_dep and options.web is not None:
  4961.         md5_pywallet = md5_file(pyw_path+"/"+pyw_filename)
  4962.         thread.start_new_thread(retrieve_last_pywallet_md5, ())
  4963.  
  4964.         webport = 8989
  4965.         if options.port is not None:
  4966.             webport = int(options.port)
  4967.         root = WIRoot()
  4968.         for viewName, className in VIEWS.items():
  4969.             root.putChild(viewName, className)
  4970.         log.startLogging(sys.stdout)
  4971.         log.msg('Starting server: %s' %str(datetime.now()))
  4972.         server = server.Site(root)
  4973.         reactor.listenTCP(webport, server)
  4974.         reactor.run()
  4975.         exit(0)
  4976.  
  4977.     if options.key_balance is not None:
  4978.         print(balance(balance_site, options.key_balance))
  4979.         exit(0)
  4980.  
  4981.     if options.dump is None and options.key is None and options.multidelete is None:
  4982.         print "A mandatory option is missing\n"
  4983.         parser.print_help()
  4984.         exit(0)
  4985.  
  4986.     if options.testnet:
  4987.         db_dir += "/testnet"
  4988.         addrtype = 111
  4989.  
  4990.     if options.namecoin or options.otherversion is not None:
  4991.         if options.datadir is None and options.keyinfo is None:
  4992.             print("You must provide your wallet directory")
  4993.             exit(0)
  4994.         else:
  4995.             if options.namecoin:
  4996.                 addrtype = 52
  4997.             else:
  4998.                 addrtype = int(options.otherversion)
  4999.  
  5000.     if options.keyinfo is not None:
  5001.         if not keyinfo(options.key, options.keyishex):
  5002.             print "Bad private key"
  5003.         exit(0)
  5004.  
  5005.     db_dir = determine_db_dir()
  5006.  
  5007.     db_env = create_env(db_dir)
  5008.  
  5009.     if options.multidelete is not None:
  5010.         filename=options.multidelete
  5011.         filin = open(filename, 'r')
  5012.         content = filin.read().split('\n')
  5013.         filin.close()
  5014.         typedel=content[0]
  5015.         kd=filter(bool,content[1:])
  5016.         try:
  5017.             r=delete_from_wallet(db_env, determine_db_name(), typedel, kd)
  5018.             print '%d element%s deleted'%(r, 's'*(int(r>1)))
  5019.         except:
  5020.             print "Error: do not try to delete a non-existing transaction."
  5021.             exit(1)
  5022.         exit(0)
  5023.  
  5024.  
  5025.     read_wallet(json_db, db_env, determine_db_name(), True, True, "", options.dumpbalance is not None)
  5026.  
  5027.     if json_db.get('minversion') > max_version:
  5028.         print "Version mismatch (must be <= %d)" % max_version
  5029.         #exit(1)
  5030.  
  5031.     if options.dump:
  5032.         print json.dumps(json_db, sort_keys=True, indent=4)
  5033.     elif options.key:
  5034.         if json_db['version'] > max_version:
  5035.             print "Version mismatch (must be <= %d)" % max_version
  5036.         elif (options.keyishex is None and options.key in private_keys) or (options.keyishex is not None and options.key in private_hex_keys):
  5037.             print "Already exists"
  5038.         else:
  5039.             db = open_wallet(db_env, determine_db_name(), writable=True)
  5040.  
  5041.             if importprivkey(db, options.key, options.label, options.reserve, options.keyishex):
  5042.                 print "Imported successfully"
  5043.             else:
  5044.                 print "Bad private key"
  5045.  
  5046.             db.close()
Add Comment
Please, Sign In to add comment