コード例 #1
0
ファイル: data.py プロジェクト: paulpw/blockstack-cli
def get_immutable(name, data_hash, data_id=None, proxy=None):
    """
    get_immutable

    Fetch a piece of immutable data.  Use @data_hash to look it up
    in the user's zonefile, and then fetch and verify the data itself
    from the configured storage providers.

    Return {'data': the data, 'hash': hash} on success
    Return {'error': ...} on failure
    """

    if proxy is None:
        proxy = get_default_proxy()

    user_zonefile = get_name_zonefile(name, proxy=proxy)
    if user_zonefile is None:
        return {'error': 'No user zonefile defined'}

    if 'error' in user_zonefile:
        return user_zonefile 

    if blockstack_profiles.is_profile_in_legacy_format( user_zonefile ) or not user_db.is_user_zonefile( user_zonefile ):
        # zonefile is really a legacy profile 
        return {'error': 'Profile is in a legacy format that does not support immutable data.'}

    if data_id is not None:
        # look up hash by name 
        h = user_db.get_immutable_data_hash( user_zonefile, data_id )
        if h is None:
            return {'error': 'No such immutable datum'}
         
        if type(h) == list:
            # this tool doesn't allow this to happen (one ID matches one hash),
            # but that doesn't preclude the user from doing this with other tools.
            if data_hash is not None and data_hash not in h:
                return {'error': 'Data ID/hash mismatch'}

            else:
                return {'error': "Multiple matches for '%s': %s" % (data_id, ",".join(h))}

        if data_hash is not None:
            if h != data_hash:
                return {'error': 'Data ID/hash mismatch'}

        else:
            data_hash = h

    elif not user_db.has_immutable_data( user_zonefile, data_hash ):
        return {'error': 'No such immutable datum'}

    data_url_hint = user_db.get_immutable_data_url( user_zonefile, data_hash )
    data = storage.get_immutable_data( data_hash, fqu=name, data_id=data_id, data_url=data_url_hint )
    if data is None:
        return {'error': 'No immutable data returned'}

    return {'data': data, 'hash': data_hash}
コード例 #2
0
def delete_immutable(name, data_key, privatekey, proxy=None, txid=None):
    """
    delete_immutable
    """

    if proxy is None:
        proxy = get_default_proxy()

    result = {}
    user = get_name_record(name)
    if 'error' in user:

        # no user data
        return {'error': "Unable to load user record: %s" % user['error']}

    # does the user record have this data?
    if not user_db.has_immutable_data(user, data_key):

        # already deleted
        return {'status': True}

    # remove hash from the user record and update it
    user_db.remove_immutable_data(user, data_key)

    user_json = user_db.serialize_user(user)

    update_result = update(name, user_json, privatekey, txid=txid, proxy=proxy)
    if 'error' in update_result:

        # update failed; caller should try again
        return update_result

    txid = update_result['transaction_hash']

    # remove the data itself data
    delete_result = storage.delete_immutable_data(data_key, txid)
    if delete_result:

        result['status'] = True

    else:

        # be sure to give back the update transaction hash, so this call can be retried
        result['error'] = 'Failed to delete immutable data'

    result['transaction_hash'] = txid
    result['value_hash'] = update_result['value_hash']

    return result
コード例 #3
0
def delete_immutable(name, data_key, privatekey, proxy=None, txid=None):
    """
    delete_immutable
    """

    if proxy is None:
        proxy = get_default_proxy()

    result = {}
    user = get_name_record(name)
    if 'error' in user:

        # no user data
        return {'error': "Unable to load user record: %s" % user['error']}

    # does the user record have this data?
    if not user_db.has_immutable_data(user, data_key):

        # already deleted
        return {'status': True}

    # remove hash from the user record and update it
    user_db.remove_immutable_data(user, data_key)

    user_json = user_db.serialize_user(user)

    update_result = update(name, user_json, privatekey, txid=txid, proxy=proxy)
    if 'error' in update_result:

        # update failed; caller should try again
        return update_result

    txid = update_result['transaction_hash']

    # remove the data itself data
    delete_result = storage.delete_immutable_data(data_key, txid)
    if delete_result:

        result['status'] = True

    else:

        # be sure to give back the update transaction hash, so this call can be retried
        result['error'] = 'Failed to delete immutable data'

    result['transaction_hash'] = txid
    result['value_hash'] = update_result['value_hash']

    return result
