Created
August 2, 2018 03:21
-
-
Save jin10086/dcedb115960daf137ee85166692f3293 to your computer and use it in GitHub Desktop.
Created using remix-ide: Realtime Ethereum Contract Compiler and Runtime. Load this file by pasting this gists URL or ID at https://remix.ethereum.org/#version=soljson-v0.4.24+commit.e67f0147.js&optimize=false&gist=
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.4.24; | |
/** | |
* , , | |
* $, $, , | |
* "ss.$ss. .s' | |
* , .ss$$$$$$$$$$s, | |
* $. s$$$$$$$$$$$$$$`$$Ss | |
* "$$$$$$$$$$$$$$$$$$o$$$ , | |
* s$$$$$$$$$$$$$$$$$$$$$$$$s, ,s | |
* s$$$$$$$$$"$$$$$$""""$$$$$$"$$$$$, | |
* s$$$$$$$$$$s""$$$$ssssss"$$$$$$$$" | |
* s$$$$$$$$$$' `"""ss"$"$s"" | |
* s$$$$$$$$$$, `"""""$ .s$$s | |
* s$$$$$$$$$$$$s,... `s$$' ` | |
* `ssss$$$$$$$$$$$$$$$$$$$$####s. .$$"$. , s- | |
* `""""$$$$$$$$$$$$$$$$$$$$#####$$$$$$" $.$' | |
* 祝你成功 "$$$$$$$$$$$$$$$$$$$$$####s"" .$$$| | |
* 福 喜喜 "$$$$$$$$$$$$$$$$$$$$$$$$##s .$$" $ | |
* $$""$$$$$$$$$$$$$$$$$$$$$$$$$$$$$" ` | |
* $$" "$"$$$$$$$$$$$$$$$$$$$$S""""' | |
* , ," ' $$$$$$$$$$$$$$$$####s | |
* $. .s$$$$$$$$$$$$$$$$$####" | |
* , "$s. ..ssS$$$$$$$$$$$$$$$$$$$####" | |
* $ .$$$S$$$$$$$$$$$$$$$$$$$$$$$$#####" | |
* Ss ..sS$$$$$$$$$$$$$$$$$$$$$$$$$$$######"" | |
* "$$sS$$$$$$$$$$$$$$$$$$$$$$$$$$$########" | |
* , s$$$$$$$$$$$$$$$$$$$$$$$$#########""' | |
* $ s$$$$$$$$$$$$$$$$$$$$$#######""' s' , | |
* $$..$$$$$$$$$$$$$$$$$$######"' ....,$$.... ,$ | |
* "$$$$$$$$$$$$$$$######"' , .sS$$$$$$$$$$$$$$$$s$$ | |
* $$$$$$$$$$$$#####" $, .s$$$$$$$$$$$$$$$$$$$$$$$$s. | |
* ) $$$$$$$$$$$#####' `$$$$$$$$$###########$$$$$$$$$$$. | |
* (( $$$$$$$$$$$##### $$$$$$$$###" "####$$$$$$$$$$ | |
* ) \ $$$$$$$$$$$$####. $$$$$$###" "###$$$$$$$$$ s' | |
* ( ) $$$$$$$$$$$$$####. $$$$$###" ####$$$$$$$$s$$' | |
* ) ( ( $$"$$$$$$$$$$$#####.$$$$$###' .###$$$$$$$$$$" | |
* ( ) ) _,$" $$$$$$$$$$$$######.$$##' .###$$$$$$$$$$ | |
* ) ( ( \. "$$$$$$$$$$$$$#######,,,. ..####$$$$$$$$$$$" | |
*( )$ ) ) ,$$$$$$$$$$$$$$$$$$####################$$$$$$$$$$$" | |
*( ($$ ( \ _sS" `"$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$S$$, | |
* ) )$$$s ) ) . . `$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$"' `$$ | |
* ( $$$Ss/ .$, .$,,s$$$$$$##S$$$$$$$$$$$$$$$$$$$$$$$$S"" ' | |
* \)_$$$$$$$$$$$$$$$$$$$$$$$##" $$ `$$. `$$. | |
* `"S$$$$$$$$$$$$$$$$$#" $ `$ `$ | |
* `"""""""""""""' ' ' ' | |
*/ | |
contract F3Devents { | |
// 只要玩家注册了名字就会被解雇 | |
event onNewName | |
( | |
uint256 indexed playerID, | |
address indexed playerAddress, | |
bytes32 indexed playerName, | |
bool isNewPlayer, | |
uint256 affiliateID, | |
address affiliateAddress, | |
bytes32 affiliateName, | |
uint256 amountPaid, | |
uint256 timeStamp | |
); | |
// 在购买或重装结束时解雇 | |
event onEndTx | |
( | |
uint256 compressedData, | |
uint256 compressedIDs, | |
bytes32 playerName, | |
address playerAddress, | |
uint256 ethIn, | |
uint256 keysBought, | |
address winnerAddr, | |
bytes32 winnerName, | |
uint256 amountWon, | |
uint256 newPot, | |
uint256 P3DAmount, | |
uint256 genAmount, | |
uint256 potAmount, | |
uint256 airDropPot | |
); | |
// 只要有人退出就会被解雇 | |
event onWithdraw | |
( | |
uint256 indexed playerID, | |
address playerAddress, | |
bytes32 playerName, | |
uint256 ethOut, | |
uint256 timeStamp | |
); | |
// 每当撤军力量结束时,就会被解雇 | |
event onWithdrawAndDistribute | |
( | |
address playerAddress, | |
bytes32 playerName, | |
uint256 ethOut, | |
uint256 compressedData, | |
uint256 compressedIDs, | |
address winnerAddr, | |
bytes32 winnerName, | |
uint256 amountWon, | |
uint256 newPot, | |
uint256 P3DAmount, | |
uint256 genAmount | |
); | |
// (fomo3d免费) 每当玩家尝试一轮又一轮的计时器时就会被解雇 | |
// 命中零,并导致结束回合 | |
event onBuyAndDistribute | |
( | |
address playerAddress, | |
bytes32 playerName, | |
uint256 ethIn, | |
uint256 compressedData, | |
uint256 compressedIDs, | |
address winnerAddr, | |
bytes32 winnerName, | |
uint256 amountWon, | |
uint256 newPot, | |
uint256 P3DAmount, | |
uint256 genAmount | |
); | |
// (fomo3d免费) 每当玩家在圆形时间后尝试重新加载时就会触发 | |
// 命中零,并导致结束回合. | |
event onReLoadAndDistribute | |
( | |
address playerAddress, | |
bytes32 playerName, | |
uint256 compressedData, | |
uint256 compressedIDs, | |
address winnerAddr, | |
bytes32 winnerName, | |
uint256 amountWon, | |
uint256 newPot, | |
uint256 P3DAmount, | |
uint256 genAmount | |
); | |
// 每当联盟会员付款时就会被解雇 | |
event onAffiliatePayout | |
( | |
uint256 indexed affiliateID, | |
address affiliateAddress, | |
bytes32 affiliateName, | |
uint256 indexed roundID, | |
uint256 indexed buyerID, | |
uint256 amount, | |
uint256 timeStamp | |
); | |
// 收到罐子掉期存款 | |
event onPotSwapDeposit | |
( | |
uint256 roundID, | |
uint256 amountAddedToPot | |
); | |
} | |
//============================================================================== | |
// _ _ _ _|_ _ _ __|_ _ _ _|_ _ . | |
// (_(_)| | | | (_|(_ | _\(/_ | |_||_) . | |
//====================================|========================================= | |
contract modularShort is F3Devents {} | |
contract WorldFomo is modularShort { | |
using SafeMath for *; | |
using NameFilter for string; | |
using F3DKeysCalcShort for uint256; | |
PlayerBookInterface constant private PlayerBook = PlayerBookInterface(0x6ed17ee485821cd47531f2e4c7b9ef8b48f2bab5); | |
//============================================================================== | |
// _ _ _ |`. _ _ _ |_ | _ _ . | |
// (_(_)| |~|~|(_||_|| (_||_)|(/__\ . (游戏设置) | |
//=================_|=========================================================== | |
address private admin = msg.sender; | |
string constant public name = "WorldFomo"; | |
string constant public symbol = "WF"; | |
uint256 private rndExtra_ = 15 seconds; // 第一个ICO的长度 | |
uint256 private rndGap_ = 30 minutes; // ICO阶段的长度,EOS设定为1年。 | |
uint256 constant private rndInit_ = 30 minutes; // 圆计时器从此开始 | |
uint256 constant private rndInc_ = 10 seconds; // 购买的每一把钥匙都会给计时器增加很多 | |
uint256 constant private rndMax_ = 12 hours; // 圆形计时器的最大长度可以是 | |
//============================================================================== | |
// _| _ _|_ _ _ _ _|_ _ . | |
// (_|(_| | (_| _\(/_ | |_||_) . (用于存储更改的游戏信息的数据) | |
//=============================|================================================ | |
uint256 public airDropPot_; // 获得空投的人赢得了这个锅的一部分 | |
uint256 public airDropTracker_ = 0; // 每次“合格”tx发生时递增。用于确定获胜的空投 | |
uint256 public rID_; // 已发生的轮次ID /总轮数 | |
//**************** | |
// 球员数据 | |
//**************** | |
mapping (address => uint256) public pIDxAddr_; // (addr => pID)按地址返回玩家ID | |
mapping (bytes32 => uint256) public pIDxName_; // (name => pID)按名称返回玩家ID | |
mapping (uint256 => F3Ddatasets.Player) public plyr_; // (pID => data) 球员数据 | |
mapping (uint256 => mapping (uint256 => F3Ddatasets.PlayerRounds)) public plyrRnds_; // (pID => rID => data) 玩家ID和轮次ID的玩家轮数据 | |
mapping (uint256 => mapping (bytes32 => bool)) public plyrNames_; // (pID => name => bool)玩家拥有的名字列表。 (用于这样您可以在您拥有的任何名称中更改您的显示名称) | |
//**************** | |
// 圆形数据 | |
//**************** | |
mapping (uint256 => F3Ddatasets.Round) public round_; // (rID => data) 圆形数据 | |
mapping (uint256 => mapping(uint256 => uint256)) public rndTmEth_; // (rID => tID => 数据)每个团队的eth,by round id和team id | |
//**************** | |
// 团队收费数据 | |
//**************** | |
mapping (uint256 => F3Ddatasets.TeamFee) public fees_; // (team => fees) 按团队分配费用 | |
mapping (uint256 => F3Ddatasets.PotSplit) public potSplit_; // (team => fees) 锅分裂由团队分配 | |
//============================================================================== | |
// _ _ _ __|_ _ __|_ _ _ . | |
// (_(_)| |_\ | | |_|(_ | (_)| . (合同部署时的初始数据设置) | |
//============================================================================== | |
constructor() | |
public | |
{ | |
// 团队分配结构 | |
// 0 = europe | |
// 1 = freeforall | |
// 2 = china | |
// 3 = americas | |
// 团队分配百分比 | |
// (F3D, P3D) + (Pot , Referrals, Community) | |
// 介绍人 / 社区奖励在数学上被设计为来自获胜者的底池份额. | |
fees_[0] = F3Ddatasets.TeamFee(32,0); //50% to pot, 15% to aff, 3% to com, 0% to pot swap, 0% to air drop pot | |
fees_[1] = F3Ddatasets.TeamFee(45,0); //37% to pot, 15% to aff, 3% to com, 0% to pot swap, 0% to air drop pot | |
fees_[2] = F3Ddatasets.TeamFee(62,0); //20% to pot, 15% to aff, 3% to com, 0% to pot swap, 0% to air drop pot | |
fees_[3] = F3Ddatasets.TeamFee(47,0); //35% to pot, 15% to aff, 3% to com, 0% to pot swap, 0% to air drop pot | |
// 如何根据选择的球队分割最终的底池 | |
// (F3D, P3D) | |
potSplit_[0] = F3Ddatasets.PotSplit(47,0); //25% to winner, 25% to next round, 3% to com | |
potSplit_[1] = F3Ddatasets.PotSplit(47,0); //25% to winner, 25% to next round, 3% to com | |
potSplit_[2] = F3Ddatasets.PotSplit(62,0); //25% to winner, 10% to next round, 3% to com | |
potSplit_[3] = F3Ddatasets.PotSplit(62,0); //25% to winner, 10% to next round,3% to com | |
} | |
//============================================================================== | |
// _ _ _ _|. |`. _ _ _ . | |
// | | |(_)(_||~|~|(/_| _\ . (这些都是安全检查) | |
//============================================================================== | |
/** | |
* @dev 用于确保在激活之前没有人可以与合同互动. | |
* | |
*/ | |
modifier isActivated() { | |
require(activated_ == true, "its not ready yet. check ?eta in discord"); | |
_; | |
} | |
/** | |
* @dev 防止合同与fomo3d交互 | |
*/ | |
modifier isHuman() { | |
require(msg.sender == tx.origin, "sorry humans only - FOR REAL THIS TIME"); | |
_; | |
} | |
/** | |
* @dev 设置传入tx的边界 | |
*/ | |
modifier isWithinLimits(uint256 _eth) { | |
require(_eth >= 1000000000, "pocket lint: not a valid currency"); | |
require(_eth <= 100000000000000000000000, "no vitalik, no"); | |
_; | |
} | |
//============================================================================== | |
// _ |_ |. _ |` _ __|_. _ _ _ . | |
// |_)|_||_)||(_ ~|~|_|| |(_ | |(_)| |_\ . (用这些来与合同互动) | |
//====|========================================================================= | |
/** | |
* @dev 紧急购买使用最后存储的会员ID和团队潜行 | |
*/ | |
function() | |
isActivated() | |
isHuman() | |
isWithinLimits(msg.value) | |
public | |
payable | |
{ | |
// 设置我们的tx事件数据并确定玩家是否是新手 | |
F3Ddatasets.EventReturns memory _eventData_ = determinePID(_eventData_); | |
// 获取玩家ID | |
uint256 _pID = pIDxAddr_[msg.sender]; | |
// 买核心 | |
buyCore(_pID, plyr_[_pID].laff, 2, _eventData_); | |
} | |
/** | |
* @dev 将所有传入的以太坊转换为键. | |
* -functionhash- 0x8f38f309 (使用ID作为会员) | |
* -functionhash- 0x98a0871d (使用联盟会员的地址) | |
* -functionhash- 0xa65b37a1 (使用联盟会员的名称) | |
* @param _affCode 获得联盟费用的玩家的ID /地址/名称 | |
* @param _team 什么球队是球员? | |
*/ | |
function buyXid(uint256 _affCode, uint256 _team) | |
isActivated() | |
isHuman() | |
isWithinLimits(msg.value) | |
public | |
payable | |
{ | |
// 设置我们的tx事件数据并确定玩家是否是新手 | |
F3Ddatasets.EventReturns memory _eventData_ = determinePID(_eventData_); | |
// 获取玩家ID | |
uint256 _pID = pIDxAddr_[msg.sender]; | |
// 管理会员残差 | |
// 如果没有给出联盟代码或者玩家试图使用他们自己的代码 | |
if (_affCode == 0 || _affCode == _pID) | |
{ | |
// 使用最后存储的联盟代码 | |
_affCode = plyr_[_pID].laff; | |
// 如果提供联属代码并且它与先前存储的不同 | |
} else if (_affCode != plyr_[_pID].laff) { | |
// 更新最后一个会员 | |
plyr_[_pID].laff = _affCode; | |
} | |
// 验证是否选择了有效的团队 | |
_team = verifyTeam(_team); | |
// 买核心 | |
buyCore(_pID, _affCode, _team, _eventData_); | |
} | |
function buyXaddr(address _affCode, uint256 _team) | |
isActivated() | |
isHuman() | |
isWithinLimits(msg.value) | |
public | |
payable | |
{ | |
// 设置我们的tx事件数据并确定玩家是否是新手 | |
F3Ddatasets.EventReturns memory _eventData_ = determinePID(_eventData_); | |
// 获取玩家ID | |
uint256 _pID = pIDxAddr_[msg.sender]; | |
// 管理会员残差 | |
uint256 _affID; | |
// 如果没有给出联盟代码或者玩家试图使用他们自己的代码 | |
if (_affCode == address(0) || _affCode == msg.sender) | |
{ | |
// 使用最后存储的联盟代码 | |
_affID = plyr_[_pID].laff; | |
// 如果是联盟代码 | |
} else { | |
// 从aff Code获取会员ID | |
_affID = pIDxAddr_[_affCode]; | |
// 如果affID与先前存储的不同 | |
if (_affID != plyr_[_pID].laff) | |
{ | |
// 更新最后一个会员 | |
plyr_[_pID].laff = _affID; | |
} | |
} | |
// 验证是否选择了有效的团队 | |
_team = verifyTeam(_team); | |
// 买核心 | |
buyCore(_pID, _affID, _team, _eventData_); | |
} | |
function buyXname(bytes32 _affCode, uint256 _team) | |
isActivated() | |
isHuman() | |
isWithinLimits(msg.value) | |
public | |
payable | |
{ | |
// 设置我们的tx事件数据并确定玩家是否是新手 | |
F3Ddatasets.EventReturns memory _eventData_ = determinePID(_eventData_); | |
// 获取玩家ID | |
uint256 _pID = pIDxAddr_[msg.sender]; | |
// 管理会员残差 | |
uint256 _affID; | |
// 如果没有给出联盟代码或者玩家试图使用他们自己的代码 | |
if (_affCode == '' || _affCode == plyr_[_pID].name) | |
{ | |
// 使用最后存储的联盟代码 | |
_affID = plyr_[_pID].laff; | |
// 如果是联盟代码 | |
} else { | |
// 从aff Code获取会员ID | |
_affID = pIDxName_[_affCode]; | |
// 如果affID与先前存储的不同 | |
if (_affID != plyr_[_pID].laff) | |
{ | |
// 更新最后一个会员 | |
plyr_[_pID].laff = _affID; | |
} | |
} | |
// 验证是否选择了有效的团队 | |
_team = verifyTeam(_team); | |
// 买核心 | |
buyCore(_pID, _affID, _team, _eventData_); | |
} | |
/** | |
* @dev 基本上与买相同,但不是你发送以太 | |
* 从您的钱包中,它使用您未提取的收入. | |
* -functionhash- 0x349cdcac (使用ID作为会员) | |
* -functionhash- 0x82bfc739 (使用联盟会员的地址) | |
* -functionhash- 0x079ce327 (使用联盟会员的名称) | |
* @param _affCode 获得联盟费用的玩家的ID /地址/名称 | |
* @param _team 球员在哪支球队? | |
* @param _eth 使用的收入金额(余额退回基金库) | |
*/ | |
function reLoadXid(uint256 _affCode, uint256 _team, uint256 _eth) | |
isActivated() | |
isHuman() | |
isWithinLimits(_eth) | |
public | |
{ | |
// 设置我们的tx事件数据 | |
F3Ddatasets.EventReturns memory _eventData_; | |
// 获取玩家ID | |
uint256 _pID = pIDxAddr_[msg.sender]; | |
// 管理会员残差 | |
// 如果没有给出联盟代码或者玩家试图使用他们自己的代码 | |
if (_affCode == 0 || _affCode == _pID) | |
{ | |
// 使用最后存储的联盟代码 | |
_affCode = plyr_[_pID].laff; | |
// 如果提供联属代码并且它与先前存储的不同 | |
} else if (_affCode != plyr_[_pID].laff) { | |
// 更新最后一个会员 | |
plyr_[_pID].laff = _affCode; | |
} | |
// 验证是否选择了有效的团队 | |
_team = verifyTeam(_team); | |
// 重装核心 | |
reLoadCore(_pID, _affCode, _team, _eth, _eventData_); | |
} | |
function reLoadXaddr(address _affCode, uint256 _team, uint256 _eth) | |
isActivated() | |
isHuman() | |
isWithinLimits(_eth) | |
public | |
{ | |
// 设置我们的tx事件数据 | |
F3Ddatasets.EventReturns memory _eventData_; | |
// 获取玩家ID | |
uint256 _pID = pIDxAddr_[msg.sender]; | |
// 管理会员残差 | |
uint256 _affID; | |
// 如果没有给出联盟代码或者玩家试图使用他们自己的代码 | |
if (_affCode == address(0) || _affCode == msg.sender) | |
{ | |
// 使用最后存储的联盟代码 | |
_affID = plyr_[_pID].laff; | |
// 如果是联盟代码 | |
} else { | |
// 从aff Code获取会员ID | |
_affID = pIDxAddr_[_affCode]; | |
// 如果affID与先前存储的不同 | |
if (_affID != plyr_[_pID].laff) | |
{ | |
// 更新最后一个会员 | |
plyr_[_pID].laff = _affID; | |
} | |
} | |
// 验证是否选择了有效的团队 | |
_team = verifyTeam(_team); | |
// 重装核心 | |
reLoadCore(_pID, _affID, _team, _eth, _eventData_); | |
} | |
function reLoadXname(bytes32 _affCode, uint256 _team, uint256 _eth) | |
isActivated() | |
isHuman() | |
isWithinLimits(_eth) | |
public | |
{ | |
// 设置我们的tx事件数据 | |
F3Ddatasets.EventReturns memory _eventData_; | |
// 获取玩家ID | |
uint256 _pID = pIDxAddr_[msg.sender]; | |
// 管理会员残差 | |
uint256 _affID; | |
// 如果没有给出联盟代码或者玩家试图使用他们自己的代码 | |
if (_affCode == '' || _affCode == plyr_[_pID].name) | |
{ | |
// 使用最后存储的联盟代码 | |
_affID = plyr_[_pID].laff; | |
// 如果是联盟代码 | |
} else { | |
// 从aff Code获取会员ID | |
_affID = pIDxName_[_affCode]; | |
// 如果affID与先前存储的不同 | |
if (_affID != plyr_[_pID].laff) | |
{ | |
// 更新最后一个会员 | |
plyr_[_pID].laff = _affID; | |
} | |
} | |
// 验证是否选择了有效的团队 | |
_team = verifyTeam(_team); | |
// 重装核心 | |
reLoadCore(_pID, _affID, _team, _eth, _eventData_); | |
} | |
/** | |
* @dev 撤回所有收入. | |
* -functionhash- 0x3ccfd60b | |
*/ | |
function withdraw() | |
isActivated() | |
isHuman() | |
public | |
{ | |
// 设置本地rID | |
uint256 _rID = rID_; | |
// 抓住时间 | |
uint256 _now = now; | |
// 获取玩家ID | |
uint256 _pID = pIDxAddr_[msg.sender]; | |
// 为玩家eth设置temp var | |
uint256 _eth; | |
// 检查圆是否已经结束并且还没有人绕圈结束 | |
if (_now > round_[_rID].end && round_[_rID].ended == false && round_[_rID].plyr != 0) | |
{ | |
// 设置我们的tx事件数据 | |
F3Ddatasets.EventReturns memory _eventData_; | |
// 圆形结束(分配锅) | |
round_[_rID].ended = true; | |
_eventData_ = endRound(_eventData_); | |
// 得到他们的收入 | |
_eth = withdrawEarnings(_pID); | |
// 给钱 | |
if (_eth > 0) | |
plyr_[_pID].addr.transfer(_eth); | |
// 构建事件数据 | |
_eventData_.compressedData = _eventData_.compressedData + (_now * 1000000000000000000); | |
_eventData_.compressedIDs = _eventData_.compressedIDs + _pID; | |
// 火灾撤回和分发事件 | |
emit F3Devents.onWithdrawAndDistribute | |
( | |
msg.sender, | |
plyr_[_pID].name, | |
_eth, | |
_eventData_.compressedData, | |
_eventData_.compressedIDs, | |
_eventData_.winnerAddr, | |
_eventData_.winnerName, | |
_eventData_.amountWon, | |
_eventData_.newPot, | |
_eventData_.P3DAmount, | |
_eventData_.genAmount | |
); | |
// 在任何其他情况下 | |
} else { | |
// 得到他们的收入 | |
_eth = withdrawEarnings(_pID); | |
// 给钱 | |
if (_eth > 0) | |
plyr_[_pID].addr.transfer(_eth); | |
// 消防事件 | |
emit F3Devents.onWithdraw(_pID, msg.sender, plyr_[_pID].name, _eth, _now); | |
} | |
} | |
/** | |
* @dev 使用这些来注册名称。它们只是将注册请求发送给PlayerBook合同的包装器。所以在这里注册与在那里注册是一样的。 | |
* UI将始终显示您注册的姓氏,但您仍将拥有所有以前注册的名称以用作会员链接。 | |
* - 必须支付注册费 | |
* - 名称必须是唯一的 | |
* - 名称将转换为小写 | |
* - 名称不能以空格开头或结尾 | |
* - 连续不能超过1个空格 | |
* - 不能只是数字 | |
* - 不能以0x开头 | |
* - name必须至少为1个字符 | |
* - 最大长度为32个字符 | |
* - 允许的字符:a-z,0-9和空格 | |
* -functionhash- 0x921dec21 (使用ID作为会员) | |
* -functionhash- 0x3ddd4698 (使用联盟会员的地址) | |
* -functionhash- 0x685ffd83 (使用联盟会员的名称) | |
* @param _nameString 球员想要的名字 | |
* @param _affCode 会员ID,地址或推荐您的人的姓名 | |
* @param _all 如果您希望将信息推送到所有游戏,则设置为true | |
* (这可能会耗费大量气体) | |
*/ | |
function registerNameXID(string _nameString, uint256 _affCode, bool _all) | |
isHuman() | |
public | |
payable | |
{ | |
bytes32 _name = _nameString.nameFilter(); | |
address _addr = msg.sender; | |
uint256 _paid = msg.value; | |
(bool _isNewPlayer, uint256 _affID) = PlayerBook.registerNameXIDFromDapp.value(_paid)(_addr, _name, _affCode, _all); | |
uint256 _pID = pIDxAddr_[_addr]; | |
// 火灾事件 | |
emit F3Devents.onNewName(_pID, _addr, _name, _isNewPlayer, _affID, plyr_[_affID].addr, plyr_[_affID].name, _paid, now); | |
} | |
function registerNameXaddr(string _nameString, address _affCode, bool _all) | |
isHuman() | |
public | |
payable | |
{ | |
bytes32 _name = _nameString.nameFilter(); | |
address _addr = msg.sender; | |
uint256 _paid = msg.value; | |
(bool _isNewPlayer, uint256 _affID) = PlayerBook.registerNameXaddrFromDapp.value(msg.value)(msg.sender, _name, _affCode, _all); | |
uint256 _pID = pIDxAddr_[_addr]; | |
// 火灾事件 | |
emit F3Devents.onNewName(_pID, _addr, _name, _isNewPlayer, _affID, plyr_[_affID].addr, plyr_[_affID].name, _paid, now); | |
} | |
function registerNameXname(string _nameString, bytes32 _affCode, bool _all) | |
isHuman() | |
public | |
payable | |
{ | |
bytes32 _name = _nameString.nameFilter(); | |
address _addr = msg.sender; | |
uint256 _paid = msg.value; | |
(bool _isNewPlayer, uint256 _affID) = PlayerBook.registerNameXnameFromDapp.value(msg.value)(msg.sender, _name, _affCode, _all); | |
uint256 _pID = pIDxAddr_[_addr]; | |
// 火灾事件 | |
emit F3Devents.onNewName(_pID, _addr, _name, _isNewPlayer, _affID, plyr_[_affID].addr, plyr_[_affID].name, _paid, now); | |
} | |
//============================================================================== | |
// _ _ _|__|_ _ _ _ . | |
// (_|(/_ | | (/_| _\ . (用于UI和查看etherscan上的东西) | |
//=====_|======================================================================= | |
/** | |
* @dev 退货价格买家将支付下一个个人钥匙. | |
* -functionhash- 0x018a25e8 | |
* @return 购买下一个钥匙的价格(以wei格式) | |
*/ | |
function getBuyPrice() | |
public | |
view | |
returns(uint256) | |
{ | |
// 设置本地rID | |
uint256 _rID = rID_; | |
// 抓住时间 | |
uint256 _now = now; | |
// 我们是一个回合? | |
if (_now > round_[_rID].strt + rndGap_ && (_now <= round_[_rID].end || (_now > round_[_rID].end && round_[_rID].plyr == 0))) | |
return ( (round_[_rID].keys.add(1000000000000000000)).ethRec(1000000000000000000) ); | |
else // rounds over. need price for new round | |
return ( 75000000000000 ); // init | |
} | |
/** | |
* @dev 返回剩余时间。不要垃圾邮件,你可以从你的节点提供商那里得到你自己 | |
* -functionhash- 0xc7e284b8 | |
* @return 时间在几秒钟内 | |
*/ | |
function getTimeLeft() | |
public | |
view | |
returns(uint256) | |
{ | |
// 设置本地rID | |
uint256 _rID = rID_; | |
// 抓住时间 | |
uint256 _now = now; | |
if (_now < round_[_rID].end) | |
if (_now > round_[_rID].strt + rndGap_) | |
return( (round_[_rID].end).sub(_now) ); | |
else | |
return( (round_[_rID].strt + rndGap_).sub(_now) ); | |
else | |
return(0); | |
} | |
/** | |
* @dev 每个金库返回玩家收入 | |
* -functionhash- 0x63066434 | |
* @return 赢得金库 | |
* @return 一般金库 | |
* @return 会员保险库 | |
*/ | |
function getPlayerVaults(uint256 _pID) | |
public | |
view | |
returns(uint256 ,uint256, uint256) | |
{ | |
// 设置本地rID | |
uint256 _rID = rID_; | |
// 如果圆结束了但圆形结束尚未运行(因此合同没有分配奖金) | |
if (now > round_[_rID].end && round_[_rID].ended == false && round_[_rID].plyr != 0) | |
{ | |
// 如果球员是胜利者 | |
if (round_[_rID].plyr == _pID) | |
{ | |
return | |
( | |
(plyr_[_pID].win).add( ((round_[_rID].pot).mul(25)) / 100 ), | |
(plyr_[_pID].gen).add( getPlayerVaultsHelper(_pID, _rID).sub(plyrRnds_[_pID][_rID].mask) ), | |
plyr_[_pID].aff | |
); | |
// 如果玩家不是赢家 | |
} else { | |
return | |
( | |
plyr_[_pID].win, | |
(plyr_[_pID].gen).add( getPlayerVaultsHelper(_pID, _rID).sub(plyrRnds_[_pID][_rID].mask) ), | |
plyr_[_pID].aff | |
); | |
} | |
// 如果圆形仍在继续,或圆形已经结束并且圆形结束已经运行 | |
} else { | |
return | |
( | |
plyr_[_pID].win, | |
(plyr_[_pID].gen).add(calcUnMaskedEarnings(_pID, plyr_[_pID].lrnd)), | |
plyr_[_pID].aff | |
); | |
} | |
} | |
/** | |
* 坚固不喜欢堆栈限制。这让我们避免那种仇恨 | |
*/ | |
function getPlayerVaultsHelper(uint256 _pID, uint256 _rID) | |
private | |
view | |
returns(uint256) | |
{ | |
return( ((((round_[_rID].mask).add(((((round_[_rID].pot).mul(potSplit_[round_[_rID].team].gen)) / 100).mul(1000000000000000000)) / (round_[_rID].keys))).mul(plyrRnds_[_pID][_rID].keys)) / 1000000000000000000) ); | |
} | |
/** | |
* @dev 返回前端所需的所有当前轮次信息 | |
* -functionhash- 0x747dff42 | |
* @return 在ICO阶段投资的eth | |
* @return 圆的身份 | |
* @return 圆的总钥匙 | |
* @return 时间到了 | |
* @return 时间开始了 | |
* @return 目前的锅 | |
* @return 领先的当前球队ID和球员ID | |
* @return 领先地址的当前玩家 | |
* @return 引导名称中的当前玩家 | |
* @return 鲸鱼为了圆形 | |
* @return b耳朵为圆形 | |
* @return 为了回合而进行的 | |
* @return 公牛队参加比赛 | |
* @return 空投跟踪器#&airdrop pot | |
*/ | |
function getCurrentRoundInfo() | |
public | |
view | |
returns(uint256, uint256, uint256, uint256, uint256, uint256, uint256, address, bytes32, uint256, uint256, uint256, uint256, uint256) | |
{ | |
// 设置本地rID | |
uint256 _rID = rID_; | |
return | |
( | |
round_[_rID].ico, //0 | |
_rID, //1 | |
round_[_rID].keys, //2 | |
round_[_rID].end, //3 | |
round_[_rID].strt, //4 | |
round_[_rID].pot, //5 | |
(round_[_rID].team + (round_[_rID].plyr * 10)), //6 | |
plyr_[round_[_rID].plyr].addr, //7 | |
plyr_[round_[_rID].plyr].name, //8 | |
rndTmEth_[_rID][0], //9 | |
rndTmEth_[_rID][1], //10 | |
rndTmEth_[_rID][2], //11 | |
rndTmEth_[_rID][3], //12 | |
airDropTracker_ + (airDropPot_ * 1000) //13 | |
); | |
} | |
/** | |
* @dev 根据地址返回玩家信息。如果没有给出地址,它会 | |
* use msg.sender | |
* -functionhash- 0xee0b5d8b | |
* @param _addr 您要查找的播放器的地址 | |
* @return 玩家ID | |
* @return 参赛者姓名 | |
* @return 密钥拥有(当前轮次) | |
* @return 赢得金库 | |
* @return 一般金库 | |
* @return 会员保险库 | |
* @return 球员圆的eth | |
*/ | |
function getPlayerInfoByAddress(address _addr) | |
public | |
view | |
returns(uint256, bytes32, uint256, uint256, uint256, uint256, uint256) | |
{ | |
// 设置本地rID | |
uint256 _rID = rID_; | |
if (_addr == address(0)) | |
{ | |
_addr == msg.sender; | |
} | |
uint256 _pID = pIDxAddr_[_addr]; | |
return | |
( | |
_pID, //0 | |
plyr_[_pID].name, //1 | |
plyrRnds_[_pID][_rID].keys, //2 | |
plyr_[_pID].win, //3 | |
(plyr_[_pID].gen).add(calcUnMaskedEarnings(_pID, plyr_[_pID].lrnd)), //4 | |
plyr_[_pID].aff, //5 | |
plyrRnds_[_pID][_rID].eth //6 | |
); | |
} | |
//============================================================================== | |
// _ _ _ _ | _ _ . _ . | |
// (_(_)| (/_ |(_)(_||(_ . (这+工具+计算+模块=我们的软件引擎) | |
//=====================_|======================================================= | |
/** | |
* @dev 每当执行买单时,逻辑就会运行。决定如何处理 | |
* 传入的道德取决于我们是否处于活跃轮次 | |
*/ | |
function buyCore(uint256 _pID, uint256 _affID, uint256 _team, F3Ddatasets.EventReturns memory _eventData_) | |
private | |
{ | |
// 设置本地rID | |
uint256 _rID = rID_; | |
// 抓住时间 | |
uint256 _now = now; | |
// 如果圆形是活跃的 | |
if (_now > round_[_rID].strt + rndGap_ && (_now <= round_[_rID].end || (_now > round_[_rID].end && round_[_rID].plyr == 0))) | |
{ | |
// 致电核心 | |
core(_rID, _pID, msg.value, _affID, _team, _eventData_); | |
// 如果圆形不活跃 | |
} else { | |
// 检查是否需要运行结束轮次 | |
if (_now > round_[_rID].end && round_[_rID].ended == false) | |
{ | |
// 结束回合(分配锅)并开始新一轮 | |
round_[_rID].ended = true; | |
_eventData_ = endRound(_eventData_); | |
// 构建事件数据 | |
_eventData_.compressedData = _eventData_.compressedData + (_now * 1000000000000000000); | |
_eventData_.compressedIDs = _eventData_.compressedIDs + _pID; | |
// 火买和分发事件 | |
emit F3Devents.onBuyAndDistribute | |
( | |
msg.sender, | |
plyr_[_pID].name, | |
msg.value, | |
_eventData_.compressedData, | |
_eventData_.compressedIDs, | |
_eventData_.winnerAddr, | |
_eventData_.winnerName, | |
_eventData_.amountWon, | |
_eventData_.newPot, | |
_eventData_.P3DAmount, | |
_eventData_.genAmount | |
); | |
} | |
// 将eth放入球员保险库中 | |
plyr_[_pID].gen = plyr_[_pID].gen.add(msg.value); | |
} | |
} | |
/** | |
* @dev 每当执行重新加载订单时,逻辑就会运行。决定如何处理 | |
* 传入的道德取决于我们是否处于活跃轮次 | |
*/ | |
function reLoadCore(uint256 _pID, uint256 _affID, uint256 _team, uint256 _eth, F3Ddatasets.EventReturns memory _eventData_) | |
private | |
{ | |
// 设置本地rID | |
uint256 _rID = rID_; | |
// 抓住时间 | |
uint256 _now = now; | |
// 如果圆形是活跃的 | |
if (_now > round_[_rID].strt + rndGap_ && (_now <= round_[_rID].end || (_now > round_[_rID].end && round_[_rID].plyr == 0))) | |
{ | |
// 从所有金库中获取收益并将未使用的金额归还给gen保险库 | |
// 因为我们使用自定义safemath库。如果玩家,这将抛出 | |
// 他们试图花更多的时间。 | |
plyr_[_pID].gen = withdrawEarnings(_pID).sub(_eth); | |
// 致电核心 | |
core(_rID, _pID, _eth, _affID, _team, _eventData_); | |
// 如果round不活动并且需要运行end round | |
} else if (_now > round_[_rID].end && round_[_rID].ended == false) { | |
// end the round (distributes pot) & start new round | |
round_[_rID].ended = true; | |
_eventData_ = endRound(_eventData_); | |
// 构建事件数据 | |
_eventData_.compressedData = _eventData_.compressedData + (_now * 1000000000000000000); | |
_eventData_.compressedIDs = _eventData_.compressedIDs + _pID; | |
// 火买和分发事件 | |
emit F3Devents.onReLoadAndDistribute | |
( | |
msg.sender, | |
plyr_[_pID].name, | |
_eventData_.compressedData, | |
_eventData_.compressedIDs, | |
_eventData_.winnerAddr, | |
_eventData_.winnerName, | |
_eventData_.amountWon, | |
_eventData_.newPot, | |
_eventData_.P3DAmount, | |
_eventData_.genAmount | |
); | |
} | |
} | |
/** | |
* @dev 这是在回合生效期间发生的任何购买/重新加载的核心逻辑 | |
*/ | |
function core(uint256 _rID, uint256 _pID, uint256 _eth, uint256 _affID, uint256 _team, F3Ddatasets.EventReturns memory _eventData_) | |
private | |
{ | |
// 如果玩家是新手 | |
if (plyrRnds_[_pID][_rID].keys == 0) | |
_eventData_ = managePlayer(_pID, _eventData_); | |
// 早期的道路限制器 | |
if (round_[_rID].eth < 100000000000000000000 && plyrRnds_[_pID][_rID].eth.add(_eth) > 1000000000000000000) | |
{ | |
uint256 _availableLimit = (1000000000000000000).sub(plyrRnds_[_pID][_rID].eth); | |
uint256 _refund = _eth.sub(_availableLimit); | |
plyr_[_pID].gen = plyr_[_pID].gen.add(_refund); | |
_eth = _availableLimit; | |
} | |
// 如果留下的eth大于min eth允许(抱歉没有口袋棉绒) | |
if (_eth > 1000000000) | |
{ | |
// 铸造新钥匙 | |
uint256 _keys = (round_[_rID].eth).keysRec(_eth); | |
// 如果他们至少买了一把钥匙 | |
if (_keys >= 1000000000000000000) | |
{ | |
updateTimer(_keys, _rID); | |
// 树立新的领导者 | |
if (round_[_rID].plyr != _pID) | |
round_[_rID].plyr = _pID; | |
if (round_[_rID].team != _team) | |
round_[_rID].team = _team; | |
// 将新的领导者布尔设为真 | |
_eventData_.compressedData = _eventData_.compressedData + 100; | |
} | |
// 存储空投跟踪器编号(自上次空投以来的购买次数) | |
_eventData_.compressedData = _eventData_.compressedData + (airDropTracker_ * 1000); | |
// 更新播放器 | |
plyrRnds_[_pID][_rID].keys = _keys.add(plyrRnds_[_pID][_rID].keys); | |
plyrRnds_[_pID][_rID].eth = _eth.add(plyrRnds_[_pID][_rID].eth); | |
// 更新回合 | |
round_[_rID].keys = _keys.add(round_[_rID].keys); | |
round_[_rID].eth = _eth.add(round_[_rID].eth); | |
rndTmEth_[_rID][_team] = _eth.add(rndTmEth_[_rID][_team]); | |
// 分配道德 | |
_eventData_ = distributeExternal(_rID, _eth, _team, _eventData_); | |
_eventData_ = distributeInternal(_rID, _pID, _eth, _affID, _team, _keys, _eventData_); | |
// 调用end tx函数来触发结束tx事件。 | |
endTx(_pID, _team, _eth, _keys, _eventData_); | |
} | |
} | |
//============================================================================== | |
// _ _ | _ | _ _|_ _ _ _ . | |
// (_(_||(_|_||(_| | (_)| _\ . | |
//============================================================================== | |
/** | |
* @dev 计算未屏蔽的收入(只计算,不更新掩码)k) | |
* @return earnings in wei format | |
*/ | |
function calcUnMaskedEarnings(uint256 _pID, uint256 _rIDlast) | |
private | |
view | |
returns(uint256) | |
{ | |
return( (((round_[_rIDlast].mask).mul(plyrRnds_[_pID][_rIDlast].keys)) / (1000000000000000000)).sub(plyrRnds_[_pID][_rIDlast].mask) ); | |
} | |
/** | |
* @dev 返回给出一定数量eth的密钥数量. | |
* -functionhash- 0xce89c80c | |
* @param _rID round ID you want price for | |
* @param _eth amount of eth sent in | |
* @return keys received | |
*/ | |
function calcKeysReceived(uint256 _rID, uint256 _eth) | |
public | |
view | |
returns(uint256) | |
{ | |
// 抓住时间 | |
uint256 _now = now; | |
// 我们是一个回合? | |
if (_now > round_[_rID].strt + rndGap_ && (_now <= round_[_rID].end || (_now > round_[_rID].end && round_[_rID].plyr == 0))) | |
return ( (round_[_rID].eth).keysRec(_eth) ); | |
else // 转过来。需要新一轮的钥匙 | |
return ( (_eth).keys() ); | |
} | |
/** | |
* @dev 返回X键的当前eth价格。 | |
* -functionhash- 0xcf808000 | |
* @param _keys 所需的键数(18位十进制格式) | |
* @return 需要发送的eth数量 | |
*/ | |
function iWantXKeys(uint256 _keys) | |
public | |
view | |
returns(uint256) | |
{ | |
// 设置本地rID | |
uint256 _rID = rID_; | |
// 抓住时间 | |
uint256 _now = now; | |
// 我们是一个回合? | |
if (_now > round_[_rID].strt + rndGap_ && (_now <= round_[_rID].end || (_now > round_[_rID].end && round_[_rID].plyr == 0))) | |
return ( (round_[_rID].keys.add(_keys)).ethRec(_keys) ); | |
else // rounds over. need price for new round | |
return ( (_keys).eth() ); | |
} | |
//============================================================================== | |
// _|_ _ _ | _ . | |
// | (_)(_)|_\ . | |
//============================================================================== | |
/** | |
* @dev 从姓名合同中接收姓名/球员信息 | |
*/ | |
function receivePlayerInfo(uint256 _pID, address _addr, bytes32 _name, uint256 _laff) | |
external | |
{ | |
require (msg.sender == address(PlayerBook), "your not playerNames contract... hmmm.."); | |
if (pIDxAddr_[_addr] != _pID) | |
pIDxAddr_[_addr] = _pID; | |
if (pIDxName_[_name] != _pID) | |
pIDxName_[_name] = _pID; | |
if (plyr_[_pID].addr != _addr) | |
plyr_[_pID].addr = _addr; | |
if (plyr_[_pID].name != _name) | |
plyr_[_pID].name = _name; | |
if (plyr_[_pID].laff != _laff) | |
plyr_[_pID].laff = _laff; | |
if (plyrNames_[_pID][_name] == false) | |
plyrNames_[_pID][_name] = true; | |
} | |
/** | |
* @dev 接收整个玩家名单 | |
*/ | |
function receivePlayerNameList(uint256 _pID, bytes32 _name) | |
external | |
{ | |
require (msg.sender == address(PlayerBook), "your not playerNames contract... hmmm.."); | |
if(plyrNames_[_pID][_name] == false) | |
plyrNames_[_pID][_name] = true; | |
} | |
/** | |
* @dev 获得现有或注册新的pID。当玩家可能是新手时使用此功能 | |
* @return pID | |
*/ | |
function determinePID(F3Ddatasets.EventReturns memory _eventData_) | |
private | |
returns (F3Ddatasets.EventReturns) | |
{ | |
uint256 _pID = pIDxAddr_[msg.sender]; | |
// 如果玩家是这个版本的worldfomo的新手 | |
if (_pID == 0) | |
{ | |
// 从玩家姓名合同中获取他们的玩家ID,姓名和最后一个身份证 | |
_pID = PlayerBook.getPlayerID(msg.sender); | |
bytes32 _name = PlayerBook.getPlayerName(_pID); | |
uint256 _laff = PlayerBook.getPlayerLAff(_pID); | |
// 设置玩家帐户 | |
pIDxAddr_[msg.sender] = _pID; | |
plyr_[_pID].addr = msg.sender; | |
if (_name != "") | |
{ | |
pIDxName_[_name] = _pID; | |
plyr_[_pID].name = _name; | |
plyrNames_[_pID][_name] = true; | |
} | |
if (_laff != 0 && _laff != _pID) | |
plyr_[_pID].laff = _laff; | |
// 将新玩家bool设置为true | |
_eventData_.compressedData = _eventData_.compressedData + 1; | |
} | |
return (_eventData_); | |
} | |
/** | |
* @dev 检查以确保用户选择了一个有效的团队。如果没有设置团队 | |
* 默认(中国) | |
*/ | |
function verifyTeam(uint256 _team) | |
private | |
pure | |
returns (uint256) | |
{ | |
if (_team < 0 || _team > 3) | |
return(2); | |
else | |
return(_team); | |
} | |
/** | |
* @dev 决定是否需要运行圆形结束并开始新一轮。而如果 | |
* 需要移动之前玩过的球员未经掩盖的收入 | |
*/ | |
function managePlayer(uint256 _pID, F3Ddatasets.EventReturns memory _eventData_) | |
private | |
returns (F3Ddatasets.EventReturns) | |
{ | |
// 如果玩家已经玩过上一轮,则移动他们未经掩盖的收益 | |
// 从那一轮到生成金库。 | |
if (plyr_[_pID].lrnd != 0) | |
updateGenVault(_pID, plyr_[_pID].lrnd); | |
// 更新玩家的最后一轮比赛 | |
plyr_[_pID].lrnd = rID_; | |
// 将连接的圆形bool设置为true | |
_eventData_.compressedData = _eventData_.compressedData + 10; | |
return(_eventData_); | |
} | |
/** | |
* @dev 结束这一轮。管理支付赢家/拆分锅 | |
*/ | |
function endRound(F3Ddatasets.EventReturns memory _eventData_) | |
private | |
returns (F3Ddatasets.EventReturns) | |
{ | |
// 设置本地rID | |
uint256 _rID = rID_; | |
// 抓住我们的获胜球员和球队ID | |
uint256 _winPID = round_[_rID].plyr; | |
uint256 _winTID = round_[_rID].team; | |
// 抓住我们的锅量 | |
uint256 _pot = round_[_rID].pot; | |
// 计算我们的赢家份额,社区奖励,发行份额, | |
// 份额,以及为下一个底池保留的金额 | |
uint256 _win = (_pot.mul(25)) / 100; | |
uint256 _com = (_pot.mul(3)) / 100; | |
uint256 _gen = (_pot.mul(potSplit_[_winTID].gen)) / 100; | |
uint256 _p3d = (_pot.mul(potSplit_[_winTID].p3d)) / 100; | |
uint256 _res = (((_pot.sub(_win)).sub(_com)).sub(_gen)).sub(_p3d); | |
// k计算圆形面罩的ppt | |
uint256 _ppt = (_gen.mul(1000000000000000000)) / (round_[_rID].keys); | |
uint256 _dust = _gen.sub((_ppt.mul(round_[_rID].keys)) / 1000000000000000000); | |
if (_dust > 0) | |
{ | |
_gen = _gen.sub(_dust); | |
_res = _res.add(_dust); | |
} | |
// 支付我们的赢家 | |
plyr_[_winPID].win = _win.add(plyr_[_winPID].win); | |
// 社区奖励 | |
admin.transfer(_com); | |
// 将gen部分分配给密钥持有者 | |
round_[_rID].mask = _ppt.add(round_[_rID].mask); | |
// 准备事件数据 | |
_eventData_.compressedData = _eventData_.compressedData + (round_[_rID].end * 1000000); | |
_eventData_.compressedIDs = _eventData_.compressedIDs + (_winPID * 100000000000000000000000000) + (_winTID * 100000000000000000); | |
_eventData_.winnerAddr = plyr_[_winPID].addr; | |
_eventData_.winnerName = plyr_[_winPID].name; | |
_eventData_.amountWon = _win; | |
_eventData_.genAmount = _gen; | |
_eventData_.P3DAmount = _p3d; | |
_eventData_.newPot = _res; | |
// 下一轮开始 | |
rID_++; | |
_rID++; | |
round_[_rID].strt = now; | |
round_[_rID].end = now.add(rndInit_).add(rndGap_); | |
round_[_rID].pot = _res; | |
return(_eventData_); | |
} | |
/** | |
* @dev moves any unmasked earnings to gen vault. updates earnings mask | |
*/ | |
function updateGenVault(uint256 _pID, uint256 _rIDlast) | |
private | |
{ | |
uint256 _earnings = calcUnMaskedEarnings(_pID, _rIDlast); | |
if (_earnings > 0) | |
{ | |
// 放入gen库 | |
plyr_[_pID].gen = _earnings.add(plyr_[_pID].gen); | |
// 通过更新面具将收入归零 | |
plyrRnds_[_pID][_rIDlast].mask = _earnings.add(plyrRnds_[_pID][_rIDlast].mask); | |
} | |
} | |
/** | |
* @dev 根据购买的全部密钥数量更新圆形计时器。 | |
*/ | |
function updateTimer(uint256 _keys, uint256 _rID) | |
private | |
{ | |
// 抓住时间 | |
uint256 _now = now; | |
// 根据购买的钥匙数计算时间 | |
uint256 _newTime; | |
if (_now > round_[_rID].end && round_[_rID].plyr == 0) | |
_newTime = (((_keys) / (1000000000000000000)).mul(rndInc_)).add(_now); | |
else | |
_newTime = (((_keys) / (1000000000000000000)).mul(rndInc_)).add(round_[_rID].end); | |
// 比较max并设置新的结束时间 | |
if (_newTime < (rndMax_).add(_now)) | |
round_[_rID].end = _newTime; | |
else | |
round_[_rID].end = rndMax_.add(_now); | |
} | |
/** | |
* @dev 生成0-99之间的随机数并检查是否存在 | |
* 导致空投获胜 | |
* @return 我们有赢家吗?我们有赢家吗? | |
*/ | |
function airdrop() | |
private | |
view | |
returns(bool) | |
{ | |
uint256 seed = uint256(keccak256(abi.encodePacked( | |
(block.timestamp).add | |
(block.difficulty).add | |
((uint256(keccak256(abi.encodePacked(block.coinbase)))) / (now)).add | |
(block.gaslimit).add | |
((uint256(keccak256(abi.encodePacked(msg.sender)))) / (now)).add | |
(block.number) | |
))); | |
if((seed - ((seed / 1000) * 1000)) < airDropTracker_) | |
return(true); | |
else | |
return(false); | |
} | |
/** | |
* @dev 根据对com,aff和p3d的费用分配eth | |
*/ | |
function distributeExternal(uint256 _rID, uint256 _eth, uint256 _team, F3Ddatasets.EventReturns memory _eventData_) | |
private | |
returns(F3Ddatasets.EventReturns) | |
{ | |
// 支付3%的社区奖励 | |
uint256 _com = (_eth.mul(3)) / 100; | |
uint256 _p3d; | |
if (!address(admin).call.value(_com)()) | |
{ | |
_p3d = _com; | |
_com = 0; | |
} | |
// 支付p3d | |
_p3d = _p3d.add((_eth.mul(fees_[_team].p3d)) / (100)); | |
if (_p3d > 0) | |
{ | |
round_[_rID].pot = round_[_rID].pot.add(_p3d); | |
// 设置事件数据 | |
_eventData_.P3DAmount = _p3d.add(_eventData_.P3DAmount); | |
} | |
return(_eventData_); | |
} | |
function potSwap() | |
external | |
payable | |
{ | |
// 设置本地rID | |
uint256 _rID = rID_ + 1; | |
round_[_rID].pot = round_[_rID].pot.add(msg.value); | |
emit F3Devents.onPotSwapDeposit(_rID, msg.value); | |
} | |
/** | |
* @dev 根据对gen和pot的费用分配eth | |
*/ | |
function distributeInternal(uint256 _rID, uint256 _pID, uint256 _eth, uint256 _affID, uint256 _team, uint256 _keys, F3Ddatasets.EventReturns memory _eventData_) | |
private | |
returns(F3Ddatasets.EventReturns) | |
{ | |
// 计算gen份额 | |
uint256 _gen = (_eth.mul(fees_[_team].gen)) / 100; | |
// distribute share to affiliate 15% | |
uint256 _aff = (_eth.mul(15)) / 100; | |
// 更新道德平衡 (eth = eth - (com share + pot swap share + aff share)) | |
_eth = _eth.sub(((_eth.mul(18)) / 100).add((_eth.mul(fees_[_team].p3d)) / 100)); | |
// 计算锅 | |
uint256 _pot = _eth.sub(_gen); | |
// decide what to do with affiliate share of fees | |
// affiliate must not be self, and must have a name registered | |
if (_affID != _pID && plyr_[_affID].name != '') { | |
plyr_[_affID].aff = _aff.add(plyr_[_affID].aff); | |
emit F3Devents.onAffiliatePayout(_affID, plyr_[_affID].addr, plyr_[_affID].name, _rID, _pID, _aff, now); | |
} else { | |
_gen = _gen.add(_aff); | |
} | |
// 分配gen份额(这就是updateMasks()所做的)并进行调整 | |
// 灰尘平衡。 | |
uint256 _dust = updateMasks(_rID, _pID, _gen, _keys); | |
if (_dust > 0) | |
_gen = _gen.sub(_dust); | |
// 添加eth到pot | |
round_[_rID].pot = _pot.add(_dust).add(round_[_rID].pot); | |
// 设置事件数据 | |
_eventData_.genAmount = _gen.add(_eventData_.genAmount); | |
_eventData_.potAmount = _pot; | |
return(_eventData_); | |
} | |
/** | |
* @dev 购买钥匙时更新圆形和玩家的面具 | |
* @return 灰尘遗留下来 | |
*/ | |
function updateMasks(uint256 _rID, uint256 _pID, uint256 _gen, uint256 _keys) | |
private | |
returns(uint256) | |
{ | |
/* 掩盖笔记 | |
收入面具对人们来说是一个棘手的事情。 | |
这里要理解的基本内容。将有一个全球性的 | |
跟踪器基于每轮的每股利润,增加 | |
相关比例增加份额。 | |
玩家将有一个额外的面具基本上说“基于 | |
在回合面具,我的股票,以及我已经撤回了多少, | |
还欠我多少钱呢?“ | |
*/ | |
// 基于此购买的每个键和圆形面具的钙利润:(灰尘进入锅) | |
uint256 _ppt = (_gen.mul(1000000000000000000)) / (round_[_rID].keys); | |
round_[_rID].mask = _ppt.add(round_[_rID].mask); | |
// 计算玩家从他们自己购买的收入(仅基于钥匙 | |
// 他们刚刚买了)。并更新玩家收入掩 | |
uint256 _pearn = (_ppt.mul(_keys)) / (1000000000000000000); | |
plyrRnds_[_pID][_rID].mask = (((round_[_rID].mask.mul(_keys)) / (1000000000000000000)).sub(_pearn)).add(plyrRnds_[_pID][_rID].mask); | |
// 计算并返回灰尘 | |
return(_gen.sub((_ppt.mul(round_[_rID].keys)) / (1000000000000000000))); | |
} | |
/** | |
* @dev 加上未公开的收入和保险金收入,将它们全部设为0 | |
* @return wei格式的收益 | |
*/ | |
function withdrawEarnings(uint256 _pID) | |
private | |
returns(uint256) | |
{ | |
// 更新gen保险库 | |
updateGenVault(_pID, plyr_[_pID].lrnd); | |
// 来自金库 | |
uint256 _earnings = (plyr_[_pID].win).add(plyr_[_pID].gen).add(plyr_[_pID].aff); | |
if (_earnings > 0) | |
{ | |
plyr_[_pID].win = 0; | |
plyr_[_pID].gen = 0; | |
plyr_[_pID].aff = 0; | |
} | |
return(_earnings); | |
} | |
/** | |
* @dev 准备压缩数据并触发事件以进行购买或重新加载tx | |
*/ | |
function endTx(uint256 _pID, uint256 _team, uint256 _eth, uint256 _keys, F3Ddatasets.EventReturns memory _eventData_) | |
private | |
{ | |
_eventData_.compressedData = _eventData_.compressedData + (now * 1000000000000000000) + (_team * 100000000000000000000000000000); | |
_eventData_.compressedIDs = _eventData_.compressedIDs + _pID + (rID_ * 10000000000000000000000000000000000000000000000000000); | |
emit F3Devents.onEndTx | |
( | |
_eventData_.compressedData, | |
_eventData_.compressedIDs, | |
plyr_[_pID].name, | |
msg.sender, | |
_eth, | |
_keys, | |
_eventData_.winnerAddr, | |
_eventData_.winnerName, | |
_eventData_.amountWon, | |
_eventData_.newPot, | |
_eventData_.P3DAmount, | |
_eventData_.genAmount, | |
_eventData_.potAmount, | |
airDropPot_ | |
); | |
} | |
//============================================================================== | |
// (~ _ _ _._|_ . | |
// _)(/_(_|_|| | | \/ . | |
//====================/========================================================= | |
/** 合同部署后,它将被停用。这是一次 | |
* 使用将激活合同的功能。我们这样做是开发者 | |
* 有时间在网络端设置 **/ | |
bool public activated_ = false; | |
function activate() | |
public | |
{ | |
// 只有团队才能激活 | |
require(msg.sender == admin, "only admin can activate"); | |
// 只能跑一次 | |
require(activated_ == false, "FOMO Free already activated"); | |
// 激活合同 | |
activated_ = true; | |
// 让我们开始第一轮 | |
rID_ = 1; | |
round_[1].strt = now + rndExtra_ - rndGap_; | |
round_[1].end = now + rndInit_ + rndExtra_; | |
} | |
} | |
//============================================================================== | |
// __|_ _ __|_ _ . | |
// _\ | | |_|(_ | _\ . | |
//============================================================================== | |
library F3Ddatasets { | |
//压缩数据密钥 | |
// [76-33][32][31][30][29][28-18][17][16-6][5-3][2][1][0] | |
// 0 - new player (bool) | |
// 1 - joined round (bool) | |
// 2 - new leader (bool) | |
// 3-5 - air drop tracker (uint 0-999) | |
// 6-16 - round end time | |
// 17 - winnerTeam | |
// 18 - 28 timestamp | |
// 29 - team | |
// 30 - 0 = reinvest (round), 1 = buy (round), 2 = buy (ico), 3 = reinvest (ico) | |
// 31 - airdrop happened bool | |
// 32 - airdrop tier | |
// 33 - airdrop amount won | |
//压缩的ID密钥 | |
// [77-52][51-26][25-0] | |
// 0-25 - pID | |
// 26-51 - winPID | |
// 52-77 - rID | |
struct EventReturns { | |
uint256 compressedData; | |
uint256 compressedIDs; | |
address winnerAddr; // 获胜者地址 | |
bytes32 winnerName; // 获胜者地址 | |
uint256 amountWon; // 金额赢了 | |
uint256 newPot; // 在新锅中的数量 | |
uint256 P3DAmount; // 金额分配给p3d | |
uint256 genAmount; // 金额分配给gen | |
uint256 potAmount; // 加入锅中的量 | |
} | |
struct Player { | |
address addr; // 球员地址 | |
bytes32 name; // 参赛者姓名 | |
uint256 win; // 赢得金库 | |
uint256 gen; // 一般金库 | |
uint256 aff; // 会员保险库 | |
uint256 lrnd; // 上一轮比赛 | |
uint256 laff; // 使用的最后一个会员ID | |
} | |
struct PlayerRounds { | |
uint256 eth; // 玩家加入回合(用于eth限制器) | |
uint256 keys; // 按键 | |
uint256 mask; // 运动员面具 | |
uint256 ico; // ICO阶段投资 | |
} | |
struct Round { | |
uint256 plyr; // 领先的玩家的pID | |
uint256 team; // 领导团队的tID | |
uint256 end; // 时间结束/结束 | |
bool ended; // 已经运行了圆端函数 | |
uint256 strt; // 时间开始了 | |
uint256 keys; // 按键 | |
uint256 eth; // 总人口 | |
uint256 pot; // 罐装(在回合期间)/最终金额支付给获胜者(在回合结束后) | |
uint256 mask; // 全球面具 | |
uint256 ico; // 在ICO阶段发送的总eth | |
uint256 icoGen; // ICO阶段的gen eth总量 | |
uint256 icoAvg; // ICO阶段的平均关键价格 | |
} | |
struct TeamFee { | |
uint256 gen; // 支付给本轮关键持有人的购买百分比 | |
uint256 p3d; // 支付给p3d持有人的购买百分比 | |
} | |
struct PotSplit { | |
uint256 gen; // 支付给本轮关键持有人的底池百分比 | |
uint256 p3d; // 付给p3d持有者的锅的百分比 | |
} | |
} | |
//============================================================================== | |
// | _ _ _ | _ . | |
// |<(/_\/ (_(_||(_ . | |
//=======/====================================================================== | |
library F3DKeysCalcShort { | |
using SafeMath for *; | |
/** | |
* @dev 计算给定X eth时收到的密钥数 | |
* @param _curEth 合同中的当前eth数量 | |
* @param _newEth eth被用掉了 | |
* @return 购买的机票数量 | |
*/ | |
function keysRec(uint256 _curEth, uint256 _newEth) | |
internal | |
pure | |
returns (uint256) | |
{ | |
return(keys((_curEth).add(_newEth)).sub(keys(_curEth))); | |
} | |
/** | |
* @dev 计算出售X键时收到的eth数量 | |
* @param _curKeys 当前存在的密钥数量 | |
* @param _sellKeys 您希望出售的钥匙数量 | |
* @return 收到的eth数量 | |
*/ | |
function ethRec(uint256 _curKeys, uint256 _sellKeys) | |
internal | |
pure | |
returns (uint256) | |
{ | |
return((eth(_curKeys)).sub(eth(_curKeys.sub(_sellKeys)))); | |
} | |
/** | |
* @dev 计算给定一定数量的eth会存在多少个密钥 | |
* @param _eth 合同中的道德 | |
* @return 将存在的密钥数 | |
*/ | |
function keys(uint256 _eth) | |
internal | |
pure | |
returns(uint256) | |
{ | |
return ((((((_eth).mul(1000000000000000000)).mul(312500000000000000000000000)).add(5624988281256103515625000000000000000000000000000000000000000000)).sqrt()).sub(74999921875000000000000000000000)) / (156250000); | |
} | |
/** | |
* @dev 在给定一些密钥的情况下计算合同中的eth数量 | |
* @param _keys “契约”中的键数 | |
* @return 存在的道德 | |
*/ | |
function eth(uint256 _keys) | |
internal | |
pure | |
returns(uint256) | |
{ | |
return ((78125000).mul(_keys.sq()).add(((149999843750000).mul(_keys.mul(1000000000000000000))) / (2))) / ((1000000000000000000).sq()); | |
} | |
} | |
//============================================================================== | |
// . _ _|_ _ _ |` _ _ _ _ . | |
// || | | (/_| ~|~(_|(_(/__\ . | |
//============================================================================== | |
interface PlayerBookInterface { | |
function getPlayerID(address _addr) external returns (uint256); | |
function getPlayerName(uint256 _pID) external view returns (bytes32); | |
function getPlayerLAff(uint256 _pID) external view returns (uint256); | |
function getPlayerAddr(uint256 _pID) external view returns (address); | |
function getNameFee() external view returns (uint256); | |
function registerNameXIDFromDapp(address _addr, bytes32 _name, uint256 _affCode, bool _all) external payable returns(bool, uint256); | |
function registerNameXaddrFromDapp(address _addr, bytes32 _name, address _affCode, bool _all) external payable returns(bool, uint256); | |
function registerNameXnameFromDapp(address _addr, bytes32 _name, bytes32 _affCode, bool _all) external payable returns(bool, uint256); | |
} | |
library NameFilter { | |
/** | |
* @dev 过滤名称字符串 | |
* -将大写转换为小写. | |
* -确保它不以空格开始/结束 | |
* -确保它不包含连续的多个空格 | |
* -不能只是数字 | |
* -不能以0x开头 | |
* -将字符限制为A-Z,a-z,0-9和空格。 | |
* @return 以字节32格式重新处理的字符串 | |
*/ | |
function nameFilter(string _input) | |
internal | |
pure | |
returns(bytes32) | |
{ | |
bytes memory _temp = bytes(_input); | |
uint256 _length = _temp.length; | |
//对不起限于32个字符 | |
require (_length <= 32 && _length > 0, "string must be between 1 and 32 characters"); | |
// 确保它不以空格开头或以空格结尾 | |
require(_temp[0] != 0x20 && _temp[_length-1] != 0x20, "string cannot start or end with space"); | |
// 确保前两个字符不是0x | |
if (_temp[0] == 0x30) | |
{ | |
require(_temp[1] != 0x78, "string cannot start with 0x"); | |
require(_temp[1] != 0x58, "string cannot start with 0X"); | |
} | |
// 创建一个bool来跟踪我们是否有非数字字符 | |
bool _hasNonNumber; | |
// 转换和检查 | |
for (uint256 i = 0; i < _length; i++) | |
{ | |
// 如果它的大写A-Z | |
if (_temp[i] > 0x40 && _temp[i] < 0x5b) | |
{ | |
// 转换为小写a-z | |
_temp[i] = byte(uint(_temp[i]) + 32); | |
// 我们有一个非数字 | |
if (_hasNonNumber == false) | |
_hasNonNumber = true; | |
} else { | |
require | |
( | |
// 要求角色是一个空间 | |
_temp[i] == 0x20 || | |
// 或小写a-z | |
(_temp[i] > 0x60 && _temp[i] < 0x7b) || | |
// 或0-9 | |
(_temp[i] > 0x2f && _temp[i] < 0x3a), | |
"string contains invalid characters" | |
); | |
// 确保连续两行不是空格 | |
if (_temp[i] == 0x20) | |
require( _temp[i+1] != 0x20, "string cannot contain consecutive spaces"); | |
// 看看我们是否有一个数字以外的字符 | |
if (_hasNonNumber == false && (_temp[i] < 0x30 || _temp[i] > 0x39)) | |
_hasNonNumber = true; | |
} | |
} | |
require(_hasNonNumber == true, "string cannot be only numbers"); | |
bytes32 _ret; | |
assembly { | |
_ret := mload(add(_temp, 32)) | |
} | |
return (_ret); | |
} | |
} | |
/** | |
* @title SafeMath v0.1.9 | |
* @dev 带有安全检查的数学运算会引发错误 | |
* - 添加 sqrt | |
* - 添加 sq | |
* - 添加 pwr | |
* - 将断言更改为需要带有错误日志输出 | |
* - 删除div,它没用 | |
*/ | |
library SafeMath { | |
/** | |
* @dev 将两个数字相乘,抛出溢出。 | |
*/ | |
function mul(uint256 a, uint256 b) | |
internal | |
pure | |
returns (uint256 c) | |
{ | |
if (a == 0) { | |
return 0; | |
} | |
c = a * b; | |
require(c / a == b, "SafeMath mul failed"); | |
return c; | |
} | |
/** | |
* @dev 减去两个数字,在溢出时抛出(即,如果减数大于减数)。 | |
*/ | |
function sub(uint256 a, uint256 b) | |
internal | |
pure | |
returns (uint256) | |
{ | |
require(b <= a, "SafeMath sub failed"); | |
return a - b; | |
} | |
/** | |
* @dev 添加两个数字,溢出时抛出。 | |
*/ | |
function add(uint256 a, uint256 b) | |
internal | |
pure | |
returns (uint256 c) | |
{ | |
c = a + b; | |
require(c >= a, "SafeMath add failed"); | |
return c; | |
} | |
/** | |
* @dev 给出给定x的平方根. | |
*/ | |
function sqrt(uint256 x) | |
internal | |
pure | |
returns (uint256 y) | |
{ | |
uint256 z = ((add(x,1)) / 2); | |
y = x; | |
while (z < y) | |
{ | |
y = z; | |
z = ((add((x / z),z)) / 2); | |
} | |
} | |
/** | |
* @dev 给广场。将x乘以x | |
*/ | |
function sq(uint256 x) | |
internal | |
pure | |
returns (uint256) | |
{ | |
return (mul(x,x)); | |
} | |
/** | |
* @dev x到y的力量 | |
*/ | |
function pwr(uint256 x, uint256 y) | |
internal | |
pure | |
returns (uint256) | |
{ | |
if (x==0) | |
return (0); | |
else if (y==0) | |
return (1); | |
else | |
{ | |
uint256 z = x; | |
for (uint256 i=1; i < y; i++) | |
z = mul(z,x); | |
return (z); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment