Contract Overview
Balance: 1.189568691702556023 Ether
Ether Value: $245.74 (@ $206.58/ETH)
Transactions: 14021 txns
Token Tracker: IdleEth (Goo)
 Latest 25 txns From a total of 14021 Transactions

TxHash Age From To Value [TxFee]
0x7d306ca91c91f3711edc7e87a7753cfa3de5fafa33d002e9171b05db1eee8a5716 days 5 hrs ago0x3a35f7142d4779f282a4ebbc5f91fb68a66ef389  IN   0xdda9bcd985b1169607546b52910a0269dff5baf10 Ether0.000138332
0x86ed24446afebc56737f5805803de8098bbfb756b0f5afa113dde3315a74ccf668 days 18 hrs ago0xff301f3b4a51a1948ae021c77379d5dd56f1377d  IN   0xdda9bcd985b1169607546b52910a0269dff5baf10 Ether0.0002904972
0x3a01bd714f1ce5b4ac55600444df307286ca045251034c5515a20f2469a43553186 days 21 hrs ago0x1ba9303cc52a8cbc05ee2b368bcd1fc0e5050923  IN   0xdda9bcd985b1169607546b52910a0269dff5baf10 Ether0.0001521652
0xcc0e5c62902982a5972fdaaaf6e6295a70db84a4f88c621d44623e86e1a9c3ec187 days 22 hrs ago0xb5c64bfd79f0048ea88e1699834273704abab3d3  IN   0xdda9bcd985b1169607546b52910a0269dff5baf10 Ether0.000028427
0x893241a425af3d1fb02c24d019fe5e8325db43846d81c713764b3ce28d443fd7190 days 8 hrs ago0x19b08a1007186b661d99fad0c75034bae473b600  IN   0xdda9bcd985b1169607546b52910a0269dff5baf10 Ether0.000070382
0x6f00dbc40ce17175eab95e350c313f413b2e5509c04acb2d9f979b4866b79951197 days 2 hrs ago0xdb9f2c93d792c14ab37f58658718b8422d29a044  IN   0xdda9bcd985b1169607546b52910a0269dff5baf10 Ether0.000035511
0x0a861a0700b8eab15ebf2fcdd7b3ef56bf12f5214f0f2f67ba0bb437360dd708197 days 3 hrs ago0xdb9f2c93d792c14ab37f58658718b8422d29a044  IN   0xdda9bcd985b1169607546b52910a0269dff5baf10 Ether0.000171976
0x33f33975b2b2a599441a6a6a42e947cf897e181954d6f98c7dc1bdda77a5925a197 days 6 hrs ago0x2e965f6d55cad05c320eb2f38ce6753037d1dbc1  IN   0xdda9bcd985b1169607546b52910a0269dff5baf10 Ether0.000035575
0x2aeb2e6823563a7247dde90e33f650edc80959536c9e2a8c18454b8b5ccfbc86197 days 9 hrs ago0x80113f7bb9ddc6693585e103fb675ba17b6a9c06  IN   0xdda9bcd985b1169607546b52910a0269dff5baf10 Ether0.000089941
0xac7cb21a82cac1f58efd88f486118bda3ed6ef9af7f53564cb61dcfa1199292c197 days 9 hrs ago0x80113f7bb9ddc6693585e103fb675ba17b6a9c06  IN   0xdda9bcd985b1169607546b52910a0269dff5baf10 Ether0.000022575
0xc7b156fe9beaa3d6e7c5c47643bda9c8f44f57b437ed104560722323c77825f2197 days 9 hrs ago0x80113f7bb9ddc6693585e103fb675ba17b6a9c06  IN   0xdda9bcd985b1169607546b52910a0269dff5baf10 Ether0.000021992
0x5ace3a45a1b4175887d14b3629db5c0b88656721c56e66c888ff0ab7fc758c94197 days 9 hrs ago0x80113f7bb9ddc6693585e103fb675ba17b6a9c06  IN   0xdda9bcd985b1169607546b52910a0269dff5baf10 Ether0.000107195
0xa85f36fb5dc7bff2a57efdd58972ecd78bd7bf012046c79a1021985f36b282cd198 days 8 hrs ago0x2aa1285a261f83adda49147dbb0d299cc3385c67  IN   0xdda9bcd985b1169607546b52910a0269dff5baf10 Ether0.000107894
0xacf2f177ca002114439e47333e3eb16c58cd671a3fe426f60e0928718ff40e3e198 days 8 hrs ago0x2aa1285a261f83adda49147dbb0d299cc3385c67  IN   0xdda9bcd985b1169607546b52910a0269dff5baf10 Ether0.000105078
0x7af31ba2b15a8618a7ab20a106050c238e65e413de60b404924e8912a599b7e5198 days 8 hrs ago0x2aa1285a261f83adda49147dbb0d299cc3385c67  IN   0xdda9bcd985b1169607546b52910a0269dff5baf10 Ether0.000107894
0x0ee7805bbfd06bde5d559a317420a6d256d9f891ae61bbcceedc27af8ac2a631198 days 8 hrs ago0x2aa1285a261f83adda49147dbb0d299cc3385c67  IN   0xdda9bcd985b1169607546b52910a0269dff5baf10 Ether0.000105078
0x4ab4171f186389a05a31fe3b84b593ffc0f37c7c5b7631299ab8fd4bf915a5bd198 days 8 hrs ago0x2aa1285a261f83adda49147dbb0d299cc3385c67  IN   0xdda9bcd985b1169607546b52910a0269dff5baf10 Ether0.000107894
0x4afe057a6db6d4c83e1ce6ee6049d4a604273ef0c6af62236c357dc178b9c426198 days 8 hrs ago0x2aa1285a261f83adda49147dbb0d299cc3385c67  IN   0xdda9bcd985b1169607546b52910a0269dff5baf10 Ether0.00011003
0x126e9e8fd1eb3eb32a4aa32e5e63b263ae585551abd8eda825dce069979fca35198 days 8 hrs ago0x2aa1285a261f83adda49147dbb0d299cc3385c67  IN   0xdda9bcd985b1169607546b52910a0269dff5baf10 Ether0.000105078
0xb45e2bdae09f0ae82a9309cf121f0dcc5ee04566ffe406c7ecc72ff69ad8a7be198 days 8 hrs ago0x2aa1285a261f83adda49147dbb0d299cc3385c67  IN   0xdda9bcd985b1169607546b52910a0269dff5baf10 Ether0.00011003
0xaa422e272689b48b2967de1912fc5495905522188c908a60c79fc085c096f008198 days 8 hrs ago0x2aa1285a261f83adda49147dbb0d299cc3385c67  IN   0xdda9bcd985b1169607546b52910a0269dff5baf10 Ether0.000110011
0xfb6cfe62649d0efcbcb9af37fee691d140791203457238b547b466942b231998198 days 10 hrs ago0x9c93c4575402195775d4ab5d83877c079723382a  IN   0xdda9bcd985b1169607546b52910a0269dff5baf10 Ether0.0000321585
0x963e869428faf0e1891a960c50744c463bd1e66ba17fd264dfa849372c90a77a199 days 14 hrs ago0x817c4749ff5d7738dee0a0be4da03665e1def4d1  IN   0xdda9bcd985b1169607546b52910a0269dff5baf10 Ether0.000028427
0x77f1cae1d87b3a3d81c4dfa9d5ee8629c49c5277d460fa2b81b09327774e81ae200 days 3 hrs ago0x9c93c4575402195775d4ab5d83877c079723382a  IN   0xdda9bcd985b1169607546b52910a0269dff5baf10 Ether0.0000180016
0x2dd3796b3d86e5baeeadc99e15e0f60ba6c9ef1d2d1838b8f0696d164ded5706200 days 5 hrs ago0x94a3d984c45b228cb6c9ff098ef7282bb511a28f  IN   0xdda9bcd985b1169607546b52910a0269dff5baf10 Ether0.000171976
[ Download CSV Export  ] 
 Internal Transactions as a result of Contract Execution
 Latest 25 Internal Txns, Click Here To View More View All
ParentTxHash Block Age From To Value
0x893241a425af3d1fb02c24d019fe5e8325db43846d81c713764b3ce28d443fd75435200190 days 8 hrs ago0xdda9bcd985b1169607546b52910a0269dff5baf10x19b08a1007186b661d99fad0c75034bae473b6006 wei
0x6f00dbc40ce17175eab95e350c313f413b2e5509c04acb2d9f979b4866b799515394709197 days 2 hrs ago0xdda9bcd985b1169607546b52910a0269dff5baf10xdb9f2c93d792c14ab37f58658718b8422d29a0440.000230853014629532 Ether
0x33f33975b2b2a599441a6a6a42e947cf897e181954d6f98c7dc1bdda77a5925a5393831197 days 6 hrs ago0xdda9bcd985b1169607546b52910a0269dff5baf10x2e965f6d55cad05c320eb2f38ce6753037d1dbc10.014587024861967068 Ether
0x2e79fb8a0eec3a39a28de6e3673688f442133171fe6d8d6e259a742124e9dbc35375432200 days 7 hrs ago0xdda9bcd985b1169607546b52910a0269dff5baf10x00adb04741091aa987a800dce951dfd8a164f9780.15885178341592835 Ether
0x81d0111873b038385bfe84f30384159a8510b6935e47e9900e953467ed44d5045375134200 days 8 hrs ago0xdda9bcd985b1169607546b52910a0269dff5baf10xb48c48bb891c75478c8ffcbe4dc02255fd4e28d6992 wei
0x07be5d2ff6a6bea19b664716b1e687ef7e879b6fe973ffb75ebb3d2aa3c9755a5373462200 days 15 hrs ago0xdda9bcd985b1169607546b52910a0269dff5baf10x764a8f5efa25c6a38e86f711cfb4e8ed0aed0c650.27174285484699014 Ether
0xd0e218589fdded61d56ebd5e9fe957bb836641075a87d21f8d52aaaed0e0510e5370224201 days 4 hrs ago0xdda9bcd985b1169607546b52910a0269dff5baf10xe44d6941c70130881561ac96ab8113b06b3136450.007499999999999989 Ether
0xde185c2b2d6dedf699af0635f1d1023f4b9f0860d097b3becc96a2fd2844b1b95370150201 days 4 hrs ago0xdda9bcd985b1169607546b52910a0269dff5baf10x4614ec6b69eaf14f51ae9b2be1220ea5011c8e960.000000000000001 Ether
0x91e3930e80aadc0fc8ea72b3352f7a2bec74b9d245c0553b6a22adeac594f46b5369533201 days 7 hrs ago0xdda9bcd985b1169607546b52910a0269dff5baf10x361084af8d45e07885b31fcedcb642b9cc7b72d70.000159062641349373 Ether
0xb69d9c5dbbe89987a3ae7f38dc633af77f11d117ca6d82fa49ee336caef264435369400201 days 7 hrs ago0xdda9bcd985b1169607546b52910a0269dff5baf10x464150caaea2c4ee1f4f88cdf9b5c24d0e9c84cb0.002654809668250342 Ether
0x064a70b6eafbfbb536114ad598396c7b6e8163dfef9703ece6563e7113d066185368772201 days 9 hrs ago0xdda9bcd985b1169607546b52910a0269dff5baf10x265084d861015b516c92fe96d08fb3c3d794e75f0.000663702417061818 Ether
0xa8ce2b3bbdec8e6cb68e2265831dc153091f9c988ad1685064465dabd56a13675367234201 days 16 hrs ago0xdda9bcd985b1169607546b52910a0269dff5baf10x0b46faecfe315c44f1ddf463ac68d1d5c3bb19120.014104232470393882 Ether
0x95e7357f7c3be0fc60713afbe88f3a2fdcce114092a6be85ab6d93184f049c525367227201 days 16 hrs ago0xdda9bcd985b1169607546b52910a0269dff5baf10x80113f7bb9ddc6693585e103fb675ba17b6a9c060.000000000000001 Ether
0x0f03fc2ed5574d8689740acb1e0ac31f93e8df570267e5832384685ae33d7b405367220201 days 16 hrs ago0xdda9bcd985b1169607546b52910a0269dff5baf10x80113f7bb9ddc6693585e103fb675ba17b6a9c060.000244119550145462 Ether
0x1a24b78a6c0fa20762c62f67810307b3c3a695593c38de97b930d8aac6081c005367045201 days 16 hrs ago0xdda9bcd985b1169607546b52910a0269dff5baf10x854058553df87ef1be2c1d8f24eea8af52a81ff10.003788663293969076 Ether
0xa83e1c4b2c17a6b891798bfcba4014d8d866133a4ba2c34ea27fbd5adcf106465366491201 days 19 hrs ago0xdda9bcd985b1169607546b52910a0269dff5baf10xb6620725ea66a00aa29e3d6b61e5e3b502c4bcc20.004504237617114632 Ether
0xb3e7c775554814168747bbc61ccaa05d850cc406d3e793cf561e70b7b80df8775366169201 days 20 hrs ago0xdda9bcd985b1169607546b52910a0269dff5baf10x38752a26db17c388108d235ac33557f4f86be69d0.00423430051482622 Ether
0xf5aa2c687c75c74ea62bb74485a71dfddd979fe3cbfc2466c78be4462fe7f3955366147201 days 20 hrs ago0xdda9bcd985b1169607546b52910a0269dff5baf10xef764bac8a438e7e498c2e5fccf0f174c3e3f8db0.11238918337891731 Ether
0xadede8478f09e37de722a21136e3df334515480f644bbbfdab120e98c11bf23c5366139201 days 20 hrs ago0xdda9bcd985b1169607546b52910a0269dff5baf10xef764bac8a438e7e498c2e5fccf0f174c3e3f8db0.074999999999999 Ether
0xcb86936cb744f3944ac32402b8ca810fc97f3f9ec93af33eaec707586b69710f5366009201 days 21 hrs ago0xdda9bcd985b1169607546b52910a0269dff5baf10xeddad54e9e1f8dd01e815d84b255998a0a901bbf0.00682372074335524 Ether
0xec14a2ba4d3143b5547586c5f4c11087db6d57e261ff1db095571aa3784514ed5365752201 days 22 hrs ago0xdda9bcd985b1169607546b52910a0269dff5baf10xf1fa9a38914e853de933fbf7df2f278701e873df0.15 Ether
0x699a531e290fadb875ed72db810c34a312ede44424da91c0915aadb75b4acffe5365514201 days 23 hrs ago0xdda9bcd985b1169607546b52910a0269dff5baf10x635c1b88ffad2c0013c7816b6dcdc9f9f772b53d0.009450545286438256 Ether
0x2dcd5d7b477ab9b67b7bc9ae9cc2462d8d69d28144b8e85402914bf360dc77305365490201 days 23 hrs ago0xdda9bcd985b1169607546b52910a0269dff5baf10x4ffe17a2a72bc7422cb176bc71c04ee6d87ce3290.1425 Ether
0x3fc02e009bb8592a97136c797cc5d133ad77e254d2ba6b86e187e2d059f81f485365412201 days 23 hrs ago0xdda9bcd985b1169607546b52910a0269dff5baf10xe8d337c900542aab7811869c738ef481caab35024.6575 Ether
0x1f01ef765d4ef91559d66ef3836ef317d2ddec6df7345d4d078371ad9d7fe8cd5365363201 days 23 hrs ago0xdda9bcd985b1169607546b52910a0269dff5baf10xe8d337c900542aab7811869c738ef481caab35020.3935386285410864 Ether
[ Download CSV Export  ] 
Warning: The Compiled Contract might be susceptible to ExpExponentCleanup (medium/high-severity), EventStructWrongData (very low-severity), NestedArrayFunctionCallDecoder (medium-severity) SolidityCompiler Bugs.

