Exemple #1
0
    def gather_to_gather(self, coin_id, from_address, amount, to_address, verification_code):
        """
        归集转归集
        :param coin_id: 币种
        :param from_address: 待归集地址
        :param amount: 归集数量
        :param to_address: 收款地址
        :param verification_code: 验证码
        :return:
        """
        conf = get_config()
        env = conf["env"]
        if env == "pd":
            vcode_service = VcodeService()
            result = vcode_service.check_sms_email_vcode('common', verification_code)
        with MysqlTools().session_scope() as session:
            record_id = generate_order_no()
            foreign_gather_record = ForeignGatherRecordModel(
                record_id=record_id,
                public_address=to_address,
                purpose_amount=amount,
                gather_status=_FOUR_S
            )
            session.add(foreign_gather_record)
            gather_record_id = foreign_gather_record.record_id
            order_no = generate_order_no()
            withdraw = ForeignWithdrawOrderRecordModel(
                order_no=order_no,
                relate_flow_no=gather_record_id,
                coin_id=coin_id,
                from_address=from_address,
                withdraw_address=to_address,
                withdraw_amount=amount,
                withdraw_type=_THREE_S,
                withdraw_status=_ZERO_S,
                audit_status=_ONE_S,
                source_status=_ZERO_S,
                transfer_at=get_utc_now()
            )
            session.add(withdraw)
            session.commit()
            withdraw_order_no = withdraw.order_no
            withdraw = session.query(ForeignWithdrawOrderRecordModel).filter(
                ForeignWithdrawOrderRecordModel.order_no == order_no).first()
            wfs = WalletForeignService()
            send_result = None
            if coin_id == _ZERO_S:  # 比特币
                send_result = wfs.btc_send_tx(withdraw)
            elif coin_id == _SIXTY_S:  # 以太坊
                send_result = wfs.eth_send_tx(withdraw)

            if send_result is True:
                gather_record_model = session.query(ForeignGatherRecordModel).filter(ForeignGatherRecordModel.record_id == gather_record_id).first()
                gather_record_model.gather_status = _ONE_S
                withdraw_reocrd_model = session.query(ForeignWithdrawOrderRecordModel).filter(ForeignWithdrawOrderRecordModel.order_no == withdraw_order_no).first()
                withdraw_reocrd_model.withdraw_status = _ONE_S
                session.commit()
            return
 def __init__(self, *args, **kwargs):
     super().__init__(*args, **kwargs)
     self.account_recharge_record_id = generate_order_no()
Exemple #3
0
 def __init__(self, *args, **kwargs):
     super().__init__(*args, **kwargs)
     self.account_id = generate_order_no(k=44)
