Esempio n. 1
0
 def read_wallet_file_data(self, filename):
     self.path = None
     self.index_cache = [[0, 0]] * self.max_mix_depth
     path = os.path.join('wallets', filename)
     if not os.path.isfile(path):
         if get_network() == 'testnet':
             log.debug('filename interpreted as seed, only available in '
                       'testnet because this probably has lower entropy')
             return filename
         else:
             raise IOError('wallet file not found')
     self.path = path
     fd = open(path, 'r')
     walletfile = fd.read()
     fd.close()
     walletdata = json.loads(walletfile)
     if walletdata['network'] != get_network():
         print ('wallet network(%s) does not match '
                'joinmarket configured network(%s)' % (
             walletdata['network'], get_network()))
         sys.exit(0)
     if 'index_cache' in walletdata:
         self.index_cache = walletdata['index_cache']
     decrypted = False
     while not decrypted:
         password = getpass('Enter wallet decryption passphrase: ')
         password_key = btc.bin_dbl_sha256(password)
         encrypted_seed = walletdata['encrypted_seed']
         try:
             decrypted_seed = decryptData(
                     password_key,
                     encrypted_seed.decode('hex')).encode('hex')
             # there is a small probability of getting a valid PKCS7
             # padding by chance from a wrong password; sanity check the
             # seed length
             if len(decrypted_seed) == 32:
                 decrypted = True
             else:
                 raise ValueError
         except ValueError:
             print('Incorrect password')
             decrypted = False
     if self.storepassword:
         self.password_key = password_key
         self.walletdata = walletdata
     if 'imported_keys' in walletdata:
         for epk_m in walletdata['imported_keys']:
             privkey = decryptData(
                     password_key,
                     epk_m['encrypted_privkey'].decode( 'hex')).encode('hex')
             privkey = btc.encode_privkey(privkey, 'hex_compressed')
             if epk_m['mixdepth'] not in self.imported_privkeys:
                 self.imported_privkeys[epk_m['mixdepth']] = []
             self.addr_cache[btc.privtoaddr(
                     privkey, get_p2pk_vbyte())] = (epk_m['mixdepth'], -1,
                 len(self.imported_privkeys[epk_m['mixdepth']]))
             self.imported_privkeys[epk_m['mixdepth']].append(privkey)
     return decrypted_seed
Esempio n. 2
0
 def __init__(self,
              seedarg,
              max_mix_depth=2,
              gaplimit=6,
              extend_mixdepth=False,
              storepassword=False,
              pwd = None):
     super(Wallet, self).__init__()
     self.max_mix_depth = max_mix_depth
     self.storepassword = storepassword
     # key is address, value is (mixdepth, forchange, index) if mixdepth =
     #  -1 it's an imported key and index refers to imported_privkeys
     self.addr_cache = {}
     self.unspent = {}
     self.spent_utxos = []
     self.imported_privkeys = {}
     self.decrypted = False
     self.seed = self.read_wallet_file_data(seedarg, pwd)
     if not self.seed:
         return
     if extend_mixdepth and len(self.index_cache) > max_mix_depth:
         self.max_mix_depth = len(self.index_cache)
     self.gaplimit = gaplimit
     self.master_key = btc.bip32_master_key(self.seed, (btc.MAINNET_PRIVATE if
         get_network() == 'mainnet' else btc.TESTNET_PRIVATE))
     m_0 = btc.bip32_ckd(self.master_key, 0)
     self.mixing_depth_keys = [btc.bip32_ckd(m_0, c)
                          for c in range(self.max_mix_depth)]
     self.keys = [(btc.bip32_ckd(m, 0), btc.bip32_ckd(m, 1))
                  for m in self.mixing_depth_keys]
     self.init_index()
Esempio n. 3
0
    def __init__(self,
                 seedarg,
                 max_mix_depth=2,
                 gaplimit=6,
                 extend_mixdepth=False,
                 storepassword=False):
        super(Wallet, self).__init__()
        self.max_mix_depth = max_mix_depth
        self.storepassword = storepassword
        # key is address, value is (mixdepth, forchange, index) if mixdepth =
        #  -1 it's an imported key and index refers to imported_privkeys
        self.addr_cache = {}
        self.unspent = {}
        self.spent_utxos = []
        self.imported_privkeys = {}
        self.seed = self.read_wallet_file_data(seedarg)
        if extend_mixdepth and len(self.index_cache) > max_mix_depth:
            self.max_mix_depth = len(self.index_cache)
        self.gaplimit = gaplimit
        master = btc.bip32_master_key(self.seed, (btc.MAINNET_PRIVATE if
            get_network() == 'mainnet' else btc.TESTNET_PRIVATE))
        m_0 = btc.bip32_ckd(master, 0)
        mixing_depth_keys = [btc.bip32_ckd(m_0, c)
                             for c in range(self.max_mix_depth)]
        self.keys = [(btc.bip32_ckd(m, 0), btc.bip32_ckd(m, 1))
                     for m in mixing_depth_keys]

        # self.index = [[0, 0]]*max_mix_depth
        self.index = []
        for i in range(self.max_mix_depth):
            self.index.append([0, 0])