Contract Source Code Verified (Exact Match)
Contract Name: Goo
Compiler Text: v0.4.21+commit.dfe3193c
Optimization Enabled: Yes
Runs (Optimiser):  200



  Contract Source Code   Find Similiar Contracts

pragma solidity ^0.4.0;

interface ERC20 {
    function totalSupply() public constant returns (uint);
    function balanceOf(address tokenOwner) public constant returns (uint balance);
    function allowance(address tokenOwner, address spender) public constant returns (uint remaining);
    function transfer(address to, uint tokens) public returns (bool success);
    function approve(address spender, uint tokens) public returns (bool success);
    function transferFrom(address from, address to, uint tokens) public returns (bool success);

    event Transfer(address indexed from, address indexed to, uint tokens);
    event Approval(address indexed tokenOwner, address indexed spender, uint tokens);
}

// GOO - Crypto Idle Game
// https://ethergoo.io

contract Goo is ERC20 {
    
    string public constant name  = "IdleEth";
    string public constant symbol = "Goo";
    uint8 public constant decimals = 0;
    uint256 private roughSupply;
    uint256 public totalGooProduction;
    address public owner; // Minor management of game
    bool public gameStarted;
    
    uint256 public totalEtherGooResearchPool; // Eth dividends to be split between players' goo production
    uint256[] public totalGooProductionSnapshots; // The total goo production for each prior day past
    uint256[] public allocatedGooResearchSnapshots; // The research eth allocated to each prior day past
    uint256 public nextSnapshotTime;
    
    uint256 private MAX_PRODUCTION_UNITS = 999; // Per type (makes balancing slightly easier)
    uint256 private constant RAFFLE_TICKET_BASE_GOO_PRICE = 1000;
    
    // Balances for each player
    mapping(address => uint256) private ethBalance;
    mapping(address => uint256) private gooBalance;
    mapping(address => mapping(uint256 => uint256)) private gooProductionSnapshots; // Store player's goo production for given day (snapshot)
    mapping(address => mapping(uint256 => bool)) private gooProductionZeroedSnapshots; // This isn't great but we need know difference between 0 production and an unused/inactive day.
    
    mapping(address => uint256) private lastGooSaveTime; // Seconds (last time player claimed their produced goo)
    mapping(address => uint256) public lastGooProductionUpdate; // Days (last snapshot player updated their production)
    mapping(address => uint256) private lastGooResearchFundClaim; // Days (snapshot number)
    mapping(address => uint256) private battleCooldown; // If user attacks they cannot attack again for short time
    
    // Stuff owned by each player
    mapping(address => mapping(uint256 => uint256)) private unitsOwned;
    mapping(address => mapping(uint256 => bool)) private upgradesOwned;
    mapping(uint256 => address) private rareItemOwner;
    mapping(uint256 => uint256) private rareItemPrice;
    
    // Rares & Upgrades (Increase unit's production / attack etc.)
    mapping(address => mapping(uint256 => uint256)) private unitGooProductionIncreases; // Adds to the goo per second
    mapping(address => mapping(uint256 => uint256)) private unitGooProductionMultiplier; // Multiplies the goo per second
    mapping(address => mapping(uint256 => uint256)) private unitAttackIncreases;
    mapping(address => mapping(uint256 => uint256)) private unitAttackMultiplier;
    mapping(address => mapping(uint256 => uint256)) private unitDefenseIncreases;
    mapping(address => mapping(uint256 => uint256)) private unitDefenseMultiplier;
    mapping(address => mapping(uint256 => uint256)) private unitGooStealingIncreases;
    mapping(address => mapping(uint256 => uint256)) private unitGooStealingMultiplier;
    
    // Mapping of approved ERC20 transfers (by player)
    mapping(address => mapping(address => uint256)) private allowed;
    mapping(address => bool) private protectedAddresses; // For npc exchanges (requires 0 goo production)
    
    // Raffle structures
    struct TicketPurchases {
        TicketPurchase[] ticketsBought;
        uint256 numPurchases; // Allows us to reset without clearing TicketPurchase[] (avoids potential for gas limit)
        uint256 raffleRareId;
    }
    
    // Allows us to query winner without looping (avoiding potential for gas limit)
    struct TicketPurchase {
        uint256 startId;
        uint256 endId;
    }
    
    // Raffle tickets
    mapping(address => TicketPurchases) private ticketsBoughtByPlayer;
    mapping(uint256 => address[]) private rafflePlayers; // Keeping a seperate list for each raffle has it's benefits.

    // Current raffle info
    uint256 private raffleEndTime;
    uint256 private raffleRareId;
    uint256 private raffleTicketsBought;
    address private raffleWinner; // Address of winner
    bool private raffleWinningTicketSelected;
    uint256 private raffleTicketThatWon;
    
    // Minor game events
    event UnitBought(address player, uint256 unitId, uint256 amount);
    event UnitSold(address player, uint256 unitId, uint256 amount);
    event PlayerAttacked(address attacker, address target, bool success, uint256 gooStolen);
    
    GooGameConfig schema;
    
    // Constructor
    function Goo() public payable {
        owner = msg.sender;
        schema = GooGameConfig(0x21912e81d7eff8bff895302b45da76f7f070e3b9);
    }
    
    function() payable { }
    
    function beginGame(uint256 firstDivsTime) external payable {
        require(msg.sender == owner);
        require(!gameStarted);
        
        gameStarted = true; // GO-OOOO!
        nextSnapshotTime = firstDivsTime;
        totalEtherGooResearchPool = msg.value; // Seed pot
    }
    
    function totalSupply() public constant returns(uint256) {
        return roughSupply; // Stored goo (rough supply as it ignores earned/unclaimed goo)
    }
    
    function balanceOf(address player) public constant returns(uint256) {
        return gooBalance[player] + balanceOfUnclaimedGoo(player);
    }
    
    function balanceOfUnclaimedGoo(address player) internal constant returns (uint256) {
        if (lastGooSaveTime[player] > 0 && lastGooSaveTime[player] < block.timestamp) {
            return (getGooProduction(player) * (block.timestamp - lastGooSaveTime[player]));
        }
        return 0;
    }
    
    function etherBalanceOf(address player) public constant returns(uint256) {
        return ethBalance[player];
    }
    
    function transfer(address recipient, uint256 amount) public returns (bool) {
        updatePlayersGoo(msg.sender);
        require(amount <= gooBalance[msg.sender]);
        
        gooBalance[msg.sender] -= amount;
        gooBalance[recipient] += amount;
        
        emit Transfer(msg.sender, recipient, amount);
        return true;
    }
    
    function transferFrom(address player, address recipient, uint256 amount) public returns (bool) {
        updatePlayersGoo(player);
        require(amount <= allowed[player][msg.sender] && amount <= gooBalance[msg.sender]);
        
        gooBalance[player] -= amount;
        gooBalance[recipient] += amount;
        allowed[player][msg.sender] -= amount;
        
        emit Transfer(player, recipient, amount);
        return true;
    }
    
    function approve(address approvee, uint256 amount) public returns (bool){
        allowed[msg.sender][approvee] = amount;
        emit Approval(msg.sender, approvee, amount);
        return true;
    }
    
    function allowance(address player, address approvee) public constant returns(uint256){
        return allowed[player][approvee];
    }
    
    function getGooProduction(address player) public constant returns (uint256){
        return gooProductionSnapshots[player][lastGooProductionUpdate[player]];
    }
    
    function updatePlayersGoo(address player) internal {
        uint256 gooGain = balanceOfUnclaimedGoo(player);
        lastGooSaveTime[player] = block.timestamp;
        roughSupply += gooGain;
        gooBalance[player] += gooGain;
    }
    
    function updatePlayersGooFromPurchase(address player, uint256 purchaseCost) internal {
        uint256 unclaimedGoo = balanceOfUnclaimedGoo(player);
        
        if (purchaseCost > unclaimedGoo) {
            uint256 gooDecrease = purchaseCost - unclaimedGoo;
            roughSupply -= gooDecrease;
            gooBalance[player] -= gooDecrease;
        } else {
            uint256 gooGain = unclaimedGoo - purchaseCost;
            roughSupply += gooGain;
            gooBalance[player] += gooGain;
        }
        
        lastGooSaveTime[player] = block.timestamp;
    }
    
    function increasePlayersGooProduction(uint256 increase) internal {
        gooProductionSnapshots[msg.sender][allocatedGooResearchSnapshots.length] = getGooProduction(msg.sender) + increase;
        lastGooProductionUpdate[msg.sender] = allocatedGooResearchSnapshots.length;
        totalGooProduction += increase;
    }
    
    function reducePlayersGooProduction(address player, uint256 decrease) internal {
        uint256 previousProduction = getGooProduction(player);
        uint256 newProduction = SafeMath.sub(previousProduction, decrease);
        
        if (newProduction == 0) { // Special case which tangles with "inactive day" snapshots (claiming divs)
            gooProductionZeroedSnapshots[player][allocatedGooResearchSnapshots.length] = true;
            delete gooProductionSnapshots[player][allocatedGooResearchSnapshots.length]; // 0
        } else {
            gooProductionSnapshots[player][allocatedGooResearchSnapshots.length] = newProduction;
        }
        
        lastGooProductionUpdate[player] = allocatedGooResearchSnapshots.length;
        totalGooProduction -= decrease;
    }
    
    function buyBasicUnit(uint256 unitId, uint256 amount) external {
        require(gameStarted);
        require(schema.validUnitId(unitId));
        require(unitsOwned[msg.sender][unitId] + amount <= MAX_PRODUCTION_UNITS);
        
        uint256 unitCost = schema.getGooCostForUnit(unitId, unitsOwned[msg.sender][unitId], amount);
        require(balanceOf(msg.sender) >= unitCost);
        require(schema.unitEthCost(unitId) == 0); // Free unit
        
        // Update players goo
        updatePlayersGooFromPurchase(msg.sender, unitCost);
        
        if (schema.unitGooProduction(unitId) > 0) {
            increasePlayersGooProduction(getUnitsProduction(msg.sender, unitId, amount));
        }
        
        unitsOwned[msg.sender][unitId] += amount;
        emit UnitBought(msg.sender, unitId, amount);
    }
    
    function buyEthUnit(uint256 unitId, uint256 amount) external payable {
        require(gameStarted);
        require(schema.validUnitId(unitId));
        require(unitsOwned[msg.sender][unitId] + amount <= MAX_PRODUCTION_UNITS);
        
        uint256 unitCost = schema.getGooCostForUnit(unitId, unitsOwned[msg.sender][unitId], amount);
        uint256 ethCost = SafeMath.mul(schema.unitEthCost(unitId), amount);
        
        require(balanceOf(msg.sender) >= unitCost);
        require(ethBalance[msg.sender] + msg.value >= ethCost);
        
        // Update players goo
        updatePlayersGooFromPurchase(msg.sender, unitCost);

        if (ethCost > msg.value) {
            ethBalance[msg.sender] -= (ethCost - msg.value);
        }
        
        uint256 devFund = ethCost / 50; // 2% fee on purchases (marketing, gameplay & maintenance)
        uint256 dividends = (ethCost - devFund) / 4; // 25% goes to pool (75% retained for sale value)
        totalEtherGooResearchPool += dividends;
        ethBalance[owner] += devFund;
        
        if (schema.unitGooProduction(unitId) > 0) {
            increasePlayersGooProduction(getUnitsProduction(msg.sender, unitId, amount));
        }
        
        unitsOwned[msg.sender][unitId] += amount;
        emit UnitBought(msg.sender, unitId, amount);
    }
    
    function sellUnit(uint256 unitId, uint256 amount) external {
        require(unitsOwned[msg.sender][unitId] >= amount);
        unitsOwned[msg.sender][unitId] -= amount;
        
        uint256 unitSalePrice = (schema.getGooCostForUnit(unitId, unitsOwned[msg.sender][unitId], amount) * 3) / 4; // 75%
        uint256 gooChange = balanceOfUnclaimedGoo(msg.sender) + unitSalePrice; // Claim unsaved goo whilst here
        lastGooSaveTime[msg.sender] = block.timestamp;
        roughSupply += gooChange;
        gooBalance[msg.sender] += gooChange;
        
        if (schema.unitGooProduction(unitId) > 0) {
            reducePlayersGooProduction(msg.sender, getUnitsProduction(msg.sender, unitId, amount));
        }
        
        if (schema.unitEthCost(unitId) > 0) { // Premium units sell for 75% of buy cost
            ethBalance[msg.sender] += ((schema.unitEthCost(unitId) * amount) * 3) / 4;
        }
        emit UnitSold(msg.sender, unitId, amount);
    }
    
    function buyUpgrade(uint256 upgradeId) external payable {
        require(gameStarted);
        require(schema.validUpgradeId(upgradeId)); // Valid upgrade
        require(!upgradesOwned[msg.sender][upgradeId]); // Haven't already purchased
        
        uint256 gooCost;
        uint256 ethCost;
        uint256 upgradeClass;
        uint256 unitId;
        uint256 upgradeValue;
        (gooCost, ethCost, upgradeClass, unitId, upgradeValue) = schema.getUpgradeInfo(upgradeId);
        
        require(balanceOf(msg.sender) >= gooCost);
        
        if (ethCost > 0) {
            require(ethBalance[msg.sender] + msg.value >= ethCost);
             if (ethCost > msg.value) { // They can use their balance instead
                ethBalance[msg.sender] -= (ethCost - msg.value);
            }
        
            uint256 devFund = ethCost / 50; // 2% fee on purchases (marketing, gameplay & maintenance)
            totalEtherGooResearchPool += (ethCost - devFund); // Rest goes to div pool (Can't sell upgrades)
            ethBalance[owner] += devFund;
        }
        
        // Update players goo
        updatePlayersGooFromPurchase(msg.sender, gooCost);

        upgradeUnitMultipliers(msg.sender, upgradeClass, unitId, upgradeValue);
        upgradesOwned[msg.sender][upgradeId] = true;
    }
    
    function upgradeUnitMultipliers(address player, uint256 upgradeClass, uint256 unitId, uint256 upgradeValue) internal {
        uint256 productionGain;
        if (upgradeClass == 0) {
            unitGooProductionIncreases[player][unitId] += upgradeValue;
            productionGain = (unitsOwned[player][unitId] * upgradeValue * (10 + unitGooProductionMultiplier[player][unitId])) / 10;
            increasePlayersGooProduction(productionGain);
        } else if (upgradeClass == 1) {
            unitGooProductionMultiplier[player][unitId] += upgradeValue;
            productionGain = (unitsOwned[player][unitId] * upgradeValue * (schema.unitGooProduction(unitId) + unitGooProductionIncreases[player][unitId])) / 10;
            increasePlayersGooProduction(productionGain);
        } else if (upgradeClass == 2) {
            unitAttackIncreases[player][unitId] += upgradeValue;
        } else if (upgradeClass == 3) {
            unitAttackMultiplier[player][unitId] += upgradeValue;
        } else if (upgradeClass == 4) {
            unitDefenseIncreases[player][unitId] += upgradeValue;
        } else if (upgradeClass == 5) {
            unitDefenseMultiplier[player][unitId] += upgradeValue;
        } else if (upgradeClass == 6) {
            unitGooStealingIncreases[player][unitId] += upgradeValue;
        } else if (upgradeClass == 7) {
            unitGooStealingMultiplier[player][unitId] += upgradeValue;
        }
    }
    
    function removeUnitMultipliers(address player, uint256 upgradeClass, uint256 unitId, uint256 upgradeValue) internal {
        uint256 productionLoss;
        if (upgradeClass == 0) {
            unitGooProductionIncreases[player][unitId] -= upgradeValue;
            productionLoss = (unitsOwned[player][unitId] * upgradeValue * (10 + unitGooProductionMultiplier[player][unitId])) / 10;
            reducePlayersGooProduction(player, productionLoss);
        } else if (upgradeClass == 1) {
            unitGooProductionMultiplier[player][unitId] -= upgradeValue;
            productionLoss = (unitsOwned[player][unitId] * upgradeValue * (schema.unitGooProduction(unitId) + unitGooProductionIncreases[player][unitId])) / 10;
            reducePlayersGooProduction(player, productionLoss);
        } else if (upgradeClass == 2) {
            unitAttackIncreases[player][unitId] -= upgradeValue;
        } else if (upgradeClass == 3) {
            unitAttackMultiplier[player][unitId] -= upgradeValue;
        } else if (upgradeClass == 4) {
            unitDefenseIncreases[player][unitId] -= upgradeValue;
        } else if (upgradeClass == 5) {
            unitDefenseMultiplier[player][unitId] -= upgradeValue;
        } else if (upgradeClass == 6) {
            unitGooStealingIncreases[player][unitId] -= upgradeValue;
        } else if (upgradeClass == 7) {
            unitGooStealingMultiplier[player][unitId] -= upgradeValue;
        }
    }
    
    function buyRareItem(uint256 rareId) external payable {
        require(schema.validRareId(rareId));
        
        address previousOwner = rareItemOwner[rareId];
        require(previousOwner != 0);

        uint256 ethCost = rareItemPrice[rareId];
        require(ethBalance[msg.sender] + msg.value >= ethCost);
        
        // We have to claim buyer's goo before updating their production values
        updatePlayersGoo(msg.sender);
        
        uint256 upgradeClass;
        uint256 unitId;
        uint256 upgradeValue;
        (upgradeClass, unitId, upgradeValue) = schema.getRareInfo(rareId);
        upgradeUnitMultipliers(msg.sender, upgradeClass, unitId, upgradeValue);
        
        // We have to claim seller's goo before reducing their production values
        updatePlayersGoo(previousOwner);
        removeUnitMultipliers(previousOwner, upgradeClass, unitId, upgradeValue);
        
        // Splitbid/Overbid
        if (ethCost > msg.value) {
            // Earlier require() said they can still afford it (so use their ingame balance)
            ethBalance[msg.sender] -= (ethCost - msg.value);
        } else if (msg.value > ethCost) {
            // Store overbid in their balance
            ethBalance[msg.sender] += msg.value - ethCost;
        }
        
        // Distribute ethCost
        uint256 devFund = ethCost / 50; // 2% fee on purchases (marketing, gameplay & maintenance)
        uint256 dividends = ethCost / 20; // 5% goes to pool (~93% goes to player)
        totalEtherGooResearchPool += dividends;
        ethBalance[owner] += devFund;
        
        // Transfer / update rare item
        rareItemOwner[rareId] = msg.sender;
        rareItemPrice[rareId] = (ethCost * 5) / 4; // 25% price flip increase
        ethBalance[previousOwner] += ethCost - (dividends + devFund);
    }
    
    function withdrawEther(uint256 amount) external {
        require(amount <= ethBalance[msg.sender]);
        ethBalance[msg.sender] -= amount;
        msg.sender.transfer(amount);
    }
    
    function claimResearchDividends(address referer, uint256 startSnapshot, uint256 endSnapShot) external {
        require(startSnapshot <= endSnapShot);
        require(startSnapshot >= lastGooResearchFundClaim[msg.sender]);
        require(endSnapShot < allocatedGooResearchSnapshots.length);
        
        uint256 researchShare;
        uint256 previousProduction = gooProductionSnapshots[msg.sender][lastGooResearchFundClaim[msg.sender] - 1]; // Underflow won't be a problem as gooProductionSnapshots[][0xffffffffff] = 0;
        for (uint256 i = startSnapshot; i <= endSnapShot; i++) {
            
            // Slightly complex things by accounting for days/snapshots when user made no tx's
            uint256 productionDuringSnapshot = gooProductionSnapshots[msg.sender][i];
            bool soldAllProduction = gooProductionZeroedSnapshots[msg.sender][i];
            if (productionDuringSnapshot == 0 && !soldAllProduction) {
                productionDuringSnapshot = previousProduction;
            } else {
               previousProduction = productionDuringSnapshot;
            }
            
            researchShare += (allocatedGooResearchSnapshots[i] * productionDuringSnapshot) / totalGooProductionSnapshots[i];
        }
        
        
        if (gooProductionSnapshots[msg.sender][endSnapShot] == 0 && !gooProductionZeroedSnapshots[msg.sender][i] && previousProduction > 0) {
            gooProductionSnapshots[msg.sender][endSnapShot] = previousProduction; // Checkpoint for next claim
        }
        
        lastGooResearchFundClaim[msg.sender] = endSnapShot + 1;
        
        uint256 referalDivs;
        if (referer != address(0) && referer != msg.sender) {
            referalDivs = researchShare / 100; // 1%
            ethBalance[referer] += referalDivs;
        }
        
        ethBalance[msg.sender] += researchShare - referalDivs;
    }
    
    // Allocate divs for the day (cron job)
    function snapshotDailyGooResearchFunding() external {
        require(msg.sender == owner);
        //require(block.timestamp >= (nextSnapshotTime - 30 minutes)); // Small bit of leeway for cron / network
        
        uint256 todaysEtherResearchFund = (totalEtherGooResearchPool / 10); // 10% of pool daily
        totalEtherGooResearchPool -= todaysEtherResearchFund;
        
        totalGooProductionSnapshots.push(totalGooProduction);
        allocatedGooResearchSnapshots.push(todaysEtherResearchFund);
        nextSnapshotTime = block.timestamp + 24 hours;
    }
    
    
    
    // Raffle for rare items
    function buyRaffleTicket(uint256 amount) external {
        require(raffleEndTime >= block.timestamp);
        require(amount > 0);
        
        uint256 ticketsCost = SafeMath.mul(RAFFLE_TICKET_BASE_GOO_PRICE, amount);
        require(balanceOf(msg.sender) >= ticketsCost);
        
        // Update players goo
        updatePlayersGooFromPurchase(msg.sender, ticketsCost);
        
        // Handle new tickets
        TicketPurchases storage purchases = ticketsBoughtByPlayer[msg.sender];
        
        // If we need to reset tickets from a previous raffle
        if (purchases.raffleRareId != raffleRareId) {
            purchases.numPurchases = 0;
            purchases.raffleRareId = raffleRareId;
            rafflePlayers[raffleRareId].push(msg.sender); // Add user to raffle
        }
        
        // Store new ticket purchase 
        if (purchases.numPurchases == purchases.ticketsBought.length) {
            purchases.ticketsBought.length += 1;
        }
        purchases.ticketsBought[purchases.numPurchases++] = TicketPurchase(raffleTicketsBought, raffleTicketsBought + (amount - 1)); // (eg: buy 10, get id's 0-9)
        
        // Finally update ticket total
        raffleTicketsBought += amount;
    }
    
    function startRareRaffle(uint256 endTime, uint256 rareId) external {
        require(msg.sender == owner);
        require(schema.validRareId(rareId));
        require(rareItemOwner[rareId] == 0);
        
        // Reset previous raffle info
        raffleWinningTicketSelected = false;
        raffleTicketThatWon = 0;
        raffleWinner = 0;
        raffleTicketsBought = 0;
        
        // Set current raffle info
        raffleEndTime = endTime;
        raffleRareId = rareId;
    }
    
    function awardRafflePrize(address checkWinner, uint256 checkIndex) external {
        require(raffleEndTime < block.timestamp);
        require(raffleWinner == 0);
        require(rareItemOwner[raffleRareId] == 0);
        
        if (!raffleWinningTicketSelected) {
            drawRandomWinner(); // Ideally do it in one call (gas limit cautious)
        }
        
        // Reduce gas by (optionally) offering an address to _check_ for winner
        if (checkWinner != 0) {
            TicketPurchases storage tickets = ticketsBoughtByPlayer[checkWinner];
            if (tickets.numPurchases > 0 && checkIndex < tickets.numPurchases && tickets.raffleRareId == raffleRareId) {
                TicketPurchase storage checkTicket = tickets.ticketsBought[checkIndex];
                if (raffleTicketThatWon >= checkTicket.startId && raffleTicketThatWon <= checkTicket.endId) {
                    assignRafflePrize(checkWinner); // WINNER!
                    return;
                }
            }
        }
        
        // Otherwise just naively try to find the winner (will work until mass amounts of players)
        for (uint256 i = 0; i < rafflePlayers[raffleRareId].length; i++) {
            address player = rafflePlayers[raffleRareId][i];
            TicketPurchases storage playersTickets = ticketsBoughtByPlayer[player];
            
            uint256 endIndex = playersTickets.numPurchases - 1;
            // Minor optimization to avoid checking every single player
            if (raffleTicketThatWon >= playersTickets.ticketsBought[0].startId && raffleTicketThatWon <= playersTickets.ticketsBought[endIndex].endId) {
                for (uint256 j = 0; j < playersTickets.numPurchases; j++) {
                    TicketPurchase storage playerTicket = playersTickets.ticketsBought[j];
                    if (raffleTicketThatWon >= playerTicket.startId && raffleTicketThatWon <= playerTicket.endId) {
                        assignRafflePrize(player); // WINNER!
                        return;
                    }
                }
            }
        }
    }
    
    function assignRafflePrize(address winner) internal {
        raffleWinner = winner;
        rareItemOwner[raffleRareId] = winner;
        rareItemPrice[raffleRareId] = (schema.rareStartPrice(raffleRareId) * 21) / 20; // Buy price slightly higher (Div pool cut)
        
        updatePlayersGoo(winner);
        uint256 upgradeClass;
        uint256 unitId;
        uint256 upgradeValue;
        (upgradeClass, unitId, upgradeValue) = schema.getRareInfo(raffleRareId);
        upgradeUnitMultipliers(winner, upgradeClass, unitId, upgradeValue);
    }
    
    // Random enough for small contests (Owner only to prevent trial & error execution)
    function drawRandomWinner() public {
        require(msg.sender == owner);
        require(raffleEndTime < block.timestamp);
        require(!raffleWinningTicketSelected);
        
        uint256 seed = raffleTicketsBought + block.timestamp;
        raffleTicketThatWon = addmod(uint256(block.blockhash(block.number-1)), seed, raffleTicketsBought);
        raffleWinningTicketSelected = true;
    }
    
    
    
    function protectAddress(address exchange, bool isProtected) external {
        require(msg.sender == owner);
        require(getGooProduction(exchange) == 0); // Can't protect actual players
        protectedAddresses[exchange] = isProtected;
    }
    
    function attackPlayer(address target) external {
        require(battleCooldown[msg.sender] < block.timestamp);
        require(target != msg.sender);
        require(!protectedAddresses[target]); //target not whitelisted (i.e. exchange wallets)
        
        uint256 attackingPower;
        uint256 defendingPower;
        uint256 stealingPower;
        (attackingPower, defendingPower, stealingPower) = getPlayersBattlePower(msg.sender, target);
        
        if (battleCooldown[target] > block.timestamp) { // When on battle cooldown you're vulnerable (starting value is 50% normal power)
            defendingPower = schema.getWeakenedDefensePower(defendingPower);
        }
        
        if (attackingPower > defendingPower) {
            battleCooldown[msg.sender] = block.timestamp + 30 minutes;
            if (balanceOf(target) > stealingPower) {
                // Save all their unclaimed goo, then steal attacker's max capacity (at same time)
                uint256 unclaimedGoo = balanceOfUnclaimedGoo(target);
                if (stealingPower > unclaimedGoo) {
                    uint256 gooDecrease = stealingPower - unclaimedGoo;
                    gooBalance[target] -= gooDecrease;
                } else {
                    uint256 gooGain = unclaimedGoo - stealingPower;
                    gooBalance[target] += gooGain;
                }
                gooBalance[msg.sender] += stealingPower;
                emit PlayerAttacked(msg.sender, target, true, stealingPower);
            } else {
                emit PlayerAttacked(msg.sender, target, true, balanceOf(target));
                gooBalance[msg.sender] += balanceOf(target);
                gooBalance[target] = 0;
            }
            
            lastGooSaveTime[target] = block.timestamp; 
            // We don't need to claim/save msg.sender's goo (as production delta is unchanged)
        } else {
            battleCooldown[msg.sender] = block.timestamp + 10 minutes;
            emit PlayerAttacked(msg.sender, target, false, 0);
        }
    }
    
    function getPlayersBattlePower(address attacker, address defender) internal constant returns (uint256, uint256, uint256) {
        uint256 startId;
        uint256 endId;
        (startId, endId) = schema.battleUnitIdRange();
        
        uint256 attackingPower;
        uint256 defendingPower;
        uint256 stealingPower;

        // Not ideal but will only be a small number of units (and saves gas when buying units)
        while (startId <= endId) {
            attackingPower += getUnitsAttack(attacker, startId, unitsOwned[attacker][startId]);
            stealingPower += getUnitsStealingCapacity(attacker, startId, unitsOwned[attacker][startId]);
            
            defendingPower += getUnitsDefense(defender, startId, unitsOwned[defender][startId]);
            startId++;
        }
        return (attackingPower, defendingPower, stealingPower);
    }
    
    function getPlayersBattleStats(address player) external constant returns (uint256, uint256, uint256) {
        uint256 startId;
        uint256 endId;
        (startId, endId) = schema.battleUnitIdRange();
        
        uint256 attackingPower;
        uint256 defendingPower;
        uint256 stealingPower;

        // Not ideal but will only be a small number of units (and saves gas when buying units)
        while (startId <= endId) {
            attackingPower += getUnitsAttack(player, startId, unitsOwned[player][startId]);
            stealingPower += getUnitsStealingCapacity(player, startId, unitsOwned[player][startId]);
            defendingPower += getUnitsDefense(player, startId, unitsOwned[player][startId]);
            startId++;
        }
        return (attackingPower, defendingPower, stealingPower);
    }
    
    function getUnitsProduction(address player, uint256 unitId, uint256 amount) internal constant returns (uint256) {
        return (amount * (schema.unitGooProduction(unitId) + unitGooProductionIncreases[player][unitId]) * (10 + unitGooProductionMultiplier[player][unitId])) / 10;
    }
    
    function getUnitsAttack(address player, uint256 unitId, uint256 amount) internal constant returns (uint256) {
        return (amount * (schema.unitAttack(unitId) + unitAttackIncreases[player][unitId]) * (10 + unitAttackMultiplier[player][unitId])) / 10;
    }
    
    function getUnitsDefense(address player, uint256 unitId, uint256 amount) internal constant returns (uint256) {
        return (amount * (schema.unitDefense(unitId) + unitDefenseIncreases[player][unitId]) * (10 + unitDefenseMultiplier[player][unitId])) / 10;
    }
    
    function getUnitsStealingCapacity(address player, uint256 unitId, uint256 amount) internal constant returns (uint256) {
        return (amount * (schema.unitStealingCapacity(unitId) + unitGooStealingIncreases[player][unitId]) * (10 + unitGooStealingMultiplier[player][unitId])) / 10;
    }
    
    
    // To display on website
    function getGameInfo() external constant returns (uint256, uint256, uint256, uint256, uint256, uint256, uint256, uint256[], bool[]){
        uint256[] memory units = new uint256[](schema.currentNumberOfUnits());
        bool[] memory upgrades = new bool[](schema.currentNumberOfUpgrades());
        
        uint256 startId;
        uint256 endId;
        (startId, endId) = schema.productionUnitIdRange();
        
        uint256 i;
        while (startId <= endId) {
            units[i] = unitsOwned[msg.sender][startId];
            i++;
            startId++;
        }
        
        (startId, endId) = schema.battleUnitIdRange();
        while (startId <= endId) {
            units[i] = unitsOwned[msg.sender][startId];
            i++;
            startId++;
        }
        
        // Reset for upgrades
        i = 0;
        (startId, endId) = schema.upgradeIdRange();
        while (startId <= endId) {
            upgrades[i] = upgradesOwned[msg.sender][startId];
            i++;
            startId++;
        }
        
        return (block.timestamp, totalEtherGooResearchPool, totalGooProduction, nextSnapshotTime, balanceOf(msg.sender), ethBalance[msg.sender], getGooProduction(msg.sender), units, upgrades);
    }
    
    // To display on website
    function getRareItemInfo() external constant returns (address[], uint256[]) {
        address[] memory itemOwners = new address[](schema.currentNumberOfRares());
        uint256[] memory itemPrices = new uint256[](schema.currentNumberOfRares());
        
        uint256 startId;
        uint256 endId;
        (startId, endId) = schema.rareIdRange();
        
        uint256 i;
        while (startId <= endId) {
            itemOwners[i] = rareItemOwner[startId];
            itemPrices[i] = rareItemPrice[startId];
            
            i++;
            startId++;
        }
        
        return (itemOwners, itemPrices);
    }
    
    // To display on website
     function viewUnclaimedResearchDividends() external constant returns (uint256, uint256, uint256) {
        uint256 startSnapshot = lastGooResearchFundClaim[msg.sender];
        uint256 latestSnapshot = allocatedGooResearchSnapshots.length - 1; // No snapshots to begin with
        
        uint256 researchShare;
        uint256 previousProduction = gooProductionSnapshots[msg.sender][lastGooResearchFundClaim[msg.sender] - 1]; // Underflow won't be a problem as gooProductionSnapshots[][0xfffffffffffff] = 0;
        for (uint256 i = startSnapshot; i <= latestSnapshot; i++) {
            
            // Slightly complex things by accounting for days/snapshots when user made no tx's
            uint256 productionDuringSnapshot = gooProductionSnapshots[msg.sender][i];
            bool soldAllProduction = gooProductionZeroedSnapshots[msg.sender][i];
            if (productionDuringSnapshot == 0 && !soldAllProduction) {
                productionDuringSnapshot = previousProduction;
            } else {
               previousProduction = productionDuringSnapshot;
            }
            
            researchShare += (allocatedGooResearchSnapshots[i] * productionDuringSnapshot) / totalGooProductionSnapshots[i];
        }
        return (researchShare, startSnapshot, latestSnapshot);
    }
    
    
    // To allow clients to verify contestants
    function getRafflePlayers(uint256 raffleId) external constant returns (address[]) {
        return (rafflePlayers[raffleId]);
    }
    
    // To allow clients to verify contestants
    function getPlayersTickets(address player) external constant returns (uint256[], uint256[]) {
        TicketPurchases storage playersTickets = ticketsBoughtByPlayer[player];
        
        if (playersTickets.raffleRareId == raffleRareId) {
            uint256[] memory startIds = new uint256[](playersTickets.numPurchases);
            uint256[] memory endIds = new uint256[](playersTickets.numPurchases);
            
            for (uint256 i = 0; i < playersTickets.numPurchases; i++) {
                startIds[i] = playersTickets.ticketsBought[i].startId;
                endIds[i] = playersTickets.ticketsBought[i].endId;
            }
        }
        
        return (startIds, endIds);
    }
    
    // To display on website
    function getLatestRaffleInfo() external constant returns (uint256, uint256, uint256, address, uint256) {
        return (raffleEndTime, raffleRareId, raffleTicketsBought, raffleWinner, raffleTicketThatWon);
    }
    
    
    // New units may be added in future, but check it matches existing schema so no-one can abuse selling.
    function updateGooConfig(address newSchemaAddress) external {
        require(msg.sender == owner);
        
        GooGameConfig newSchema = GooGameConfig(newSchemaAddress);
        requireExistingUnitsSame(newSchema);
        requireExistingUpgradesSame(newSchema);
        
        // Finally update config
        schema = GooGameConfig(newSchema);
    }
    
    function requireExistingUnitsSame(GooGameConfig newSchema) internal constant {
        // Requires units eth costs match up or fail execution
        
        uint256 startId;
        uint256 endId;
        (startId, endId) = schema.productionUnitIdRange();
        while (startId <= endId) {
            require(schema.unitEthCost(startId) == newSchema.unitEthCost(startId));
            require(schema.unitGooProduction(startId) == newSchema.unitGooProduction(startId));
            startId++;
        }
        
        (startId, endId) = schema.battleUnitIdRange();
        while (startId <= endId) {
            require(schema.unitEthCost(startId) == newSchema.unitEthCost(startId));
            require(schema.unitAttack(startId) == newSchema.unitAttack(startId));
            require(schema.unitDefense(startId) == newSchema.unitDefense(startId));
            require(schema.unitStealingCapacity(startId) == newSchema.unitStealingCapacity(startId));
            startId++;
        }
    }
    
    function requireExistingUpgradesSame(GooGameConfig newSchema) internal constant {
        uint256 startId;
        uint256 endId;
        
        uint256 oldClass;
        uint256 oldUnitId;
        uint256 oldValue;
        
        uint256 newClass;
        uint256 newUnitId;
        uint256 newValue;
        
        // Requires ALL upgrade stats match up or fail execution
        (startId, endId) = schema.rareIdRange();
        while (startId <= endId) {
            uint256 oldGooCost;
            uint256 oldEthCost;
            (oldGooCost, oldEthCost, oldClass, oldUnitId, oldValue) = schema.getUpgradeInfo(startId);
            
            uint256 newGooCost;
            uint256 newEthCost;
            (newGooCost, newEthCost, newClass, newUnitId, newValue) = newSchema.getUpgradeInfo(startId);
            
            require(oldGooCost == newGooCost);
            require(oldEthCost == oldEthCost);
            require(oldClass == oldClass);
            require(oldUnitId == newUnitId);
            require(oldValue == newValue);
            startId++;
        }
        
        // Requires ALL rare stats match up or fail execution
        (startId, endId) = schema.rareIdRange();
        while (startId <= endId) {
            (oldClass, oldUnitId, oldValue) = schema.getRareInfo(startId);
            (newClass, newUnitId, newValue) = newSchema.getRareInfo(startId);
            
            require(oldClass == newClass);
            require(oldUnitId == newUnitId);
            require(oldValue == newValue);
            startId++;
        }
    }
}


