Пример #1
0
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)
Пример #2
0
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)
Пример #3
0
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)
Пример #4
0
 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
Пример #6
0
	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
Пример #7
0
	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
Пример #8
0
	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
Пример #10
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()})
Пример #11
0
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
Пример #12
0
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!")
Пример #13
0
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)
Пример #14
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
Пример #15
0
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
Пример #17
0
 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
Пример #18
0
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
Пример #19
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 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
Пример #21
0
 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)
Пример #22
0
    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)
Пример #23
0
 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)
Пример #24
0
 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()
Пример #25
0
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)
Пример #26
0
 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
Пример #27
0
 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)
Пример #28
0
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)
Пример #29
0
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)
Пример #30
0
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
Пример #31
0
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
Пример #32
0
 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)))
Пример #33
0
 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
Пример #34
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
Пример #35
0
    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
Пример #36
0
 def create_message(self, command, payload):
     return (pack("<I12sI", self.magic, command, len(payload))
         + btc.bin_dbl_sha256(payload)[:4] + payload)
Пример #37
0
     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?
Пример #38
0
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)