Пример #1
0
    def deploy(_deploy_data,
               _token_id,
               _exchange_contract_id,
               _creating_org_id=None):
        smart_token_result = bt.deploy_smart_token(**_deploy_data)

        address = smart_token_result['smart_token_address']
        subexchange_address = smart_token_result['subexchange_address']

        _token = Token.query.get(_token_id)
        _token.address = address

        _exchange_contract = ExchangeContract.query.get(_exchange_contract_id)
        _exchange_contract.add_token(_token, subexchange_address,
                                     reserve_ratio_ppm)

        if _creating_org_id:

            _creating_org = Organisation.query.get(_creating_org_id)
            _creating_org.bind_token(_token)
            _creating_org.org_level_transfer_account.set_balance_offset(
                int(_deploy_data['issue_amount_wei'] / 1e16))

            bal = bt.get_wallet_balance(
                _creating_org.primary_blockchain_address, _token)

            print(f'Balance is {bal}')

        db.session.commit()
Пример #2
0
def cached_funds_available(allowed_cache_age_seconds=60):
    """
    IF refreshing cash THEN:
        return: [current blockchain balance] - [all transfers with blockchain state pending or unknown]
        save to cache: [funds available], [ID of highest transfer used in cache], [cache creation datetime]
    ELSE
        return: [funds available at last cache] - [all non-failed transfers since last cache]
    Max Txn ID is a simple way to determine whether txn was used in cache or not, and thus needs to be accounted for
    :param allowed_cache_age_seconds: how long between checking the blockchain for external funds added or removed
    :return: amount of funds available
    """
    token = g.active_organisation.org_level_transfer_account.token

    balance_wei = bt.get_wallet_balance(
        g.active_organisation.org_level_transfer_account.blockchain_address,
        token)

    return token.token_amount_to_system(balance_wei)

    refresh_cache = False
    funds_available_cache = red.get('funds_available_cache')

    try:
        parsed_cache = json.loads(funds_available_cache)

        last_updated_datetime = datetime.datetime.fromtimestamp(
            float(parsed_cache['last_updated']))

        earliest_allowed = datetime.datetime.utcnow() - datetime.timedelta(
            seconds=allowed_cache_age_seconds)
        if last_updated_datetime < earliest_allowed:
            refresh_cache = True

    except Exception as e:
        refresh_cache = True

    if refresh_cache:

        master_wallet_balance = bt.get_wallet_balance()

        highest_transfer_id_checked = 0
        required_blockchain_statuses = ['PENDING', 'UNKNOWN']

    else:
        cached_funds_available = parsed_cache['cached_funds_available']
        highest_transfer_id_checked = parsed_cache[
            'highest_transfer_id_checked']
        required_blockchain_statuses = ['PENDING', 'UNKNOWN', 'COMPLETE']

    new_dibursements = (CreditTransfer.query.filter(
        CreditTransfer.transfer_type == TransferTypeEnum.PAYMENT).filter(
            CreditTransfer.transfer_subtype == TransferSubTypeEnum.DISBURSEMENT
        ).filter(CreditTransfer.transfer_status ==
                 TransferStatusEnum.COMPLETE).filter(
                     CreditTransfer.id > highest_transfer_id_checked).filter(
                         CreditTransfer.created > datetime.datetime.utcnow() -
                         datetime.timedelta(hours=36)).all())

    local_disbursement_value = 0
    for disbursement in new_dibursements:

        status = disbursement.blockchain_status

        if status in required_blockchain_statuses:
            local_disbursement_value += disbursement.transfer_amount

    if refresh_cache:

        balance = master_wallet_balance - local_disbursement_value

        if len(new_dibursements) > 0:
            highest_transfer_id_checked = new_dibursements[-1].id
        else:
            all_transfers = CreditTransfer.query.all()
            if len(all_transfers) > 0:
                highest_transfer_id_checked = all_transfers[-1].id
            else:
                highest_transfer_id_checked = 0

        cache_data = {
            'cached_funds_available': balance,
            'highest_transfer_id_checked': highest_transfer_id_checked,
            'last_updated': datetime.datetime.utcnow().timestamp()
        }

        red.set('funds_available_cache', json.dumps(cache_data))

        balance = master_wallet_balance - local_disbursement_value

        return balance

    else:

        balance = cached_funds_available - local_disbursement_value

        return balance
