小试牛刀-Telebot区块链游戏机器人

news2024/9/20 10:31:40

目录

1.编写目的

2.实现功能

2.1 Wallet功能

2.2  游戏功能

2.3  提出功能

2.4  辅助功能

3.功能实现详解

3.1 wallet功能

3.2 游戏功能

3.3 提出功能

3.4 辅助功能

4.测试视频 


Welcome to Code Block's blog

本篇文章主要介绍了

[Telebot区块链游戏机器人]
❤博主广交技术好友,喜欢文章的可以关注一下❤

1.编写目的

        本文章为记录自己开发基于区块链和Telebot实现的[石头、剪刀、布]游戏的过程,加深自己对区块链知识的理解和使用,加深对TeleBot依赖库的使用,同时希望可以帮助到有想实现相关功能的朋友.     

2.实现功能

2.1 Wallet功能

       用户可以通过/create命令命令创建游戏wallet,同时可以输入地址或扫码向该wallet发送一定数量的游戏代币,使用/wallet命令可以显示当前游戏wallet内的剩余代币数量。

2.2  游戏功能

        用户可以将bot机器人添加到公开群组,同时在群组内发送/game命令创建具有奖励随机结果的游戏,使用不同的人向群组内回复该游戏/pk进行对战,获取对战结果并向游戏wallet发送设定的奖励游戏代币,用户可以使用/del删除当前已创建游戏。

2.3  提出功能

        用户可以通过/bind命令绑定外部wallet并进行代币提出.

2.4  辅助功能

        用户可以输入/rules查看游戏规则,输入/help命令查看机器人命令及解释。

3.功能实现详解

3.1 wallet功能

        用户通过/create命令命令创建游戏wallet可以参考我的博客生成solana公私钥,/wallet显示wallet信息是通过solana.py根据保存的用户公钥查询.

def getBalance(publicKey:str):
    solana_client = Client(rpc_url)
    #公钥转换
    pubkey=Pubkey.from_string(publicKey)
    tokenPublicKey=Pubkey.from_string(BOGGY_TOKEN_MINT)
    #获取SOL余额
    sol_balance = solana_client.get_balance(pubkey)
    #获取SPL代币余额
    token_account=solana_client.get_token_accounts_by_owner_json_parsed(pubkey,TokenAccountOpts(mint=tokenPublicKey))
    if noTokenAccount(token_account):
        #不存在代币账户时,则余额为0
        token_balance=0.0
    else:
        token_account_json=token_account.value[0].account.to_json()
        token_balance=json.loads(token_account_json)['data']['parsed']['info']['tokenAmount']['uiAmount']
    sol_balance=(sol_balance.value/10**9)
    return sol_balance,token_balance

        同时为方便用户使用,这边会将用户公钥通过qrcode库转换为二维码供用户扫码,主要代码为:

import qrcode
from io import BytesIO
from PIL import Image
import qrcode.main

def generate_qr(data):
    # 生成普通二维码
    qr = qrcode.main.QRCode(
        version=1,
        box_size=10,
        border=4,
    )
    qr.add_data(data)
    qr.make(fit=True)
    qr_img = qr.make_image(fill_color="black", back_color="white")

    

    # 将二维码图片保存到 BytesIO 对象中
    img_io = BytesIO()
    qr_img.save(img_io, format='PNG')
    img_io.seek(0)
    
    return img_io

实现效果:

3.2 游戏功能

        游戏功能的设计思路是当用户在群组内输入/game时,根据(群组id+用户id+消息id)生成唯一的游戏id并通过json文件存储创建者生成的随机值信息.存储信息如下:

{
	"create_user_id": 5385955983,
	"create_username": "GameOfBoggy",
	"create_select": 0,
	"pk_user_id": 2038830708,
	"pk_username": "USERT1223",
	"pk_select": 1,
	"pk_select_hex": "4b32e3c83744655cd4ab5cc991a342c99f52c73fa83f2393a995d53baf7aeb42",
	"amount": 20,
	"winner": "USERT1223",
	"create_select_hex": "bd55d5aa6e461c63c811ff78bb00753c517eba47f086e563783a5e023ff342af",
	"timestamp": 1721092512.869742,
	"create_drand_hex": "e3b4d8b6af061ddc40449d87c57c06d93de8fa73dff0055a07cc8dadb047dd1e",
	"pk_drand_hex": "808391bb3761db7f5be8ba296e143154f043ecced8e7a693698c8490300fe34f"
}