コード例 #4
0
def get_immutable(name, data_key):
    """
    get_immutable
    """

    user = get_name_record(name)
    if 'error' in user:

        # no user data
        return {'error': "Unable to load user record: %s" % user['error']}

    if not user_db.has_immutable_data(user, data_key):

        # no data
        return {'error': 'Profile has no such immutable data'}

    data = storage.get_immutable_data(data_key)
    if data is None:

        # no data
        return {'error': 'No immutable data found'}

    return {'data': data}
コード例 #5
0
def get_immutable(name, data_key):
    """
    get_immutable
    """

    user = get_name_record(name)
    if 'error' in user:

        # no user data
        return {'error': "Unable to load user record: %s" % user['error']}

    if not user_db.has_immutable_data(user, data_key):

        # no data
        return {'error': 'Profile has no such immutable data'}

    data = storage.get_immutable_data(data_key)
    if data is None:

        # no data
        return {'error': 'No immutable data found'}

    return {'data': data}
コード例 #6
0
ファイル: data.py プロジェクト: paulpw/blockstack-cli
def delete_immutable(name, data_key, data_id=None, proxy=None, txid=None, wallet_keys=None):
    """
    delete_immutable

    Remove an immutable datum from a name's profile, given by @data_key.
    Return a dict with {'status': True} on success
    Return a dict with {'error': ...} on failure
    """

    from backend.nameops import do_update

    if proxy is None:
        proxy = get_default_proxy()

    legacy = False
    user_zonefile = get_name_zonefile( name, proxy=proxy, include_name_record=True )
    if user_zonefile is None or 'error' in user_zonefile:
        if user_zonefile is None:
            return {'error': 'No user zonefile'}
        else:
            return user_zonefile

    name_record = user_zonefile['name_record']
    del user_zonefile['name_record']

    if blockstack_profiles.is_profile_in_legacy_format( user_zonefile ) or not user_db.is_user_zonefile( user_zonefile ):
        # zonefile is a legacy profile.  There is no immutable data 
        log.info("Profile is in legacy format.  No immutable data.")
        return {'status': True}

    if data_key is None:
        if data_id is not None:
            # look up the key (or list of keys)
            # shouldn't be a list--this tool prevents that--but deal with it nevertheless
            data_key = user_db.get_immutable_data_hash( user_zonefile, data_id )
            if type(data_key) == list:
                return {'error': "Multiple hashes for '%s': %s" % (data_id, ",".join(data_key)) }

            if data_key is None:
                return {'error': "No hash for '%s'" % data_id}

        else:
            return {'error': 'No data hash or data ID given'}

    # already deleted?
    if not user_db.has_immutable_data( user_zonefile, data_key ):
        return {'status': True}

    # remove 
    user_db.remove_immutable_data_zonefile( user_zonefile, data_key )

    zonefile_hash = hash_zonefile( user_zonefile )
    
    if txid is None:
        # actually send the transaction
        _, payment_privkey = get_payment_keypair(wallet_keys=wallet_keys, config_path=proxy.conf['path'])
        _, owner_privkey = get_owner_keypair(wallet_keys=wallet_keys, config_path=proxy.conf['path'])
        utxo_client = get_utxo_provider_client( config_path=proxy.conf['path'] )
        broadcaster_client = get_tx_broadcaster( config_path=proxy.conf['path'] )

        update_result = do_update( name, zonefile_hash, owner_privkey, payment_privkey, utxo_client, broadcaster_client, config_path=proxy.conf['path'], proxy=proxy )
        if 'error' in update_result:
            # failed to remove from zonefile 
            return update_result 

        txid = update_result['transaction_hash']

    result = {
        'zonefile_hash': zonefile_hash,
        'transaction_hash': txid
    }
    
    # put new zonefile 
    rc = store_name_zonefile( name, user_zonefile, txid )
    if not rc:
        result['error'] = 'Failed to put new zonefile'
        return result

    # delete immutable data 
    data_privkey = get_data_or_owner_privkey( user_zonefile, name_record['address'], wallet_keys=wallet_keys, config_path=proxy.conf['path'] )
    if 'error' in data_privkey:
        return {'error': data_privkey['error']}
    else:
        data_privkey = data_privkey['privatekey']
        assert data_privkey is not None

    rc = storage.delete_immutable_data( data_key, txid, data_privkey )
    if not rc:
        result['error'] = 'Failed to delete immutable data'
        return result

    else:
        result['status'] = True
        return result