contract VRF is VRFConsumerBase, Ownable {

    using SafeMath for uint256;

    bytes32 public keyHash;
    uint256 public fee;
    uint256 public randomnessDrawn;

    event RandomNumberRequested(bytes32 indexed vrfRequestID);
    event RandomNumberReceived(bytes32 indexed requestId, uint256 indexed randomness);

    constructor(
        address _vrfCoordinator, 
        address _link, 
        bytes32 _keyHash, 
        uint256 _fee
    ) public VRFConsumerBase(_vrfCoordinator, _link) {
        keyHash = _keyHash;
        fee = _fee;
    }

    function requestRandomNumber(bytes32 inputHash) external onlyOwner {
        require(LINK.balanceOf(address(this)) >= fee, "Not enough LINK in contract");
        bytes32 vrfRequestID = requestRandomness(keyHash, fee);
        emit RandomNumberRequested(vrfRequestID);
    }

    function fulfillRandomness(bytes32 requestId, uint256 randomness) internal override {
        randomnessDrawn = randomness;
        emit RandomNumberReceived(requestId, randomness);
    }

    function generateWinners(uint256 candidatesNum, uint256 winners) public view returns (uint256[] memory expandedValues) {
        require(randomnessDrawn > 0, "VRF: random number not drawn");
        expandedValues = new uint256[](winners);
        for (uint256 i = 0; i < winners; i++) {
            expandedValues[i] = 1 + SafeMath.mod(
                uint256(keccak256(abi.encode(randomnessDrawn, i))),
                candidatesNum
            );
        }
        return expandedValues;
    }

    function getLINKAddress() external view returns(address) {
        return address(LINK);
    }

    /// @notice to avoid locking funds within the contract
    function withdrawLink() external onlyOwner {
        require(LINK.transfer(msg.sender, LINK.balanceOf(address(this))), "Unable to transfer funds out of contract");
    }

}
function withdrawLink() external onlyOwner {
    require(LINK.transfer(msg.sender, LINK.balanceOf(address(this))), "Unable to transfer funds out of contract");
}

/// @notice to avoid locking funds within the contract