Exemple #4
0
    def operation_gather(self, user_name, sub_public_address, conditions, coin_id, to_address, verification_code):
        """
        归集操作
        :param user_name: 用户名
        :param sub_public_address: 钱包地址
        :param conditions: 归集条件(大于等于xx个单位)
        :param coin_id: 币种(必填)
        :param to_address: 归集账户
        :param verification_code: 验证码
        :return:
        """
        conf = get_config()
        env = conf["env"]
        if env == "pd":
            vcode_service = VcodeService()
            result = vcode_service.check_sms_email_vcode('common', verification_code)
        f_filters = {}
        u_filters = {}
        if user_name:
            u_filters["user_name"] = user_name
        if sub_public_address:
            f_filters["sub_public_address"] = sub_public_address
        if not conditions:
            conditions = 0
        wfs = WalletForeignService()

        with MysqlTools().session_scope() as session:
            model = None
            if coin_id == _ZERO_S:
                model = WalletBtcModel
            elif coin_id == _SIXTY_S:
                model = WalletEthModel
            # token_conf = session.query(TokenConfModel).filter(TokenConfModel.coin_id == coin_id).first()
            # gather_minimum_amount = token_conf.gather_minimum_amount
            gather_minimum_amount = wfs.eth_get_gas()

            wallet_list = session.query(model, UserAccountModel).filter(
                model.amount >= conditions, model.account_id != "").filter_by(**f_filters).outerjoin(
                UserAccountModel,
                model.account_id == UserAccountModel.account_id).filter_by(**u_filters)
            total_amount = 0
            available_wallet_list = []
            for w in wallet_list:
                amount = 0
                if coin_id == _ZERO_S:
                    amount = w.WalletBtcModel.amount
                elif coin_id == _SIXTY_S:
                    amount = w.WalletEthModel.amount
                if gather_minimum_amount < amount:
                    available_wallet_list.append(w)
                    total_amount = total_amount + amount

            record_id = generate_order_no()
            foreign_gather_record = ForeignGatherRecordModel(
                record_id=record_id,
                coin_id=coin_id,
                public_address=to_address,
                conditions=conditions,
                purpose_amount=total_amount
            )
            session.add(foreign_gather_record)
            foreign_withdraw_order_record_list = []
            wallet_list = available_wallet_list
            if coin_id == _ZERO_S:
                for wallet in wallet_list:
                    if wallet.WalletBtcModel.amount > 0:
                        foreign_withdraw_order_record = ForeignWithdrawOrderRecordModel(
                            order_no=generate_order_no(),
                            relate_flow_no=foreign_gather_record.record_id,
                            account_id=wallet.WalletBtcModel.account_id,
                            coin_id=coin_id,
                            from_address=wallet.WalletBtcModel.sub_public_address,
                            withdraw_address=to_address,
                            withdraw_amount=wallet.WalletBtcModel.amount,
                            withdraw_type=_TWO,
                            withdraw_status=_ZERO,
                            audit_status=_ONE,
                            source_status=_ONE
                        )
                        foreign_withdraw_order_record_list.append(foreign_withdraw_order_record)
            elif coin_id == _SIXTY_S:
                for wallet in wallet_list:
                    if wallet.WalletEthModel.amount > 0:
                        foreign_withdraw_order_record = ForeignWithdrawOrderRecordModel(
                            order_no=generate_order_no(),
                            relate_flow_no=foreign_gather_record.record_id,
                            account_id=wallet.WalletEthModel.account_id,
                            coin_id=coin_id,
                            from_address=wallet.WalletEthModel.sub_public_address,
                            withdraw_address=to_address,
                            withdraw_amount=wallet.WalletEthModel.amount,
                            withdraw_type=_TWO,
                            withdraw_status=_ZERO,
                            audit_status=_ONE,
                            source_status=_ONE
                        )
                        foreign_withdraw_order_record_list.append(foreign_withdraw_order_record)
            session.add_all(foreign_withdraw_order_record_list)
            session.commit()

            if coin_id == _ZERO_S:  # 比特币
                for withdraw in foreign_withdraw_order_record_list:
                    wfs.btc_send_tx(withdraw)
            elif coin_id == _SIXTY_S:  # 以太坊
                for withdraw in foreign_withdraw_order_record_list:
                    wfs.eth_send_tx(withdraw)
            return
    def process_notify_and_insert(self, account_related_trx_info_dict, account_related_trx_info_withdraw_dict):
        # tx_list_eos_model_list = []
        if not self.wallet_callback:
            self.wallet_callback = WalletCallbackService()

        with self.mysql_tool.session_scope() as session:
            # 提现手续费
            withdraw_actual_fee = 0.02
            token_conf_model = session.query(TokenConfModel).filter(TokenConfModel.coin_id == self.eos_coin_id).first()
            if token_conf_model:
                withdraw_actual_fee = token_conf_model.withdraw_fee
            # 充值
            for trx_id, trx_info in account_related_trx_info_dict.items():
                transaction_id = generate_order_no()
                sub_public_address = trx_info["address"]
                token_amount = get_decimal(trx_info["quantity"], digits=_TEN)
                do_recharge_result = ""
                wallet_eos_model = session.query(WalletEosModel).filter(WalletEosModel.sub_public_address == sub_public_address).with_for_update().first()
                wallet_eos_gather_model = session.query(WalletEosGatherModel).filter(WalletEosGatherModel.sub_public_address == self.eos_gather_address).with_for_update().first()
                if wallet_eos_model:
                    # 加钱 给 账户钱包
                    wallet_eos_model.amount += token_amount
                    wallet_eos_gather_model.amount += token_amount
                    # 通知 账户模块
                    account_id = wallet_eos_model.account_id
                    do_recharge_result = self.wallet_callback.recharge_notify_callback(account_id, token_amount, self.eos_coin_id, sub_public_address, transaction_id)
                    # 存充值记录表
                tmp_tx_list_eos_model = TxListEosModel(
                    tx_id=transaction_id,
                    tx_no=trx_id,
                    block_no=trx_info["block_num"],
                    value=token_amount,
                    address=sub_public_address,
                    sender=trx_info["sender"],
                    do_recharge_result=do_recharge_result,
                )
                session.add(tmp_tx_list_eos_model)
                session.commit()
            # 提现
            for withdraw_trx_id, withdraw_trx_info in account_related_trx_info_withdraw_dict.items():
                withdraw_actual_amount = get_decimal(withdraw_trx_info["quantity"], digits=_TEN)
                foreign_withdraw_model = session.query(ForeignWithdrawOrderRecordModel).filter(ForeignWithdrawOrderRecordModel.order_no == withdraw_trx_info["record_no"]).first()
                if foreign_withdraw_model:
                    account_id = foreign_withdraw_model.account_id
                    order_no = foreign_withdraw_model.order_no
                    req_no = foreign_withdraw_model.req_no
                    withdraw_result = self.withdraw_offline_success if withdraw_trx_info["source_status"] == _ONE_S else self.withdraw_online_success
                    # 通知
                    do_withdraw_result = self.wallet_callback.withdraw_notify_callback(req_no, order_no, withdraw_result, withdraw_actual_amount, withdraw_actual_fee)
                    # 更新提现状态
                    foreign_withdraw_model.withdraw_actual_amount = withdraw_actual_amount
                    foreign_withdraw_model.withdraw_actual_fee = withdraw_actual_fee
                    foreign_withdraw_model.withdraw_status = self.withdraw_success
                    foreign_withdraw_model.do_withdraw_result = do_withdraw_result
                    # 修改冻结金额
                    wallet_eos_model = session.query(WalletEosModel).filter(WalletEosModel.account_id == account_id).with_for_update().first()
                    wallet_eos_gather_model = session.query(WalletEosGatherModel).filter(WalletEosGatherModel.sub_public_address == self.eos_gather_address).with_for_update().first()
                    if wallet_eos_model:
                        amount_frozen = withdraw_actual_amount + withdraw_actual_fee
                        wallet_eos_model.amount_frozen -= amount_frozen
                        wallet_eos_gather_model.amount_frozen -= amount_frozen
                        wallet_eos_gather_model.amount += withdraw_actual_fee
                    else:
                        self.slog.error("withdraw not has WalletEosModel by ForeignWithdrawOrderRecordModel.account_id: " + str(account_id))
                else:
                    self.slog.error("withdraw not has ForeignWithdrawOrderRecordModel by TxListeningEosModel.record_no: " + str(withdraw_trx_info["record_no"]))

                # 更新提现记录表侦听状态
                tx_listening_eos_model = session.query(TxListeningEosModel).filter(TxListeningEosModel.order_no == withdraw_trx_info["order_no"]).first()
                if tx_listening_eos_model:
                    tx_listening_eos_model.block_no = withdraw_trx_info["block_num"]
                    tx_listening_eos_model.listen_flag = _ZERO
                    tx_listening_eos_model.memo = withdraw_trx_info["memo"]
                else:
                    self.slog.error("withdraw not has TxListeningEosModel by TxListeningEosModel.order_no: " + str(withdraw_trx_info["order_no"]))
                session.commit()
 def __init__(self, *args, **kwargs):
     super().__init__(*args, **kwargs)
     self.record_id = generate_order_no()