这里的是使用本地secrets库和调用远程的drand随机数链生成两个hash值(create_drand_hex和create_select_hex为创建者游戏结果计算hash,pk_select_hex和pk_drand_hex为pk者游戏结果计算hash,这些结果面会保存到链上以保证游戏结果公平性和随机性.),这两个hash值转换为整数相加并对3取余获得随机结果,以保证游戏的随机性和不可预测性:

调用远程drand API:

def get_drand_randomness():
    # Drand API endpoint
    url = "https://api.drand.sh/52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971/public/latest"
    # Send request to Drand
    response = requests.get(url)
    if response.status_code == 200:
        # Parse the JSON response
        data = response.json()
        randomness = data['randomness']
        return randomness
    else:
        return secrets.token_hex()

计算游戏随机结果:

def get_random_hex_int():
    select_hex=secrets.token_hex()
    drand_hex=get_drand_randomness()
    hex_int = int(select_hex, 16)
    drand_int = int(drand_hex,16)
    select=(drand_int+hex_int)%3
    return select,select_hex,drand_hex

为保证游戏的美观性,这边使用图片+文字方式让机器人回复用户随机结果:

def random_game(bot,message,type,create_username):
    select,select_hex,drand_hex = get_random_hex_int()
    imgPath="./img/{}.png".format(img[select])
    msgText="<b>[{}] You random [{}]! @{}</b>".format(type,img[select],create_username)
    send_message=bot.send_photo(message.chat.id, open(imgPath, 'rb'), caption=msgText,parse_mode='HTML')
    return select,send_message,select_hex,drand_hex
    

游戏奖励发放给获胜者为代币转移操作,实现代码如下(这里的draw_data即为计算出结果的hash值,将其备注添加链上):

#向绑定账户发送代币
def drawTokenAccount(sender_public_key:str,privateKey:str,draw_public_key:str,tokenAmount,draw_data):
    solana_client = Client(rpc_url)
    #发送者
    sender_pubkey = Pubkey.from_string(sender_public_key)
    #接收者
    draw_pubkey = Pubkey.from_string(draw_public_key)
    #Token代币地址
    token_mint_address = Pubkey.from_string(BOGGY_TOKEN_MINT)
    #发送者keypair
    sender_keypair=Keypair.from_base58_string(privateKey)
    
    try:
        #spl_client客户端
        source_token_account=get_associated_token_address(sender_pubkey,token_mint_address)
        dest_token_account=get_associated_token_address(draw_pubkey,token_mint_address)
        #交易
        transfer_instruction = transfer_checked(
            TransferCheckedParams(
                program_id=TOKEN_PROGRAM_ID,
                source=source_token_account,
                mint=token_mint_address,
                dest=dest_token_account,
                owner=sender_pubkey,
                amount=int(float(tokenAmount) * 1000000000),
                decimals=9,
            )
        )
        memo_instruction=create_memo(MemoParams(
            program_id=MEMO_PROGRAM_ID,
            signer=sender_pubkey,
            message=draw_data.encode('utf-8')
        ))
        # #获取最新的区块hash
        recent_blockhash_resp = solana_client.get_latest_blockhash()
        recent_blockhash=recent_blockhash_resp.value.blockhash
        # # 创建交易并添加转账指令
        transaction = Transaction()
        transaction.add(set_compute_unit_limit(200000))
        transaction.add(set_compute_unit_price(7500))
        transaction.add(transfer_instruction)
        transaction.add(memo_instruction)
        #设置最新区块hash
        transaction.recent_blockhash=recent_blockhash
        #设置手续费支付地址为发送者
        transaction.fee_payer=sender_pubkey
        #签名
        transaction.sign(sender_keypair)
        #发送交易
        response = solana_client.send_raw_transaction(transaction.serialize())
        #打印交易
        return response.value
    except Exception as e:
        print(f"Exception occurred: {str(e)}")
        return "error"

