def serialize_extended_key(version_bytes, depth, parent_key_fingerprint, child_number, extended_key): depth = depth.to_bytes(1, byteorder='big') index = child_number.to_bytes(4, byteorder='big') serialized = version_bytes + depth + parent_key_fingerprint + index + extended_key checksum = bitcoin.bin_dbl_sha256(serialized)[0:4] serialized += checksum return bitcoin.changebase(serialized, 256, 58)
def pubkey_to_address(pubkey, isTestnet=False): base58_pubkey = TESTNET_MAGIC_BYTE if isTestnet else MAGIC_BYTE pubkey_bin = bytes.fromhex(pubkey) pub_hash = bitcoin.bin_hash160(pubkey_bin) data = bytes([base58_pubkey]) + pub_hash checksum = bitcoin.bin_dbl_sha256(data)[0:4] return b58encode(data + checksum)
def pubkey_to_address(pub_key, dash_network: str): """Convert public key to a Dash address.""" pubkey_bin = bytes.fromhex(pub_key) pub_hash = bitcoin.bin_hash160(pubkey_bin) data = bytes([get_chain_params(dash_network).PREFIX_PUBKEY_ADDRESS]) + pub_hash checksum = bitcoin.bin_dbl_sha256(data)[0:4] return base58.b58encode(data + checksum)
def get_seed(self, seedarg): path = os.path.join('wallets', seedarg) if not os.path.isfile(path): if get_network() == 'testnet': debug( 'seedarg interpreted as seed, only available in testnet because this probably has lower entropy' ) return seedarg else: raise IOError('wallet file not found') #debug('seedarg interpreted as wallet file name') try: import aes except ImportError: print 'You must install slowaes\nTry running: sudo pip install slowaes' sys.exit(0) 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) password = getpass.getpass('Enter wallet decryption passphrase: ') password_key = btc.bin_dbl_sha256(password) decrypted_seed = aes.decryptData( password_key, walletdata['encrypted_seed'].decode('hex')).encode('hex') return decrypted_seed
def validate_address(address: str, dash_network: typing.Optional[str]) -> bool: """Validates if the 'address' is a valid Dash address. :address: address to be validated :dash_network: the dash network type against which the address will be validated; if the value is None, then the network type prefix validation will be skipped """ try: data = base58.b58decode(address) if len(data) > 5: prefix = data[0] if dash_network: prefix_valid = (prefix == get_chain_params( dash_network).PREFIX_PUBKEY_ADDRESS) else: prefix_valid = ( prefix == ChainParamsMainNet.PREFIX_PUBKEY_ADDRESS or prefix == ChainParamsTestNet.PREFIX_PUBKEY_ADDRESS) if prefix_valid: pubkey_hash = data[:-4] checksum = data[-4:] if bitcoin.bin_dbl_sha256(pubkey_hash)[0:4] == checksum: return True except Exception: logging.exception('Address validation failure.') return False
def get_seed(self, seedarg): self.path = None self.index_cache = [[0, 0]]*self.max_mix_depth path = os.path.join('wallets', seedarg) if not os.path.isfile(path): if get_network() == 'testnet': debug('seedarg interpreted as seed, only available in testnet because this probably has lower entropy') return seedarg else: raise IOError('wallet file not found') #debug('seedarg interpreted as wallet file name') 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.getpass('Enter wallet decryption passphrase: ') password_key = btc.bin_dbl_sha256(password) encrypted_seed = walletdata['encrypted_seed'] try: decrypted_seed = slowaes.decryptData(password_key, encrypted_seed .decode('hex')).encode('hex') decrypted = True except ValueError: print 'Incorrect password' decrypted = False return decrypted_seed
def get_seed(self, seedarg): path = os.path.join('wallets', seedarg) if not os.path.isfile(path): if get_network() == 'testnet': debug('seedarg interpreted as seed, only available in testnet because this probably has lower entropy') return seedarg else: raise IOError('wallet file not found') #debug('seedarg interpreted as wallet file name') try: import aes except ImportError: print 'You must install slowaes\nTry running: sudo pip install slowaes' sys.exit(0) 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) password = getpass.getpass('Enter wallet decryption passphrase: ') password_key = btc.bin_dbl_sha256(password) decrypted_seed = aes.decryptData(password_key, walletdata['encrypted_seed'] .decode('hex')).encode('hex') return decrypted_seed
def validate_wif_privkey(privkey: str, dash_network: str): try: data = base58.b58decode(privkey) if len(data) not in (37, 38): raise Exception('Invalid private key length') if data[0] != get_chain_params(dash_network).PREFIX_SECRET_KEY: raise Exception('Invalid private key prefix.') checksum = data[-4:] data = data[:-4] if len(data) == 34: compressed = data[-1] else: compressed = 0 if compressed not in (0, 1): raise Exception('Invalid the compressed byte value: ' + str(compressed)) checksum_cur = bitcoin.bin_dbl_sha256(data)[0:4] if checksum != checksum_cur: raise Exception('Invalid private key checksum') except Exception as e: logging.warning(str(e)) return False return True
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 generate_wif_from_key(childKey, network,compressed=True): prefix = public_wif_prefix if network == Network.MAINNET else testnet_wif_prefix wif_binary = prefix.to_bytes(1,'big') + childKey if compressed: wif_binary += 0x01.to_bytes(1,'big') checksum = bitcoin.bin_dbl_sha256(wif_binary)[0:4] wif = bitcoin.changebase(wif_binary + checksum, 256, 58) return wif
def binary_verify_checksum(data_and_checksum, checksum_length): entropy = data_and_checksum[0:-checksum_length] checksum = data_and_checksum[-checksum_length:] digest = bitcoin.bin_dbl_sha256(bytes(entropy)) computed_checksum = digest[0:checksum_length] debug_print("computed: " + print_hex(digest)) if computed_checksum != checksum: print("checksum failed!")
def pubkeyhash_to_address(pkey_hash, isTestnet=False, isCold=False): if isCold: base58_secret = TESTNET_STAKE_MAGIC_BYTE if isTestnet else STAKE_MAGIC_BYTE else: base58_secret = TESTNET_MAGIC_BYTE if isTestnet else MAGIC_BYTE data = bytes([base58_secret]) + pkey_hash checksum = bitcoin.bin_dbl_sha256(data)[0:4] return b58encode(data + checksum)
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 pubkey_to_address(pubkey): """ Based on project: https://github.com/chaeplin/dashmnb with some changes related to usage of bitcoin library. """ pubkey_bin = bytes.fromhex(pubkey) pub_hash = bitcoin.bin_hash160(pubkey_bin) data = bytes([76]) + pub_hash checksum = bitcoin.bin_dbl_sha256(data)[0:4] return base58.b58encode(data + checksum)
def wif_privkey_to_uncompressed(wif_key: str): privkey_encoded = base58.b58decode(wif_key) if len(privkey_encoded) == 38 and privkey_encoded[33] == 0x01: # [1-byte prefix][32-byte privkey][optional 1-byte compression suffix][4-byte checksum] data = privkey_encoded[:33] checksum = bitcoin.bin_dbl_sha256(data)[0:4] return base58.b58encode(data + checksum) else: return wif_key
def get_hash(self): self.sig_message = self.mn_outpoint.serialize() self.sig_message += self.block_hash[::-1].hex() self.sig_message += self.sig_time.to_bytes(8, "little").hex() self.sig_message += self.sentinel_is_current.to_bytes(1, "little").hex() self.sig_message += self.sentinel_version.to_bytes(4, "little").hex() self.sig_message += self.daemon_version.to_bytes(4, "little").hex() hash = bitcoin.bin_dbl_sha256(bytes.fromhex(self.sig_message)) return hash
def convert_core_to_electrum_merkle_proof(proof): proof = binascii.unhexlify(proof) pos = [0] def read_as_int(bytez): pos[0] += bytez return btc.decode(proof[pos[0] - bytez:pos[0]][::-1], 256) def read_var_int(): pos[0] += 1 val = btc.from_byte_to_int(proof[pos[0] - 1]) if val < 253: return val return read_as_int(pow(2, val - 252)) def read_bytes(bytez): pos[0] += bytez return proof[pos[0] - bytez:pos[0]] pos[0] = 80 txcount = read_as_int(4) hash_count = read_var_int() hashes = [ binascii.hexlify(read_bytes(32)[::-1]).decode() for i in range(hash_count) ] flags_count = read_var_int() flags = read_bytes(flags_count) print(hashes) print([flags[i // 8] & 1 << i % 8 != 0 for i in range(len(flags) * 8)]) print(txcount) root_node = deserialize_core_format_merkle_proof(hashes, flags, txcount) print(root_node) hashes_list = [] expand_tree_electrum_format(root_node, hashes_list) #remove the first or second element which is the txhash tx = hashes_list[0] if hashes_list[1].startswith("tx"): tx = hashes_list[1] assert (tx.startswith("tx")) hashes_list.remove(tx) #if the txhash was duplicated, that is included in electrum's format if hashes_list[0].startswith("tx"): hashes_list[0] = tx.split(":")[2] pos, txid = tx.split(":")[1:3] pos = int(pos) blockhash = binascii.hexlify(btc.bin_dbl_sha256(proof[:80])[::-1]) result = { "pos": pos, "merkle": hashes_list, "txid": txid, "blockhash": blockhash.decode() } return result
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 address_to_pubkey_hash(address: str) -> typing.Optional[bytes]: try: data = base58.b58decode(address) if len(data) > 5: pubkey_hash = data[0:-4] checksum = data[-4:] if bitcoin.bin_dbl_sha256(pubkey_hash)[0:4] == checksum: return pubkey_hash[1:] except Exception: logging.exception('Address validation failure.') return None
def test_pubkey_to_address(self): # generate random private key and convert to public randomPubKey = bitcoin.privkey_to_pubkey(generate_privkey()) # compute address randomPivxAddr = pubkey_to_address(randomPubKey) # check leading char 'D' self.assertEqual(randomPivxAddr[0], 'D') # decode and verify checksum randomPivxAddr_bin = bytes.fromhex(b58decode(randomPivxAddr).hex()) randomPivxAddr_bin_check = bitcoin.bin_dbl_sha256(randomPivxAddr_bin[0:-4])[0:4] self.assertEqual(randomPivxAddr_bin[-4:], randomPivxAddr_bin_check)
def bin_to_b58check(self, inp, magicbyte=0, magicbyte_length=1): inp_fmtd = int(magicbyte).to_bytes(magicbyte_length, 'big') + inp checksum = bitcoin.bin_dbl_sha256(inp_fmtd)[:4] leadingzbytes = 0 for x in inp_fmtd: if x != 0: break leadingzbytes += 1 return '1' * leadingzbytes + bitcoin.changebase(inp_fmtd + checksum, 256, 58)
def test_generate_privkey(self): # generate random private key randomKey = generate_privkey() # check length self.assertEqual(len(randomKey), 51) # check leading char '8' self.assertEqual(randomKey[0], '8') # decode and verify checksum randomKey_bin = bytes.fromhex(b58decode(randomKey).hex()) randomKey_bin_check = bitcoin.bin_dbl_sha256(randomKey_bin[0:-4])[0:4] self.assertEqual(randomKey_bin[-4:], randomKey_bin_check)
def getNewBroadcastMessage(self): self.sig_time = int(time.time()) pk1 = bytes.fromhex(self.collateral['pubKey']) pk2 = bytes.fromhex(self.mnPubKey) ss = (1).to_bytes(4, byteorder='little') ss += bytes.fromhex(ipmap(self.ip, self.port)) ss += (self.sig_time).to_bytes(8, byteorder='little') ss += (len(pk1).to_bytes(1, byteorder='little') + pk1) ss += (len(pk2).to_bytes(1, byteorder='little') + pk2) ss += (self.protocol_version).to_bytes(4, byteorder='little') res = bitcoin.bin_dbl_sha256(ss)[::-1] return res.hex()
def generate_privkey(): """ Based on Andreas Antonopolous work from 'Mastering Bitcoin'. """ valid = False privkey = 0 while not valid: privkey = bitcoin.random_key() decoded_private_key = bitcoin.decode_privkey(privkey, 'hex') valid = 0 < decoded_private_key < bitcoin.N data = bytes([204]) + bytes.fromhex(privkey) checksum = bitcoin.bin_dbl_sha256(data)[0:4] return base58.b58encode(data + checksum)
def getBudgetVoteMess(self, fNewSigs, txid, txidn, hash, vote_code, sig_time): if fNewSigs: ss = bytes.fromhex(txid)[::-1] ss += (txidn).to_bytes(4, byteorder='little') ss += bytes([0, 255, 255, 255, 255]) ss += bytes.fromhex(hash)[::-1] ss += (vote_code).to_bytes(4, byteorder='little') ss += (sig_time).to_bytes(8, byteorder='little') return bitcoin.bin_dbl_sha256(ss) else: serialize_for_sig = '%s-%d' % (txid, txidn) serialize_for_sig += hash + str(vote_code) + str(sig_time) return serialize_for_sig
def getPingMessage(self, fNewSigs, block_hash): if fNewSigs: ss = bytes.fromhex(self.collateral["txid"])[::-1] ss += (self.collateral["txidn"]).to_bytes(4, byteorder='little') ss += bytes([0, 255, 255, 255, 255]) ss += bytes.fromhex(block_hash)[::-1] ss += (self.sig_time).to_bytes(8, byteorder='little') return bitcoin.bin_dbl_sha256(ss) else: scriptSig = '' sequence = 0xffffffff return serialize_input_str(self.collateral['txid'], self.collateral['txidn'], sequence, scriptSig) + \ block_hash + str(self.sig_time)
def generate_privkey(dash_network: str): """ Based on Andreas Antonopolous work from 'Mastering Bitcoin'. """ valid = False privkey = 0 while not valid: privkey = bitcoin.random_key() decoded_private_key = bitcoin.decode_privkey(privkey, 'hex') valid = 0 < decoded_private_key < bitcoin.N data = bytes([get_chain_params(dash_network).PREFIX_SECRET_KEY]) + bytes.fromhex(privkey) checksum = bitcoin.bin_dbl_sha256(data)[0:4] return base58.b58encode(data + checksum)
def generate_privkey(isTestnet=False): """ Based on Andreas Antonopolous work from 'Mastering Bitcoin'. """ base58_secret = TESTNET_WIF_PREFIX if isTestnet else WIF_PREFIX valid = False privkey = 0 while not valid: privkey = bitcoin.random_key() decoded_private_key = bitcoin.decode_privkey(privkey, 'hex') valid = 0 < decoded_private_key < bitcoin.N data = bytes([base58_secret]) + bytes.fromhex(privkey) checksum = bitcoin.bin_dbl_sha256(data)[0:4] return b58encode(data + checksum)
def checkPivxAddr(address): try: # check leading char 'D' if address[0] != 'D': return False # decode and verify checksum addr_bin = bytes.fromhex(b58decode(address).hex()) addr_bin_check = bin_dbl_sha256(addr_bin[0:-4])[0:4] if addr_bin[-4:] != addr_bin_check: return False return True except Exception: return False
def checkPivxAddr(address, isTestnet=False): try: # check leading char 'D' or (for testnet) 'x' or 'y' if isTestnet and address[0] not in P2PKH_PREFIXES_TNET + P2SH_PREFIXES_TNET: return False if not isTestnet and address[0] not in P2PKH_PREFIXES + P2SH_PREFIXES: return False # decode and verify checksum addr_bin = bytes.fromhex(b58decode(address).hex()) addr_bin_check = bin_dbl_sha256(addr_bin[0:-4])[0:4] if addr_bin[-4:] != addr_bin_check: return False return True except Exception: return False
def handle_message(self, p2p, command, length, payload): P2PMessageHandler.handle_message(self, p2p, command, length, payload) ptr = [0] if command == 'addr': addr_count = read_var_int(ptr, payload) log.info('got ' + str(addr_count) + ' addresses') for i in xrange(addr_count): 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)))
def get_seed(self, seedarg): self.path = None self.index_cache = [[0, 0]] * self.max_mix_depth path = os.path.join("wallets", seedarg) if not os.path.isfile(path): if get_network() == "testnet": debug("seedarg interpreted as seed, only available in testnet because this probably has lower entropy") return seedarg else: raise IOError("wallet file not found") # debug('seedarg interpreted as wallet file name') 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.getpass("Enter wallet decryption passphrase: ") password_key = btc.bin_dbl_sha256(password) encrypted_seed = walletdata["encrypted_seed"] try: decrypted_seed = slowaes.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 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
def run(self): services = 0 #headers only st = int(time.time()) nonce = 0 start_height = 0 buffer_size = 4096 netaddr = create_net_addr(ip_to_hex('0.0.0.0'), 0) version_message = (pack('<iQQ', PROTOCOL_VERSION, services, st) + netaddr + netaddr + pack('<Q', nonce) + create_var_str(self.user_agent) + pack('<I', start_height) + ('\x01' if self.relay_txes else '\x00')) data = self.create_message('version', version_message) while True: try: log.info('connecting to bitcoin peer (magic=' + hex(self.magic) + ') at ' + str(self.remote_hostport) + ' with proxy ' + str(self.socks5_hostport)) if self.socks5_hostport == None: self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) else: setdefaultproxy(PROXY_TYPE_SOCKS5, self.socks5_hostport[0], self.socks5_hostport[1], True) self.sock = socksocket() self.sock.settimeout(self.connect_timeout) self.sock.connect(self.remote_hostport) self.sock.sendall(data) break except IOError as e: if len(self.dns_seeds) == 0: raise e else: ##cycle to the next dns seed time.sleep(0.5) log.debug('connection attempts = ' + str(self.connection_attempts)) self.connection_attempts -= 1 if self.connection_attempts == 0: raise e self.dns_index = (self.dns_index + 1) % len(self.dns_seeds) self.remote_hostport = (self.dns_seeds[self.dns_index], self.remote_hostport[1]) log.info('connected') self.sock.settimeout(self.heartbeat_interval) self.closed = False try: recv_buffer = "" payload_length = -1 #-1 means waiting for header command = None checksum = None while not self.closed: try: recv_data = self.sock.recv(4096) if not recv_data or len(recv_data) == 0: raise EOFError() recv_buffer += recv_data #this is O(N^2) scaling in time, another way would be to store in a list #and combine at the end with "".join() #but this isnt really timing critical so didnt optimize it data_remaining = True while data_remaining and not self.closed: if payload_length == -1 and len(recv_buffer) >= HEADER_LENGTH: net_magic, command, payload_length, checksum = unpack('<I12sI4s', recv_buffer[:HEADER_LENGTH]) recv_buffer = recv_buffer[HEADER_LENGTH:] if net_magic != self.magic: log.error('wrong MAGIC: ' + hex(net_magic)) self.sock.close() break command = command.strip('\0') data_remaining = True else: data_remaining = False if payload_length >= 0 and len(recv_buffer) >= payload_length: payload = recv_buffer[:payload_length] recv_buffer = recv_buffer[payload_length:] if btc.bin_dbl_sha256(payload)[:4] == checksum: self.p2p_message_handler.handle_message(self, command, payload_length, payload) else: log.error('wrong checksum, dropping message, cmd=' + command + ' payloadlen=' + str(payload_length)) payload_length = -1 data_remaining = True else: data_remaining = False except socket.timeout: self.p2p_message_handler.check_keepalive(self) self.p2p_message_handler.on_heartbeat(self) except EOFError as e: self.closed = True except IOError as e: import traceback log.error("logging traceback from %s: \n" % traceback.format_exc()) self.closed = True finally: try: self.sock.close() except Exception as e: pass
def create_message(self, command, payload): return (pack("<I12sI", self.magic, command, len(payload)) + btc.bin_dbl_sha256(payload)[:4] + payload)
words = mn_encode(seed) print("Write down this wallet recovery seed\n\n" + " ".join(words) + "\n") elif method == "recover": words = raw_input("Input 12 word recovery seed: ") words = words.split() # default for split is 1 or more whitespace chars if len(words) != 12: print("ERROR: Recovery seed phrase must be exactly 12 words.") sys.exit(0) seed = mn_decode(words) print(seed) password = getpass.getpass("Enter wallet encryption passphrase: ") password2 = getpass.getpass("Reenter wallet encryption passphrase: ") if password != password2: print("ERROR. Passwords did not match") sys.exit(0) password_key = btc.bin_dbl_sha256(password) encrypted_seed = encryptData(password_key, seed.decode("hex")) timestamp = datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S") walletfile = json.dumps( { "creator": "joinmarket project", "creation_time": timestamp, "encrypted_seed": encrypted_seed.encode("hex"), "network": get_network(), } ) walletname = raw_input("Input wallet file name (default: wallet.json): ") if len(walletname) == 0: walletname = "wallet.json" walletpath = os.path.join("wallets", walletname) # Does a wallet with the same name exist?
def pubkeyhash_to_address(pkey_hash, isTestnet=False): base58_pubkey = TESTNET_MAGIC_BYTE if isTestnet else MAGIC_BYTE data = bytes([base58_pubkey]) + pkey_hash checksum = bitcoin.bin_dbl_sha256(data)[0:4] return b58encode(data + checksum)