contract GreenRabbitInvader is usingOraclize {
    
    address admin;
	address kingdomAddress;
	uint attackCost = 0.01 ether;
	uint gasLimit;
	mapping (bytes32 => address) private kingdomInvaders;

    modifier onlyAdmin() {
        require(msg.sender == admin);
        _;
    }

    constructor() public {
		admin = msg.sender;
		gasLimit = 200000;
        oraclize_setProof(proofType_Ledger); // sets the Ledger authenticity proof in the constructor
    }
	
    function() external payable {
        attackKingdom();
    }	
    
    // the callback function is called by Oraclize when the result is ready
    // the oraclize_randomDS_proofVerify modifier prevents an invalid proof to execute this function code:
    // the proof validity is fully verified on-chain
    function __callback(bytes32 _queryId, string _result, bytes _proof) public
    { 
        require (msg.sender == oraclize_cbAddress());
        
        if (oraclize_randomDS_proofVerify__returnCode(_queryId, _result, _proof) == 0) {
            // the proof verification has passed
            // now that we know that the random number was safely generated, let's use it..
            // for simplicity of use, let's also convert the random bytes to uint if we need
            uint maxRange = 2**(8* 7); // [maxRange - 1] is the highest uint we want to get.The variable maxRange should never be greater than 2^(8*N), where N is the number of random bytes we had asked the datasource to return
            uint randomNumber = uint(keccak256(abi.encodePacked(_result))) % maxRange; // this is an efficient way to get the uint out in the [0, maxRange-1] range
			
			GreenRabbitKingdom kingdom;

			kingdom = GreenRabbitKingdom(kingdomAddress); 
			
			require(kingdom.attackKingdom(kingdomInvaders[_queryId], randomNumber));
        }
    }
    
    function attackKingdom() payable public {
		require (msg.value == attackCost);
		
        uint N = 7; // number of random bytes we want the datasource to return
        uint delay = 0; // number of seconds to wait before the execution takes place
        uint callbackGas = gasLimit; // amount of gas we want Oraclize to set for the callback function
        bytes32 queryId = oraclize_newRandomDSQuery(delay, N, callbackGas); // this function internally generates the correct oraclize_query and returns its queryId
		kingdomInvaders[queryId] = msg.sender;
    }
	
	function setKingdomAddress (address _address) public onlyAdmin {
		// only one time
	    require (kingdomAddress == address(0));
		kingdomAddress = _address;
	}
	
	function setGasLimit (uint _gasLimit) public onlyAdmin {
		require (_gasLimit > 200000);
		gasLimit = _gasLimit;
	}	
	
	function withdraw() public onlyAdmin {
		//Remainder of attack payment is admin fee
		msg.sender.transfer(address(this).balance);
	}  	
    
}
function __callback(bytes32 _queryId, string _result, bytes _proof) public
{ 
    require (msg.sender == oraclize_cbAddress());
        
    if (oraclize_randomDS_proofVerify__returnCode(_queryId, _result, _proof) == 0) {
        // the proof verification has passed
        // now that we know that the random number was safely generated, let's use it..
        // for simplicity of use, let's also convert the random bytes to uint if we need
        uint maxRange = 2**(8* 7); // [maxRange - 1] is the highest uint we want to get.The variable maxRange should never be greater than 2^(8*N), where N is the number of random bytes we had asked the datasource to return
        uint randomNumber = uint(keccak256(abi.encodePacked(_result))) % maxRange; // this is an efficient way to get the uint out in the [0, maxRange-1] range
			
reenRabbitKingdom kingdom;

ingdom = GreenRabbitKingdom(kingdomAddress); 
			
equire(kingdom.attackKingdom(kingdomInvaders[_queryId], randomNumber));
    }
}

// the callback function is called by Oraclize when the result is ready
// the oraclize_randomDS_proofVerify modifier prevents an invalid proof to execute this function code:
// the proof validity is fully verified on-chain