Transaction Hash:
Block:
4905952 at Jan-14-2018 07:59:05 AM +UTC
Transaction Fee:
0.002667776 ETH
$4.83
Gas Used:
41,684 Gas / 64 Gwei
Emitted Events:
14 |
CSToken.Transfer( from=[Sender] 0xe8a6c59c50eeab5a66c906fbaf45a85e77128cc2, to=0xC179FBDDC946694d11185d4e15DbBa5Fd0aDac0a, value=100000000000 )
|
Account State Difference:
Address | Before | After | State Difference | ||
---|---|---|---|---|---|
0x27695E09...4c39e9eb9 | |||||
0xb2930B35...e543a0347
Miner
| (MiningPoolHub: Old Address) | 16,094.657122963712052684 Eth | 16,094.659790739712052684 Eth | 0.002667776 | |
0xE8A6C59c...e77128cC2 |
24.898839910345415016 Eth
Nonce: 670
|
24.896172134345415016 Eth
Nonce: 671
| 0.002667776 |
Execution Trace
CSToken.transfer( _to=0xC179FBDDC946694d11185d4e15DbBa5Fd0aDac0a, _value=100000000000 ) => ( success=True )
transfer[CSToken (ln:261)]
_checkMyAging[CSToken (ln:262)]
safeSub[CSToken (ln:366)]
_addDividendsForAddress[CSToken (ln:264)]
safeAdd[CSToken (ln:245)]
Transfer[CSToken (ln:246)]
Issuance[CSToken (ln:247)]
safeAdd[CSToken (ln:248)]
safeAdd[CSToken (ln:251)]
safeAdd[CSToken (ln:253)]
_addDividendsForAddress[CSToken (ln:265)]
safeAdd[CSToken (ln:245)]
Transfer[CSToken (ln:246)]
Issuance[CSToken (ln:247)]
safeAdd[CSToken (ln:248)]
safeAdd[CSToken (ln:251)]
safeAdd[CSToken (ln:253)]
accountBalance[CSToken (ln:268)]
safeSub[CSToken (ln:381)]
safeSub[CSToken (ln:271)]
_addToAging[CSToken (ln:274)]
safeAdd[CSToken (ln:305)]
safeAdd[CSToken (ln:306)]
AgingTransfer[CSToken (ln:307)]
safeAdd[CSToken (ln:277)]
_addIndex[CSToken (ln:279)]
Transfer[CSToken (ln:280)]
pragma solidity ^0.4.2; contract owned { address public owner; function owned() { owner = msg.sender; } function changeOwner(address newOwner) onlyOwner { owner = newOwner; } modifier onlyOwner { require(msg.sender == owner); _; } } contract tokenRecipient {function receiveApproval(address _from, uint256 _value, address _token, bytes _extraData);} contract Utils { /** constructor */ function Utils() { } // validates an address - currently only checks that it isn't null modifier validAddress(address _address) { require(_address != 0x0); _; } // verifies that the address is different than this contract address modifier notThis(address _address) { require(_address != address(this)); _; } // Overflow protected math functions /** @dev returns the sum of _x and _y, asserts if the calculation overflows @param _x value 1 @param _y value 2 @return sum */ function safeAdd(uint256 _x, uint256 _y) internal returns (uint256) { uint256 z = _x + _y; assert(z >= _x); return z; } /** @dev returns the difference of _x minus _y, asserts if the subtraction results in a negative number @param _x minuend @param _y subtrahend @return difference */ function safeSub(uint256 _x, uint256 _y) internal returns (uint256) { assert(_x >= _y); return _x - _y; } } contract CSToken is owned, Utils { struct Dividend {uint256 time; uint256 tenThousandth; uint256 countComplete;} /* Public variables of the token */ string public standard = 'Token 0.1'; string public name = 'KickCoin'; string public symbol = 'KICK'; uint8 public decimals = 8; uint256 _totalSupply = 0; /* Is allowed to burn tokens */ bool public allowManuallyBurnTokens = true; /* This creates an array with all balances */ mapping (address => uint256) balances; mapping (address => mapping (uint256 => uint256)) public agingBalanceOf; uint[] agingTimes; Dividend[] dividends; mapping (address => mapping (address => uint256)) allowed; /* This generates a public event on the blockchain that will notify clients */ event Transfer(address indexed from, address indexed to, uint256 value); event AgingTransfer(address indexed from, address indexed to, uint256 value, uint256 agingTime); event Approval(address indexed _owner, address indexed _spender, uint256 _value); // triggered when the total supply is increased event Issuance(uint256 _amount); // triggered when the total supply is decreased event Destruction(uint256 _amount); // This notifies clients about the amount burnt event Burn(address indexed from, uint256 value); address[] public addressByIndex; mapping (address => bool) addressAddedToIndex; mapping (address => uint) agingTimesForPools; uint16 currentDividendIndex = 1; mapping (address => uint) calculatedDividendsIndex; bool public transfersEnabled = true; event NewSmartToken(address _token); /* Initializes contract with initial supply tokens to the creator of the contract */ function CSToken() { owner = msg.sender; // So that the index starts with 1 dividends.push(Dividend(0, 0, 0)); // 31.10.2017 09:00:00 dividends.push(Dividend(1509440400, 30, 0)); // 30.11.2017 09:00:00 dividends.push(Dividend(1512032400, 20, 0)); // 31.12.2017 09:00:00 dividends.push(Dividend(1514710800, 10, 0)); // 31.01.2018 09:00:00 dividends.push(Dividend(1517389200, 5, 0)); // 28.02.2018 09:00:00 dividends.push(Dividend(1519808400, 10, 0)); // 31.03.2018 09:00:00 dividends.push(Dividend(1522486800, 20, 0)); // 30.04.2018 09:00:00 dividends.push(Dividend(1525078800, 30, 0)); // 31.05.2018 09:00:00 dividends.push(Dividend(1527757200, 50, 0)); // 30.06.2018 09:00:00 dividends.push(Dividend(1530349200, 30, 0)); // 31.07.2018 09:00:00 dividends.push(Dividend(1533027600, 20, 0)); // 31.08.2018 09:00:00 dividends.push(Dividend(1535706000, 10, 0)); // 30.09.2018 09:00:00 dividends.push(Dividend(1538298000, 5, 0)); // 31.10.2018 09:00:00 dividends.push(Dividend(1540976400, 10, 0)); // 30.11.2018 09:00:00 dividends.push(Dividend(1543568400, 20, 0)); // 31.12.2018 09:00:00 dividends.push(Dividend(1546246800, 30, 0)); // 31.01.2019 09:00:00 dividends.push(Dividend(1548925200, 60, 0)); // 28.02.2019 09:00:00 dividends.push(Dividend(1551344400, 30, 0)); // 31.03.2019 09:00:00 dividends.push(Dividend(1554022800, 20, 0)); // 30.04.2019 09:00:00 dividends.push(Dividend(1556614800, 10, 0)); // 31.05.2019 09:00:00 dividends.push(Dividend(1559307600, 20, 0)); // 30.06.2019 09:00:00 dividends.push(Dividend(1561885200, 30, 0)); // 31.07.2019 09:00:00 dividends.push(Dividend(1564563600, 20, 0)); // 31.08.2019 09:00:00 dividends.push(Dividend(1567242000, 10, 0)); // 30.09.2019 09:00:00 dividends.push(Dividend(1569834000, 5, 0)); NewSmartToken(address(this)); } modifier transfersAllowed { assert(transfersEnabled); _; } function totalSupply() constant returns (uint256 totalSupply) { totalSupply = _totalSupply; } function balanceOf(address _owner) constant returns (uint256 balance) { return balances[_owner]; } function allowance(address _owner, address _spender) constant returns (uint256 remaining) { return allowed[_owner][_spender]; } bool allAgingTimesHasBeenAdded = false; function addAgingTime(uint256 time) onlyOwner { require(!allAgingTimesHasBeenAdded); agingTimes.push(time); } function allAgingTimesAdded() onlyOwner { allAgingTimesHasBeenAdded = true; } function calculateDividends(uint256 limit) { require(now >= dividends[currentDividendIndex].time); require(limit > 0); limit = safeAdd(dividends[currentDividendIndex].countComplete, limit); if (limit > addressByIndex.length) { limit = addressByIndex.length; } for (uint256 i = dividends[currentDividendIndex].countComplete; i < limit; i++) { _addDividendsForAddress(addressByIndex[i]); } if (limit == addressByIndex.length) { currentDividendIndex++; } else { dividends[currentDividendIndex].countComplete = limit; } } /* User can himself receive dividends without waiting for a global accruals */ function receiveDividends() public { require(now >= dividends[currentDividendIndex].time); assert(_addDividendsForAddress(msg.sender)); } function _addDividendsForAddress(address _address) internal returns (bool success) { // skip calculating dividends, if already calculated for this address if (calculatedDividendsIndex[_address] >= currentDividendIndex) return false; uint256 add = balances[_address] * dividends[currentDividendIndex].tenThousandth / 1000; balances[_address] = safeAdd(balances[_address], add); Transfer(this, _address, add); Issuance(add); _totalSupply = safeAdd(_totalSupply, add); if (agingBalanceOf[_address][0] > 0) { agingBalanceOf[_address][0] = safeAdd(agingBalanceOf[_address][0], agingBalanceOf[_address][0] * dividends[currentDividendIndex].tenThousandth / 1000); for (uint256 k = 0; k < agingTimes.length; k++) { agingBalanceOf[_address][agingTimes[k]] = safeAdd(agingBalanceOf[_address][agingTimes[k]], agingBalanceOf[_address][agingTimes[k]] * dividends[currentDividendIndex].tenThousandth / 1000); } } calculatedDividendsIndex[_address] = currentDividendIndex; return true; } /* Send coins */ function transfer(address _to, uint256 _value) transfersAllowed returns (bool success) { _checkMyAging(msg.sender); if (currentDividendIndex < dividends.length && now >= dividends[currentDividendIndex].time) { _addDividendsForAddress(msg.sender); _addDividendsForAddress(_to); } require(accountBalance(msg.sender) >= _value); // Subtract from the sender balances[msg.sender] = safeSub(balances[msg.sender], _value); if (agingTimesForPools[msg.sender] > 0 && agingTimesForPools[msg.sender] > now) { _addToAging(msg.sender, _to, agingTimesForPools[msg.sender], _value); } balances[_to] = safeAdd(balances[_to], _value); _addIndex(_to); Transfer(msg.sender, _to, _value); return true; } function mintToken(address target, uint256 mintedAmount, uint256 agingTime) onlyOwner { if (agingTime > now) { _addToAging(owner, target, agingTime, mintedAmount); } balances[target] = safeAdd(balances[target], mintedAmount); _totalSupply = safeAdd(_totalSupply, mintedAmount); Issuance(mintedAmount); _addIndex(target); Transfer(this, target, mintedAmount); } function _addIndex(address _address) internal { if (!addressAddedToIndex[_address]) { addressAddedToIndex[_address] = true; addressByIndex.push(_address); } } function _addToAging(address from, address target, uint256 agingTime, uint256 amount) internal { agingBalanceOf[target][0] = safeAdd(agingBalanceOf[target][0], amount); agingBalanceOf[target][agingTime] = safeAdd(agingBalanceOf[target][agingTime], amount); AgingTransfer(from, target, amount, agingTime); } /* Allow another contract to spend some tokens in your behalf */ function approve(address _spender, uint256 _value) returns (bool success) { allowed[msg.sender][_spender] = _value; Approval(msg.sender, _spender, _value); return true; } /* Approve and then communicate the approved contract in a single tx */ function approveAndCall(address _spender, uint256 _value, bytes _extraData) returns (bool success) { tokenRecipient spender = tokenRecipient(_spender); if (approve(_spender, _value)) { spender.receiveApproval(msg.sender, _value, this, _extraData); return true; } } /* A contract attempts to get the coins */ function transferFrom(address _from, address _to, uint256 _value) transfersAllowed returns (bool success) { _checkMyAging(_from); if (currentDividendIndex < dividends.length && now >= dividends[currentDividendIndex].time) { _addDividendsForAddress(_from); _addDividendsForAddress(_to); } // Check if the sender has enough require(accountBalance(_from) >= _value); // Check allowed require(_value <= allowed[_from][msg.sender]); // Subtract from the sender balances[_from] = safeSub(balances[_from], _value); // Add the same to the recipient balances[_to] = safeAdd(balances[_to], _value); allowed[_from][msg.sender] = safeSub(allowed[_from][msg.sender], _value); if (agingTimesForPools[_from] > 0 && agingTimesForPools[_from] > now) { _addToAging(_from, _to, agingTimesForPools[_from], _value); } _addIndex(_to); Transfer(_from, _to, _value); return true; } /* This unnamed function is called whenever someone tries to send ether to it */ function() { revert(); // Prevents accidental sending of ether } function _checkMyAging(address sender) internal { if (agingBalanceOf[sender][0] == 0) return; for (uint256 k = 0; k < agingTimes.length; k++) { if (agingTimes[k] < now) { agingBalanceOf[sender][0] = safeSub(agingBalanceOf[sender][0], agingBalanceOf[sender][agingTimes[k]]); agingBalanceOf[sender][agingTimes[k]] = 0; } } } function addAgingTimesForPool(address poolAddress, uint256 agingTime) onlyOwner { agingTimesForPools[poolAddress] = agingTime; } function countAddresses() constant returns (uint256 length) { return addressByIndex.length; } function accountBalance(address _address) constant returns (uint256 balance) { return safeSub(balances[_address], agingBalanceOf[_address][0]); } function disableTransfers(bool _disable) public onlyOwner { transfersEnabled = !_disable; } function issue(address _to, uint256 _amount) public onlyOwner validAddress(_to) notThis(_to) { _totalSupply = safeAdd(_totalSupply, _amount); balances[_to] = safeAdd(balances[_to], _amount); _addIndex(_to); Issuance(_amount); Transfer(this, _to, _amount); } /** * Destroy tokens * Remove `_value` tokens from the system irreversibly * @param _value the amount of money to burn */ function burn(uint256 _value) returns (bool success) { destroy(msg.sender, _value); Burn(msg.sender, _value); return true; } /** * Destroy tokens * Remove `_amount` tokens from the system irreversibly * @param _from the address from which tokens will be burnt * @param _amount the amount of money to burn */ function destroy(address _from, uint256 _amount) public { _checkMyAging(_from); // validate input require((msg.sender == _from && allowManuallyBurnTokens) || msg.sender == owner); require(accountBalance(_from) >= _amount); balances[_from] = safeSub(balances[_from], _amount); _totalSupply = safeSub(_totalSupply, _amount); Transfer(_from, this, _amount); Destruction(_amount); } function disableManuallyBurnTokens(bool _disable) public onlyOwner { allowManuallyBurnTokens = !_disable; } }