FlyToTheMoon(飞向月球)是一款类似Fomo3D资金盘游戏的简化版,去除Fomo3D游戏中4个Team的区分,也取消了邀请分红,核心代码大大简化,全部采用ETH智能合约实现,仅有500多行。
由于Fomo3D游戏进行到后期,Key价格越来越高,除了中大奖几乎无法收回成本,因此FlyToTheMoon把每一轮游戏分成两个阶段:第一个阶段是买Key拿分红,第二个阶段是竞拍阶段,不分红仅角逐大奖。
两个游戏到现在都还没有结束,体验地址如下:
Fomo3D地址:http://exitscam.me
FlyToTheMoon地址:https://flytothemoon.io/
FlyToTheMoon(飞向月球)规则解析:
1 游戏玩法
游戏为多轮制,每一轮分2个阶段,但不是每一轮都能进入第二阶段。
第一阶段名称:燃料填充,购买KEY为火箭发射增加动力。
第二阶段名称:火箭发射,不再需要购买KEY, 直接采用拍卖模式进行Boom,拍卖最后一位将成为最大赢家,拿到最终大奖。
2 游戏倒计时
游戏中会有倒计时,倒计时长 = 12小时
用户购买的key数量 >= 1, 则重置倒计时;
3 游戏开始结束
智能合约发布,游戏即开始;
如果超过12小时没有用户打币,本轮结束;
如果接下来有用户打币进来,那么进入下一轮;
游戏永远不结束;
4 游戏分红
在游戏第一阶段进入的所有用户均可参与分红,分红可随时提取
在游戏第二阶段进入的所有用户均不参与分红,仅参与最终大奖争夺
游戏分红比例:60%
5 游戏大奖
每一轮倒计时结束之前购买的最后一位用户可以获得大奖
游戏大奖比例:35%
6 团队费用
每一轮结束之后,团队会保留一部分eth作为团队费用支出
游戏费用比例:5%
7 KEY的实时价格计算
初始价格:0.000075 eth
KEY总数:key_amount
ETH总数:eth_amount
换算关系:
eth_amount = (0.000000000078125 * key_amount * key_amount + 0.000074999921875 * key_amount)
1000万KEY以内的实时价格计算:
key_price = eth_amount(key_amount + 1) - eth_amount(key_amount)
8 竞拍价格
竞拍底价:0 eth
竞拍价格:
price = last_price + [0.1 eth, 10 eth]
每次竞拍需在上次的出价上增加[0.1 eth, 10 eth]范围内的eth数量,多余退回。
竞拍阶段不参与分红,没有KEY分配,仅角逐最终大奖。
FlyToTheMoon(飞向月球)代码解析:
完整代码请参考:
https://etherscan.io/address/0x0B588A1d41518991a94590a7884f52B8836df38d#code
address indexed player;
indexed: 用在event数据结构中,该关键字表示address会被索引,可以根据该字段进行查询。
参考web3.eth.filter的用法。一个event数据结构中最多只能有3个indexed字段。
struct Round;
游戏的每一轮状态数据结构。
struct PlayRound;
用户的每一次购买状态数据结构。
uint256 constant private rndFirStage_ = 12 hours;
uint256 constant private rndSecStage_ = 12 hours;
游戏每一轮分2个阶段,每个阶段的倒计时都是12小时。
mapping (uint256 => Round) public round_m;
每一轮游戏的状态都作为全局数据保存。
mapping (uint256 => mapping (address => PlayerRound)) public playerRound_m;
两层mapping,每一轮游戏的每个用户的每个购买状态都会作为全局数据保存。
modifier onlyHuman()
与本合约交互的不能是合约代码。
modifier isWithinLimits(uint256 _eth) ;
eth交易量最小值:0.000000001,最大值:100000
modifier onlyOwner()
有些方法只能owner才能调用,owner默认为合约创建者
function withdrawByRndNo(uint256 _rndNo)
uint256 _total = (((round_m[_rndNo].eth).mul(playerRound_m[_rndNo][msg.sender].keys)).mul(60) / ((round_m[_rndNo].keys).mul(100)));
total_eths * keys * 0.6 / total_keys
实时分红:60%
total_eths * 0.6
function awardByRndNo(uint256 _rndNo)
本轮游戏结束,最后一人拿大奖
uint256 _ethOut = ((round_m[_rndNo].eth).mul(35) / (100));
最后大奖:35%
toatal_eths * 0.35
function feeWithdraw()
uint256 _total = (totalEth.mul(5) / (100));
团队分成:5%
total_eths * 0.05
function getCurrentRoundInfo()
获取当前round信息
internal function keysRec(uint256 _curEth, uint256 _newEth)
return(keys((_curEth).add(_newEth)).sub(keys(_curEth)));
增加eth的数量对应keys的增加数量
对应用户打eth,能购买keys的数量
internal function keys(uint256 _eth)
return ((((((_eth).mul(1000000000000000000)).mul(312500000000000000000000000)).add(5624988281256103515625000000000000000000000000000000000000000000)).sqrt()).sub(74999921875000000000000000000000)) / (156250000);
eth数量与对应keys的数量关系
keys = sqrt(eth_amount * 12800000000 + 230399520000.25) - 479999.5
inernal function ethRec(uint256 _curKeys, uint256 _sellKeys)
return((eth(_curKeys)).sub(eth(_curKeys.sub(_sellKeys))));
增加keys需要的eth数量
对应用户购买多少keys,需要对应的eth的数量
用于计算keys的价格
internal function eth(uint256 _keys)
return ((78125000).mul(_keys.sq()).add(((149999843750000).mul(_keys.mul(1000000000000000000))) / (2))) / ((1000000000000000000).sq());
eth_amount = (0.000000000078125 * keys * keys + 0.000074999921875 * keys)
keys数量与对应的eth数量关系
function getBuyPrice()
获取key的实时价格
1 key的初始价格:0.000075 eth
2 key的数量在1000万以内的计算公式:
return ((round_m[_rndNo].keys.add(1000000000000000000)).ethRec(1000000000000000000));
price = (keys + 1).ethRec(1)
或者
price = eth_amount(keys + 1) - eth_amount(keys)
3 key的数量超过1000万,key价格为0,不接受key的购买。
function()
匿名函数,用户转账到合约地址,即会触发该函数,根据转账eth数量,计算购买key的数量。
买key的流程逻辑:
1> 判断是否应该进入下一轮:
当前时间 > 截止时间,进入下一轮;
没有继续当前轮;
2> 当前keys的总数少于1000万:
1000万key === 8562.5 eth
计算用户打入的eth可以购买多少keys数量
如果当前keys的总数+用户能购买的keys数量 > 10000万:
如果当前eth数量大于8562.5个eth,那么打入的eth全部进入第二阶段;
如果当前eth数量小于8562.5个eth,那么使用的eth数量 = min(8562.5 - eth, eth)
如果有剩余的eth将直接退回给用户;
只要购买的key的数量超过1,就重置定时器;
更新Round信息;
更新PlayRound信息;
写入第一阶段购买信息;
3> 当前keys的总数大于1000万:
进入第二阶段
竞拍底价为0
new_price >= lastPrice + 0.1 eth
new_price < lastPrice + 10 eth
如果超过10eth,只使用10eth,剩余退回。
只要超过0.1eth,重置定时器;
更新Round信息;
更新PlayRound信息;
写入第二阶段购买信息;
网友评论