contract GooGameConfig {
    
    mapping(uint256 => Unit) private unitInfo;
    mapping(uint256 => Upgrade) private upgradeInfo;
    mapping(uint256 => Rare) private rareInfo;
    
    uint256 public constant currentNumberOfUnits = 14;
    uint256 public constant currentNumberOfUpgrades = 42;
    uint256 public constant currentNumberOfRares = 2;
    
    struct Unit {
        uint256 unitId;
        uint256 baseGooCost;
        uint256 gooCostIncreaseHalf; // Halfed to make maths slightly less (cancels a 2 out)
        uint256 ethCost;
        uint256 baseGooProduction;
        
        uint256 attackValue;
        uint256 defenseValue;
        uint256 gooStealingCapacity;
    }
    
    struct Upgrade {
        uint256 upgradeId;
        uint256 gooCost;
        uint256 ethCost;
        uint256 upgradeClass;
        uint256 unitId;
        uint256 upgradeValue;
    }
    
     struct Rare {
        uint256 rareId;
        uint256 ethCost;
        uint256 rareClass;
        uint256 unitId;
        uint256 rareValue;
    }
    
    // Constructor
    function GooGameConfig() public {
        
        unitInfo[1] = Unit(1, 0, 10, 0, 1, 0, 0, 0);
        unitInfo[2] = Unit(2, 100, 50, 0, 2, 0, 0, 0);
        unitInfo[3] = Unit(3, 0, 0, 0.01 ether, 12, 0, 0, 0);
        unitInfo[4] = Unit(4, 500, 250, 0, 4, 0, 0, 0);
        unitInfo[5] = Unit(5, 2500, 1250, 0, 6, 0, 0, 0);
        unitInfo[6] = Unit(6, 10000, 5000, 0, 8, 0, 0, 0);
        unitInfo[7] = Unit(7, 0, 1000, 0.05 ether, 60, 0, 0, 0);
        unitInfo[8] = Unit(8, 25000, 12500, 0, 10, 0, 0, 0);
        
        unitInfo[40] = Unit(40, 100, 50, 0, 0, 10, 10, 20);
        unitInfo[41] = Unit(41, 250, 125, 0, 0, 1, 25, 1);
        unitInfo[42] = Unit(42, 0, 50, 0.01 ether, 0, 100, 10, 5);
        unitInfo[43] = Unit(43, 1000, 500, 0, 0, 25, 1, 50);
        unitInfo[44] = Unit(44, 2500, 1250, 0, 0, 20, 40, 100);
        unitInfo[45] = Unit(45, 0, 500, 0.02 ether, 0, 0, 0, 1000);
        
        upgradeInfo[1] = Upgrade(1, 500, 0, 0, 1, 1); // +1
        upgradeInfo[2] = Upgrade(2, 0, 0.1 ether, 1, 1, 10); // 10 = +100%
        upgradeInfo[3] = Upgrade(3, 10000, 0, 1, 1, 5); // 5 = +50%
        
        upgradeInfo[4] = Upgrade(4, 0, 0.1 ether, 0, 2, 2); // +1
        upgradeInfo[5] = Upgrade(5, 2000, 0, 1, 2, 5); // 10 = +50%
        upgradeInfo[6] = Upgrade(6, 0, 0.2 ether, 0, 2, 2); // +2
        
        upgradeInfo[7] = Upgrade(7, 2500, 0, 0, 3, 2); // +2
        upgradeInfo[8] = Upgrade(8, 0, 0.5 ether, 1, 3, 10); // 10 = +100%
        upgradeInfo[9] = Upgrade(9, 25000, 0, 1, 3, 5); // 5 = +50%
        
        upgradeInfo[10] = Upgrade(10, 0, 0.1 ether, 0, 4, 1); // +1
        upgradeInfo[11] = Upgrade(11, 5000, 0, 1, 4, 5); // 10 = +50%
        upgradeInfo[12] = Upgrade(12, 0, 0.2 ether, 0, 4, 2); // +2
        
        upgradeInfo[13] = Upgrade(13, 10000, 0, 0, 5, 2); // +2
        upgradeInfo[14] = Upgrade(14, 0, 0.5 ether, 1, 5, 10); // 10 = +100%
        upgradeInfo[15] = Upgrade(15, 25000, 0, 1, 5, 5); // 5 = +50%
        
        upgradeInfo[16] = Upgrade(16, 0, 0.1 ether, 0, 6, 1); // +1
        upgradeInfo[17] = Upgrade(17, 25000, 0, 1, 6, 5); // 10 = +50%
        upgradeInfo[18] = Upgrade(18, 0, 0.2 ether, 0, 6, 2); // +2
        
        upgradeInfo[19] = Upgrade(13, 50000, 0, 0, 7, 2); // +2
        upgradeInfo[20] = Upgrade(20, 0, 0.2 ether, 1, 7, 5); // 5 = +50%
        upgradeInfo[21] = Upgrade(21, 100000, 0, 1, 7, 5); // 5 = +50%
        
        upgradeInfo[22] = Upgrade(22, 0, 0.1 ether, 0, 8, 2); // +1
        upgradeInfo[23] = Upgrade(23, 25000, 0, 1, 8, 5); // 10 = +50%
        upgradeInfo[24] = Upgrade(24, 0, 0.2 ether, 0, 8, 4); // +2
        
        
        
        upgradeInfo[25] = Upgrade(25, 500, 0, 2, 40, 10); // +10
        upgradeInfo[26] = Upgrade(26, 0, 0.1 ether, 4, 40, 10); // +10
        upgradeInfo[27] = Upgrade(27, 10000, 0, 6, 40, 10); // +10
        
        upgradeInfo[28] = Upgrade(28, 0, 0.2 ether, 3, 41, 5); // +50 %
        upgradeInfo[29] = Upgrade(29, 5000, 0, 4, 41, 10); // +10
        upgradeInfo[30] = Upgrade(30, 0, 0.5 ether, 6, 41, 4); // +4
        
        upgradeInfo[31] = Upgrade(31, 2500, 0, 5, 42, 5); // +50 %
        upgradeInfo[32] = Upgrade(32, 0, 0.2 ether, 6, 42, 10); // +10
        upgradeInfo[33] = Upgrade(33, 20000, 0, 7, 42, 5); // +50 %
        
        upgradeInfo[34] = Upgrade(34, 0, 0.1 ether, 2, 43, 5); // +5
        upgradeInfo[35] = Upgrade(35, 10000, 0, 4, 43, 5); // +5
        upgradeInfo[36] = Upgrade(36, 0, 0.2 ether, 5, 43, 5); // +50%
        
        upgradeInfo[37] = Upgrade(37, 0, 0.1 ether, 2, 44, 15); // +15
        upgradeInfo[38] = Upgrade(38, 25000, 0, 3, 44, 5); // +50%
        upgradeInfo[39] = Upgrade(39, 0, 0.2 ether, 4, 44, 15); // +15
        
        upgradeInfo[40] = Upgrade(40, 50000, 0, 6, 45, 500); // +500
        upgradeInfo[41] = Upgrade(41, 0, 0.5 ether, 7, 45, 10); // +100 %
        upgradeInfo[42] = Upgrade(42, 250000, 0, 7, 45, 5); // +50 %
    
        
        rareInfo[1] = Rare(1, 0.5 ether, 1, 1, 30); // 30 = +300%
        rareInfo[2] = Rare(2, 0.5 ether, 0, 2, 4); // +4
    }
    
    function getGooCostForUnit(uint256 unitId, uint256 existing, uint256 amount) public constant returns (uint256) {
        if (amount == 1) { // 1
            if (existing == 0) {
                return unitInfo[unitId].baseGooCost;
            } else {
                return unitInfo[unitId].baseGooCost + (existing * unitInfo[unitId].gooCostIncreaseHalf * 2);
            }
        } else if (amount > 1) {
            uint256 existingCost;
            if (existing > 0) {
                existingCost = (unitInfo[unitId].baseGooCost * existing) + (existing * (existing - 1) * unitInfo[unitId].gooCostIncreaseHalf);
            }
            
            existing += amount;
            uint256 newCost = SafeMath.add(SafeMath.mul(unitInfo[unitId].baseGooCost, existing), SafeMath.mul(SafeMath.mul(existing, (existing - 1)), unitInfo[unitId].gooCostIncreaseHalf));
            return newCost - existingCost;
        }
    }
    
    function getWeakenedDefensePower(uint256 defendingPower) external constant returns (uint256) {
        return defendingPower / 2;
    }
    
    function validUnitId(uint256 unitId) external constant returns (bool) {
        return ((unitId > 0 && unitId < 9) || (unitId > 39 && unitId < 46));
    }
    
    function validUpgradeId(uint256 upgradeId) external constant returns (bool) {
        return (upgradeId > 0 && upgradeId < 43);
    }
    
    function validRareId(uint256 rareId) external constant returns (bool) {
        return (rareId > 0 && rareId < 3);
    }
    
    function unitEthCost(uint256 unitId) external constant returns (uint256) {
        return unitInfo[unitId].ethCost;
    }
    
    function unitGooProduction(uint256 unitId) external constant returns (uint256) {
        return unitInfo[unitId].baseGooProduction;
    }
    
    function unitAttack(uint256 unitId) external constant returns (uint256) {
        return unitInfo[unitId].attackValue;
    }
    
    function unitDefense(uint256 unitId) external constant returns (uint256) {
        return unitInfo[unitId].defenseValue;
    }
    
    function unitStealingCapacity(uint256 unitId) external constant returns (uint256) {
        return unitInfo[unitId].gooStealingCapacity;
    }
    
    function rareStartPrice(uint256 rareId) external constant returns (uint256) {
        return rareInfo[rareId].ethCost;
    }
    
    function productionUnitIdRange() external constant returns (uint256, uint256) {
        return (1, 8);
    }
    
    function battleUnitIdRange() external constant returns (uint256, uint256) {
        return (40, 45);
    }
    
    function upgradeIdRange() external constant returns (uint256, uint256) {
        return (1, 42);
    }
    
    function rareIdRange() external constant returns (uint256, uint256) {
        return (1, 2);
    }
    
    function getUpgradeInfo(uint256 upgradeId) external constant returns (uint256, uint256, uint256, uint256, uint256) {
        return (upgradeInfo[upgradeId].gooCost, upgradeInfo[upgradeId].ethCost, upgradeInfo[upgradeId].upgradeClass,
        upgradeInfo[upgradeId].unitId, upgradeInfo[upgradeId].upgradeValue);
    }
    
    function getRareInfo(uint256 rareId) external constant returns (uint256, uint256, uint256) {
        return (rareInfo[rareId].rareClass, rareInfo[rareId].unitId, rareInfo[rareId].rareValue);
    }
    
}