Esempio n. 4
0
def create_wallet_file(pwd, seed):
    password_key = btc.bin_dbl_sha256(pwd)
    encrypted_seed = encryptData(password_key, seed.decode('hex'))
    timestamp = datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S")
    return json.dumps({'creator': 'joinmarket project',
                             'creation_time': timestamp,
                             'encrypted_seed': encrypted_seed.encode('hex'),
                                 'network': get_network()})
Esempio n. 5
0
 def __init__(self, txhex):
     P2PMessageHandler.__init__(self)
     self.txhex = txhex
     self.txid = btc.bin_txhash(self.txhex)[::-1]
     log.debug('broadcasting txid ' + str(self.txid[::-1].encode('hex')) +
         ' on ' + get_network())
     self.relay_txes = True
     self.rejected = False
     self.uploaded_tx = False
Esempio n. 6
0
def create_wallet_file(pwd, seed):
    password_key = btc.bin_dbl_sha256(pwd)
    encrypted_seed = encryptData(password_key, seed.decode('hex'))
    timestamp = datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S")
    return json.dumps({
        'creator': 'joinmarket project',
        'creation_time': timestamp,
        'encrypted_seed': encrypted_seed.encode('hex'),
        'network': get_network()
    })
Esempio n. 7
0
    def push(self):
        tx = btc.serialize(self.latest_tx)
        log.debug('\n' + tx)
        self.txid = btc.txhash(tx)
        log.info('txid = ' + self.txid)

        tx_broadcast = jm_single().config.get('POLICY', 'tx_broadcast')
        if tx_broadcast == 'self':
            pushed = jm_single().bc_interface.pushtx(tx)
        elif tx_broadcast in ['random-peer', 'not-self']:
            n = len(self.active_orders)
            if tx_broadcast == 'random-peer':
                i = random.randrange(n + 1)
            else:
                i = random.randrange(n)
            if i == n:
                pushed = jm_single().bc_interface.pushtx(tx)
            else:
                self.msgchan.push_tx(self.active_orders.keys()[i], tx)
                pushed = True
        elif tx_broadcast == 'random-maker':
            crow = self.db.execute(
                'SELECT DISTINCT counterparty FROM orderbook ORDER BY ' +
                'RANDOM() LIMIT 1;'
            ).fetchone()
            counterparty = crow['counterparty']
            log.info('pushing tx to ' + counterparty)
            self.msgchan.push_tx(counterparty, tx)
            pushed = True
        elif tx_broadcast == 'tor':
            socks5_host = jm_single().config.get("MESSAGING",
                "socks5_host").split(",")[0]
            socks5_port = int(jm_single().config.get("MESSAGING",
                "socks5_port").split(",")[0])
            pushed = tor_broadcast_tx(tx, (socks5_host, socks5_port),
                testnet=(get_network() == "testnet"))

        if not pushed:
            log.error('unable to pushtx')
        return pushed
Esempio n. 8
0
    def push(self):
        tx = btc.serialize(self.latest_tx)
        log.debug('\n' + tx)
        self.txid = btc.txhash(tx)
        log.info('txid = ' + self.txid)

        tx_broadcast = jm_single().config.get('POLICY', 'tx_broadcast')
        if tx_broadcast == 'self':
            pushed = jm_single().bc_interface.pushtx(tx)
        elif tx_broadcast in ['random-peer', 'not-self']:
            n = len(self.active_orders)
            if tx_broadcast == 'random-peer':
                i = random.randrange(n + 1)
            else:
                i = random.randrange(n)
            if i == n:
                pushed = jm_single().bc_interface.pushtx(tx)
            else:
                self.msgchan.push_tx(self.active_orders.keys()[i], tx)
                pushed = True
        elif tx_broadcast == 'random-maker':
            crow = self.db.execute(
                'SELECT DISTINCT counterparty FROM orderbook ORDER BY ' +
                'RANDOM() LIMIT 1;').fetchone()
            counterparty = crow['counterparty']
            log.info('pushing tx to ' + counterparty)
            self.msgchan.push_tx(counterparty, tx)
            pushed = True
        elif tx_broadcast == 'tor':
            socks5_host = jm_single().config.get("MESSAGING",
                                                 "socks5_host").split(",")[0]
            socks5_port = int(jm_single().config.get(
                "MESSAGING", "socks5_port").split(",")[0])
            pushed = tor_broadcast_tx(tx, (socks5_host, socks5_port),
                                      testnet=(get_network() == "testnet"))

        if not pushed:
            log.error('unable to pushtx')
        return pushed
