def query_users_number_amount(sender_address, rd, number): # 根据该地址对应期数的用户投注号码,查询该号码的投注金额 if not IsValid(sender_address): raise Exception("Incorrect address format.") amount_key = concat(concat(concat(rd, KEY_BETTING_AMOUNT), number), sender_address) return Get(amount_key)
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 draw_number(): # 开奖号码生成 number = [] for i in range(1, 7): number.append(i) result = [] rd = GetRand(3) for i in range(len(rd)): index = int(rd[i]) % len(number) result.append(str(number[index])) res = concat(concat(result[0], result[1]), result[2]) return res # 返回一个字符串
def get_period_generation(): # 期数生成器 now_time = GetTime() now_time = TimeFormat(now_time) # 格式 2019-09-25 17:15:30 time = split(now_time, " ") # 分成两个元素 time_01 = time[0] # 年月日 time_02 = time[1] # 分时秒 time_01 = split(time_01, "-") time_02 = split(time_02, ":") a = join("", time_01) b = concat(concat(time_02[0], time_02[1]), time_02[2]) period = concat(a, b) # 拼接 return period
def invitation_code_generation(): # 邀请码生成 sender = GetTxSender() # 获取当前操作人 for i in range(5, len(sender)): invitation_code = concat(concat(sender[i], sender[i + 1]), concat(sender[i + 2], sender[i + 3])) if query_invitation_code_user(invitation_code): # 判断该邀请码是否已经有归属地址 continue else: key = concat(KEY_INVITATION_CODE, sender) Put(key, invitation_code) # 提交用户的邀请码信息 key = concat(KEY_INVITATION_CODE, invitation_code) Put(key, sender) # 提交邀请码对应的人的信息 break return True
def add_user_grade(call): # 添加用户标记的号码 sender = GetTxSender() now_period = issue() # 当期期号 numbers = split(call, "-") # 用户传进来的号码 numbers.append("$") user_ls = query_user_table_generation(sender, now_period) # 查询用户购买的表单 for i in range(len(numbers)): if not elt_in(user_ls, numbers[i]): raise Exception("用户标记的号码,不在自身购买表单中") garde_key = concat(concat(KEY_USER_GRADE, sender), now_period) PutArray(garde_key, numbers) # 提交用户标记的号码 return True
def init(): if Get(KEY_OWNER): return False now_time = GetTime() Put(KEY_OWNER, OWNER) # 添加owner 地址 Put(KEY_NUMBER_DRAWS, get_period_generation()) # 当前期数 ,格式:20190925 draws_time_key = concat(Get(KEY_NUMBER_DRAWS), KEY_PERIODS_TIME) Put(draws_time_key, now_time) # 当前期号对应的时间戳 note_key = concat(Get(KEY_NUMBER_DRAWS), KEY_CALUCLATION_NOTE) Put(note_key, 0) # 投注数 key = concat(Get(KEY_NUMBER_DRAWS), KEY_DRAWS_PID) Put(key, get_pid()) # 初始期数的pid PutArray(KEY_PERIODS_LIST, [Get(KEY_NUMBER_DRAWS)]) # 存放一天内的期号列表 return True
def stake(game_type, operation_type): # 用户购买 sender = GetTxSender() user_list = emoji_random() # 随机表情列表 period = get_period_generation() # 当期期号 if query_user_time_condition(sender): # 查询是否过去5秒 stake_info_key = concat(concat(KEY_USER_STAKE_INFO, sender), period) PutArray(stake_info_key, user_list) # Put 用户购买后产生的列表 # Put 用户的投注列表,最多保持24个记录 stake_list = query_user_stake_list(sender) stake_list_key = concat(KEY_USER_STAKE_LIST, sender) if len(stake_list) == 0: PutArray(stake_list_key, [period]) if len(stake_list) == 24: new_stake_list = [] for i in range(len(stake_list)): if i != len(stake_list) - 1: new_stake_list.append(stake_list[i + 1]) new_stake_list.append(period) PutArray(stake_list_key, new_stake_list) else: new_stake_list = [] for i in range(len(stake_list)): new_stake_list.append(stake_list[i]) new_stake_list.append(period) PutArray(stake_list_key, new_stake_list) period_type_key = concat(concat(KEY_USER_PERIOD_TYPE, sender), period) Put(period_type_key, game_type) # Put 用户当期期数的类型,即表情包 amount = 200 * GARD_FACTOR if BalanceOf(sender, [GARD_DENOM])[0] < amount: raise Exception("余额不足") inject_stake_pool(amount) # 给合约地址转钱 add_user_stake_amount(sender, amount) # 加入自己的消费额中 time = GetTime() period_time_key = concat(concat(KEY_USER_PERIOD_TIME, sender), period) Put(period_time_key, time) # Put 用户期数的时间戳 save_period_key = concat(KEY_SAVE_PERIOD, sender) if operation_type == 1: # 1为 直接stake save_period_key = concat(KEY_SAVE_PERIOD, sender) PutArray(save_period_key, []) # 把用户保存的表清空 if operation_type != 1: # 0 为继续 save_period_list = GetArray(save_period_key) # 查询用户保存的期号列表 if len(save_period_list) == 0: raise Exception("当期不是继续的场景") return True else: raise Exception("请等待时间")
def deposit(amount): # 存款 sender = GetTxSender() if BalanceOf(sender, [GARD_DENOM])[0] <= amount: raise Exception("余额不足") if amount % BOX_PRICE != 0: raise Exception("存款必须是最少所存量的倍数") if query_box_status() != DEPOSIT_STATUS: raise Exception("当前不处于存款吸纳期,无法存款") if amount > BOX_CEILING: raise Exception("大于最大允许的存款量") deposit_amount = query_deposit_amount() # 盒子存款总量 if not deposit_amount: Put(KEY_BOX_DEPOSIT_AMOUNT, amount) else: sub = BOX_CEILING - deposit_amount if amount > sub: raise Exception("超过可存入的最大存款数") else: Put(KEY_BOX_DEPOSIT_AMOUNT, deposit_amount + amount) # 提交存款盒子总量 user_deposit_amount = query_user_deposit_amount(sender) user_deposit_key = concat(KEY_USER_DEPOSIT_AMOUNT, sender) if not user_deposit_amount: Put(user_deposit_key, amount) else: Put(user_deposit_key, user_deposit_amount + amount) # 提交用户的的存款量 ContractBalanceInject(sender, GARD_DENOM, amount) # 给盒子转账 return True
def interest_injection(amount): # 利息注入 sender = GetTxSender() interest_balance = query_interest_balance() # 查询盒子注入利息 user_interest_amount = query_user_inject_interest(sender) # 用户对盒子注入的利息 user_inject_key = concat(KEY_USER_INJECT_INTEREST, sender) if BalanceOf(sender, [GARD_DENOM])[0] <= amount: raise Exception("余额不足") if query_box_status() != ISSUE_STATUS: raise Exception("当前不处于发行期") if amount > BOX_INTEREST: raise Exception("大于最大应存利息数") if not interest_balance: Put(KEY_BOX_INTEREST, amount) # 记录利息 else: sub = BOX_INTEREST - interest_balance if amount > sub: raise Exception("超过可存入的利息总额") else: Put(KEY_BOX_INTEREST, interest_balance + amount) if not user_interest_amount: # 提交用户注入利息 Put(user_inject_key, amount) else: Put(user_inject_key, user_interest_amount + amount) ContractBalanceInject(sender, GARD_DENOM, amount) # 转账利息到合约地址 return True
def add_user_stake_amount(sender, amount): key = concat(KEY_USER_STAKE_AMOUNT, sender) stake_amount = Get(key) if not stake_amount: Put(key, amount) else: stake_amount = stake_amount + amount Put(key, stake_amount)
def if_update_period(): # 判断是否过去了五分钟 now_period = Get(KEY_GAME_PERIOD) # 当前期号 pid_key = concat(KEY_GAME_PID, now_period) now_period_pid = Get(pid_key) # 当前期号的 pid now_pid = get_peroid_pid() # 当前 pid if now_pid > now_period_pid: # 判断是否过去了五分钟 return True return False
def add_user_withdraw_amount(address, amount): key = concat(KEY_USER_WITHDRAW_AMOUNT, address) withdraw_amount = Get(key) if not withdraw_amount: Put(key, amount) else: withdraw_amount = withdraw_amount + amount Put(key, withdraw_amount)
def if_lottery(): # 判断是否可以开奖 rd = Get(KEY_NUMBER_DRAWS) # 当前期 note_key = concat(rd, KEY_CALUCLATION_NOTE) # 这一期的的投注次数 notes = Get(note_key) pid = get_pid() # 当前的pid if notes > 0 and pid > query_draws_pid(): # 判断当前期数的pid 是不是还未动,因为pid是个递增的 并且判断当前是否有人投注 return True return False
def init(): if Get(KEY_OWNER): raise Exception("已经初始化过") time = GetTime() Put(KEY_OWNER, OWNER) # Put 合约的 owenr now_period = get_period_generation() Put(KEY_GAME_PERIOD, now_period) # Put 最开始的期号 time_key = concat(KEY_GAME_TIME, now_period) Put(time_key, time) # Put 最开始的期号时间戳 period_ls = [now_period] PutArray(KEY_GAME_LIST, period_ls) # Put 期数列表
def box_transfer(to_address): # 存款盒子凭证交易 if not IsValid(to_address): raise Exception("请填写正确的地址") sender = GetTxSender() if not transfer_on(): raise Exception("不允许存款凭证交易") box_status = query_box_status() if box_status != LOCK_STATUS: raise Exception("当前不允许交易存款凭证") sender_deposit_amount = query_user_deposit_amount(sender) # 用户的存款 if not sender_deposit_amount or sender_deposit_amount == 0: raise Exception("当前用户没有存款,无法转让") sender_deposit_key = concat(KEY_USER_DEPOSIT_AMOUNT, sender) # 转让人 to_address_deposit_key = concat(KEY_USER_DEPOSIT_AMOUNT, to_address) # 接收人 Put(sender_deposit_key, 0) # 提交转让人的额度变成 0 Put(to_address_deposit_key, sender_deposit_amount) # 提交接收人的额度 return True
def get_periods_exceeds(address, rd): # 返回一个一天内的投注列表 stake_all_key = concat(KEY_MY_ALL_STAKE, address) # 我所有的投注期号记录,只记录三天以内的 stake_all_value = GetArray(stake_all_key) # 期数列表 now_time = GetTime() list = [] for i in range(len(stake_all_value)): time = query_periods_time(stake_all_value[i]) # 根据期数查询时间戳 sub = now_time - time if rd != stake_all_value[i] and 0 < sub <= 60 * 60 * 24 * 1: # 小于1天和不重复的 list.append(stake_all_value[i]) list.append(rd) return list
def save(number): # 用户保存号码 sender = GetTxSender() numbers = split(number, "-") stake_list = query_user_stake_list(sender) # 查询用户的投注列表 if len(stake_list) == 0: raise Exception("当期用户没有投注") last_stake = stake_list[len(stake_list) - 1] old_time = query_user_period_time(sender, last_stake) # 最后一期的时间戳 now_time = GetTime() if now_time - old_time > 30: raise Exception("当期已经过了时间,无法标记") last_stake_info = query_user_stake_info(sender, last_stake) # 查询用户该期的表单 if numbers[0] != numbers[1]: raise Exception("标记的不是同一个") num = 0 for i in range(len(last_stake_info)): if last_stake_info[i] == numbers[0]: num = num + 1 if num < 2: raise Exception("标记的号码在表情中未出现两次") save_num_key = concat(concat(KEY_SAVE_NUMBER, sender), last_stake) Put(save_num_key, number) # 存取用户保存的号码 save_period_key = concat(KEY_SAVE_PERIOD, sender) save_period = GetArray(save_period_key) new_save = [] if len(save_period) != 0: for i in range(len(save_period)): new_save.append(save_period[i]) new_save.append(last_stake) PutArray(save_period_key, new_save) # 存取用户保存的期号 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(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 issue(total, symbol, symbol_des): sender = GetTxSender() # 获取操作者地址 if issue_owner(symbol): raise Exception("此积分已发行") AssetInit(sender, total, symbol) # 给操作者发行积分 issue_num = issue_number() if not issue_num: # 如果通过该合约暂时没有积分 Put(KEY_ISSUE_NUMBER, 1) else: Put(KEY_ISSUE_NUMBER, issue_num + 1) des_key = concat(KEY_DESCRIPTION, symbol) Put(des_key, symbol_des) # Put 此积分的描述 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 query_user_stake_amount(sender): # 查询用户总共抵押的钱 key = concat(KEY_USER_STAKE_AMOUNT, sender) return Get(key)
def add_user_period_withdraw_amount(address, period, amount): key = concat(concat(KEY_USER_WITHDRAW_AMOUNT, address), period) Put(key, amount)
def query_user_period_withdraw_amount(address, period): # 查询用户指定期兑奖的金额 key = concat(concat(KEY_USER_WITHDRAW_AMOUNT, address), period) return Get(key)
def query_user_withdraw_amount(address): # 查询用户兑奖的金额 key = concat(KEY_USER_WITHDRAW_AMOUNT, address) return Get(key)