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()
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.account_id = generate_order_no(k=44)
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()
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