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
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()
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])
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()})
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
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() })
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
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
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'
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()
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 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