目录
- 1-从零开发EOS区块链小游戏系列 - 使用EOS Studio
- 2-从零开发EOS区块链小游戏系列 - 智能合约设计与实现
- 3-从零开发EOS区块链小游戏系列 - 游戏公平性及安全性
- 4-从零开发EOS区块链小游戏系列 - 加入Token体系
- 5-从零开发EOS区块链小游戏系列 - 实现玩家免CPU玩游戏(终)
前言
记得EOS主网是去年6月底上线的,号称区块链3.0,因为当时ETH(以太坊)平均出块时间10几秒,而EOS是每秒2个,试想如果一个系统你去请求,然后他10几秒才告诉你结果是什么感觉。因此导致很多项目不适用。当然并不代表EOS比ETH强,只是大家取舍不一样。
EOS发展是非常快的,记得很短时间注册账号就过百万了,第一批涌现的应该是“菠菜”类的Dapp,那时候可以说是每隔两三天就会出现一款,因为开发成本相当低,当然体验也是非常差的。知道大概年底的时候,出现了一款放置型的去中心化游戏EOS Knight,是韩国公司开发的一款游戏,智能合约代码完全开源,日活一直占据EOS前几名,游戏内有自由交易市场,购买装备或者素材,可以升级和合成装备,BOSS战,定时挑战任务等,当年我也是他们的氪金玩家,当然氪的是EOS[微笑]。
EOS游戏大致可分为[仅资产上链]和[逻辑和资产上链]两类,这里资产指游戏中的金币、装备等。逻辑指游戏的执行逻辑,如玩家砍BOSS一刀,扣血、暴击、伤害计算等这些就算是执行逻辑。
怎么定义一款游戏属于哪类?首先我们要了解的是在区块链游戏中,每做一个决策,理论上都是需要玩家输入密码确认的,当然可以通过设置白名单解决,但仍然是一个非常重的操作。所以一般博弈类的游戏,如五子棋,只能选择仅资产上链,否则玩家每下一步棋,都需要输入密码确认,这体验显然无法接受。一些放置型的游戏是可以考虑逻辑和资产都上链的,所以Knight就是属于后者那类。战斗玩法是:玩家只需要做一次开始战斗的决策,人物就会自动一直打怪,知道人物阵亡,再做一次结束战斗决策,就可以获取经验和装备。
这两类游戏去年自己都开发过,现在都还在主网跑,但都是半年前的事了。 当时EOSIO版本还是1.2+,连EOSIO.CDT(Contract Development Toolkit)都还没有。EOS智能合约使用的开发语言是C++,在1.3版本之后,语法发生了很大的变化,现在最新版本好像是1.8了,而且生态也已经慢慢形成。为什么又想继续捡回?一方面想熟悉1.3后的新语法,更重要的是最近发现有一款EOS开发集成工具EOS Studio面世了,开发到测试到部署一条龙服务。想想当初只能靠CLION来写合约代码,然后来回切节点调式的艰苦日子即将过去,前路又充满了阳光。
从零开发一款区块链小游戏
本系列的目的是想深入了解EOS Stuio的使用,并熟悉EOSIO1.8新语法,看看与旧的区别,所以实际去开发一个Dapp是最有效的学习方式。
下面我们来开发一款逻辑和资产都上链的小游戏,设想的游戏大概是这样的:
- 玩家需要注册账号,同时获得1000个SJ币(水晶),并得到一个人物用于战斗,人物有攻击力和血量2个属性,攻击力初始35-70,血量初始500。
- 玩家获得人物后,点击战斗(做一次决策),挑战一个BOSS(攻击力50-70,血量700)。
- 玩家先开始攻击,然后BOSS攻击,一直重复,直到任何一方血量<=0,战斗结束。
- 玩家每一次攻击,有25%的概率触发暴击,暴击增加100点伤害,仅在一回合有效。
- 玩家胜利,可以随机获得一个金、银、铜宝箱。玩家战败,减少100SJ币。
环境配置
开发环境:MacOS 10.13.6、Python3.6
区块链环境:kylin测试链
工具:EOS Studio、Docker、Scatter、Atom、PyCharm、EOSIO v1.8
架构图
EOS Studio: EOS开发集成工具
Docker: EOS studio必须依赖docker,已达到切换环境需求
Scatter:是一个EOS账号管理工具
Atom: 用来编写前端代码,也可以使用sublime代替
PyCharm: 使用Python开发上图中链接器程序
EOSIO:EOS客户端程序,后面用来可以执行cleos命令
以上工具需要用到的时候再下载也可以
熟悉EOS Studio
先是下载并安装好Docker和EOS Studio,启动玩Docker后,再启动EOS Studio,此时界面应该是这样的:
因为我先前已经把需要的都装好了,所以可以直接下一步。
首先在你本地创建一个目录,我这里就叫kof(king of fighter)也就是拳皇。
mkdir kof
进入到开发界面,中间展示的是配置信息,然后左边是目录结构,往上有几个按钮,分别是新建合约、构建、部署、测试和设置。然后右上角那三个模块是环境和账号相关的。可以看出其实功能还是比较少的,毕竟刚发布的工具。
在创建项目之前,我们先为合约创建一个EOS账户,这里直接使用kylin(麒麟)测试链:右上角-Network-kylin。然后再点击Account-Create Account,再弹窗输入一个合法的账号,所谓EOS合法账号格式就是长度12位:a-z 、1-5和. ,这里我们注册一个账号:kingofighter。然后右上角选中该账号后,可以看到展示出一个界面:
这个就是与你账号相关的信息:
- Account:可以看到你的总余额,也就是EOS,可用余额,CPU和NET抵押的金额、返回的金额。
- Resources:资源。第一个是RAM是内存,每一个账号都需要内存来保存数据,而部署了智能合约的账号,RAM用于存放合约代码和日后产生的数据。CPU用于发生交易时消耗,NET用于交易时打包数据消耗。这些资源都需要抵押EOS来获得,这就是为什么会有Staked、Refund的存在。这里只是抵押你的EOS,可以赎回。注意:这里有点差别的是,RAM是购买,所以都叫buy ram,你也可以将你多余的RAM卖出去。二CPU和NET是抵押,也可以赎回。
- Permission Keys:权限。两个EOSxxx开头的都是这个账号关联的公钥,关于EOS的账户与公钥权限设计已经有好多文章说过了,有兴趣可以自行搜索。owner是一些较敏感的操作需要用到,如修改公钥,active是一些普通操作如发送交易、部署合约、抵押资源等。
现在我们已经有了EOS账号,我们把这个作为游戏的合约账户,所以后面需要将写好的代码部署的上面,这就需要用到RAM了,而购买RAM就需要一定的EOS,所以我们先去搞一些EOS。好在这里我们使用的是测试网络,一切都可以免费得到。
看到右上角的4个图标了吗?第二个就是免费获取EOS的,有个很生动的名称叫faucet,点击一下就给你100EOS,每个账号每天只能获取1000个EOS。接着继续点击第三个图标,购买RAM,点击一下,这是我们的资源就是这样了:
拥有200个EOS,使用了大概6个去购买RAM,现在RAM是209。36KB。CPU和NET我没有找到可以抵押的按钮,没关系,后面需要用到的时候,我们直接用CLEOS命令来抵押就可以了。
有了资源,我们可以新建一个项目:点击左上角"Create New Project...",在弹窗选择位置为上创建的kof目录,输入项目名称,这里项目名称提示我们必须是EOS账号,所以这里输入刚刚注册好的:kingofighter
工具自动为我们生成了两个C++文件,随便浏览下,发现是写helloworld的相关代码,里面其实是一个完整的合约demo了。重点看下cpp的文件:
#include
ACTION kingofighter::hi(name user) {
require_auth(user);
print("Hello, ", name{user});
}
合约中一个接口称为action,这个action的名字是hi,入参有一个name类型的user,所以这里的意思是user必须传入一个EOS账号类型。v1.2版本是叫account_name类型。require_auth(user);
是要求当前调用者必须是user,如果不是就直接终止。请记住这一句代码,在安全性方面这一句很重要,特别是在一些涉及EOS交易的合约中,而且后面我们也会经常使用
print("Hello, ", name{user});
打印出“Hello,账号名称”。name{}是转换成字符串的形式显示,因为name类型实际上存储类型是uint64_t,无符号64位整形,所以需要进行转换。
跟着下来,我们尝试下构建和部署合约,尝试点击左上角的图标(Build)。
嗯,很合理的报错了。直接看错误信息,很明显是不知道他在说什么的,于是我去了他们论坛搜,没搜到,然后自己发了一个帖子,等了几个小时,没人回答。后来直接去电报找到软件的作者寻找解决办法:
根据作者的回复,是要在 Add a resource path for inclusion -R
那一项 随意填一些内容就可以了,这应该是软件的一个BUG。我填写的是合约的名称,再点击构建:
发现多处了两个文件.abi、.wasm。一个是描述文件,告诉外界这个合约有哪些action及参数,另一个是合约的代码文件。
接着,我们尝试部署(Deploy),很顺利的成功了,这时候我们回到账号信息界面,发现RAM已被使用了大概14KB:
好,我试下最后一个功能测试(Test),点击后,要求安装一些必要的工具,这里我选默认项目,点击初始化:
初始化完成后,界面展示了几段JS代码,我估计这里所谓测试就是帮你下载了一些eosjs相关的包,然后通过调用eosjs提供的接口来实现单元测试,我们将第三段的
can get account "eosio"
修改一下:
//期望部署的合约与我们指定的名称相同
it('can get account "kingofighter"', async () => {
const eosioAccount = await eos.getAccount('kingofighter');
expect(eosioAccount.account_name).to.equal('kingofighter');
});
然后保存文件,点击Test按钮:
Global eos
✓ is an object
✓ can get chain info and chainId is 5fff1dae8dc8e2fc4d5b23b2c7665c97f9e9d8edf2b6485a86ba311c25639191 (1072ms)
✓ can get account "kingofighter" (1108ms)
3 passing (2s)
当然还可以测试更多的信息,我尝试去EOS Studio官网看看有没有关于Test的文档,发现这个版块还在建设中
如果你对eosjs很熟悉可以继续深入,我还是等等官方到时候给出的列子吧,加上测试这里不影响后面的进度。
总结
本章开头讲了一些关于EOS游戏的发展,重点尝试了EOS Studio的各项重要功能,总得来说EOS Studio为开发Dapp提供了很大的便利性:以前需要安装EOSIO客户端,合约的 很多操作都需要使用CLEOS来实现,比较麻烦。当然不足的地方也不少:只是实现了最基本的功能、无法直接跳转的源代码、缺少快捷键、假死情况频繁等。但毕竟是刚刚上线的产品,可以理解。这里感谢开发者的无私付出。
好了,下一章开始智能合约的设计与编写...