We will create a lottery contract which has a prize pool and players.

When someone send Eth to the contract he will be added to the players. Once enough person have participated , a Manager will tell the contract to pick a random winner and send him all the money in the prize pool.

The contract then reset and is ready to accept new players.

variables :

manager: person who created the contract

players

functions

enter: enter a player

pickwinner: choose a winner

pragma solidity ^0.4.17;

contract Lottery {
    address public manager;
    address[] public players;

    modifier onlyOwner() {
        require(isOwner());
        _;
    }
    function isOwner() public view returns (bool) {
        return msg.sender == manager;
    }

    function Lottery() public {
        manager = msg.sender;
    }
    
    function enter() public payable {
        // participants need to pay 1ether
        require(msg.value == 1 ether);
        // we don't want the manager to participate
        require(msg.sender != manager);
        // add the player 
        players.push(msg.sender);
    }
    // pick a winner from all the players and empties players array
    function pickWinner() public onlyOwner returns(address)  {
        // require(msg.sender == manager);
        uint index = random();
        players[index].transfer(this.balance);
        players = new address[](0);
    }
    // Generate a random number and returns it
    function random() private view returns (uint){
        uint randNonce=0;
        uint randomNumberGenerated = uint(keccak256(now, msg.sender,randNonce,block.difficulty)) % players.length;
        return randomNumberGenerated;
    }
    
}

Updated contract with transfer to manager method and 8.3.9 VERSION

// SPDX-License-Identifier: MIT
 
pragma solidity ^0.8.9;
 
contract Lottery {
    address payable public manager;
    address payable[] public players;
    address public previousWinner;

    // Events
    event PlayerAdded(address _address);

    // Only owner can call 
    modifier onlyOwner() {
        require(isOwner());
        _;
    }
    // Only owner cannot call
    modifier notOwner() {
        require(!isOwner());
        _;
    }
    
    function isOwner() public view returns (bool) {
        return msg.sender == manager;
    }

    constructor() {
        manager = payable(msg.sender);
    }

    function getPlayers() public view returns(address payable[] memory) {
        return players;
    }
    
    // we don't want the manager to participate
    function enter() public notOwner payable {
        // participants need to pay 1ether
        require(msg.value > 0.01 ether);
        // add the player 
        players.push(payable(msg.sender));
        emit PlayerAdded(msg.sender);
    }
    // pick a winner from all the players and empties players array
    function pickWinner() public onlyOwner {
        uint index = random();
        previousWinner = players[index];

        payable(players[index]).transfer(address(this).balance);
        players = new address payable[](0);
    }
    // Generate a random number and returns it
    function random() private view returns (uint){
        uint randNonce=0;
        uint randomNumberGenerated = uint(keccak256(abi.encodePacked(block.timestamp, msg.sender,randNonce,block.difficulty))) % players.length;
        return randomNumberGenerated;
    }
    function transfer() public onlyOwner {
        // send the owner of the contract all of the eth
        manager.transfer(address(this).balance);
        // reset the players array
        players = new address payable[](0);
    }
    
}