Transaction Hash:
Block:
6820352 at Dec-03-2018 08:01:44 PM +UTC
Transaction Fee:
0.004658064 ETH
$8.96
Gas Used:
582,258 Gas / 8 Gwei
Account State Difference:
Address | Before | After | State Difference | ||
---|---|---|---|---|---|
0x5302D0b6...262027560 |
0.551181725002769072 Eth
Nonce: 6423
|
0.546523661002769072 Eth
Nonce: 6424
| 0.004658064 | ||
0xEA674fdD...16B898ec8
Miner
| (Ethermine) | 693.798415073206527309 Eth | 693.803073137206527309 Eth | 0.004658064 |
Execution Trace
claimEgg[MainBase (ln:158)]
claimEgg[MainBase (ln:164)]
emitEggClaimed[MainBase (ln:166)]
emitDistributionUpdated[MainBase (ln:167)]
File 1 of 3: MainBase
File 2 of 3: CoreController
File 3 of 3: Distribution
pragma solidity 0.4.25; contract Ownable { address public owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); function _validateAddress(address _addr) internal pure { require(_addr != address(0), "invalid address"); } constructor() public { owner = msg.sender; } modifier onlyOwner() { require(msg.sender == owner, "not a contract owner"); _; } function transferOwnership(address newOwner) public onlyOwner { _validateAddress(newOwner); emit OwnershipTransferred(owner, newOwner); owner = newOwner; } } contract Pausable is Ownable { event Pause(); event Unpause(); bool public paused = false; modifier whenNotPaused() { require(!paused, "contract is paused"); _; } modifier whenPaused() { require(paused, "contract is not paused"); _; } function pause() public onlyOwner whenNotPaused { paused = true; emit Pause(); } function unpause() public onlyOwner whenPaused { paused = false; emit Unpause(); } } contract Controllable is Ownable { mapping(address => bool) controllers; modifier onlyController { require(_isController(msg.sender), "no controller rights"); _; } function _isController(address _controller) internal view returns (bool) { return controllers[_controller]; } function _setControllers(address[] _controllers) internal { for (uint256 i = 0; i < _controllers.length; i++) { _validateAddress(_controllers[i]); controllers[_controllers[i]] = true; } } } contract Upgradable is Controllable { address[] internalDependencies; address[] externalDependencies; function getInternalDependencies() public view returns(address[]) { return internalDependencies; } function getExternalDependencies() public view returns(address[]) { return externalDependencies; } function setInternalDependencies(address[] _newDependencies) public onlyOwner { for (uint256 i = 0; i < _newDependencies.length; i++) { _validateAddress(_newDependencies[i]); } internalDependencies = _newDependencies; } function setExternalDependencies(address[] _newDependencies) public onlyOwner { externalDependencies = _newDependencies; _setControllers(_newDependencies); } } contract HumanOriented { modifier onlyHuman() { require(msg.sender == tx.origin, "not a human"); _; } } contract Events { function emitEggClaimed(address, uint256) external {} function emitEggSentToNest(address, uint256) external {} function emitDragonUpgraded(uint256) external {} function emitEggHatched(address, uint256, uint256) external {} function emitEggCreated(address, uint256) external {} function emitDistributionUpdated(uint256, uint256, uint256) external {} function emitSkillSet(uint256) external {} function emitSkillUsed(uint256, uint256) external {} function emitDragonNameSet(uint256, bytes32) external {} function emitDragonTacticsSet(uint256, uint8, uint8) external {} function emitUserNameSet(address, bytes32) external {} function emitLeaderboardRewardsDistributed(uint256[10], address[10]) external {} } contract User { mapping (bytes32 => bool) public existingNames; mapping (address => bytes32) public names; function getName(address) external view returns (bytes32) {} function setName(address, string) external returns (bytes32) {} } contract CoreController { function claimEgg(address, uint8) external returns (uint256, uint256, uint256, uint256) {} function sendToNest(address, uint256) external returns (bool, uint256, uint256, address) {} function breed(address, uint256, uint256) external returns (uint256) {} function upgradeDragonGenes(address, uint256, uint16[10]) external {} function setDragonTactics(address, uint256, uint8, uint8) external {} function setDragonName(address, uint256, string) external returns (bytes32) {} function setDragonSpecialPeacefulSkill(address, uint256, uint8) external {} function useDragonSpecialPeacefulSkill(address, uint256, uint256) external {} function distributeLeaderboardRewards() external returns (uint256[10], address[10]) {} } //////////////CONTRACT////////////// contract MainBase is Pausable, Upgradable, HumanOriented { CoreController coreController; User user; Events events; function claimEgg(uint8 _dragonType) external onlyHuman whenNotPaused { ( uint256 _eggId, uint256 _restAmount, uint256 _lastBlock, uint256 _interval ) = coreController.claimEgg(msg.sender, _dragonType); events.emitEggClaimed(msg.sender, _eggId); events.emitDistributionUpdated(_restAmount, _lastBlock, _interval); } // ACTIONS WITH OWN TOKENS function sendToNest( uint256 _eggId ) external onlyHuman whenNotPaused { ( bool _isHatched, uint256 _newDragonId, uint256 _hatchedId, address _owner ) = coreController.sendToNest(msg.sender, _eggId); events.emitEggSentToNest(msg.sender, _eggId); if (_isHatched) { events.emitEggHatched(_owner, _newDragonId, _hatchedId); } } function breed(uint256 _momId, uint256 _dadId) external onlyHuman whenNotPaused { uint256 eggId = coreController.breed(msg.sender, _momId, _dadId); events.emitEggCreated(msg.sender, eggId); } function upgradeDragonGenes(uint256 _id, uint16[10] _dnaPoints) external onlyHuman whenNotPaused { coreController.upgradeDragonGenes(msg.sender, _id, _dnaPoints); events.emitDragonUpgraded(_id); } function setDragonTactics(uint256 _id, uint8 _melee, uint8 _attack) external onlyHuman whenNotPaused { coreController.setDragonTactics(msg.sender, _id, _melee, _attack); events.emitDragonTacticsSet(_id, _melee, _attack); } function setDragonName(uint256 _id, string _name) external onlyHuman whenNotPaused returns (bytes32 name) { name = coreController.setDragonName(msg.sender, _id, _name); events.emitDragonNameSet(_id, name); } function setDragonSpecialPeacefulSkill(uint256 _id, uint8 _class) external onlyHuman whenNotPaused { coreController.setDragonSpecialPeacefulSkill(msg.sender, _id, _class); events.emitSkillSet(_id); } function useDragonSpecialPeacefulSkill(uint256 _id, uint256 _target) external onlyHuman whenNotPaused { coreController.useDragonSpecialPeacefulSkill(msg.sender, _id, _target); events.emitSkillUsed(_id, _target); } // LEADERBOARD function distributeLeaderboardRewards() external onlyHuman whenNotPaused { ( uint256[10] memory _dragons, address[10] memory _users ) = coreController.distributeLeaderboardRewards(); events.emitLeaderboardRewardsDistributed(_dragons, _users); } // USER function setName(string _name) external onlyHuman whenNotPaused returns (bytes32 name) { name = user.setName(msg.sender, _name); events.emitUserNameSet(msg.sender, name); } function getName(address _user) external view returns (bytes32) { return user.getName(_user); } // UPDATE CONTRACT function setInternalDependencies(address[] _newDependencies) public onlyOwner { super.setInternalDependencies(_newDependencies); coreController = CoreController(_newDependencies[0]); user = User(_newDependencies[1]); events = Events(_newDependencies[2]); } }
File 2 of 3: CoreController
pragma solidity 0.4.25; library SafeMath256 { function mul(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) { return 0; } uint256 c = a * b; assert(c / a == b); return c; } function div(uint256 a, uint256 b) internal pure returns (uint256) { return a / b; } function sub(uint256 a, uint256 b) internal pure returns (uint256) { assert(b <= a); return a - b; } function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; assert(c >= a); return c; } function pow(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) return 0; if (b == 0) return 1; uint256 c = a ** b; assert(c / (a ** (b - 1)) == a); return c; } } contract Ownable { address public owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); function _validateAddress(address _addr) internal pure { require(_addr != address(0), "invalid address"); } constructor() public { owner = msg.sender; } modifier onlyOwner() { require(msg.sender == owner, "not a contract owner"); _; } function transferOwnership(address newOwner) public onlyOwner { _validateAddress(newOwner); emit OwnershipTransferred(owner, newOwner); owner = newOwner; } } contract Controllable is Ownable { mapping(address => bool) controllers; modifier onlyController { require(_isController(msg.sender), "no controller rights"); _; } function _isController(address _controller) internal view returns (bool) { return controllers[_controller]; } function _setControllers(address[] _controllers) internal { for (uint256 i = 0; i < _controllers.length; i++) { _validateAddress(_controllers[i]); controllers[_controllers[i]] = true; } } } contract Upgradable is Controllable { address[] internalDependencies; address[] externalDependencies; function getInternalDependencies() public view returns(address[]) { return internalDependencies; } function getExternalDependencies() public view returns(address[]) { return externalDependencies; } function setInternalDependencies(address[] _newDependencies) public onlyOwner { for (uint256 i = 0; i < _newDependencies.length; i++) { _validateAddress(_newDependencies[i]); } internalDependencies = _newDependencies; } function setExternalDependencies(address[] _newDependencies) public onlyOwner { externalDependencies = _newDependencies; _setControllers(_newDependencies); } } contract Core { function isEggOwner(address, uint256) external view returns (bool); function createEgg(address, uint8) external returns (uint256); function sendToNest(uint256) external returns (bool, uint256, uint256, address); function openEgg(address, uint256, uint256) internal returns (uint256); function breed(address, uint256, uint256) external returns (uint256); function setDragonRemainingHealthAndMana(uint256, uint32, uint32) external; function increaseDragonExperience(uint256, uint256) external; function upgradeDragonGenes(uint256, uint16[10]) external; function increaseDragonWins(uint256) external; function increaseDragonDefeats(uint256) external; function setDragonTactics(uint256, uint8, uint8) external; function setDragonName(uint256, string) external returns (bytes32); function setDragonSpecialPeacefulSkill(uint256, uint8) external; function useDragonSpecialPeacefulSkill(address, uint256, uint256) external; function updateLeaderboardRewardTime() external; function getDragonsFromLeaderboard() external view returns (uint256[10]); function getLeaderboardRewards(uint256) external view returns (uint256[10]); } contract Treasury { uint256 public hatchingPrice; function giveGold(address, uint256) external; function takeGold(uint256) external; function burnGold(uint256) external; function remainingGold() external view returns (uint256); } contract Getter { function getDragonsAmount() external view returns (uint256); function isDragonBreedingAllowed(uint256) external view returns (bool); function getDragonNamePriceByLength(uint256) external view returns (uint256); function isEggOnSale(uint256) external view returns (bool); function isDragonOnSale(uint256) public view returns (bool); function isBreedingOnSale(uint256) public view returns (bool); function isDragonOwner(address, uint256) external view returns (bool); function ownerOfDragon(uint256) public view returns (address); function isDragonInGladiatorBattle(uint256) public view returns (bool); } contract Distribution { function claim(uint8) external returns (uint256, uint256, uint256); } //////////////CONTRACT////////////// contract CoreController is Upgradable { using SafeMath256 for uint256; Core core; Treasury treasury; Getter getter; Distribution distribution; function _isDragonOwner(address _user, uint256 _id) internal view returns (bool) { return getter.isDragonOwner(_user, _id); } function _checkTheDragonIsNotInGladiatorBattle(uint256 _id) internal view { require(!getter.isDragonInGladiatorBattle(_id), "dragon participates in gladiator battle"); } function _checkTheDragonIsNotOnSale(uint256 _id) internal view { require(!getter.isDragonOnSale(_id), "dragon is on sale"); } function _checkTheDragonIsNotOnBreeding(uint256 _id) internal view { require(!getter.isBreedingOnSale(_id), "dragon is on breeding sale"); } function _checkThatEnoughDNAPoints(uint256 _id) internal view { require(getter.isDragonBreedingAllowed(_id), "dragon has no enough DNA points for breeding"); } function _checkDragonOwner(address _user, uint256 _id) internal view { require(_isDragonOwner(_user, _id), "not an owner"); } function claimEgg( address _sender, uint8 _dragonType ) external onlyController returns ( uint256 eggId, uint256 restAmount, uint256 lastBlock, uint256 interval ) { (restAmount, lastBlock, interval) = distribution.claim(_dragonType); eggId = core.createEgg(_sender, _dragonType); uint256 _goldReward = treasury.hatchingPrice(); uint256 _goldAmount = treasury.remainingGold(); if (_goldReward > _goldAmount) _goldReward = _goldAmount; treasury.giveGold(_sender, _goldReward); } // ACTIONS WITH OWN TOKEN function sendToNest( address _sender, uint256 _eggId ) external onlyController returns (bool, uint256, uint256, address) { require(!getter.isEggOnSale(_eggId), "egg is on sale"); require(core.isEggOwner(_sender, _eggId), "not an egg owner"); uint256 _hatchingPrice = treasury.hatchingPrice(); treasury.takeGold(_hatchingPrice); if (getter.getDragonsAmount() > 9997) { // 9997 + 2 (in the nest) + 1 (just sent) = 10000 dragons without gold burning treasury.burnGold(_hatchingPrice.div(2)); } return core.sendToNest(_eggId); } function breed( address _sender, uint256 _momId, uint256 _dadId ) external onlyController returns (uint256 eggId) { _checkThatEnoughDNAPoints(_momId); _checkThatEnoughDNAPoints(_dadId); _checkTheDragonIsNotOnBreeding(_momId); _checkTheDragonIsNotOnBreeding(_dadId); _checkTheDragonIsNotOnSale(_momId); _checkTheDragonIsNotOnSale(_dadId); _checkTheDragonIsNotInGladiatorBattle(_momId); _checkTheDragonIsNotInGladiatorBattle(_dadId); _checkDragonOwner(_sender, _momId); _checkDragonOwner(_sender, _dadId); require(_momId != _dadId, "the same dragon"); return core.breed(_sender, _momId, _dadId); } function upgradeDragonGenes( address _sender, uint256 _id, uint16[10] _dnaPoints ) external onlyController { _checkTheDragonIsNotOnBreeding(_id); _checkTheDragonIsNotOnSale(_id); _checkTheDragonIsNotInGladiatorBattle(_id); _checkDragonOwner(_sender, _id); core.upgradeDragonGenes(_id, _dnaPoints); } function setDragonTactics( address _sender, uint256 _id, uint8 _melee, uint8 _attack ) external onlyController { _checkDragonOwner(_sender, _id); core.setDragonTactics(_id, _melee, _attack); } function setDragonName( address _sender, uint256 _id, string _name ) external onlyController returns (bytes32) { _checkDragonOwner(_sender, _id); uint256 _length = bytes(_name).length; uint256 _price = getter.getDragonNamePriceByLength(_length); if (_price > 0) { treasury.takeGold(_price); } return core.setDragonName(_id, _name); } function setDragonSpecialPeacefulSkill(address _sender, uint256 _id, uint8 _class) external onlyController { _checkDragonOwner(_sender, _id); core.setDragonSpecialPeacefulSkill(_id, _class); } function useDragonSpecialPeacefulSkill(address _sender, uint256 _id, uint256 _target) external onlyController { _checkDragonOwner(_sender, _id); _checkTheDragonIsNotInGladiatorBattle(_id); _checkTheDragonIsNotInGladiatorBattle(_target); core.useDragonSpecialPeacefulSkill(_sender, _id, _target); } function distributeLeaderboardRewards() external onlyController returns ( uint256[10] dragons, address[10] users ) { core.updateLeaderboardRewardTime(); uint256 _hatchingPrice = treasury.hatchingPrice(); uint256[10] memory _rewards = core.getLeaderboardRewards(_hatchingPrice); dragons = core.getDragonsFromLeaderboard(); uint8 i; for (i = 0; i < dragons.length; i++) { if (dragons[i] == 0) continue; users[i] = getter.ownerOfDragon(dragons[i]); } uint256 _remainingGold = treasury.remainingGold(); uint256 _reward; for (i = 0; i < users.length; i++) { if (_remainingGold == 0) break; if (users[i] == address(0)) continue; _reward = _rewards[i]; if (_reward > _remainingGold) { _reward = _remainingGold; } treasury.giveGold(users[i], _reward); _remainingGold = _remainingGold.sub(_reward); } } // UPDATE CONTRACT function setInternalDependencies(address[] _newDependencies) public onlyOwner { super.setInternalDependencies(_newDependencies); core = Core(_newDependencies[0]); treasury = Treasury(_newDependencies[1]); getter = Getter(_newDependencies[2]); distribution = Distribution(_newDependencies[3]); } }
File 3 of 3: Distribution
pragma solidity 0.4.25; library SafeConvert { function toUint8(uint256 _value) internal pure returns (uint8) { assert(_value <= 255); return uint8(_value); } function toUint16(uint256 _value) internal pure returns (uint16) { assert(_value <= 2**16 - 1); return uint16(_value); } function toUint32(uint256 _value) internal pure returns (uint32) { assert(_value <= 2**32 - 1); return uint32(_value); } } library SafeMath256 { function mul(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) { return 0; } uint256 c = a * b; assert(c / a == b); return c; } function div(uint256 a, uint256 b) internal pure returns (uint256) { return a / b; } function sub(uint256 a, uint256 b) internal pure returns (uint256) { assert(b <= a); return a - b; } function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; assert(c >= a); return c; } function pow(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) return 0; if (b == 0) return 1; uint256 c = a ** b; assert(c / (a ** (b - 1)) == a); return c; } } contract Ownable { address public owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); function _validateAddress(address _addr) internal pure { require(_addr != address(0), "invalid address"); } constructor() public { owner = msg.sender; } modifier onlyOwner() { require(msg.sender == owner, "not a contract owner"); _; } function transferOwnership(address newOwner) public onlyOwner { _validateAddress(newOwner); emit OwnershipTransferred(owner, newOwner); owner = newOwner; } } contract Controllable is Ownable { mapping(address => bool) controllers; modifier onlyController { require(_isController(msg.sender), "no controller rights"); _; } function _isController(address _controller) internal view returns (bool) { return controllers[_controller]; } function _setControllers(address[] _controllers) internal { for (uint256 i = 0; i < _controllers.length; i++) { _validateAddress(_controllers[i]); controllers[_controllers[i]] = true; } } } contract Upgradable is Controllable { address[] internalDependencies; address[] externalDependencies; function getInternalDependencies() public view returns(address[]) { return internalDependencies; } function getExternalDependencies() public view returns(address[]) { return externalDependencies; } function setInternalDependencies(address[] _newDependencies) public onlyOwner { for (uint256 i = 0; i < _newDependencies.length; i++) { _validateAddress(_newDependencies[i]); } internalDependencies = _newDependencies; } function setExternalDependencies(address[] _newDependencies) public onlyOwner { externalDependencies = _newDependencies; _setControllers(_newDependencies); } } //////////////CONTRACT////////////// contract Distribution is Upgradable { using SafeMath256 for uint256; using SafeConvert for uint256; uint256 restAmount; uint256 releasedAmount; uint256 lastBlock; uint256 interval; // in blocks uint256 constant NUMBER_OF_DRAGON_TYPES = 5; // [0..4] constructor() public { releasedAmount = 10000; // released amount of eggs restAmount = releasedAmount; lastBlock = 6790679; // start block number interval = 1; } function _updateInterval() internal { if (restAmount == 5000) { interval = 2; } else if (restAmount == 3750) { interval = 4; } else if (restAmount == 2500) { interval = 8; } else if (restAmount == 1250) { interval = 16; } } function _burnGas() internal pure { uint256[26950] memory _local; for (uint256 i = 0; i < _local.length; i++) { _local[i] = i; } } function claim(uint8 _requestedType) external onlyController returns (uint256, uint256, uint256) { require(restAmount > 0, "eggs are over"); require(lastBlock.add(interval) <= block.number, "too early"); uint256 _index = releasedAmount.sub(restAmount); // next egg index uint8 currentType = (_index % NUMBER_OF_DRAGON_TYPES).toUint8(); require(currentType == _requestedType, "not a current type of dragon"); lastBlock = block.number; restAmount = restAmount.sub(1); _updateInterval(); _burnGas(); return (restAmount, lastBlock, interval); } function getInfo() external view returns (uint256, uint256, uint256, uint256, uint256) { return ( restAmount, releasedAmount, lastBlock, interval, NUMBER_OF_DRAGON_TYPES ); } }