コード例 #1
0
ファイル: wallet.py プロジェクト: warrenween/blockstack-core
def make_wallet(password, config_path=CONFIG_PATH, payment_privkey_info=None, owner_privkey_info=None, data_privkey_info=None, test_legacy=False, encrypt=True):
    """
    Make a new, encrypted wallet structure.
    The owner and payment keys will be 2-of-3 multisig key bundles.
    The data keypair will be a single-key bundle.

    Return the new wallet on success.
    Return {'error': ...} on failure
    """
    
    if test_legacy and not BLOCKSTACK_TEST:
        raise Exception("Not in testing but tried to make a legacy wallet")

    # default to 2-of-3 multisig key info if data isn't given
    payment_privkey_info = virtualchain.make_multisig_wallet(2, 3) if payment_privkey_info is None and not test_legacy else payment_privkey_info
    owner_privkey_info = virtualchain.make_multisig_wallet(2, 3) if owner_privkey_info is None and not test_legacy else owner_privkey_info
    data_privkey_info = ecdsa_private_key().to_hex() if data_privkey_info is None and not test_legacy else data_privkey_info

    decrypted_wallet = {
        'owner_addresses': [virtualchain.get_privkey_address(owner_privkey_info)],
        'owner_privkey': owner_privkey_info,
        'payment_addresses': [virtualchain.get_privkey_address(payment_privkey_info)],
        'payment_privkey': payment_privkey_info,
        'data_pubkey': ecdsa_private_key(data_privkey_info).public_key().to_hex(),
        'data_pubkeys': [ecdsa_private_key(data_privkey_info).public_key().to_hex()],
        'data_privkey': data_privkey_info,
        'version': SERIES_VERSION,
    }
    
    if not test_legacy:
        jsonschema.validate(decrypted_wallet, WALLET_SCHEMA_CURRENT)

    if encrypt:
        encrypted_wallet = encrypt_wallet(decrypted_wallet, password, test_legacy=test_legacy)
        if 'error' in encrypted_wallet:
            return encrypted_wallet

        # sanity check
        try:
            jsonschema.validate(encrypted_wallet, ENCRYPTED_WALLET_SCHEMA_CURRENT)
        except ValidationError as ve:
            if test_legacy:
                # no data key is permitted 
                assert BLOCKSTACK_TEST
                jsonschema.validate(encrypted_wallet, ENCRYPTED_WALLET_SCHEMA_CURRENT_NODATAKEY)
            else:
                raise

        return encrypted_wallet

    else:
        return decrypted_wallet
コード例 #2
0
def make_wallet(password, config_path=CONFIG_PATH, payment_privkey_info=None, owner_privkey_info=None, data_privkey_info=None, test_legacy=False, encrypt=True):
    """
    Make a new, encrypted wallet structure.
    The owner and payment keys will be 2-of-3 multisig key bundles.
    The data keypair will be a single-key bundle.

    Return the new wallet on success.
    Return {'error': ...} on failure
    """
    
    if test_legacy and not BLOCKSTACK_TEST:
        raise Exception("Not in testing but tried to make a legacy wallet")

    # default to 2-of-3 multisig key info if data isn't given
    payment_privkey_info = virtualchain.make_multisig_wallet(2, 3) if payment_privkey_info is None and not test_legacy else payment_privkey_info
    owner_privkey_info = virtualchain.make_multisig_wallet(2, 3) if owner_privkey_info is None and not test_legacy else owner_privkey_info
    data_privkey_info = ecdsa_private_key().to_hex() if data_privkey_info is None and not test_legacy else data_privkey_info

    decrypted_wallet = {
        'owner_addresses': [virtualchain.get_privkey_address(owner_privkey_info)],
        'owner_privkey': owner_privkey_info,
        'payment_addresses': [virtualchain.get_privkey_address(payment_privkey_info)],
        'payment_privkey': payment_privkey_info,
        'data_pubkey': ecdsa_private_key(data_privkey_info).public_key().to_hex(),
        'data_pubkeys': [ecdsa_private_key(data_privkey_info).public_key().to_hex()],
        'data_privkey': data_privkey_info,
        'version': SERIES_VERSION,
    }
    
    if not test_legacy:
        jsonschema.validate(decrypted_wallet, WALLET_SCHEMA_CURRENT)

    if encrypt:
        encrypted_wallet = encrypt_wallet(decrypted_wallet, password, test_legacy=test_legacy)
        if 'error' in encrypted_wallet:
            return encrypted_wallet

        # sanity check
        try:
            jsonschema.validate(encrypted_wallet, ENCRYPTED_WALLET_SCHEMA_CURRENT)
        except ValidationError as ve:
            if test_legacy:
                # no data key is permitted 
                assert BLOCKSTACK_TEST
                jsonschema.validate(encrypted_wallet, ENCRYPTED_WALLET_SCHEMA_CURRENT_NODATAKEY)
            else:
                raise

        return encrypted_wallet

    else:
        return decrypted_wallet