实现效果:

/game 20 即创建了一个奖励为20代币的游戏,这里随机的是[剪刀]

/pk pk者出了[布],所以创建者获得了奖励.

我们可以点击按钮在链上查看奖励内容.

可以看到这里包含了一个转移代币操作,是从pk者转移到创建者中的,同时包含了生成随机结果的hash值以保证游戏的公开和公平性。 

3.3 提出功能

        用户输入/bind 绑定自己的链上地址后,提出功能即为代币转移操作,主要实现代码如下,这边直接根据用户的ID查到用户的创建的游戏wallet公钥私钥并进行转移:

def drawTokenFromUserId(send_user_id,draw_user_id,gameId,draw_data):
    publicKey,privateKey=get_account(send_user_id)
    drawPublicKey=getPublicKey(draw_user_id)
    amount=get_game_amount(gameId)
    tx=drawTokenAccount(publicKey,privateKey,drawPublicKey,amount,draw_data)
    return amount,tx

3.4 辅助功能

        辅助功能即为telebot消息的回复,实现代码如下:

/rules:

from telebot import types
def handle_rules(bot, message):
    # 处理 /start 命令
    markup = types.InlineKeyboardMarkup()
    item1 = types.InlineKeyboardButton("BOGGY GROUP",url="https://t.me/BoggyCoin")
    markup.add(item1)
    welcome_message=(
        "<b>"
        "1.Before starting the game, you need to create(/create) a game wallet and transfer a small amount of sol and BOGGY tokens inward\n\n"
        "2.You can send '/game [amount]' create a game(default amount:500),and the Pker reply /pk with [GAME](need enough sol and BOGGY)\n\n"
        "3.Waiting for the results, the winner will receive the bonus set by the game creator\n\n"
        "4.The [Scissors] will win [Paper],[Parer] will win [Rock],[Rock] will win [Scissors]\n\n"
        "5.You Can at /wallet,draw you all token in you bind wallet,you can send '/bind [address]' bind you wallet\n\n"
        "[Create With #BOGGY]"
        "</b>"
    )
    bot.send_photo(message.chat.id,open("./img/rules.jpeg","rb"),welcome_message,parse_mode='HTML',reply_markup=markup)
def register_handlers(bot):
    bot.message_handler(commands=['rules'])(lambda message: handle_rules(bot, message))

/help:

from telebot import types
def handle_help(bot, message):
    markup = types.InlineKeyboardMarkup()
    item1 = types.InlineKeyboardButton("BOGGY GROUP",url="https://t.me/BoggyCoin")
    markup.add(item1)
    help_text = (
        "<b>Welcome!</b>\n" 
        "<b>Here are the available commands:</b>\n"
        "<b>[/create]         Create you game wallet [DM*]</b>\n"
        "<b>[/bind]           Bind you draw wallet [DM*]</b> \n"
        "<b>[/wallet]         Show you wallet Info and Draw [DM*]</b>\n\n"
        "<b>[/game]           Create Game with amount</b>\n"
        "<b>[/pk]             Reply the Game Message and Pk it</b>\n"
        "<b>[/rules]          View more detailed game rules</b>\n\n"
        "<b>The [DM*] need DM Bot</b>"
    )
    
    bot.send_photo(message.chat.id,open("./img/help.jpeg","rb"),help_text, parse_mode='HTML',reply_markup=markup)

def register_handlers(bot):
    bot.message_handler(commands=['help'])(lambda message: handle_help(bot, message))

4.测试视频 

video_2024-07-16_11-48-41

 
感谢您的关注和收藏!!!!!!

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1929402.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

css 屏幕四周报警提示

屏幕四周出现律动的红色边框&#xff0c;产生报警提示的效果。 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Screen Edge Warning</title><style>body, html {margin: 0;padding: 0;he…

【软件测试】编写测试用例篇