Пример #3
0
def deploy_cic_token(post_data, creating_org=None):

    name = post_data['name']
    symbol = post_data['symbol']
    decimals = post_data.get('decimals', 18)
    issue_amount_wei = int(post_data['issue_amount_wei'])
    reserve_deposit_wei = int(post_data['reserve_deposit_wei'])
    exchange_contract_id = post_data['exchange_contract_id']
    reserve_ratio_ppm = post_data.get('reserve_ratio_ppm', 250000)

    if creating_org:
        deploying_address = creating_org.primary_blockchain_address
    else:
        deploying_address = g.user.primary_blockchain_address


    if not exchange_contract_id:
        response_object = {
            'message': 'Must supply exchange contract id if deploying smart token contract'
        }

        return response_object, 400

    exchange_contract = ExchangeContract.query.get(exchange_contract_id)

    if not exchange_contract:
        response_object = {
            'message': 'Exchange contract not found for id {}'.format(exchange_contract_id)
        }

        return response_object, 400

    balance_wei = bt.get_wallet_balance(deploying_address, exchange_contract.reserve_token)

    if balance_wei < reserve_deposit_wei:

        load_amount = int((reserve_deposit_wei - balance_wei) / 1e16)

        master_org = Organisation.master_organisation()

        print(f'Insufficient reserve funds (balance in wei: {balance_wei}), loading')

        if master_org.org_level_transfer_account.balance < load_amount:
            response_object = {
                'message': f'Insufficient reserve funds for both deploying account  ({balance_wei} wei), '
                           f'and master ({master_org.org_level_transfer_account.balance * 1e16} wei)'
            }

            return response_object, 400

        load_task_uuid = bt.make_token_transfer(
            signing_address=master_org.primary_blockchain_address,
            token=exchange_contract.reserve_token,
            from_address=master_org.primary_blockchain_address,
            to_address=deploying_address,
            amount=load_amount
        )

        try:
            bt.await_task_success(load_task_uuid)
        except TimeoutError:
            response_object = {
                'message': f'Insufficient reserve funds (balance in wei: {balance_wei}), and could not load from master'
            }

            return response_object, 400

        master_org.org_level_transfer_account.balance -= load_amount

    token = Token(name=name, symbol=symbol, token_type=TokenType.LIQUID)
    db.session.add(token)
    db.session.flush()

    deploy_data = dict(
        deploying_address=deploying_address,
        name=name, symbol=symbol, decimals=decimals,
        reserve_deposit_wei=reserve_deposit_wei,
        issue_amount_wei=issue_amount_wei,
        contract_registry_address=exchange_contract.contract_registry_blockchain_address,
        reserve_token_address=exchange_contract.reserve_token.address,
        reserve_ratio_ppm=reserve_ratio_ppm
    )

    @copy_current_request_context
    def deploy(_deploy_data, _token_id, _exchange_contract_id, _creating_org_id=None):
        smart_token_result = bt.deploy_smart_token(**_deploy_data)

        address = smart_token_result['smart_token_address']
        subexchange_address = smart_token_result['subexchange_address']

        _token = Token.query.get(_token_id)
        _token.address = address

        _exchange_contract = ExchangeContract.query.get(_exchange_contract_id)
        _exchange_contract.add_token(_token, subexchange_address, reserve_ratio_ppm)

        if _creating_org_id:

            _creating_org = Organisation.query.get(_creating_org_id)
            _creating_org.bind_token(_token)
            _creating_org.org_level_transfer_account.balance = int(_deploy_data['issue_amount_wei'] / 1e16)

            bal = bt.get_wallet_balance(_creating_org.primary_blockchain_address, _token)

            print(f'Balance is {bal}')

        db.session.commit()

    if creating_org:
        creating_org_id = creating_org.id
    else:
        creating_org_id = None

    t = threading.Thread(target=deploy,
                         args=(deploy_data, token.id, exchange_contract_id, creating_org_id))
    t.daemon = True
    t.start()

    response_object = {
        'message': 'success',
        'data': {
            'token_id': token.id
        }
    }

    return response_object, 201