def withdraw(period): # 用户bingo以往的,场景:用户提交标记号码,中奖了,可能没有及时bingo sender = GetTxSender() grade_list = query_user_grade(sender, period) # 用户标记的号码 if len(grade_list) == 0: raise Exception("用户该期没有标记过号码") if query_period_bingo_status(period): raise Exception("当期已经有人中奖了,无法 BINGO, 请等待当期结束,下次手速快点哦!") user_table = query_user_table_generation(sender, period) if len(user_table) == 0: raise Exception("当期没有购买卡单") if not draw_rules(sender, period): raise Exception("当期没有中奖") bingo_key = concat(KEY_GAME_BINGO_STATUS, period) Put(bingo_key, True) # 将当期改为 bingo 为 true 的状态 multiple_key = concat(concat(KEY_MULTIPLE, sender), period) # 用户该期的倍数 multiple = Get(multiple_key) amount = multiple * 10000 * GARD_FACTOR withdraw_amount_key = concat(KEY_USER_WITHDRAWS_AMOUNT, sender) withdraw_user_amount = query_user_withdraw_amount(sender) # 查询用户兑奖的奖励 if not withdraw_user_amount: Put(withdraw_amount_key, amount) else: withdraw_user_amount = withdraw_user_amount + amount Put(withdraw_amount_key, withdraw_user_amount) # Put 用户兑奖的奖励 ContractBalanceSend(sender, GARD_DENOM, amount) # 给用户转账 return True
def bingo(call): # 用户中奖按兑奖 bingo sender = GetTxSender() now_period = issue() # 当期 user_table = query_user_table_generation(sender, now_period) add_user_grade(call) if len(user_table) == 0: raise Exception("当期没有购买卡单") if query_period_bingo_status(now_period): raise Exception("当期已经有人中奖了,无法 BINGO, 请等待当期结束,下次手速快点哦!") if not draw_rules(sender, now_period): raise Exception("当期没有中奖") bingo_key = concat(KEY_GAME_BINGO_STATUS, now_period) Put(bingo_key, True) # 将当期改为 bingo 为 true 的状态 multiple_key = concat(concat(KEY_MULTIPLE, sender), now_period) # 用户该期的倍数 multiple = Get(multiple_key) amount = multiple * 10000 * GARD_FACTOR withdraw_amount_key = concat(KEY_USER_WITHDRAWS_AMOUNT, sender) withdraw_user_amount = query_user_withdraw_amount(sender) # 查询用户兑奖的奖励 if not withdraw_user_amount: Put(withdraw_amount_key, amount) else: withdraw_user_amount = withdraw_user_amount + amount Put(withdraw_amount_key, withdraw_user_amount) # Put 用户兑奖的奖励 ContractBalanceSend(sender, GARD_DENOM, amount) # 给用户转钱 return True
def withdraw_stake_pool(amount): # 取回用户奖池额度 if GetTxSender() != Get(KEY_OWNER): raise Exception("请使用合约 owner 地址调用") if amount < 0: raise Exception("请输入正确的金额") balance_amount = stakepool() - amount if balance_amount < 0: raise Exception("系统奖池余额不足") ContractBalanceSend(Get(KEY_OWNER), GARD_DENOM, amount) Put(KEY_STAKE_POOL, balance_amount) return True
def withdraw_system_pool(amount): # 取回系统奖池额度 if GetTxSender() != Get(KEY_OWNER): raise Exception("请使用合约 owner 地址调用") if amount < 0: raise Exception("请输入正确的金额") balance_amount = syspool() - amount if balance_amount < 0: raise Exception("系统奖池余额不足") ContractBalanceSend(Get(KEY_OWNER), GARD_DENOM, amount) key = concat(KEY_SYSTEM_POOL, ContractAccAddressGet()) Put(key, balance_amount) return True
def withdraw(): # 取出奖励 sender = GetTxSender() save_period = query_user_save_period(sender) # 查询用户标记的期数 save_period_length = len(save_period) if save_period_length == 0: raise Exception("当期没有标记,无法兑奖") amount = 0 for i in range(save_period_length): amount = (i + 1) * 100 * GARD_FACTOR + amount add_user_period_withdraw_amount(sender, save_period[i], (i + 1) * 100 * GARD_FACTOR) add_user_withdraw_amount(sender, amount) ContractBalanceSend(sender, GARD_DENOM, amount) sys_amount = syspool() - amount Put(KEY_SYSTEM_POOL, sys_amount) # 更新系统奖池 save_period_key = concat(KEY_SAVE_PERIOD, sender) PutArray(save_period_key, []) # 把用户保存的表清空 return True
def redeem(amount): # 赎回,取出存款 sender = GetTxSender() box_deposit_amount = query_deposit_amount() # 查询盒子的总存款 user_deposit_amount = query_user_deposit_amount(sender) # 查询该用户的存款 user_deposit_key = concat(KEY_USER_DEPOSIT_AMOUNT, sender) box_stauts = query_box_status() if box_stauts != BOX_FAILED and box_stauts != DEPOSIT_STATUS: raise Exception("当前无法取出存款") if not user_deposit_amount or user_deposit_amount == 0: raise Exception("没有存款,无法取出") if amount > user_deposit_amount: raise Exception("剩余存款额度不足取出") Put(KEY_BOX_DEPOSIT_AMOUNT, box_deposit_amount - amount) # 提交新的剩余存款额度 Put(user_deposit_key, user_deposit_amount - amount) # 提交新的用户存款额度 ContractBalanceSend(sender, GARD_DENOM, amount) # 给其转账 return True
def interest_withdraw(amount): # 利息取回 sender = GetTxSender() user_interest_amount = query_user_inject_interest(sender) # 用户对盒子注入的利息 interest_balance = query_interest_balance() # 盒子总利息 user_inject_key = concat(KEY_USER_INJECT_INTEREST, sender) if not user_interest_amount or user_interest_amount == 0: raise Exception("没有存入利息") box_stauts = query_box_status() if box_stauts != BOX_FAILED and box_stauts != ISSUE_STATUS: raise Exception("当前盒子状态无法取回注入利息") if amount > user_interest_amount: raise Exception("取出金额大于注入的利息") Put(user_inject_key, user_interest_amount - amount) # 更改用户的利息 Put(KEY_BOX_INTEREST, interest_balance - amount) ContractBalanceSend(sender, GARD_DENOM, amount) # 给其转入取出的利息 return True
def withdraw(): # 取出存款和利润 sender = GetTxSender() box_status = query_box_status() if box_status != BOX_END: raise Exception("当前无法取出本金和利息") user_deposit_amount = query_user_deposit_amount(sender) if not user_deposit_amount or user_deposit_amount == 0: raise Exception("当前用户没有存款") if query_user_profit(sender) > 0: raise Exception("已经取出") box_interest = query_interest_balance() user_profit = user_deposit_amount * box_interest / BOX_CEILING # 用户占利息的几成 user_receive_key = concat(KEY_USER_RECEIVE, sender) Put(user_receive_key, user_profit) # 更新用户利息获得 ContractBalanceSend(sender, GARD_DENOM, user_deposit_amount + user_profit) # 给用户转入存款和获得的利息 return True
def withdraw(period): # 兑奖 sender = GetTxSender() amount = query_user_if_prize(sender, period) if amount <= 0: raise Exception("用户没有中奖") withdraw_amount = query_user_withdraw_issue(sender, period) if withdraw_amount > 0: raise Exception("用户已经兑过奖") withdraw_user_amount = query_user_withdraw(sender) user_withdraw_key = concat(KEY_USER_WITHDRAW, sender) if not withdraw_user_amount: Put(user_withdraw_key, amount) else: withdraw_user_amount = withdraw_user_amount + amount Put(user_withdraw_key, withdraw_user_amount) # Put 用户总共获得奖励 user_withdraw_period_key = concat(concat(KEY_USER_WITHDRAW, sender), period) Put(user_withdraw_period_key, amount) # Put 用户该期获得的奖励 sys_amount = syspool() - amount Put(KEY_SYSTEM_POOL, sys_amount) # 更新系统奖池 withdraw_info_key = concat(KEY_GAME_WITHDRAW_INFO, period) withdraw_list_info = query_withdraw_info(period) withdraw_ls = [] if len(withdraw_list_info) > 0: for i in range(len(withdraw_list_info)): withdraw_ls.append(withdraw_list_info[i]) withdraw_ls.append(sender) PutArray(withdraw_info_key, withdraw_ls) # 提交该期的总共兑奖人 ContractBalanceSend(sender, GARD_DENOM, amount) # 给用户转钱 return True
def withdraw(draws): # 根据期数兑奖 sender = GetTxSender() now_draws = Get(KEY_NUMBER_DRAWS) # 当前期数 time = GetTime() # 当前时间 last_number = GetArray(KEY_LAST_NUMBER_DRAWS) if query_user_withdraw_status(draws, sender): raise Exception("当期已经兑过奖") if len(last_number) == 0: raise Exception("当前期还无法兑奖") last_draws_time = int(last_number[1]) # 最后一期时间 if int(draws) >= int(now_draws): raise Exception("当前期无法兑奖") if len(query_users_number(sender, draws)) == 0: raise Exception("当前期数没有投注") if time - last_draws_time >= 60 * 60 * 24 * 1: # 计算是否超过一天 raise Exception("当前已经超过一天未兑奖,无法兑现") amount_award_list = query_amount_award(draws) # 查询每一期的中奖额度信息 lottery_sys_pool = int(amount_award_list[0]) # 开奖时的系统池额度 lottery_users_pool = int(amount_award_list[1]) # 开奖时的用户池额度 fist_pool_amount = int(amount_award_list[2]) # 开奖时候的一等奖额度 second_pool_amount = int(amount_award_list[3]) # 开奖时候的二等奖额度 thrid_pool_amount = int(amount_award_list[4]) # 开奖时候的三等奖额度 numbers = query_users_number(sender, draws) # 用户投注的所有号码 withdraws_all_amount = 0 # 应该获取到的所有奖金额度 user_pool_amount = 0 # 应该要减去的用户奖池额度 sys_pool_amount = 0 # 应该要减去的系统奖池额度 fist_withdraws_amount = 0 # 用户兑奖的一等奖额度 second_withdraws_amount = 0 # 用户兑奖的二等奖额度 thrid_withdraws_amount = 0 # 用户兑奖的三等奖额度 for num in numbers: # 遍历所有号码 if first_prize_match(draws, num): fist_amount = query_users_number_amount(sender, draws, num) withdraws_fist_amount = fist_amount * lottery_users_pool / 10 * 4 / fist_pool_amount + lottery_sys_pool / 1000 user_pool_amount = user_pool_amount + fist_amount * lottery_users_pool / 10 * 4 / fist_pool_amount sys_pool_amount = sys_pool_amount + lottery_sys_pool / 1000 withdraws_all_amount = withdraws_all_amount + withdraws_fist_amount fist_withdraws_amount = fist_withdraws_amount + withdraws_fist_amount continue if second_prize_match(draws, num): second_amount = query_users_number_amount(sender, draws, num) withdraw_second_amount = second_amount * lottery_users_pool / 10 * 2 / second_pool_amount withdraws_all_amount = withdraws_all_amount + withdraw_second_amount user_pool_amount = user_pool_amount + withdraw_second_amount second_withdraws_amount = second_withdraws_amount + withdraw_second_amount continue if thrid_prize_match(draws, num): thrid_amount = query_users_number_amount(sender, draws, num) withdraws_thrid_amount = thrid_amount * lottery_users_pool / 10 * 1 / thrid_pool_amount withdraws_all_amount = withdraws_all_amount + withdraws_thrid_amount user_pool_amount = user_pool_amount + withdraws_thrid_amount thrid_withdraws_amount = thrid_withdraws_amount + withdraws_thrid_amount continue if withdraws_all_amount > 0: # 如果中奖则给其转账,并判断邀请逻辑 inviter_address = query_my_inviter(sender) # 上级地址 event_pool = ppool() # 查询活动奖池额度 sys_pool = syspool() # 查询系统奖池额度 user_pool = stakepool() # 查询活动奖池 if inviter_address and event_pool > 0: # 如果存在邀请者,并或活动奖池大于0 rd = int(GetRand(1)) # 随机字符串 pted_event_amount = event_pool / 1000 + event_pool * rd / 1000 # 分配随机 0.1% 到 1% 不等 sr_key = concat(KEY_SHARED_REWARD, sender) # 被邀请的被推广奖励 sender_reward_list = GetArray(sr_key) if len(sender_reward_list) == 0: PutArray(sr_key, [str(0), str(pted_event_amount)]) else: promotion_amount = sender_reward_list[0] # 推广奖励 promoted_amount = int(sender_reward_list[1]) # 被推广奖励 PutArray(sr_key, [ promotion_amount, str(promoted_amount + pted_event_amount) ]) # 提交自己的被推广奖励 rd = int(GetRand(1)) # 随机字符串 pro_event_amount = event_pool / 1000 + event_pool * rd / 1000 # 分配随机 0.1% 到 1% 不等 sr_key = concat(KEY_SHARED_REWARD, inviter_address) # 推广者的推广奖励 invited_reward_list = GetArray(sr_key) # 邀请者 if len(invited_reward_list) == 0: PutArray(sr_key, [str(pro_event_amount), str(0)]) else: promotion_amount = int(invited_reward_list[0]) # 推广奖励 promoted_amount = invited_reward_list[1] # 被推广奖励 PutArray(sr_key, [ str(promotion_amount + pro_event_amount), promoted_amount ]) # 提交推广者的推广奖励 ContractBalanceSend(sender, GARD_DENOM, pted_event_amount) # 给投注人转入被邀请奖励 ContractBalanceSend(inviter_address, GARD_DENOM, pro_event_amount) # 给邀请人转推广奖励 now_event_pool = event_pool - pted_event_amount - pro_event_amount Put(KEY_EVENT_POOL, now_event_pool) # 更新活动奖池额度 issue_account = query_issue_account() # 查询总的中奖额度信息 withdraw_account = query_withdraw_account(draws) # 查询该兑奖期的兑奖额度信息 withdraw_account_key = concat(KEY_ISSUE_ACCOUNT, draws) if len(issue_account) != 0: old_fist = int(issue_account[0]) old_second = int(issue_account[1]) old_thrid = int(issue_account[2]) PutArray(KEY_ISSUE_ACCOUNT, [ str(old_fist + fist_withdraws_amount), str(old_second + second_withdraws_amount), str(old_thrid + thrid_withdraws_amount) ]) # 提交总的中奖额度信息 else: PutArray(KEY_ISSUE_ACCOUNT, [ str(fist_withdraws_amount), str(second_withdraws_amount), str(thrid_withdraws_amount) ]) # 提交总的中奖额度信息 if len(withdraw_account) != 0: old_withdraws_fist = int(withdraw_account[0]) old_withdraws_second = int(withdraw_account[1]) old_withdraws_thrid = int(withdraw_account[2]) PutArray(withdraw_account_key, [ str(old_withdraws_fist + fist_withdraws_amount), str(old_withdraws_second + second_withdraws_amount), str(old_withdraws_thrid + thrid_withdraws_amount) ]) # 提交指定期的兑奖额度信息 else: PutArray(withdraw_account_key, [ str(fist_withdraws_amount), str(second_withdraws_amount), str(thrid_withdraws_amount) ]) # 提交指定期的兑奖额度信息 Put(KEY_USER_POOL, user_pool - user_pool_amount) # 提交用户奖池 Put(KEY_SYSTEM_POOL, sys_pool - sys_pool_amount) # 提交系统奖池额度 stake_count_key = concat(KEY_MY_STAKE_COUNT, sender) # 我的投注统计,包括投注的总 token,和获取奖励的总 token count_value = GetArray(stake_count_key) betting_amount = count_value[0] # 总共投注 reward_amount = int(count_value[1]) # 获得奖励 PutArray(stake_count_key, [betting_amount, str(reward_amount + withdraws_all_amount)]) # 提交自己投注记录 key = concat(concat(KEY_REDEMPTION_USER, draws), sender) # 兑奖信息 PutArray(key, [str(time), str(withdraws_all_amount)]) # 提交用户的兑奖信息 withdraw_status_key = concat(concat(KEY_WITZHDRAWS_STATUS, draws), sender) Put(withdraw_status_key, True) # 将用户此期的兑奖状态改成true ContractBalanceSend(sender, GARD_DENOM, withdraws_all_amount) # 给投注人转入获取的奖励 return True else: raise Exception("当前投注没有中奖")
def draw(): # 开奖 if not if_lottery(): raise Exception("当前期数还在进行时") draws = Get(KEY_NUMBER_DRAWS) # 当前期数 sender = GetTxSender() if BalanceOf(sender, [GARD_DENOM])[0] <= 0: raise Exception("当前账户没有持有 GARD,无法开奖") sys_pool = syspool() # 当前的系统奖池额度 now_users_pool = stakepool() # 当前用户池额度 now_time = GetTime() # 获取当前时间 prize_number = GetRand(3) # 生成中奖号码 prize_key = concat(KEY_PRIZE_NUMBER, draws) Put(prize_key, prize_number) # 记录每一期的中奖号码 rand_amount = int(GetRand(4)) # 生成随机开奖奖励 amount lettry_amount = rand_amount * GARD_FACTOR draws_lettry_key = concat(KEY_LOTTERY_USER, draws) PutArray(draws_lettry_key, [sender, str(now_time), str(lettry_amount)]) # 增加开奖人记录 now_users_pool = now_users_pool - lettry_amount Put(KEY_USER_POOL, now_users_pool) # 先从用户奖池扣除这一部分开奖奖金 # 算出当前中奖人数有多少个 note_key = concat(draws, KEY_CALUCLATION_NOTE) note_num = Get(note_key) # 当期有多少个投注数, 返回是个int fist_amount = 0 # 第一名的总额度 second_amount = 0 # 二等奖中奖总token额度 thrid_amount = 0 # 三等奖中奖总token额度 for i in range(1, note_num + 1): betting_info = query_bets_note(draws, str(i)) number = betting_info[2] if first_prize_match(draws, number): fist_amount = int(betting_info[3]) + fist_amount continue if second_prize_match(draws, number): second_amount = int(betting_info[3]) + second_amount continue if thrid_prize_match(draws, number): thrid_amount = int(betting_info[3]) + thrid_amount continue award_key = concat(draws, KEY_AMOUNT_EACH_AWARD) # 中奖额度信息 PutArray(award_key, [ str(sys_pool), str(now_users_pool), str(fist_amount), str(second_amount), str(thrid_amount) ]) # 记录每一期的中奖额度信息 PutArray(KEY_LAST_NUMBER_DRAWS, [draws, str(now_time)]) # 最后一期期数和期数结束时间 draws = get_period_generation() Put(KEY_NUMBER_DRAWS, draws) # 期数变更 key = concat(draws, KEY_DRAWS_PID) now_pid = get_pid() Put(key, now_pid) # 更改这期的pid draws_time_key = concat(draws, KEY_PERIODS_TIME) Put(draws_time_key, now_time) # 当前期号对应的时间戳 all_periods = query_periods_list() list = [] for i in range(len(all_periods)): list.append(all_periods[i]) if len(list) == 24: list = list[1:] list.append(draws) PutArray(KEY_PERIODS_LIST, list) # 所有列表 24 个 ContractBalanceSend(sender, GARD_DENOM, lettry_amount) # 给开奖人奖金 return True