library SafeMath {

  /**
  * @dev Multiplies two numbers, throws on overflow.
  */
  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;
  }

  /**
  * @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 c;
  }

  /**
  * @dev Substracts 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) {
    uint256 c = a + b;
    assert(c >= a);
    return c;
  }
}

    Contract ABI  
[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"approvee","type":"address"},{"name":"amount","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"totalGooProductionSnapshots","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getGameInfo","outputs":[{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"uint256[]"},{"name":"","type":"bool[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"player","type":"address"}],"name":"etherBalanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"player","type":"address"}],"name":"getGooProduction","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"player","type":"address"},{"name":"recipient","type":"address"},{"name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"firstDivsTime","type":"uint256"}],"name":"beginGame","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[{"name":"player","type":"address"}],"name":"getPlayersTickets","outputs":[{"name":"","type":"uint256[]"},{"name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"unitId","type":"uint256"},{"name":"amount","type":"uint256"}],"name":"buyBasicUnit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"lastGooProductionUpdate","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalEtherGooResearchPool","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"amount","type":"uint256"}],"name":"withdrawEther","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getLatestRaffleInfo","outputs":[{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"address"},{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"checkWinner","type":"address"},{"name":"checkIndex","type":"uint256"}],"name":"awardRafflePrize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"viewUnclaimedResearchDividends","outputs":[{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"target","type":"address"}],"name":"attackPlayer","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"gameStarted","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"allocatedGooResearchSnapshots","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"player","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"exchange","type":"address"},{"name":"isProtected","type":"bool"}],"name":"protectAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"unitId","type":"uint256"},{"name":"amount","type":"uint256"}],"name":"sellUnit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"raffleId","type":"uint256"}],"name":"getRafflePlayers","outputs":[{"name":"","type":"address[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newSchemaAddress","type":"address"}],"name":"updateGooConfig","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalGooProduction","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"player","type":"address"}],"name":"getPlayersBattleStats","outputs":[{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"referer","type":"address"},{"name":"startSnapshot","type":"uint256"},{"name":"endSnapShot","type":"uint256"}],"name":"claimResearchDividends","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"rareId","type":"uint256"}],"name":"buyRareItem","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"upgradeId","type":"uint256"}],"name":"buyUpgrade","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"nextSnapshotTime","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"recipient","type":"address"},{"name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getRareItemInfo","outputs":[{"name":"","type":"address[]"},{"name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"amount","type":"uint256"}],"name":"buyRaffleTicket","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"drawRandomWinner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"snapshotDailyGooResearchFunding","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"unitId","type":"uint256"},{"name":"amount","type":"uint256"}],"name":"buyEthUnit","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"endTime","type":"uint256"},{"name":"rareId","type":"uint256"}],"name":"startRareRaffle","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"player","type":"address"},{"name":"approvee","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[],"payable":true,"stateMutability":"payable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":false,"name":"player","type":"address"},{"indexed":false,"name":"unitId","type":"uint256"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"UnitBought","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"player","type":"address"},{"indexed":false,"name":"unitId","type":"uint256"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"UnitSold","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"attacker","type":"address"},{"indexed":false,"name":"target","type":"address"},{"indexed":false,"name":"success","type":"bool"},{"indexed":false,"name":"gooStolen","type":"uint256"}],"name":"PlayerAttacked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"tokens","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"tokenOwner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"tokens","type":"uint256"}],"name":"Approval","type":"event"}]

  Contract Creation Code Switch To Opcodes View
60606040526103e760075560028054600160a060020a033316600160a060020a031991821617909155602580549091167321912e81d7eff8bff895302b45da76f7f070e3b91790556146dd806100566000396000f3006060604052600436106101ea5763ffffffff60e060020a60003504166306fdde0381146101ec578063095ea7b31461027657806313e3a4bc146102ac5780631746bd1b146102d4578063179fc99f146103b157806318160ddd146103d057806319e9e5de146103e357806323b872dd1461040257806325a7650a1461042a5780632693c150146104355780632bfd2e06146104ed5780633081fe3f14610506578063313ce5671461052557806338198c651461054e5780633bed33ce14610561578063431dbd9e1461057757806349c9dcf5146105c45780634efdd4f9146105e65780635dc22cce1461061d5780635e123ce41461063c578063616af9341461064f57806370a082311461066557806370bc52fb14610684578063751fef65146106a8578063789a12fd146106c15780637c85a7571461072a5780637ef58e731461074957806380fa79021461075c5780638da5cb5b1461077b5780638fafb286146107aa57806395d89b41146107cf5780639e30dd5f146107e2578063a5a2cb19146107ed578063a89cdad9146107f8578063a9059cbb1461080b578063b1d660031461082d578063b9de1c4114610840578063c2de290914610856578063c38f074114610869578063d8737d8a1461087c578063da7d57f91461088a578063dd62ed3e146108a3575b005b34156101f757600080fd5b6101ff6108c8565b60405160208082528190810183818151815260200191508051906020019080838360005b8381101561023b578082015183820152602001610223565b50505050905090810190601f1680156102685780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561028157600080fd5b610298600160a060020a03600435166024356108ff565b604051901515815260200160405180910390f35b34156102b757600080fd5b6102c260043561096b565b60405190815260200160405180910390f35b34156102df57600080fd5b6102e761098a565b604051808a81526020018981526020018881526020018781526020018681526020018581526020018481526020018060200180602001838103835285818151815260200191508051906020019060200280838360005b8381101561035557808201518382015260200161033d565b50505050905001838103825284818151815260200191508051906020019060200280838360005b8381101561039457808201518382015260200161037c565b505050509050019b50505050505050505050505060405180910390f35b34156103bc57600080fd5b6102c2600160a060020a0360043516610d1b565b34156103db57600080fd5b6102c2610d3a565b34156103ee57600080fd5b6102c2600160a060020a0360043516610d41565b341561040d57600080fd5b610298600160a060020a0360043581169060243516604435610d6e565b6101ea600435610e60565b341561044057600080fd5b610454600160a060020a0360043516610ebf565b604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b83811015610498578082015183820152602001610480565b50505050905001838103825284818151815260200191508051906020019060200280838360005b838110156104d75780820151838201526020016104bf565b5050505090500194505050505060405180910390f35b34156104f857600080fd5b6101ea600435602435610fe5565b341561051157600080fd5b6102c2600160a060020a03600435166112bf565b341561053057600080fd5b6105386112d1565b60405160ff909116815260200160405180910390f35b341561055957600080fd5b6102c26112d6565b341561056c57600080fd5b6101ea6004356112dc565b341561058257600080fd5b61058a61134c565b6040519485526020850193909352604080850192909252600160a060020a03166060840152608083019190915260a0909101905180910390f35b34156105cf57600080fd5b6101ea600160a060020a036004351660243561136c565b34156105f157600080fd5b6105f96115c0565b60405180848152602001838152602001828152602001935050505060405180910390f35b341561062857600080fd5b6101ea600160a060020a03600435166116c2565b341561064757600080fd5b610298611a29565b341561065a57600080fd5b6102c2600435611a39565b341561067057600080fd5b6102c2600160a060020a0360043516611a47565b341561068f57600080fd5b6101ea600160a060020a03600435166024351515611a73565b34156106b357600080fd5b6101ea600435602435611acc565b34156106cc57600080fd5b6106d7600435611dba565b60405160208082528190810183818151815260200191508051906020019060200280838360005b838110156107165780820151838201526020016106fe565b505050509050019250505060405180910390f35b341561073557600080fd5b6101ea600160a060020a0360043516611e35565b341561075457600080fd5b6102c2611e97565b341561076757600080fd5b6105f9600160a060020a0360043516611e9d565b341561078657600080fd5b61078e611fcd565b604051600160a060020a03909116815260200160405180910390f35b34156107b557600080fd5b6101ea600160a060020a0360043516602435604435611fdc565b34156107da57600080fd5b6101ff612230565b6101ea600435612267565b6101ea6004356124c9565b341561080357600080fd5b6102c26126fe565b341561081657600080fd5b610298600160a060020a0360043516602435612704565b341561083857600080fd5b6104546127a2565b341561084b57600080fd5b6101ea600435612997565b341561086157600080fd5b6101ea612aef565b341561087457600080fd5b6101ea612b76565b6101ea600435602435612bf9565b341561089557600080fd5b6101ea600435602435612f62565b34156108ae57600080fd5b6102c2600160a060020a036004358116906024351661303e565b60408051908101604052600781527f49646c6545746800000000000000000000000000000000000000000000000000602082015281565b600160a060020a033381166000818152601c6020908152604080832094871680845294909152808220859055909291907f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259085905190815260200160405180910390a350600192915050565b600480548290811061097957fe5b600091825260209091200154905081565b600080600080600080600061099d614611565b6109a5614611565b6109ad614611565b6109b5614611565b60255460009081908190600160a060020a0316638975e45f6040518163ffffffff1660e060020a028152600401602060405180830381600087803b15156109fb57600080fd5b5af11515610a0857600080fd5b50505060405180519050604051805910610a1f5750595b9080825280602002602001820160405250602554909550600160a060020a031663f10a98486040518163ffffffff1660e060020a028152600401602060405180830381600087803b1515610a7257600080fd5b5af11515610a7f57600080fd5b50505060405180519050604051805910610a965750595b9080825280602002602001820160405250602554909450600160a060020a03166328bdbdca6040518163ffffffff1660e060020a0281526004016040805180830381600087803b1515610ae857600080fd5b5af11515610af557600080fd5b5050506040518051906020018051919450909250505b818311610b5857600160a060020a0333166000908152601060209081526040808320868452909152902054858281518110610b4257fe5b6020908102909101015260019283019201610b0b565b602554600160a060020a0316636026bb866040518163ffffffff1660e060020a0281526004016040805180830381600087803b1515610b9657600080fd5b5af11515610ba357600080fd5b5050506040518051906020018051919450909250505b818311610c0657600160a060020a0333166000908152601060209081526040808320868452909152902054858281518110610bf057fe5b6020908102909101015260019283019201610bb9565b50602554600090600160a060020a031663709e6ed46040518163ffffffff1660e060020a0281526004016040805180830381600087803b1515610c4857600080fd5b5af11515610c5557600080fd5b5050506040518051906020018051919450909250505b818311610cc057600160a060020a033316600090815260116020908152604080832086845290915290205460ff16848281518110610ca557fe5b91151560209283029091019091015260019283019201610c6b565b42600354600154600654610cd333611a47565b33600160a060020a03811660009081526008602052604090205490610cf790610d41565b8b8b9d509d509d509d509d509d509d509d509d505050505050909192939495969798565b600160a060020a0381166000908152600860205260409020545b919050565b6000545b90565b600160a060020a03166000908152600a60209081526040808320600d835281842054845290915290205490565b6000610d7984613069565b600160a060020a038085166000908152601c6020908152604080832033909416835292905220548211801590610dc75750600160a060020a0333166000908152600960205260409020548211155b1515610dd257600080fd5b600160a060020a03808516600081815260096020908152604080832080548890039055878516808452818420805489019055848452601c83528184203390961684529490915290819020805486900390557fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9085905190815260200160405180910390a35060019392505050565b60025433600160a060020a03908116911614610e7b57600080fd5b60025460a060020a900460ff1615610e9257600080fd5b6002805474ff0000000000000000000000000000000000000000191660a060020a17905560065534600355565b610ec7614611565b610ecf614611565b6000610ed9614611565b610ee1614611565b600160a060020a0386166000908152601e6020526040812060215460028201549195501415610fd9578360010154604051805910610f1c5750595b908082528060200260200182016040525092508360010154604051805910610f415750595b90808252806020026020018201604052509150600090505b8360010154811015610fd9578354849082908110610f7357fe5b906000526020600020906002020160000154838281518110610f9157fe5b602090810290910101528354849082908110610fa957fe5b906000526020600020906002020160010154828281518110610fc757fe5b60209081029091010152600101610f59565b50909590945092505050565b60025460009060a060020a900460ff16151561100057600080fd5b602554600160a060020a0316634677fe538460405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b151561104857600080fd5b5af1151561105557600080fd5b50505060405180519050151561106a57600080fd5b600754600160a060020a03331660009081526010602090815260408083208784529091529020548301111561109e57600080fd5b602554600160a060020a03338116600090815260106020908152604080832088845290915290819020549190921691633837e9bd91869186905160e060020a63ffffffff8616028152600481019390935260248301919091526044820152606401602060405180830381600087803b151561111857600080fd5b5af1151561112557600080fd5b5050506040518051905090508061113b33611a47565b101561114657600080fd5b602554600160a060020a031663ee9cebde8460405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b151561118e57600080fd5b5af1151561119b57600080fd5b50505060405180511590506111af57600080fd5b6111b933826130ab565b602554600090600160a060020a031663c46e3e858560405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b151561120457600080fd5b5af1151561121157600080fd5b5050506040518051905011156112345761123461122f33858561313e565b6131f0565b33600160a060020a0381166000908152601060209081526040808320878452909152908190208054850190557fb6d35f558a34938047f09ebf800fa2e15ec407c357a8eab97a5dd67b4d015b5b919085908590518084600160a060020a0316600160a060020a03168152602001838152602001828152602001935050505060405180910390a1505050565b600d6020526000908152604090205481565b600081565b60035481565b600160a060020a03331660009081526008602052604090205481111561130157600080fd5b600160a060020a033316600081815260086020526040908190208054849003905582156108fc0290839051600060405180830381858888f19350505050151561134957600080fd5b50565b602054602154602254602354602454600160a060020a0390911691929394565b6000806000806000806000804260205410151561138857600080fd5b602354600160a060020a03161561139e57600080fd5b602154600090815260126020526040902054600160a060020a0316156113c357600080fd5b60235460a060020a900460ff1615156113de576113de612aef565b600160a060020a038a161561148057600160a060020a038a166000908152601e60205260408120600181015490995011801561141d5750876001015489105b801561142e57506021548860020154145b1561148057875488908a90811061144157fe5b9060005260206000209060020201965086600001546024541015801561146d5750866001015460245411155b156114805761147b8a613241565b6115b4565b600095505b6021546000908152601f60205260409020548610156115b4576021546000908152601f602052604090208054879081106114bb57fe5b6000918252602080832090910154600160a060020a0316808352601e909152604082206001810154815492985090965060001901945085919081106114fc57fe5b906000526020600020906002020160000154602454101580156115405750835484908490811061152857fe5b90600052602060002090600202016001015460245411155b156115a957600091505b83600101548210156115a957835484908390811061156457fe5b906000526020600020906002020190508060000154602454101580156115905750806001015460245411155b1561159e5761147b85613241565b60019091019061154a565b600190950194611485565b50505050505050505050565b600160a060020a0333166000908152600e6020908152604080832054600554600a8452828520600019808401875294529184205484938493019083908382805b8583116116b1575050600160a060020a0333166000818152600a60209081526040808320858452825280832054938352600b825280832085845290915290205460ff168115801561164f575080155b1561165c57839150611660565b8193505b600480548490811061166e57fe5b9060005260206000209001548260058581548110151561168a57fe5b906000526020600020900154028115156116a057fe5b049490940193600190920191611600565b509298949750929550929350505050565b600160a060020a0333166000908152600f6020526040812054819081908190819081904290106116f157600080fd5b33600160a060020a031687600160a060020a03161415151561171257600080fd5b600160a060020a0387166000908152601d602052604090205460ff161561173857600080fd5b61174233886133a5565b600160a060020a038a166000908152600f60205260409020549298509096509450429011156117cc57602554600160a060020a03166394b67b1c8660405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b15156117b357600080fd5b5af115156117c057600080fd5b50505060405180519550505b848611156119a357600160a060020a0333166000908152600f6020526040902061070842019055836117fd88611a47565b11156118ea5761180c876134d6565b92508284111561184157600160a060020a03871660009081526009602052604090208054848603908190039091559150611866565b50600160a060020a038616600090815260096020526040902080548484039081019091555b33600160a060020a038116600090815260096020526040908190208054870190557fb06cb54b17603e70140ce0216d86cef7e3e645e5a77c76f0cd1e4afe1b5b9e3f91908990600190889051600160a060020a03948516815292909316602083015215156040808301919091526060820192909252608001905180910390a1611983565b7fb06cb54b17603e70140ce0216d86cef7e3e645e5a77c76f0cd1e4afe1b5b9e3f338860016119188b611a47565b604051600160a060020a03948516815292909316602083015215156040808301919091526060820192909252608001905180910390a161195787611a47565b600160a060020a0333811660009081526009602052604080822080549094019093559089168152908120555b600160a060020a0387166000908152600c60205260409020429055611a20565b33600160a060020a0381166000908152600f6020526040808220426102580190557fb06cb54b17603e70140ce0216d86cef7e3e645e5a77c76f0cd1e4afe1b5b9e3f92918a91819051600160a060020a03948516815292909316602083015215156040808301919091526060820192909252608001905180910390a15b50505050505050565b60025460a060020a900460ff1681565b600580548290811061097957fe5b6000611a52826134d6565b600160a060020a038316600090815260096020526040902054019050919050565b60025433600160a060020a03908116911614611a8e57600080fd5b611a9782610d41565b15611aa157600080fd5b600160a060020a03919091166000908152601d60205260409020805460ff1916911515919091179055565b600160a060020a0333166000908152601060209081526040808320858452909152812054819083901015611aff57600080fd5b600160a060020a033381166000908152601060209081526040808320888452909152908190208054869003908190556025546004931691633837e9bd91889188905160e060020a63ffffffff8616028152600481019390935260248301919091526044820152606401602060405180830381600087803b1515611b8157600080fd5b5af11515611b8e57600080fd5b50505060405180519050600302811515611ba457fe5b04915081611bb1336134d6565b600160a060020a033381166000908152600c6020908152604080832042905582549590940194850182556009905282812080548501905560255493945092169063c46e3e859087905160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515611c2d57600080fd5b5af11515611c3a57600080fd5b505050604051805190501115611c5e57611c5e33611c5933878761313e565b61354f565b602554600090600160a060020a031663ee9cebde8660405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515611ca957600080fd5b5af11515611cb657600080fd5b505050604051805190501115611d5b576025546004908490600160a060020a031663ee9cebde8760405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515611d1357600080fd5b5af11515611d2057600080fd5b5050506040518051905002600302811515611d3757fe5b33600160a060020a0316600090815260086020526040902080549290910490910190555b7f9c8076df639d56f1ef3ca3d4d8dc6ed089f8c4756bc5bf5d574f1cec4ef13c543385856040518084600160a060020a0316600160a060020a03168152602001838152602001828152602001935050505060405180910390a150505050565b611dc2614611565b601f6000838152602001908152602001600020805480602002602001604051908101604052809291908181526020018280548015611e2957602002820191906000526020600020905b8154600160a060020a03168152600190910190602001808311611e0b575b50505050509050919050565b60025460009033600160a060020a03908116911614611e5357600080fd5b5080611e5e81613613565b611e6781613bb9565b6025805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a039290921691909117905550565b60015481565b6025546000908190819081908190819081908190600160a060020a0316636026bb866040518163ffffffff1660e060020a0281526004016040805180830381600087803b1515611eec57600080fd5b5af11515611ef957600080fd5b5050506040518051906020018051919650909450505b838511611fbe57600160a060020a0389166000908152601060209081526040808320888452909152902054611f47908a908790613f05565b600160a060020a038a166000908152601060209081526040808320898452909152902054930192611f7b908a908790613f8a565b600160a060020a038a166000908152601060209081526040808320898452909152902054910190611faf908a90879061400f565b60019095019490910190611f0f565b91989097509095509350505050565b600254600160a060020a031681565b6000808080808086881115611ff057600080fd5b600160a060020a0333166000908152600e602052604090205488101561201557600080fd5b600554871061202357600080fd5b600160a060020a0333166000908152600a60209081526040808320600e83528184205460001901845290915290205494508793505b86841161210c57600160a060020a0333166000818152600a60209081526040808320888452825280832054938352600b825280832088845290915290205490935060ff169150821580156120aa575081155b156120b7578492506120bb565b8294505b60048054859081106120c957fe5b906000526020600020900154836005868154811015156120e557fe5b906000526020600020900154028115156120fb57fe5b049590950194600190930192612058565b600160a060020a0333166000908152600a602090815260408083208a84529091529020541580156121615750600160a060020a0333166000908152600b6020908152604080832087845290915290205460ff16155b801561216d5750600085115b1561219957600160a060020a0333166000908152600a602090815260408083208a845290915290208590555b600160a060020a033381166000908152600e602052604090206001890190558916158015906121da575033600160a060020a031689600160a060020a031614155b156122055750600160a060020a03881660009081526008602052604090208054606487049081019091555b600160a060020a03331660009081526008602052604090208054919096030190945550505050505050565b60408051908101604052600381527f476f6f0000000000000000000000000000000000000000000000000000000000602082015281565b602554600090819081908190819081908190600160a060020a03166297b6078960405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b15156122bd57600080fd5b5af115156122ca57600080fd5b5050506040518051905015156122df57600080fd5b600088815260126020526040902054600160a060020a0316965086151561230557600080fd5b600088815260136020908152604080832054600160a060020a033316845260089092529091205490965034018690101561233e57600080fd5b61234733613069565b602554600160a060020a031663275babee8960405160e060020a63ffffffff84160281526004810191909152602401606060405180830381600087803b151561238f57600080fd5b5af1151561239c57600080fd5b50505060405180519060200180519060200180519297509095509093506123c7905033868686614094565b6123d087613069565b6123dc8786868661432d565b3486111561240a57600160a060020a0333166000908152600860205260409020805434880390039055612434565b8534111561243457600160a060020a03331660009081526008602052604090208054348890030190555b50506003805460148604908101909155600254600160a060020a039081166000908152600860208181526040808420805460328c049081019091559b845260128252808420805473ffffffffffffffffffffffffffffffffffffffff191633871617905560138252808420600460058c0204905599909316825290915295909520805496909501909303909401909255505050565b600080600080600080600260149054906101000a900460ff1615156124ed57600080fd5b602554600160a060020a03166347751b988860405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b151561253557600080fd5b5af1151561254257600080fd5b50505060405180519050151561255757600080fd5b600160a060020a03331660009081526011602090815260408083208a845290915290205460ff161561258857600080fd5b602554600160a060020a03166328a42e9d8860405160e060020a63ffffffff8416028152600481019190915260240160a060405180830381600087803b15156125d057600080fd5b5af115156125dd57600080fd5b5050506040518051906020018051906020018051906020018051906020018051949a50929850909650945090925086905061261733611a47565b101561262257600080fd5b60008511156126b057600160a060020a03331660009081526008602052604090205434018590101561265357600080fd5b3485111561267d57600160a060020a03331660009081526008602052604090208054348703900390555b506003805460328604808703909101909155600254600160a060020a031660009081526008602052604090208054820190555b6126ba33876130ab565b6126c633858585614094565b505050600160a060020a033316600090815260116020908152604080832096835295905293909320805460ff19166001179055505050565b60065481565b600061270f33613069565b600160a060020a03331660009081526009602052604090205482111561273457600080fd5b600160a060020a033381166000818152600960205260408082208054879003905592861680825290839020805486019055917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9085905190815260200160405180910390a350600192915050565b6127aa614611565b6127b2614611565b6127ba614611565b6127c2614611565b60255460009081908190600160a060020a031663a528cb4f6040518163ffffffff1660e060020a028152600401602060405180830381600087803b151561280857600080fd5b5af1151561281557600080fd5b5050506040518051905060405180591061282c5750595b9080825280602002602001820160405250602554909550600160a060020a031663a528cb4f6040518163ffffffff1660e060020a028152600401602060405180830381600087803b151561287f57600080fd5b5af1151561288c57600080fd5b505050604051805190506040518059106128a35750595b9080825280602002602001820160405250602554909450600160a060020a0316634ecdf1656040518163ffffffff1660e060020a0281526004016040805180830381600087803b15156128f557600080fd5b5af1151561290257600080fd5b5050506040518051906020018051919450909250505b81831161298a57600083815260126020526040902054600160a060020a031685828151811061294357fe5b600160a060020a03909216602092830290910182015260008481526013909152604090205484828151811061297457fe5b6020908102909101015260019283019201612918565b5092959194509092505050565b60008042602054101515156129ab57600080fd5b600083116129b857600080fd5b6129c46103e8846145c9565b9150816129d033611a47565b10156129db57600080fd5b6129e533836130ab565b50600160a060020a0333166000908152601e60205260409020602154600282015414612a6e5760006001808301829055602154600284018190558252601f6020526040909120805490918101612a3b8382614623565b506000918252602090912001805473ffffffffffffffffffffffffffffffffffffffff191633600160a060020a03161790555b805460018201541415612a8c578054600101612a8a8282614647565b505b60408051908101604052602254808252840160001901602082015260018281018054918201905582548391908110612ac057fe5b906000526020600020906002020160008201518155602082015160019091015550506022805490920190915550565b60025460009033600160a060020a03908116911614612b0d57600080fd5b602054429010612b1c57600080fd5b60235460a060020a900460ff1615612b3357600080fd5b5060225442810190801515612b4457fe5b8160001943014008602455506023805474ff0000000000000000000000000000000000000000191660a060020a179055565b60025460009033600160a060020a03908116911614612b9457600080fd5b5060038054600a8104908190039091556004805460018101612bb68382614623565b916000526020600020900160006001549091909150555060058054806001018281612be19190614623565b50600091825260209091200155620151804201600655565b600080600080600260149054906101000a900460ff161515612c1a57600080fd5b602554600160a060020a0316634677fe538760405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515612c6257600080fd5b5af11515612c6f57600080fd5b505050604051805190501515612c8457600080fd5b600754600160a060020a03331660009081526010602090815260408083208a845290915290205486011115612cb857600080fd5b602554600160a060020a0333811660009081526010602090815260408083208b845290915290819020549190921691633837e9bd91899189905160e060020a63ffffffff8616028152600481019390935260248301919091526044820152606401602060405180830381600087803b1515612d3257600080fd5b5af11515612d3f57600080fd5b5050506040518051602554909550612db49150600160a060020a031663ee9cebde8860405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515612d9757600080fd5b5af11515612da457600080fd5b50505060405180519050866145c9565b925083612dc033611a47565b1015612dcb57600080fd5b600160a060020a033316600090815260086020526040902054340183901015612df357600080fd5b612dfd33856130ab565b34831115612e2757600160a060020a03331660009081526008602052604090208054348503900390555b50506003805460046032840480850391909104918201909255600254600160a060020a039081166000908152600860205260408082208054860190556025549192919091169063c46e3e859089905160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515612ea957600080fd5b5af11515612eb657600080fd5b505050604051805190501115612ed457612ed461122f33888861313e565b33600160a060020a03811660009081526010602090815260408083208a8452909152908190208054880190557fb6d35f558a34938047f09ebf800fa2e15ec407c357a8eab97a5dd67b4d015b5b919088908890518084600160a060020a0316600160a060020a03168152602001838152602001828152602001935050505060405180910390a1505050505050565b60025433600160a060020a03908116911614612f7d57600080fd5b602554600160a060020a03166297b6078260405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515612fc457600080fd5b5af11515612fd157600080fd5b505050604051805190501515612fe657600080fd5b600081815260126020526040902054600160a060020a03161561300857600080fd5b602380546000602481905574ffffffffffffffffffffffffffffffffffffffffff19909116909155602255602091909155602155565b600160a060020a039182166000908152601c6020908152604080832093909416825291909152205490565b6000613074826134d6565b600160a060020a039092166000908152600c6020908152604080832042905582548501835560099091529020805490920190915550565b60008060006130b9856134d6565b9250828411156130f45760008054848603908190038255600160a060020a03871682526009602052604090912080548290039055915061311e565b50600080548484039081018255600160a060020a0386168252600960205260409091208054820190555b50505050600160a060020a03166000908152600c60205260409020429055565b600160a060020a03808416600081815260156020908152604080832087845282528083205493835260148252808320878452909152808220546025549294600a94850193919291169063c46e3e859088905160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b15156131c357600080fd5b5af115156131d057600080fd5b50505060405180519050018402028115156131e757fe5b04949350505050565b806131fa33610d41565b600160a060020a0333166000818152600a60209081526040808320600580548552908352818420969095019095559254918152600d90925291902055600180549091019055565b60238054600160a060020a0380841673ffffffffffffffffffffffffffffffffffffffff199283168117909355602180546000908152601260205260408082208054909516909517909355602554905492938493849360149316916357f1f6ca91905160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b15156132d757600080fd5b5af115156132e457600080fd5b505050604051805190506015028115156132fa57fe5b6021546000908152601360205260409020919004905561331984613069565b602554602154600160a060020a039091169063275babee9060405160e060020a63ffffffff84160281526004810191909152602401606060405180830381600087803b151561336757600080fd5b5af1151561337457600080fd5b505050604051805190602001805190602001805192955090935090915061339f905084848484614094565b50505050565b6025546000908190819081908190819081908190600160a060020a0316636026bb866040518163ffffffff1660e060020a0281526004016040805180830381600087803b15156133f457600080fd5b5af1151561340157600080fd5b5050506040518051906020018051919650909450505b8385116134c657600160a060020a038a16600090815260106020908152604080832088845290915290205461344f908b908790613f05565b600160a060020a038b166000908152601060209081526040808320898452909152902054930192613483908b908790613f8a565b600160a060020a038a1660009081526010602090815260408083208984529091529020549101906134b7908a90879061400f565b60019095019490910190613417565b9199909850909650945050505050565b600160a060020a0381166000908152600c602052604081205481901180156135165750600160a060020a0382166000908152600c60205260409020544290105b1561354757600160a060020a0382166000908152600c6020526040902054420361353f83610d41565b029050610d35565b506000919050565b60008061355b84610d41565b915061356782846145ff565b90508015156135bc57600160a060020a0384166000818152600b60209081526040808320600580548552908352818420805460ff19166001179055938352600a825280832093548352929052908120556135e5565b600160a060020a0384166000908152600a60209081526040808320600554845290915290208190555b5050600554600160a060020a039092166000908152600d602052604090209190915560018054919091039055565b6025546000908190600160a060020a03166328bdbdca6040518163ffffffff1660e060020a0281526004016040805180830381600087803b151561365657600080fd5b5af1151561366357600080fd5b5050506040518051906020018051919350909150505b80821161381d5782600160a060020a031663ee9cebde8360405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b15156136c657600080fd5b5af115156136d357600080fd5b5050506040518051602554909150600160a060020a031663ee9cebde8460405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b151561372657600080fd5b5af1151561373357600080fd5b5050506040518051905014151561374957600080fd5b82600160a060020a031663c46e3e858360405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b151561378f57600080fd5b5af1151561379c57600080fd5b5050506040518051602554909150600160a060020a031663c46e3e858460405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b15156137ef57600080fd5b5af115156137fc57600080fd5b5050506040518051905014151561381257600080fd5b600190910190613679565b602554600160a060020a0316636026bb866040518163ffffffff1660e060020a0281526004016040805180830381600087803b151561385b57600080fd5b5af1151561386857600080fd5b5050506040518051906020018051919350909150505b808211613bb45782600160a060020a031663ee9cebde8360405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b15156138cb57600080fd5b5af115156138d857600080fd5b5050506040518051602554909150600160a060020a031663ee9cebde8460405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b151561392b57600080fd5b5af1151561393857600080fd5b5050506040518051905014151561394e57600080fd5b82600160a060020a03166369632f568360405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b151561399457600080fd5b5af115156139a157600080fd5b5050506040518051602554909150600160a060020a03166369632f568460405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b15156139f457600080fd5b5af11515613a0157600080fd5b50505060405180519050141515613a1757600080fd5b82600160a060020a03166321446cfe8360405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515613a5d57600080fd5b5af11515613a6a57600080fd5b5050506040518051602554909150600160a060020a03166321446cfe8460405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515613abd57600080fd5b5af11515613aca57600080fd5b50505060405180519050141515613ae057600080fd5b82600160a060020a0316636101a1f78360405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515613b2657600080fd5b5af11515613b3357600080fd5b5050506040518051602554909150600160a060020a0316636101a1f78460405160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b1515613b8657600080fd5b5af11515613b9357600080fd5b50505060405180519050141515613ba957600080fd5b60019091019061387e565b505050565b600080600080600080600080600080600080602560009054906101000a9004600160a060020a0316600160a060020a0316634ecdf1656040518163ffffffff1660e060020a0281526004016040805180830381600087803b1515613c1c57600080fd5b5af11515613c2957600080fd5b5050506040518051906020018051919d50909b50505b8a8c11613d7b57602554600160a060020a03166328a42e9d8d60405160e060020a63ffffffff8416028152600481019190915260240160a060405180830381600087803b1515613c8e57600080fd5b5af11515613c9b57600080fd5b5050506040518051906020018051906020018051906020018051906020018051929e50909c50909a50919550935050600160a060020a038d166328a42e9d8d60405160e060020a63ffffffff8416028152600481019190915260240160a060405180830381600087803b1515613d1057600080fd5b5af11515613d1d57600080fd5b5050506040518051906020018051906020018051906020018051906020018051929b50909950909750919350915050838214613d5857600080fd5b888614613d6457600080fd5b878514613d7057600080fd5b6001909b019a613c3f565b602554600160a060020a0316634ecdf1656040518163ffffffff1660e060020a0281526004016040805180830381600087803b1515613db957600080fd5b5af11515613dc657600080fd5b5050506040518051906020018051919d50909b50505b8a8c11613ef657602554600160a060020a031663275babee8d60405160e060020a63ffffffff84160281526004810191909152602401606060405180830381600087803b1515613e2b57600080fd5b5af11515613e3857600080fd5b5050506040518051906020018051906020018051929c50909a5090985050600160a060020a038d1663275babee8d60405160e060020a63ffffffff84160281526004810191909152602401606060405180830381600087803b1515613e9c57600080fd5b5af11515613ea957600080fd5b505050604051805190602001805190602001805192995090975090955050898714613ed357600080fd5b888614613edf57600080fd5b878514613eeb57600080fd5b6001909b019a613ddc565b50505050505050505050505050565b600160a060020a03808416600081815260176020908152604080832087845282528083205493835260168252808320878452909152808220546025549294600a9485019391929116906369632f569088905160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b15156131c357600080fd5b600160a060020a038084166000818152601b60209081526040808320878452825280832054938352601a8252808320878452909152808220546025549294600a948501939192911690636101a1f79088905160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b15156131c357600080fd5b600160a060020a03808416600081815260196020908152604080832087845282528083205493835260188252808320878452909152808220546025549294600a9485019391929116906321446cfe9088905160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b15156131c357600080fd5b600083151561410757600160a060020a038516600081815260146020908152604080832087845282528083208054870190558383526015825280832087845282528083205493835260108252808320878452909152902054600a918201908402025b049050614102816131f0565b614326565b83600114156141e057600160a060020a038086166000818152601560209081526040808320888452825280832080548801905592825260148152828220878352905281902054602554600a93919291169063c46e3e859087905160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b151561419457600080fd5b5af115156141a157600080fd5b5050506040518051600160a060020a03891660009081526010602090815260408083208a8452909152902054860292019190910290508115156140f657fe5b836002141561421757600160a060020a03851660009081526016602090815260408083208684529091529020805483019055614326565b836003141561424e57600160a060020a03851660009081526017602090815260408083208684529091529020805483019055614326565b836004141561428557600160a060020a03851660009081526018602090815260408083208684529091529020805483019055614326565b83600514156142bc57600160a060020a03851660009081526019602090815260408083208684529091529020805483019055614326565b83600614156142f357600160a060020a0385166000908152601a602090815260408083208684529091529020805483019055614326565b836007141561432657600160a060020a0385166000908152601b6020908152604080832086845290915290208054830190555b5050505050565b600083151561439d57600160a060020a03851660008181526014602090815260408083208784528252808320805487900390558383526015825280832087845282528083205493835260108252808320878452909152902054600a918201908402025b049050614102858261354f565b836001141561447757600160a060020a03808616600081815260156020908152604080832088845282528083208054889003905592825260148152828220878352905281902054602554600a93919291169063c46e3e859087905160e060020a63ffffffff84160281526004810191909152602401602060405180830381600087803b151561442b57600080fd5b5af1151561443857600080fd5b5050506040518051600160a060020a03891660009081526010602090815260408083208a84529091529020548602920191909102905081151561439057fe5b83600214156144af57600160a060020a0385166000908152601660209081526040808320868452909152902080548390039055614326565b83600314156144e757600160a060020a0385166000908152601760209081526040808320868452909152902080548390039055614326565b836004141561451f57600160a060020a0385166000908152601860209081526040808320868452909152902080548390039055614326565b836005141561455757600160a060020a0385166000908152601960209081526040808320868452909152902080548390039055614326565b836006141561458f57600160a060020a0385166000908152601a60209081526040808320868452909152902080548390039055614326565b836007141561432657600160a060020a0385166000908152601b602090815260408083208684529091529020805483900390555050505050565b6000808315156145dc57600091506145f8565b508282028284828115156145ec57fe5b04146145f457fe5b8091505b5092915050565b60008282111561460b57fe5b50900390565b60206040519081016040526000815290565b815481835581811511613bb457600083815260209020613bb4918101908301614673565b815481835581811511613bb457600202816002028360005260206000209182019101613bb49190614691565b610d3e91905b8082111561468d5760008155600101614679565b5090565b610d3e91905b8082111561468d57600080825560018201556002016146975600a165627a7a72305820ae34a2e0cd26a642ebf0feb477e2acbd6179b8a4cc4ee64d8b8a0c232cd8af480029

   Swarm Source:
bzzr://ae34a2e0cd26a642ebf0feb477e2acbd6179b8a4cc4ee64d8b8a0c232cd8af48

 

View All
Block Age transaction Difficulty GasUsed Reward
View All
Block Age UncleNumber Difficulty GasUsed Reward
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.