Transaction Hash:
Block:
7686512 at May-03-2019 06:37:27 AM +UTC
Transaction Fee:
0.001118871 ETH
$2.10
Gas Used:
248,638 Gas / 4.5 Gwei
Emitted Events:
125 |
GameCell.Transfer( from=0xb28520FF4CD5E8775e6644b594072d76ce857899, to=[Sender] 0x1ca48c1d2806f9e5d489fc91b3dac94494c0de77, value=56344500000000000000 )
|
126 |
0xb28520ff4cd5e8775e6644b594072d76ce857899.0xdc6012455eb1f4c2ab8bdf189cdc1f85c17d1f8e0d16325640b2248dc27af4b8( 0xdc6012455eb1f4c2ab8bdf189cdc1f85c17d1f8e0d16325640b2248dc27af4b8, 0000000000000000000000001ca48c1d2806f9e5d489fc91b3dac94494c0de77, 0000000000000000000000000000000000000000000000030defe0395aff4000 )
|
127 |
0xcf5c47ee42fdf4962ae3646bd82f7d5164fdf981.0x6454ebe98bd73a282adcaa44bfaf3c21f4ed59466be5897e5fde4a9eb47e9adc( 0x6454ebe98bd73a282adcaa44bfaf3c21f4ed59466be5897e5fde4a9eb47e9adc, 0000000000000000000000001ca48c1d2806f9e5d489fc91b3dac94494c0de77, 000000000000000000000000000000000000000000000003371772c31c6b0000 )
|
Account State Difference:
Address | Before | After | State Difference | ||
---|---|---|---|---|---|
0x1cA48c1d...494C0DE77 |
0.0048079188 Eth
Nonce: 3
|
0.0036890478 Eth
Nonce: 4
| 0.001118871 | ||
0x3336e979...6814dbc40 | |||||
0x5A0b54D5...D3E029c4c
Miner
| (Spark Pool) | 5,192.332634758284244471 Eth | 5,192.333753629284244471 Eth | 0.001118871 | |
0x8BcB64bf...44e777A20 | |||||
0x8c83499b...985728B20 |
Execution Trace
0xb4a00005aacb2d82d9c6d9a4cc4ab5a942f0fbcc.CALL( )
0xcf5c47ee42fdf4962ae3646bd82f7d5164fdf981.19165587( )
-
0x8c83499bf5699a0e9ff082035da6226985728b20.a232d082( )
-
0x8c83499bf5699a0e9ff082035da6226985728b20.d09b8ed5( )
-
0x8c83499bf5699a0e9ff082035da6226985728b20.fc804f07( )
-
0x68c492e39817d61b473be3c3c81303cf4a0b31a8.b67d77c5( )
-
0x68c492e39817d61b473be3c3c81303cf4a0b31a8.a391c15b( )
-
0x8c83499bf5699a0e9ff082035da6226985728b20.82b9d1bb( )
-
0x68c492e39817d61b473be3c3c81303cf4a0b31a8.b67d77c5( )
-
0x8c83499bf5699a0e9ff082035da6226985728b20.e9e61cb1( )
-
0x68c492e39817d61b473be3c3c81303cf4a0b31a8.c8a4ac9c( )
-
0x8c83499bf5699a0e9ff082035da6226985728b20.2105de24( )
-
0x8c83499bf5699a0e9ff082035da6226985728b20.2290429f( )
-
0x68c492e39817d61b473be3c3c81303cf4a0b31a8.771602f7( )
-
0x8c83499bf5699a0e9ff082035da6226985728b20.ef350589( )
-
0x68c492e39817d61b473be3c3c81303cf4a0b31a8.c8a4ac9c( )
-
0x8c83499bf5699a0e9ff082035da6226985728b20.6f3341d1( )
-
0x8c83499bf5699a0e9ff082035da6226985728b20.95e2d7bc( )
-
0x68c492e39817d61b473be3c3c81303cf4a0b31a8.b67d77c5( )
-
0x8c83499bf5699a0e9ff082035da6226985728b20.400dc2fa( )
-
0x68c492e39817d61b473be3c3c81303cf4a0b31a8.771602f7( )
-
0x8c83499bf5699a0e9ff082035da6226985728b20.aea4d9b5( )
-
0x8c83499bf5699a0e9ff082035da6226985728b20.6f3341d1( )
-
0x8c83499bf5699a0e9ff082035da6226985728b20.95e2d7bc( )
-
0x68c492e39817d61b473be3c3c81303cf4a0b31a8.b67d77c5( )
-
0x68c492e39817d61b473be3c3c81303cf4a0b31a8.c8a4ac9c( )
-
0x68c492e39817d61b473be3c3c81303cf4a0b31a8.a391c15b( )
-
0x68c492e39817d61b473be3c3c81303cf4a0b31a8.c8a4ac9c( )
-
0x68c492e39817d61b473be3c3c81303cf4a0b31a8.a391c15b( )
-
0x68c492e39817d61b473be3c3c81303cf4a0b31a8.b67d77c5( )
0x3336e979d2dd73369420c03044f49786814dbc40.9dd3045b( )
-
0x8c83499bf5699a0e9ff082035da6226985728b20.STATICCALL( )
-
0x68c492e39817d61b473be3c3c81303cf4a0b31a8.a391c15b( )
-
0x68c492e39817d61b473be3c3c81303cf4a0b31a8.771602f7( )
-
0x8c83499bf5699a0e9ff082035da6226985728b20.c1f33ad5( )
-
0x8c83499bf5699a0e9ff082035da6226985728b20.95e2d7bc( )
-
0x68c492e39817d61b473be3c3c81303cf4a0b31a8.771602f7( )
-
0x8c83499bf5699a0e9ff082035da6226985728b20.2709ffdf( )
-
0x8c83499bf5699a0e9ff082035da6226985728b20.82b9d1bb( )
-
0x68c492e39817d61b473be3c3c81303cf4a0b31a8.771602f7( )
-
0x8c83499bf5699a0e9ff082035da6226985728b20.d060872a( )
-
0x8c83499bf5699a0e9ff082035da6226985728b20.6a23196b( )
-
0x8c83499bf5699a0e9ff082035da6226985728b20.2105de24( )
-
0x68c492e39817d61b473be3c3c81303cf4a0b31a8.771602f7( )
-
0x8c83499bf5699a0e9ff082035da6226985728b20.2290429f( )
-
0x8c83499bf5699a0e9ff082035da6226985728b20.6f3341d1( )
-
0x8c83499bf5699a0e9ff082035da6226985728b20.95e2d7bc( )
-
pragma solidity ^0.4.24; // File: node_modules\zeppelin-solidity\contracts\math\SafeMath.sol /** * @title SafeMath * @dev Math operations with safety checks that throw on error */ library SafeMath { /** * @dev Multiplies two numbers, throws on overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256 c) { // Gas optimization: this is cheaper than asserting 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 if (a == 0) { return 0; } c = a * b; assert(c / a == b); return c; } /** * @dev Integer division of two numbers, truncating the quotient. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { // assert(b > 0); // Solidity automatically throws when dividing by 0 // uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return a / b; } /** * @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend). */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { assert(b <= a); return a - b; } /** * @dev Adds two numbers, throws on overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256 c) { c = a + b; assert(c >= a); return c; } } // File: node_modules\zeppelin-solidity\contracts\ownership\Ownable.sol /** * @title Ownable * @dev The Ownable contract has an owner address, and provides basic authorization control * functions, this simplifies the implementation of "user permissions". */ contract Ownable { address public owner; event OwnershipTransferred( address indexed previousOwner, address indexed newOwner ); /** * @dev The Ownable constructor sets the original `owner` of the contract to the sender * account. */ constructor() public { owner = msg.sender; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(msg.sender == owner); _; } /** * @dev Allows the current owner to transfer control of the contract to a newOwner. * @param _newOwner The address to transfer ownership to. */ function transferOwnership(address _newOwner) public onlyOwner { _transferOwnership(_newOwner); } /** * @dev Transfers control of the contract to a newOwner. * @param _newOwner The address to transfer ownership to. */ function _transferOwnership(address _newOwner) internal { require(_newOwner != address(0)); emit OwnershipTransferred(owner, _newOwner); owner = _newOwner; } } // File: node_modules\zeppelin-solidity\contracts\token\ERC20\ERC20Basic.sol /** * @title ERC20Basic * @dev Simpler version of ERC20 interface * See https://github.com/ethereum/EIPs/issues/179 */ contract ERC20Basic { function totalSupply() public view returns (uint256); function balanceOf(address who) public view returns (uint256); function transfer(address to, uint256 value) public returns (bool); event Transfer(address indexed from, address indexed to, uint256 value); } // File: node_modules\zeppelin-solidity\contracts\token\ERC20\BasicToken.sol /** * @title Basic token * @dev Basic version of StandardToken, with no allowances. */ contract BasicToken is ERC20Basic { using SafeMath for uint256; mapping(address => uint256) balances; uint256 totalSupply_; /** * @dev Total number of tokens in existence */ function totalSupply() public view returns (uint256) { return totalSupply_; } /** * @dev Transfer token for a specified address * @param _to The address to transfer to. * @param _value The amount to be transferred. */ function transfer(address _to, uint256 _value) public returns (bool) { require(_to != address(0)); require(_value <= balances[msg.sender]); balances[msg.sender] = balances[msg.sender].sub(_value); balances[_to] = balances[_to].add(_value); emit Transfer(msg.sender, _to, _value); return true; } /** * @dev Gets the balance of the specified address. * @param _owner The address to query the the balance of. * @return An uint256 representing the amount owned by the passed address. */ function balanceOf(address _owner) public view returns (uint256) { return balances[_owner]; } } // File: node_modules\zeppelin-solidity\contracts\token\ERC20\ERC20.sol /** * @title ERC20 interface * @dev see https://github.com/ethereum/EIPs/issues/20 */ contract ERC20 is ERC20Basic { function allowance(address owner, address spender) public view returns (uint256); function transferFrom(address from, address to, uint256 value) public returns (bool); function approve(address spender, uint256 value) public returns (bool); event Approval( address indexed owner, address indexed spender, uint256 value ); } // File: node_modules\zeppelin-solidity\contracts\token\ERC20\StandardToken.sol /** * @title Standard ERC20 token * * @dev Implementation of the basic standard token. * https://github.com/ethereum/EIPs/issues/20 * Based on code by FirstBlood: https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol */ contract StandardToken is ERC20, BasicToken { mapping (address => mapping (address => uint256)) internal allowed; /** * @dev Transfer tokens from one address to another * @param _from address The address which you want to send tokens from * @param _to address The address which you want to transfer to * @param _value uint256 the amount of tokens to be transferred */ function transferFrom( address _from, address _to, uint256 _value ) public returns (bool) { require(_to != address(0)); require(_value <= balances[_from]); require(_value <= allowed[_from][msg.sender]); balances[_from] = balances[_from].sub(_value); balances[_to] = balances[_to].add(_value); allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value); emit Transfer(_from, _to, _value); return true; } /** * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender. * Beware that changing an allowance with this method brings the risk that someone may use both the old * and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this * race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * @param _spender The address which will spend the funds. * @param _value The amount of tokens to be spent. */ function approve(address _spender, uint256 _value) public returns (bool) { allowed[msg.sender][_spender] = _value; emit Approval(msg.sender, _spender, _value); return true; } /** * @dev Function to check the amount of tokens that an owner allowed to a spender. * @param _owner address The address which owns the funds. * @param _spender address The address which will spend the funds. * @return A uint256 specifying the amount of tokens still available for the spender. */ function allowance( address _owner, address _spender ) public view returns (uint256) { return allowed[_owner][_spender]; } /** * @dev Increase the amount of tokens that an owner allowed to a spender. * approve should be called when allowed[_spender] == 0. To increment * allowed value is better to use this function to avoid 2 calls (and wait until * the first transaction is mined) * From MonolithDAO Token.sol * @param _spender The address which will spend the funds. * @param _addedValue The amount of tokens to increase the allowance by. */ function increaseApproval( address _spender, uint256 _addedValue ) public returns (bool) { allowed[msg.sender][_spender] = ( allowed[msg.sender][_spender].add(_addedValue)); emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]); return true; } /** * @dev Decrease the amount of tokens that an owner allowed to a spender. * approve should be called when allowed[_spender] == 0. To decrement * allowed value is better to use this function to avoid 2 calls (and wait until * the first transaction is mined) * From MonolithDAO Token.sol * @param _spender The address which will spend the funds. * @param _subtractedValue The amount of tokens to decrease the allowance by. */ function decreaseApproval( address _spender, uint256 _subtractedValue ) public returns (bool) { uint256 oldValue = allowed[msg.sender][_spender]; if (_subtractedValue >= oldValue) { allowed[msg.sender][_spender] = 0; } else { allowed[msg.sender][_spender] = oldValue.sub(_subtractedValue); } emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]); return true; } } // File: node_modules\zeppelin-solidity\contracts\lifecycle\Pausable.sol /** * @title Pausable * @dev Base contract which allows children to implement an emergency stop mechanism. */ contract Pausable is Ownable { event Pause(); event Unpause(); bool public paused = false; /** * @dev Modifier to make a function callable only when the contract is not paused. */ modifier whenNotPaused() { require(!paused); _; } /** * @dev Modifier to make a function callable only when the contract is paused. */ modifier whenPaused() { require(paused); _; } /** * @dev called by the owner to pause, triggers stopped state */ function pause() onlyOwner whenNotPaused public { paused = true; emit Pause(); } /** * @dev called by the owner to unpause, returns to normal state */ function unpause() onlyOwner whenPaused public { paused = false; emit Unpause(); } } // File: node_modules\zeppelin-solidity\contracts\token\ERC20\PausableToken.sol /** * @title Pausable token * @dev StandardToken modified with pausable transfers. **/ contract PausableToken is StandardToken, Pausable { function transfer( address _to, uint256 _value ) public whenNotPaused returns (bool) { return super.transfer(_to, _value); } function transferFrom( address _from, address _to, uint256 _value ) public whenNotPaused returns (bool) { return super.transferFrom(_from, _to, _value); } function approve( address _spender, uint256 _value ) public whenNotPaused returns (bool) { return super.approve(_spender, _value); } function increaseApproval( address _spender, uint _addedValue ) public whenNotPaused returns (bool success) { return super.increaseApproval(_spender, _addedValue); } function decreaseApproval( address _spender, uint _subtractedValue ) public whenNotPaused returns (bool success) { return super.decreaseApproval(_spender, _subtractedValue); } } // File: contracts\GameCell.sol /***************************************************************************** * *Copyright 2018 GameCell * *Licensed under the Apache License, Version 2.0 (the "License"); *you may not use this file except in compliance with the License. *You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * *Unless required by applicable law or agreed to in writing, software *distributed under the License is distributed on an "AS IS" BASIS, *WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *See the License for the specific language governing permissions and *limitations under the License. * *****************************************************************************/ contract GameCell is PausableToken { using SafeMath for uint256; // ERC20 constants string public name="GameCell"; string public symbol="GCC"; string public standard="ERC20"; uint8 public constant decimals = 18; // solium-disable-line uppercase uint256 public constant INITIAL_SUPPLY = 25 *(10**8)*(10 ** uint256(decimals)); event NewLock(address indexed target,uint256 indexed locktime,uint256 lockamount); event UnLock(address indexed target,uint256 indexed unlocktime,uint256 unlockamount); mapping(address => TimeLock[]) public allocations; struct TimeLock { uint256 releaseTime; uint256 balance; } /*Here is the constructor function that is executed when the instance is created*/ constructor() public { totalSupply_ = INITIAL_SUPPLY; balances[msg.sender] = INITIAL_SUPPLY; emit Transfer(address(0), msg.sender, INITIAL_SUPPLY); } function transfer(address _to, uint256 _value) public returns (bool) { require(canSubAllocation(msg.sender, _value)); subAllocation(msg.sender); return super.transfer(_to, _value); } function transferFrom(address _from, address _to,uint256 _value) public returns (bool) { require(canSubAllocation(_from, _value)); subAllocation(_from); return super.transferFrom(_from,_to, _value); } function canSubAllocation(address sender, uint256 sub_value) constant private returns (bool) { if (sub_value==0) { return false; } if (balances[sender] < sub_value) { return false; } if (allocations[sender].length == 0) { return true; } uint256 alllock_sum = 0; for (uint j=0; j<allocations[sender].length; j++) { if (allocations[sender][j].releaseTime >= block.timestamp) { alllock_sum = alllock_sum.add(allocations[sender][j].balance); } } uint256 can_unlock = balances[sender].sub(alllock_sum); return can_unlock >= sub_value; } function subAllocation(address sender) private { uint256 total_lockamount = 0; uint256 total_unlockamount = 0; for (uint j=0; j<allocations[sender].length; j++) { if (allocations[sender][j].releaseTime < block.timestamp) { total_unlockamount = total_unlockamount.add(allocations[sender][j].balance); allocations[sender][j].balance = 0; } else { total_lockamount = total_lockamount.add(allocations[sender][j].balance); } } if (total_unlockamount > 0) { emit UnLock(sender, block.timestamp, total_unlockamount); } if(total_lockamount == 0 && allocations[sender].length > 0) { delete allocations[sender]; } } function setAllocation(address _address, uint256 total_value, uint[] times, uint256[] balanceRequires) public onlyOwner returns (bool) { require(times.length == balanceRequires.length); require(balances[msg.sender]>=total_value); uint256 sum = 0; for (uint x=0; x<balanceRequires.length; x++) { require(balanceRequires[x]>0); sum = sum.add(balanceRequires[x]); } require(total_value >= sum); for (uint i=0; i<times.length; i++) { bool find = false; for (uint j=0; j<allocations[_address].length; j++) { if (allocations[_address][j].releaseTime == times[i]) { allocations[_address][j].balance = allocations[_address][j].balance.add(balanceRequires[i]); find = true; break; } } if (!find) { allocations[_address].push(TimeLock(times[i], balanceRequires[i])); } } emit NewLock(_address, block.timestamp, sum); return super.transfer(_address, total_value); } }