コード例 #3
0
ファイル: wallet.py プロジェクト: testimx62/blockstack-core
def make_wallet(password,
                config_path=CONFIG_PATH,
                payment_privkey_info=None,
                owner_privkey_info=None,
                data_privkey_info=None,
                test_legacy=False,
                encrypt=True):
    """
    Make a new, encrypted wallet structure.
    The owner and payment keys will be 2-of-3 multisig key bundles.
    The data keypair will be a single-key bundle.

    Return the new wallet on success.
    Return {'error': ...} on failure
    """

    if test_legacy and not BLOCKSTACK_TEST:
        raise Exception("Not in testing but tried to make a legacy wallet")

    # default to 2-of-3 multisig key info if data isn't given
    payment_privkey_info = virtualchain.make_multisig_wallet(
        2, 3
    ) if payment_privkey_info is None and not test_legacy else payment_privkey_info
    owner_privkey_info = virtualchain.make_multisig_wallet(
        2, 3
    ) if owner_privkey_info is None and not test_legacy else owner_privkey_info
    data_privkey_info = ECPrivateKey().to_wif(
    ) if data_privkey_info is None and not test_legacy else data_privkey_info

    new_wallet = _make_encrypted_wallet_data(password,
                                             payment_privkey_info,
                                             owner_privkey_info,
                                             data_privkey_info,
                                             test_legacy=test_legacy)

    if 'error' in new_wallet:
        return new_wallet

    # sanity check
    if not test_legacy:
        jsonschema.validate(new_wallet, ENCRYPTED_WALLET_SCHEMA_CURRENT)

    if encrypt:
        return new_wallet

    # decrypt and return
    wallet_info = decrypt_wallet(new_wallet, password, config_path=config_path)
    assert 'error' not in wallet_info, "Failed to decrypt new wallet: {}".format(
        wallet_info['error'])

    return wallet_info['wallet']
コード例 #4
0
ファイル: wallet.py プロジェクト: reddink/blockstack-cli
def make_wallet(password,
                hex_privkey=None,
                payment_privkey_info=None,
                owner_privkey_info=None,
                data_privkey_info=None,
                config_path=CONFIG_PATH):
    """
    Make a wallet structure.
    By default, the owner and payment keys will be key bundles set up to require 2-of-3 signatures.
    @payment_privkey_info, @owner_privkey_info, and @data_privkey_info can either be individual private keys, or 
    dicts with {'redeem_script': ..., 'private_keys': ...} defined.

    Return the new wallet on success.
    Return {'error': ...} on failure
    """

    hex_password = hexlify(password)

    wallet = HDWallet(hex_privkey)
    if hex_privkey is None:
        hex_privkey = wallet.get_master_privkey()

    child = wallet.get_child_keypairs(count=3, include_privkey=True)

    data = {}
    encrypted_key = aes_encrypt(hex_privkey, hex_password)
    data['encrypted_master_private_key'] = encrypted_key

    multisig = False
    curr_height = get_block_height(config_path=config_path)
    if curr_height >= config.EPOCH_HEIGHT_MINIMUM:
        # safe to use multisig
        multisig = True

    # default to 2-of-3 multisig key info if data isn't given
    if payment_privkey_info is None:
        if multisig:
            payment_privkey_info = virtualchain.make_multisig_wallet(2, 3)
        else:
            payment_privkey_info = virtualchain.BitcoinPrivateKey().to_wif()

    if not is_singlesig(payment_privkey_info) and not is_multisig(
            payment_privkey_info):
        return {
            'error':
            'Payment private key info must be either a single private key or a multisig bundle'
        }

    if not multisig and is_multisig(payment_privkey_info):
        return {'error': 'Multisig payment private key info is not supported'}

    if owner_privkey_info is None:
        if multisig:
            owner_privkey_info = virtualchain.make_multisig_wallet(2, 3)
        else:
            owner_privkey_info = virtualchain.BitcoinPrivateKey().to_wif()

    if not is_singlesig(owner_privkey_info) and not is_multisig(
            owner_privkey_info):
        return {
            'error':
            'Owner private key info must be either a single private key or a multisig bundle'
        }

    if not multisig and is_multisig(owner_privkey_info):
        return {'error': 'Multisig owner private key info is not supported'}

    if data_privkey_info is None:
        # TODO: for now, this must be a single private key
        data_privkey_info = child[2][1]

    elif not is_singlesig(data_privkey_info):
        return {'error': 'Data private key info must be a single private key'}

    enc_payment_info = encrypt_private_key_info(payment_privkey_info, password)
    if 'error' in enc_payment_info:
        return {'error': enc_payment_info['error']}

    enc_owner_info = encrypt_private_key_info(owner_privkey_info, password)
    if 'error' in enc_owner_info:
        return {'error': enc_owner_info['error']}

    enc_data_info = encrypt_private_key_info(data_privkey_info, password)
    if 'error' in enc_data_info:
        return {'error': enc_data_info['error']}

    payment_addr = enc_payment_info['encrypted_private_key_info']['address']
    owner_addr = enc_owner_info['encrypted_private_key_info']['address']

    enc_payment_info = enc_payment_info['encrypted_private_key_info'][
        'private_key_info']
    enc_owner_info = enc_owner_info['encrypted_private_key_info'][
        'private_key_info']
    enc_data_info = enc_data_info['encrypted_private_key_info'][
        'private_key_info']

    data['encrypted_payment_privkey'] = enc_payment_info
    data['payment_addresses'] = [payment_addr]

    data['encrypted_owner_privkey'] = enc_owner_info
    data['owner_addresses'] = [owner_addr]

    data['encrypted_data_privkey'] = enc_data_info
    data['data_pubkeys'] = [
        virtualchain.BitcoinPrivateKey(
            data_privkey_info).public_key().to_hex()
    ]
    data['data_pubkey'] = data['data_pubkeys'][0]
    return data