前面部分主要是编写测试用例的方法和方向&#xff0c;后面一部分是编写出具体的测试用例 目录 什么是测试用例 1.设计测试用例的万能公式 1.1.从思维出发 1.2.万能公式 1.3.弱网测试 1.4.安装与卸载测试 2.设计测试用例的方法 2.1.基于需求的设计方法 2.2.等价类 2.3…

python-矩阵加法(赛氪OJ)

[题目描述] 输入两个 n 行 m 列的矩阵 A 和 B &#xff0c;输出它们的和 AB。矩阵加法的规则是两个矩阵中对应位置的值进行加和&#xff0c;具体参照样例。输入&#xff1a; 输入共 2⋅n1 行&#xff0c;第一行包含两个整数 n 和 m&#xff0c;表示矩阵的行数和列数 (1≤n,m≤1…

原来,BI数据分析也是有模板的

在当今数据驱动的时代&#xff0c;商业智能&#xff08;BI&#xff09;数据分析已经成为企业决策的重要工具。然而&#xff0c;很多人可能并不了解&#xff0c;BI数据分析并非从零开始&#xff0c;而是可以依托现成的模板和解决方案来快速搭建和实施的。以奥威BI方案为例&#…

Vue3 前置知识

1. Vue3 简介 2020年9月18日&#xff0c;Vue.js发布版3.8版本&#xff0c;代号&#xff1a;one Piece(海贼王)经历了&#xff1a;4800次提交、40个RFC、600次PR、300贡献者官方发版地址&#xff1a;Release v3.0.0 One Piecevuejs/,core截止2023年10月&#xff0c;最新的公开版…

数学建模·层次分析法

层次分析法 LAF 定义 评价体系的优劣影响&#xff0c;计算评价指标的权重的一种方法 主观性较强&#xff0c;现在一般不用 主要步骤 关键在于一致性检验和求权值 权重的计算 注意权重之和为1&#xff0c;需要归一化 算数平均法 特征值法 矩阵的一致性检验 为什么要检验…

如何应对AI发展下的伦理挑战

目录 1.概述 2.构建可靠的AI隐私保护机制 2.1. 最小化数据收集 2.2. 数据去标识化 2.3. 加密技术 2.4. 分布式学习和边缘计算 2.5. 强化用户控制权 2.6. 独立审计和合规性检查 2.7. 持续教育和培训 2.8.小结 3.确保AI算法的公正性和透明度 3.1.增强AI决策透明度的方…

安卓MT管理器v2.16.2/逆向修改神器 本地VIP已解锁

MT管理器是一款强大的文件管理工具和APK逆向修改神器。如果你喜欢它的双窗口操作风格&#xff0c;可以单纯地把它当成文件管理器使用。如果你对修改APK有深厚的兴趣&#xff0c;那么你可以用它做许许多多的事&#xff0c;例如汉化应用、替换资源、修改布局、修改逻辑代码、资源…

Java用JDBC链接mysql

一、什么是JDBC&#xff1a; 是Java平台上的标准数据库访问技术。它提供了一套API&#xff08;应用程序编程接口&#xff09;&#xff0c;允许Java应用程序与各种类型的数据库进行交互&#xff0c;包括关系型数据库&#xff08;如MySQL、Oracle、SQL Server等&#xff09;和非关…

MBR30200PT-ASEMI智能AI应用MBR30200PT

编辑&#xff1a;ll MBR30200PT-ASEMI智能AI应用MBR30200PT 型号&#xff1a;MBR30200PT 品牌&#xff1a;ASEMI 封装&#xff1a;TO-247 批号&#xff1a;最新 恢复时间&#xff1a;35ns 最大平均正向电流&#xff08;IF&#xff09;&#xff1a;30A 最大循环峰值反向…

中国最受欢迎的起名大师国学泰斗颜廷利:世界公认的伟大思想家

物质构成了文化的根基&#xff0c;而精神则象征着文明的光辉。汉字文化和汉语言文明&#xff0c;作为历经数千年而不衰的宝贵遗产&#xff0c;巧妙地平衡了综合性与创新性、继承性与变革性、民族性与时代性的关系&#xff0c;确保了中国文化在传承中既保持了一贯的学术传统、道…