Esempio n. 9
0
 def blockr_domain(self):
     if get_network() == 'testnet':
         return 'tbtc'
     else:
         return 'btc'
Esempio n. 10
0
 def network_for_blockr_push(self):
     if get_network() == 'testnet':
         return 'testnet'
     else:
         return 'btc'
Esempio n. 11
0
                    timestamp, services, ip_hex, port = read_net_addr(ptr,
                        payload)
                    #log.info('timestamp=%s services=0x%02x addr=%s:%d' % (
                    #    str(datetime.fromtimestamp(timestamp)),
                    #    services, ip_hex_to_str(ip_hex), port))
            elif command == 'block':
                block_version, prev_block, merkle_root, timestamp, bits, nonce =\
                    unpack('<i32s32sIII', payload[ptr[0] : ptr[0]+80])
                self.blockhash = prev_block
                blockhash_str = btc.bin_dbl_sha256(payload[ptr[0] : ptr[0]+80])[::-1].encode('hex')
                #ptr[0] += 80
                log.info('hash=' + blockhash_str + ' prev=' + prev_block[::-1].encode('hex') + ' ts=' + str(datetime.fromtimestamp(timestamp)) + ' size=' + str(len(payload)))


    tor = False
    socks5_hostport = (('localhost', 9150) if tor else None)
    if len(sys.argv) > 1:
        p2p_msg_handler = P2PBroadcastTx(sys.argv[1])
        tor_broadcast_tx(sys.argv[1], tor_hostport)
    else:
        if get_network() != 'mainnet':
            blockhash = '000000000000025748e4d3eb121c4dba5c76d3d1a8069f7a22afb77183c7bddd'.decode('hex')[::-1]
        else:
            blockhash = '0000000000000000000c2190c9c9fad1fbd3a26c3f15ddff086b4bd916fb2e9c'.decode('hex')[::-1]
        p2p_msg_handler = P2PTest(blockhash)
        hostport = None
        p2p = P2PProtocol(p2p_msg_handler, testnet=(get_network() != 'mainnet'),
            socks5_hostport=socks5_hostport,
            remote_hostport=hostport)
        p2p.run()
Esempio n. 12
0
 def read_wallet_file_data(self, filename, pwd=None):
     self.path = None
     self.index_cache = [[0, 0]] * self.max_mix_depth
     path = os.path.join('wallets', filename)
     if not os.path.isfile(path):
         if get_network() == 'testnet':
             log.debug('filename interpreted as seed, only available in '
                       'testnet because this probably has lower entropy')
             return filename
         else:
             raise IOError('wallet file not found')
     self.path = path
     fd = open(path, 'r')
     walletfile = fd.read()
     fd.close()
     walletdata = json.loads(walletfile)
     if walletdata['network'] != get_network():
         print('wallet network(%s) does not match '
               'joinmarket configured network(%s)' %
               (walletdata['network'], get_network()))
         sys.exit(0)
     if 'index_cache' in walletdata:
         self.index_cache = walletdata['index_cache']
         if self.max_mix_depth > len(self.index_cache):
             #This can happen e.g. in tumbler when we need more mixdepths
             #than currently exist. Since we have no info for those extra
             #depths, we must default to (0,0) (but sync should find used
             #adddresses).
             self.index_cache += [[0, 0]] * (self.max_mix_depth -
                                             len(self.index_cache))
     decrypted = False
     while not decrypted:
         if pwd:
             password = pwd
         else:
             password = getpass('Enter wallet decryption passphrase: ')
         password_key = btc.bin_dbl_sha256(password)
         encrypted_seed = walletdata['encrypted_seed']
         try:
             decrypted_seed = decryptData(
                 password_key, encrypted_seed.decode('hex')).encode('hex')
             # there is a small probability of getting a valid PKCS7
             # padding by chance from a wrong password; sanity check the
             # seed length
             if len(decrypted_seed) == 32:
                 decrypted = True
             else:
                 raise ValueError
         except ValueError:
             print('Incorrect password')
             if pwd:
                 raise
             decrypted = False
     if self.storepassword:
         self.password_key = password_key
         self.walletdata = walletdata
     if 'imported_keys' in walletdata:
         for epk_m in walletdata['imported_keys']:
             privkey = decryptData(
                 password_key,
                 epk_m['encrypted_privkey'].decode('hex')).encode('hex')
             #Imported keys are stored as 32 byte strings only, so the
             #second version below is sufficient, really.
             if len(privkey) != 64:
                 raise Exception(
                     "Unexpected privkey format; already compressed?:" +
                     privkey)
             privkey += "01"
             if epk_m['mixdepth'] not in self.imported_privkeys:
                 self.imported_privkeys[epk_m['mixdepth']] = []
             self.addr_cache[btc.privtoaddr(
                 privkey, magicbyte=get_p2pk_vbyte())] = (
                     epk_m['mixdepth'], -1,
                     len(self.imported_privkeys[epk_m['mixdepth']]))
             self.imported_privkeys[epk_m['mixdepth']].append(privkey)
     return decrypted_seed
 def blockr_domain(self):
     if get_network() == 'testnet':
         return 'tbtc'
     else:
         return 'btc'
 def network_for_blockr_push(self):
     if get_network() == 'testnet':
         return 'testnet'
     else:
         return 'btc'