コード例 #5
0
def make_wallet(password, payment_privkey_info=None, owner_privkey_info=None, data_privkey_info=None, test_legacy=False, encrypt=True, segwit=None):
    """
    Make a new, encrypted wallet structure.
    The owner and payment keys will be 2-of-3 multisig key bundles.
    The data keypair will be a single-key bundle.

    Return the new wallet on success.
    Return {'error': ...} on failure
    """

    if test_legacy and not BLOCKSTACK_TEST:
        raise Exception("Not in testing but tried to make a legacy wallet")

    if segwit is None:
        # no preference given.
        # safe to use by default post-F-day 2017 (Dec 1 2017)
        '''
        if time.time() >= 1512086400:
            segwit = True

        else:
            # defer to virtualchain
            segwit = virtualchain.get_features('segwit')
        '''
        # disable for now
        segwit = False

    # default to 2-of-3 multisig key info if data isn't given
    if segwit:
        payment_privkey_info = virtualchain.make_multisig_segwit_wallet(2,3) if payment_privkey_info is None and not test_legacy else payment_privkey_info
        owner_privkey_info = virtualchain.make_multisig_segwit_wallet(2,3) if owner_privkey_info is None and not test_legacy else owner_privkey_info

    else:
        payment_privkey_info = virtualchain.make_multisig_wallet(2,3) if payment_privkey_info is None and not test_legacy else payment_privkey_info
        owner_privkey_info = virtualchain.make_multisig_wallet(2,3) if owner_privkey_info is None and not test_legacy else owner_privkey_info

    data_privkey_info = ecdsa_private_key().to_hex() if data_privkey_info is None and not test_legacy else data_privkey_info

    decrypted_wallet = {
        'owner_addresses': [virtualchain.get_privkey_address(owner_privkey_info)],
        'owner_privkey': owner_privkey_info,
        'payment_addresses': [virtualchain.get_privkey_address(payment_privkey_info)],
        'payment_privkey': payment_privkey_info,
        'data_pubkey': ecdsa_private_key(data_privkey_info).public_key().to_hex(),
        'data_pubkeys': [ecdsa_private_key(data_privkey_info).public_key().to_hex()],
        'data_privkey': data_privkey_info,
        'version': SERIES_VERSION,
    }

    if not test_legacy:
        jsonschema.validate(decrypted_wallet, WALLET_SCHEMA_CURRENT)

    if encrypt:
        encrypted_wallet = encrypt_wallet(decrypted_wallet, password, test_legacy=test_legacy)
        if 'error' in encrypted_wallet:
            return encrypted_wallet

        # sanity check
        try:
            jsonschema.validate(encrypted_wallet, ENCRYPTED_WALLET_SCHEMA_CURRENT)
        except ValidationError as ve:
            if test_legacy:
                # no data key is permitted 
                assert BLOCKSTACK_TEST
                jsonschema.validate(encrypted_wallet, ENCRYPTED_WALLET_SCHEMA_CURRENT_NODATAKEY)
            else:
                raise

        return encrypted_wallet

    else:
        return decrypted_wallet