Exemple #7
0
    def sync_block(self, token_conf, last_net_block_num, last_local_block, address_list, gather_address_list, eth_tx_list):
        confirm_last_block_num = token_conf["confirm_last_block_num"]
        end_listen_block_num = int(last_net_block_num) - int(confirm_last_block_num)
        # 确认起始侦听区块号
        if not last_local_block:
            begin_listen_block_num = end_listen_block_num
        else:
            if end_listen_block_num <= _ZERO:
                raise Exception("last net_block_num less than confirm_last_block_num")
            last_local_block_num = last_local_block["block_no"]
            last_local_block_status = last_local_block["status"]
            begin_listen_block_num = last_local_block_num + _ONE if last_local_block_status else last_local_block_num

        for listen_num in range(begin_listen_block_num, end_listen_block_num + _ONE):
            if self.process_index is not None:
                if listen_num % self.process_count != self.process_index:
                    continue
            self.slog.info("listen block: ", str(listen_num))
            block_info = self.get_eth_block_info(listen_num)
            block_hash = block_info["hash"]
            block_number = block_info["number"]
            transactions = block_info["transactions"]
            tx_model_list = []
            multi_withdraw_record = None
            foreign_gather_record = None
            wallet_eth = None
            with MysqlTools().session_scope() as session:
                for tx in transactions:
                    # 查询交易详情
                    tx_info = self.get_eth_tx_info(tx)
                    if not tx_info:
                        continue
                    tx_info_receipt = self.get_eth_tx_info_receipt(tx)
                    # 处理 块上的交易Tx 是否碰撞 平台发起的交易Tx
                    if tx in eth_tx_list:
                        # 获取实际到账金额 和 手续费
                        listening_value_ether = get_decimal(self.w3.fromWei(tx_info["value"], self.unit) if tx_info["value"] else _ZERO_S, 18)
                        listening_gas_price_ether = get_decimal(self.w3.fromWei(int(tx_info["gasPrice"]), self.unit) if tx_info["gasPrice"] else _ZERO_S, 18)
                        listening_gas_price_used_ether = get_decimal(tx_info_receipt["gasUsed"] if tx_info_receipt["gasUsed"] else _ZERO_S, 18)
                        listening_gas_ether = listening_gas_price_ether * listening_gas_price_used_ether
                        # 如果存在 更改listening 提现侦听表 状态
                        listening_tx = self.update_wallet_eth_tx(session, tx)
                        listening_tx.listen_flag = _ZERO
                        listening_tx.block_no = block_number
                        record_no = listening_tx.record_no
                        # 改流水表 成功
                        withdraw_order_record = self.get_foreign_withdraw_order_record(session, record_no)
                        if not withdraw_order_record:
                            self.slog.error("没有找到withdraw_order_record根据listening_tx.record_no:", record_no)
                            continue
                        withdraw_order_record.withdraw_status = self.withdraw_success
                        withdraw_order_record.confirm_at = get_utc_now()

                        # 计算已花费未上块时消耗的手续费累计,如果没有一般是0
                        withdraw_consume_total_fee = get_decimal(withdraw_order_record.withdraw_consume_total_fee, 18)
                        # 计算预计冻结金额
                        amount_frozen = withdraw_order_record.withdraw_amount
                        # 计算花费完手续费剩余返还给用户的金额
                        withdraw_remain_fee = amount_frozen - listening_value_ether - listening_gas_ether - withdraw_consume_total_fee
                        # 判断 提现类型 用户提现和中奖
                        if withdraw_order_record.withdraw_type in self.account_withdraw_type_list:

                            # 获取 批量提现流水
                            if not multi_withdraw_record:
                                multi_withdraw_record = self.get_foreign_multi_withdraw_order_record(session, withdraw_order_record.relate_flow_no)

                            # 通知 账户成功
                            withdraw_result = _FOUR_S
                            do_withdraw_result = WalletCallbackService.withdraw_notify_callback(withdraw_order_record.req_no, withdraw_order_record.order_no, withdraw_result,
                                                                                                listening_value_ether, listening_gas_ether, withdraw_remain_fee)
                            # 保存 账户处理结果
                            withdraw_order_record.do_withdraw_result = do_withdraw_result

                            # 判断用户系统返回结果 "0"是正确
                            if do_withdraw_result == _ZERO_S:
                                # 加钱 提现流水 单笔
                                withdraw_order_record.withdraw_actual_amount = listening_value_ether
                                withdraw_order_record.withdraw_actual_fee = listening_gas_ether + withdraw_consume_total_fee

                                # 加钱 批量提现流水 累计
                                multi_withdraw_record.verified_amount += listening_value_ether
                                multi_withdraw_record.verified_gas += listening_gas_ether + withdraw_consume_total_fee

                                # 减钱 归集地址 冻结金额
                                wallet_eth = self.get_wallet_eth_gather(session, withdraw_order_record.from_address)
                                wallet_eth.amount_frozen -= amount_frozen
                                wallet_eth.amount += withdraw_remain_fee

                        # 判断 提现类型 普通归集和归集转归集
                        elif withdraw_order_record.withdraw_type in self.gather_withdraw_type_list:

                            # 获取 归集操作流水
                            if not foreign_gather_record:
                                foreign_gather_record = self.get_foreign_gather_record(session, withdraw_order_record.relate_flow_no)

                            # 加钱 提现流水 单笔
                            withdraw_order_record.withdraw_actual_amount = listening_value_ether
                            withdraw_order_record.withdraw_actual_fee = listening_gas_ether + withdraw_consume_total_fee

                            # 加钱 归集流水 累计
                            foreign_gather_record.actual_amount += listening_value_ether
                            foreign_gather_record.actual_fee += listening_gas_ether + withdraw_consume_total_fee

                            # 更新 归集流水 部分成功
                            foreign_gather_record.gather_status = self.withdraw_part_success

                            # 判断 普通归集
                            if withdraw_order_record.withdraw_type == _TWO_S:
                                # 获取 用户地址
                                wallet_eth = self.get_wallet_eth(session, withdraw_order_record.from_address)
                            # 判断 归集转归集
                            elif withdraw_order_record.withdraw_type == _THREE_S:
                                # 获取 归集地址
                                wallet_eth = self.get_wallet_eth_gather(session, withdraw_order_record.from_address)

                            # 减钱 相关地址 冻结金额
                            wallet_eth.amount_frozen -= amount_frozen
                            wallet_eth.amount += withdraw_remain_fee
                        else:
                            # 其他类型 暂不处理
                            pass
                        self.slog.info("listening block_number: ", str(block_number))
                        self.slog.info("listening tx: ", str(tx))
                        self.slog.info("listening amount: ", str(listening_value_ether))
                        self.slog.info("listening gas: ", str(listening_gas_ether))

                    # 处理 块上的每笔交易Tx详情 to_address 是否碰撞 平台的子钱包地址 和 归集账户的地址
                    listening_address = tx_info["to"]
                    check_address_flag = None
                    source_status = None
                    do_recharge_result = ""
                    if listening_address in address_list:
                        check_address_flag = _ZERO
                    elif listening_address in gather_address_list:
                        check_address_flag = _ONE
                    if check_address_flag is not None:
                        listening_value_ether = get_decimal(self.w3.fromWei(tx_info["value"], self.unit) if tx_info["value"] else _ZERO_S, 18)

                        # 检查 有没有记录过这个tx在tx_list_eth流水
                        tx_list_model = session.query(TxListEthModel).filter(TxListEthModel.tx_no == tx).first()
                        if not tx_list_model:
                            tx_id = generate_order_no()
                            # 更新子钱包和归集账户地址的钱
                            wallet_model = self.wallet_model_list[check_address_flag]
                            sub_wallet = session.query(wallet_model).filter(wallet_model.sub_public_address == listening_address).first()
                            if check_address_flag == _ZERO:
                                account_id = sub_wallet.account_id
                                # 通知账户加钱
                                do_recharge_result = WalletCallbackService.recharge_notify_callback(account_id, listening_value_ether, self.coin_id, listening_address, tx_id)
                                if do_recharge_result == _ZERO_S:
                                    # 更新子钱包和归集账户地址的钱
                                    sub_wallet.amount += listening_value_ether
                                source_status = _ZERO_S  # 线上用户地址充值
                            elif check_address_flag == _ONE:
                                if tx not in eth_tx_list:
                                    source_status = _ONE_S  # 线下归集账户充值
                                else:
                                    source_status = _ZERO_S  # 线上普通归集归集转归集
                                sub_wallet.amount += listening_value_ether  # 线下充值或者归集

                            # 增加tx_list记录
                            tx_model = TxListEthModel(
                                tx_id=tx_id,
                                tx_no=tx,
                                block_no=block_number,
                                value=listening_value_ether,
                                address=listening_address,
                                source_status=source_status,
                                do_recharge_result=do_recharge_result
                            )
                            tx_model_list.append(tx_model)
                        if tx not in eth_tx_list:
                            self.slog.info("recharge block_number: ", str(block_number))
                            self.slog.info("recharge tx: ", str(tx))
                            self.slog.info("recharge address: ", str(listening_address))
                            self.slog.info("recharge amount: ", str(listening_value_ether))

                if tx_model_list:
                    session.add_all(tx_model_list)
                # 更新SyncBlockModel本地同步远程节点数据块编号
                if not self.block_num_temp:
                    self.update_wallet_eth_address(session, listen_num, block_hash)

                # 提交事物
                session.commit()
        return True