# Optimization of weightedWinner() and random() function

I have written a Lottery contract that picks winner based on the amount they contributed to the pool. I am looking if the code of weightedWinner function can be optimized. And if there is a better way to write the random function.

pragma solidity ^0.5.12;

//import "./SafeMath.sol";

contract WeightedLottery {
//using SafeMath for uint256;

uint256 totalAmount = 0;

constructor() public {
owner = msg.sender;
}

function random() private view returns (uint) {
return uint(keccak256(abi.encodePacked(blockhash(block.number - 1 - players.length), block.difficulty, now, players)));
}

function weightedWinner() private view returns(address payable) {
require(msg.sender == owner);
require(totalAmount != 0);
require(players.length != 0);
uint256 val = random() % totalAmount;
uint256 temp = 0;
for(uint256 i = 0; i < players.length; i++) {
temp += amounts[players[i]];
if(val < temp) {
return players[i];
}
}
}

function getPlayers() public view returns(address payable[] memory) {
return players;
}

function join() payable public {
require(msg.sender != owner);
require(msg.value != 0);
if(amounts[msg.sender] == 0) {
players.push(msg.sender);
}
amounts[msg.sender] += msg.value;
totalAmount += msg.value;
}

function pickWinner() public {
winner.transfer(totalAmount);
}
}


How it works

Players join with an initial amount of tokens. Later s/he can increase the amount. When pickWinner is called, player with the highest amount has the height probability of winning.

Example:

1. player 1 joins with 10 tokens.
2. player 2 joins with 10 tokens.
3. player 1 adds 10 tokens.
4. player 3 joins with 10 tokens.
5. player 3 adds 10 tokens.
6. pickWinner is called.

Now we have player 1 and 3 with 20 tokens and 2 has 10 tokens. So player 1 and 3 has (20/50) probability of winning and player 2 has (10/50) probability.