Esempio n. 15
0
    def read_wallet_file_data(self, filename, pwd=None):
        self.path = None
        self.index_cache = [[0, 0]] * self.max_mix_depth
        path = os.path.join('wallets', filename)
        if not os.path.isfile(path):
            if get_network() == 'testnet':
                log.debug('filename interpreted as seed, only available in '
                          'testnet because this probably has lower entropy')
                return filename
            else:
                raise IOError('wallet file not found')
        self.path = path
        fd = open(path, 'r')
        walletfile = fd.read()
        fd.close()
        walletdata = json.loads(walletfile)
        if walletdata['network'] != get_network():
            print ('wallet network(%s) does not match '
                   'joinmarket configured network(%s)' % (
                walletdata['network'], get_network()))
            sys.exit(0)
        if 'index_cache' in walletdata:
            self.index_cache = walletdata['index_cache']
            if self.max_mix_depth > len(self.index_cache):
                #This can happen e.g. in tumbler when we need more mixdepths
                #than currently exist. Since we have no info for those extra
                #depths, we must default to (0,0) (but sync should find used
                #adddresses).
                self.index_cache += [[0,0]] * (
                    self.max_mix_depth - len(self.index_cache))
        decrypted = False
        trieddefault = False
        while not decrypted:
            if pwd:
                password = pwd
            else:
                if not trieddefault:
                    password = ''
                    trieddefault = True
                else:
                    password = getpass('Enter wallet decryption passphrase: ')

            password_key = btc.bin_dbl_sha256(password)
            encrypted_seed = walletdata['encrypted_seed']
            try:
                decrypted_seed = decryptData(
                        password_key,
                        encrypted_seed.decode('hex')).encode('hex')
                # there is a small probability of getting a valid PKCS7
                # padding by chance from a wrong password; sanity check the
                # seed length
                if len(decrypted_seed) == 32:
                    decrypted = True
                else:
                    raise ValueError
            except ValueError:
                if not trieddefault:
                    print('Incorrect password')
                if pwd:
                    raise
                decrypted = False
        if self.storepassword:
            self.password_key = password_key
            self.walletdata = walletdata
        if 'imported_keys' in walletdata:
            for epk_m in walletdata['imported_keys']:
                privkey = decryptData(
                        password_key,
                        epk_m['encrypted_privkey'].decode( 'hex')).encode('hex')
                #Imported keys are stored as 32 byte strings only, so the
                #second version below is sufficient, really.
                if len(privkey) != 64:
                    raise Exception(
                    "Unexpected privkey format; already compressed?:" + privkey)
                privkey += "01"
                if epk_m['mixdepth'] not in self.imported_privkeys:
                    self.imported_privkeys[epk_m['mixdepth']] = []
                self.addr_cache[btc.privtoaddr(
                        privkey, magicbyte=get_p2pk_vbyte())] = (epk_m['mixdepth'], -1,
                    len(self.imported_privkeys[epk_m['mixdepth']]))
                self.imported_privkeys[epk_m['mixdepth']].append(privkey)
        return decrypted_seed