最近做一个区块链的项目,需要彻底分析FOMO3D的智能合约,顺便熟悉一下区块链的开发流程。
首先为了能跑FOMO3D的智能合约我尝试了truffle+galanche,对我来说不太理想,我就自己用python+solc做了一个类似的框架。
可以编译部署发布合约,自动生成前端的JS合约对象以及跑一个aiohttp的测试环境,该环境已经开源https://github.com/bluehook/pyw3c.git,
示例就是全套FOMO3D的智能合约,在分析的过程中我又重新写了一遍FOMO3D也放在示例合约中叫TinyF3D,把所有功能都整合在这一个合约里面,所有FOMO3D实现的功能,Tiny3D都有实现,并且函数名称也保持一致,可以复制到remix里面部署方便测试,交流可加微信号:bluehook。
网上已经有一些FOMO3D的分析文章,我尽量写一些没有分析到的部分。
从另外一个怪异的角度介绍一下FOMO3D这个项目,这个项目的核心是一个函数,这个函数的公式是这样f(x)=sqrt(totala+b^2)-b)/c。
公式不重要,只需要知道这个函数是递增的,比如x=1,f(x)返回1000,x=2,f(x)返回1100,每次x传一样的值返回都一样,了解这个就够了。
现在有这么一个机制:我用x代表奖池的值,f(x)就是整个公式的返回代表当前奖池的值为x时,能够购买的key数量。
这个假设清楚了就继续,那么我现在要购买0.1以太币的keys,我不知道买多少个,反正我就买这么多以太币的,那么可以买多个呢?因为函数是固定的,每一局游戏开始时奖池都是从0开始,也就是说都是从x=0开始,那么我当时能够购买多少keys,反过来想就是要确定当我买了0.1以太币时奖池总奖金x能购买多少keys再减去现在我没有买时奖池总奖金x能购买的keys数量就是我出0.1以太币这一段能买到的keys,
看看公式不难理解:
0.1eth / ( (sqrt((total+0.1)a+b^2)-b)/c) - (sqrt(totala+b^2)-b)/c) ),其中total代表当前总奖池金额。
上面一段是FOMO3D最核心的公式,也是最复杂的公式,剩余的就是流程逻辑,现在来结合流程把上面的函数组合进去。
首先这个合约需要部署,原合约有5个主合约太繁琐,我用我重写合并成的1个主合约TinyF3D来讲,同样适用于FOMO3D,只是不用在合约之间切换。
合约部署后,要开始运行,需要第一个调用的是activate(),这个里面初始化5个地址,第1个是合约的管理者,后面4个是合约的资金流向账户,原FOMO3D通过一个1/N多重签名合约来管理资金,这个模块可以完全根据需要去除让资金自己留向4个账户就可以了。activate()后面再设置开始局的开始时间和结束时间,局ID,最重要是把激活标志设置为activated_ = true;
调用activate()之后,就可以调用一个叫registerNameXID的方法注册一个游戏ID,拿到游戏ID之后,调用buyXid()购买keys,这里就需要上面的公式了,我向buyXid()传入我要购买的金额:0.1以太币,
通过上面的公式:在奖池0的情况下f(0)返回1331个,也就是可以买1331个keys,
如果你再继续买0.1以太币,那么相当于就是f(0.1)(上次花费的钱不可能全部进奖池,这里只是方便)返回1328个,
也就是奖池x=0.1的时候,同样0.1以太币智能购买1328个keys,这就是FOMO3D这个游戏越到后期购买keys越贵的原理,
也是这个游戏最难理解的部分,如果这个理解了,其他基本上没有上面难度,只是有些流程比较绕,所以我重写了FOMO3D合约,去除了多重签名,把playerbook合约的功能集成到了主合约,直接查看TinyF3D就能清楚整个DAPP的游戏逻辑。
只要理解了上面就理解了整个核心逻辑,剩下的枝节我相信有开发经验的都能明白。**
原文地址:http://blog.51cto.com/1557154/2166044