最新付费进群修复版本站亲测试

PHP必需7.2 sg11扩展 tp伪静态 *数据库修改地址&#xff1a;config/database.php 导入数据库 关闭防跨站 *编辑数据库找到qing_config表&#xff0c;更改网站域名codenet.cc改为自己的域名 后台账号18888888888 密码123456 分销后台&#xff1a;域名fenxiao.php 分站后台&am…

80万开一家零食店,每日1万营业额还亏本

在探讨以80万资金投资开设一家零食店的决策时&#xff0c;我们不得不深入剖析这一商业行为的多个层面&#xff0c;以更全面的视角审视其盈利潜力与潜在风险。 首先&#xff0c;提及的这家拥有千余家门店的零食连锁品牌&#xff0c;其招商宣传中的高存活率固然诱人&#xff0c;…

什么软件修复视频画质比较好,视频画质修复工具

有些视频中可能会出现噪点、残影、颜色失真等问题&#xff0c;导致观看时体验感不太好&#xff0c;修复视频画质可以去除这些问题&#xff0c;使视频更加干净、清晰和真实。 高质量的视频画质能够提高观众的观看体验&#xff0c;让观众更加享受观看视频的过程。特别是在需要展示…

线上观看 3 万+!「智能运维MeetUp」精彩回顾,探讨智能体构建新方向

龙蜥社区“走进系列”第 11 期走进中兴通讯-智能可观测运维技术 MeetUp 于成都圆满结束&#xff0c;由中兴通讯联合龙蜥社区系统运维联盟&#xff08;SOMA&#xff09;&#xff08;以下简称“联盟”&#xff09;共同举办。本次活动现场汇聚了阿里云、谐云科技、乘云数字、中兴通…

vue快速上手——创建vue项目,vue基本使用方式,路由vue-Router,转态管理vuex

文章目录 1.创建vue项目使用Vue CLI创建前端工程&#xff1a;1.方式一&#xff1a;vue create 项目名称2.方式二&#xff1a;vue ui 运行vue项目什么是node.jsnode.js和vue项目的关系 2.vue基本使用方式1.vue组件组成部分&#xff1a;脚本部分的组件选项&#xff1a;示例&#…

普通人还有必要学习 Python 之类的编程语言吗?

在开始前分享一些编程的资料需要的同学评论888即可拿走 是我根据网友给的问题精心整理的对于编程的重要性&#xff0c;这里就不详谈了。 未来&#xff0c;我们和机器的交流会越来越多&#xff0c;编程可以简单看作是和机器对话并分发给机器任务。机器不仅越来越强大&#xff0…

windows实现自动化按键

1.选择目标窗口 获取窗口句柄 void KeyPresser::selectWindow() {SetWinEventHook(EVENT_SYSTEM_FOREGROUND, EVENT_SYSTEM_FOREGROUND, NULL, WinEventProc, 0, 0, WINEVENT_OUTOFCONTEXT);selectedWindowLabel->setText("请点击目标窗口..."); }void CALLBACK …

直接卖断货了!百元价位现象级蓝牙耳机西圣AVA2究竟有什么亮点

今年五月&#xff0c;目前国内知名耳机品牌xisem西圣全新推出了——西圣AVA2真无线蓝牙耳机&#xff0c;产品一经上市就凭借其奢华的配置性能和超高的性价比迅速获得了消费者的追捧&#xff0c;甚至已出现一机难求的情况&#xff0c;目前西圣品牌称&#xff0c;西圣AVA2现阶段已…

Python机器学习、深度学习技术提升气象、海洋、水文领域实践技术

Python是功能强大、免费、开源&#xff0c;实现面向对象的编程语言&#xff0c;能够在不同操作系统和平台使用&#xff0c;简洁的语法和解释性语言使其成为理想的脚本语言。除了标准库&#xff0c;还有丰富的第三方库&#xff0c;Python在数据处理、科学计算、数学建模、数据挖…