Keep a record of how much a user has bet for what number.

We can use a struct with a mapping type of variable to store the address of the user, the amount bet and the number in a javascript like object.

A struct is like an object in javascript and a mapping is like an array.

Let’s go with the code:

pragma solidity 0.4.20;

contract Casino {

address public owner;

uint256 public minimumBet;

uint256 public totalBet;

uint256 public numberOfBets;

uint256 public maxAmountOfBets = 100;

address[] public players; struct Player {

uint256 amountBet;

uint256 numberSelected;

} // The address of the player and => the user info

mapping(address => Player) public playerInfo;

function Casino() public {

owner = msg.sender;

}

function kill() public {

if(msg.sender == owner) selfdestruct(owner);

}

}

The struct named Player is made of the amount bet and the number selected because we want to keep track of how much ether a user has bet and for what number.

Then we create a mapping called playerInfo to do something like this playerInfo[here_goes_his_address].amountBet where we can use the address as the “key” in a javascript object to access it’s properties.

We want to have an array of players to know who is playing the game for distributing the rewards to the winners.

Modify the constructor to define the minimum bet for the game so that you can select a variable number of minimum bets for distributing the prizes:

function Casino(uint256 _minimumBet){

owner = msg.sender;

if(_minimumBet != 0 ) minimumBet = _minimumBet;

}

Now create a function at the end of the contract to bet for the numbers between 1 and 10, both inclusive:

pragma solidity 0.4.20;

contract Casino {

address public owner;

uint256 public minimumBet;

uint256 public totalBet;

uint256 public numberOfBets;

uint256 public maxAmountOfBets = 100;

address[] public players; struct Player {

uint256 amountBet;

uint256 numberSelected;

} // The address of the player and => the user info

mapping(address => Player) public playerInfo; function Casino(uint256 _minimumBet) public {

owner = msg.sender;

if(_minimumBet != 0 ) minimumBet = _minimumBet;

} function kill() public {

if(msg.sender == owner) selfdestruct(owner);

} // To bet for a number between 1 and 10 both inclusive

function bet(uint256 numberSelected) public payable {

require(!checkPlayerExists(msg.sender));

require(numberSelected >= 1 && numberSelected <= 10);

require(msg.value >= minimumBet); playerInfo[msg.sender].amountBet = msg.value;

playerInfo[msg.sender].numberSelected = numberSelected;

numberOfBets++;

players.push(msg.sender);

totalBet += msg.value;

}

}

The word payable is a modifier that it’s used to indicate that this function can receive ether when you execute it.

is a that it’s used to indicate that this function can receive ether when you execute it. The require() function is like an if statement that must return true. If the condition inside the require evaluates to false, the function stops and the ether paid is reverted to the sender. We use it to verify that the player hasn’t played already, that the number is in range and that the bet paid is more or equal the minimum bet.

function is like an statement that must return true. If the condition inside the require evaluates to false, the function stops and the ether paid is reverted to the sender. We use it to verify that the player hasn’t played already, that the number is in range and that the bet paid is more or equal the minimum bet. msg.sender and msg.value are values defined by the user when he executes the contract. The sender is his address and the value is the amount of ether he paid when executing this payable function.

and are values defined by the user when he executes the contract. The sender is his address and the value is the amount of ether he paid when executing this function. Then we define the amount bet for that user with playerInfo[msg.sender].amountBet = msg.sender; . msg.sender is the address of the user that executed that function.

. is the address of the user that executed that function. Then we increase the numberOfBets by 1. This variable is a counter used to see how many bets there are for this game to stop it when there are 100 and distribute the rewards.

by 1. This variable is a counter used to see how many bets there are for this game to stop it when there are 100 and distribute the rewards. Finally we increase the totalAmount bet for this game that will be spread across the winners.

You can see that in the first require statement of that funcion:

require(!checkPlayerExists(msg.sender));

I’m invoking a function called checkPlayerExists() to check that the user has not played already because we only want that each person only plays once per game. The function is not yet there. So let’s create it now:

pragma solidity 0.4.20;

contract Casino {

address public owner;

uint256 public minimumBet;

uint256 public totalBet;

uint256 public numberOfBets;

uint256 public maxAmountOfBets = 100;

address[] public players; struct Player {

uint256 amountBet;

uint256 numberSelected;

} // The address of the player and => the user info

mapping(address => Player) public playerInfo; function Casino(uint256 _minimumBet) public {

owner = msg.sender;

if(_minimumBet != 0 ) minimumBet = _minimumBet;

} function kill() public {

if(msg.sender == owner) selfdestruct(owner);

} function checkPlayerExists(address player) public constant returns(bool){

for(uint256 i = 0; i < players.length; i++){

if(players[i] == player) return true;

}

return false;

} // To bet for a number between 1 and 10 both inclusive

function bet(uint256 numberSelected) public payable {

require(!checkPlayerExists(msg.sender));

require(numberSelected >= 1 && numberSelected <= 10);

require(msg.value >= minimumBet); playerInfo[msg.sender].amountBet = msg.value;

playerInfo[msg.sender].numberSelected = numberSelected;

numberOfBets++;

players.push(msg.sender);

totalBet += msg.value;

}

}

The constant keyword of the function, indicates that this is a function that doesn’t cost any gas to run because it’s returning an already existing value from the blockchain. It’s reading a value. That’s why it’s free.

After creating those cool functions, we have to check if the number of bets is bigger or equal the maximum so we can generate the winner number. Because when there are 99 bets, we want that the next bet, the bet number 100, releases the prices and executes the needed calculations. Get it?

Great, add this at the end of the bet() function for that purpose:

if(numberOfBets >= maxAmountOfBets) generateNumberWinner();

Now we have to create the function generateNumberWinner() that will randomly generate a number between 1 and 10 to decide the winner:

pragma solidity 0.4.20;

contract Casino {

address public owner;

uint256 public minimumBet;

uint256 public totalBet;

uint256 public numberOfBets;

uint256 public maxAmountOfBets = 100;

address[] public players; struct Player {

uint256 amountBet;

uint256 numberSelected;

} // The address of the player and => the user info

mapping(address => Player) public playerInfo; function Casino(uint256 _minimumBet) public {

owner = msg.sender;

if(_minimumBet != 0 ) minimumBet = _minimumBet;

} function kill() public {

if(msg.sender == owner) selfdestruct(owner);

} function checkPlayerExists(address player) public constant returns(bool){

for(uint256 i = 0; i < players.length; i++){

if(players[i] == player) return true;

}

return false;

} // To bet for a number between 1 and 10 both inclusive

function bet(uint256 numberSelected) public payable {

require(!checkPlayerExists(msg.sender));

require(numberSelected >= 1 && numberSelected <= 10);

require(msg.value >= minimumBet); playerInfo[msg.sender].amountBet = msg.value;

playerInfo[msg.sender].numberSelected = numberSelected;

numberOfBets++;

players.push(msg.sender);

totalBet += msg.value;

} // Generates a number between 1 and 10 that will be the winner

function generateNumberWinner() public {

uint256 numberGenerated = block.number % 10 + 1; // This isn't secure

distributePrizes(numberGenerated);

}

}

It takes the current block number and gets the last number + 1 so if the block number is 128142 the number generated will be 128142 % 10 = 2 and 2 +1 = 3.

This isn’t secure because it’s easy to know what number will be the winner depending on the conditions. The miners can decide see the block number for their own benefit.

Then, we distribute the prizes for the winners with the function distributePrices(numberGenerated) :

pragma solidity 0.4.20;

contract Casino {

address public owner;

uint256 public minimumBet;

uint256 public totalBet;

uint256 public numberOfBets;

uint256 public maxAmountOfBets = 100;

address[] public players; struct Player {

uint256 amountBet;

uint256 numberSelected;

} // The address of the player and => the user info

mapping(address => Player) public playerInfo; function Casino(uint256 _minimumBet) public {

owner = msg.sender;

if(_minimumBet != 0 ) minimumBet = _minimumBet;

} function kill() public {

if(msg.sender == owner) selfdestruct(owner);

} function checkPlayerExists(address player) public constant returns(bool){

for(uint256 i = 0; i < players.length; i++){

if(players[i] == player) return true;

}

return false;

} // To bet for a number between 1 and 10 both inclusive

function bet(uint256 numberSelected) public payable {

require(!checkPlayerExists(msg.sender));

require(numberSelected >= 1 && numberSelected <= 10);

require(msg.value >= minimumBet); playerInfo[msg.sender].amountBet = msg.value;

playerInfo[msg.sender].numberSelected = numberSelected;

numberOfBets++;

players.push(msg.sender);

totalBet += msg.value;

} // Generates a number between 1 and 10 that will be the winner

function generateNumberWinner() public {

uint256 numberGenerated = block.number % 10 + 1; // This isn't secure

distributePrizes(numberGenerated);

} // Sends the corresponding ether to each winner depending on the total bets

function distributePrizes(uint256 numberWinner) public {

address[100] memory winners; // We have to create a temporary in memory array with fixed size

uint256 count = 0; // This is the count for the array of winners for(uint256 i = 0; i < players.length; i++){

address playerAddress = players[i];

if(playerInfo[playerAddress].numberSelected == numberWinner){

winners[count] = playerAddress;

count++;

}

delete playerInfo[playerAddress]; // Delete all the players

} players.length = 0; // Delete all the players array uint256 winnerEtherAmount = totalBet / winners.length; // How much each winner gets for(uint256 j = 0; j < count; j++){

if(winners[j] != address(0)) // Check that the address in this fixed array is not empty

winners[j].transfer(winnerEtherAmount);

}

}

}

This function does the following:

First generates an array of winners called winners by checking if the player’s numberSelected is the numberWinner . The winners array is a memory array that get’s deleted after the function executes. It must have a fixed size. Then it calculates the amount of ether each winner gets depending on the total bet amount and the amount of winners. The less winners, the bigger the prize. Then it sends the corresponding amount of ether for each winner with winners[j].transfer .

This should be it. Now we have a working contract that allows people to play as a simple casino.

One last thing that I like to do is to create an anonymous fallback function , a function without name that has the modifier payable that it’s executed when you send ether to the contract without executing any function:

// Fallback function in case someone sends ether to the contract so it doesn't get lost and to increase the treasury of this contract that will be distributed in each game

function() public payable {}

This will allow you to save the ether you send to the contract. Otherwise it would be rejected.

This is the complete contract that you just created:

pragma solidity 0.4.20;

contract Casino {

address public owner;

uint256 public minimumBet;

uint256 public totalBet;

uint256 public numberOfBets;

uint256 public maxAmountOfBets = 100;

address[] public players; struct Player {

uint256 amountBet;

uint256 numberSelected;

} // The address of the player and => the user info

mapping(address => Player) public playerInfo; function() public payable {} function Casino(uint256 _minimumBet) public {

owner = msg.sender;

if(_minimumBet != 0 ) minimumBet = _minimumBet;

} function kill() public {

if(msg.sender == owner) selfdestruct(owner);

} function checkPlayerExists(address player) public constant returns(bool){

for(uint256 i = 0; i < players.length; i++){

if(players[i] == player) return true;

}

return false;

} // To bet for a number between 1 and 10 both inclusive

function bet(uint256 numberSelected) public payable {

require(!checkPlayerExists(msg.sender));

require(numberSelected >= 1 && numberSelected <= 10);

require(msg.value >= minimumBet); playerInfo[msg.sender].amountBet = msg.value;

playerInfo[msg.sender].numberSelected = numberSelected;

numberOfBets++;

players.push(msg.sender);

totalBet += msg.value;

} // Generates a number between 1 and 10 that will be the winner

function generateNumberWinner() public {

uint256 numberGenerated = block.number % 10 + 1; // This isn't secure

distributePrizes(numberGenerated);

} // Sends the corresponding ether to each winner depending on the total bets

function distributePrizes(uint256 numberWinner) public {

address[100] memory winners; // We have to create a temporary in memory array with fixed size

uint256 count = 0; // This is the count for the array of winners for(uint256 i = 0; i < players.length; i++){

address playerAddress = players[i];

if(playerInfo[playerAddress].numberSelected == numberWinner){

winners[count] = playerAddress;

count++;

}

delete playerInfo[playerAddress]; // Delete all the players

} players.length = 0; // Delete all the players array uint256 winnerEtherAmount = totalBet / winners.length; // How much each winner gets for(uint256 j = 0; j < count; j++){

if(winners[j] != address(0)) // Check that the address in this fixed array is not empty

winners[j].transfer(winnerEtherAmount);

}

}

}

You can see the complete and updated contract in my github https://github.com/merlox/casino-ethereum inside the contracts folder. It’s an advanced version with an oraclize for secure random number generation.

Now that the contract is done we have 2 options:

Write tests using truffle and deploying the contract in testrpc during those tests.

during those tests. Test the contract manually using the Solidity’s IDE https://remix.ethereum.org. This is the official tool to write, test and deploy contracts.

Because I don’t want to make this article too long, we’ll use the remix IDE to test the contract quickly altough you must make the tests with truffle to make sure your apps work as expected and are secure every time you update them.

Before continuing, you must download metamask.io from that link. It’s the tool used to execute Smart Contracts on your browser and also an Ethereum wallet.

After installing it, open it, follow the steps and create an account. Make sure to save the 12 word passphrase because it’s the only way to recover your account if you forget your password or private key. You should see something like this:

Hey! That’s me on the left

You now have an account in metamask and you can use it for interacting with dapps and Smart Contracts.

So go to the Remix IDE and paste the contract:

This is the remix ide

This is what we’re going to do in the remix IDE:

Deploy the contract to the Testnet Ropsten Blockchain, the blockchain where ether has no real value.

Use metamask to pay for the gas of each function.

Make sure that all functions work as expected.

You have 2 panels, the left with your code and the right one where you can do interesting stuff with that contract.

On the right panel, click on the Run tab:

You should see there is a red button that says Create with an input field that has a placeholder saying uint256 _minimumBet . That’s the minimum bet of the constructor. You can leave it empty or write a number.

Now open the Metamask extension and change your network to the Ropsten Testnet Network like in the image.

Next go to https://faucet.metamask.io/ and request 1 free ether. The faucet is a place where you can get ether for your Ropsten account.

After a while you’ll see that your account has some nice amount of ether in it.

Go to the Remix IDE and make sure that you are in the Environment: Injected web3:

This means that you are using the blockchain injected from Metamask. Now click on Create to deploy your contract, you’ll see a notification window from metamask:

Just click on Submit to pay for the deployment and you are done, your contract is live on the Ropsten network.

If for some reason, you can’t change the enviroment or you don’t see the notification window, press the F12 key to open the Chrome dev tools. Click and hold the reload button in chrome and select the last option:

Empty the cache and reload the page

That should fix those bugs.

After deploying the contract you’ll see the address of the contract, the functions and more interesting data on the right panel.

Something like this:

At the top you have a button that says Copy address that you can use to save that contract’s address for later use. Just click it and save the address somewhere.

Then, the blue buttons are constant or public functions and variables. This means that when you declare a public variable like uint256 public totalBet; you can access it’s value anytime because it’s public.

You can say that it has a getter method automatically generated.

Then the constant functions are those that return a value and don’t modify the state of the contract. This means that they don’t modify the contract’s variables, they just execute and give you a result.

Let’s start by executing the functions one by one.

If you click on minimumBet you’ll instantly get the value of that variable because it’s public:

In my case is that amount because I set it in the constructor when creating the contract

It returns uint256: 1000000000000000 in Wei, which is 0.1 ether. Remember that you interact using Wei, not ether.

Next, the red buttons are those that consume gas to execute functions that save values to the blockchain.

If you see that a function like checkPlayerExists() is in read, you must change the contract to set it constant because it returns a value and doesn’t modify the main variables.

So before changing the contract, we have to destroy the current contract. Execute the kill function and modify the contract (You don’t need to do this if the function is already constant but you can try killing the contract anyway):

function checkPlayerExists(address player) constant returns(bool){

Deploy it again and you’ll see that the checkPlayerExists button is now blue. That means that it won’t consume gas to operate.

The function is constant, doesn’t require gas to execute and returns a boolean value

Note that bytes32 and string must be in double quotes " to work. It’s a common problem that happens when you paste an address because they require json values, which are double-quoted.

The bet function requires that you send an amount of ether bigger than the minimum bet and that you select a number between 1 and 10.

To test it go to the top section of the right column and send a monetary value like in the image:

100 finney is 0.1 ether, you can’t write float values like 0.1 because of precision issues so we use a smaller unit

That’s the value that will be available as msg.value in the contract. Send something bigger than the minimumBet that you set for your contract and execute the function by sending the number to bet for.

If it says that the gas exceeds the gas limit, refresh the page removing the cookies as I taught you before.

After playing with the functions I realized that the distributePrizes() function doesn’t reset all the variables of the contract so the totalBet and the numberOfBets stayed the same after the first game.

So I created a new function like this:

function resetData(){

players.length = 0; // Delete all the players array

totalBet = 0;

numberOfBets = 0;

}

And I called it from the distributePrizes() function. I found a potential problem that I didn’t know before, that’s the power of testing!

Now before going to the next part, let’s compile the contract to use it later with the frontend application.

Create the file 2_deploy_contracts.js inside the migrations folder. In this file is where you set up the values that the constructor of your contract will receive, in my case it’s:

var Casino = artifacts.require("./Casino.sol"); module.exports = function(deployer) {

deployer.deploy(web3.toWei(0.1, 'ether'), 100, {gas: 3000000});

};

Explanation:

First we require the Casino.sol contract.

contract. Then, in the . deploy() method we specify the minimum bet, in this case it’s 0.1 ether converted to wei with that function.

method we specify the minimum bet, in this case it’s converted to with that function. 100 is the max amount of players.

Finally the gas limit that we are willing to use to deploy the contract.

After that, go to your project folder and execute the command truffle compile . This will generate a json file that will have all the needed data about the contract.

We won’t use this data but just so you know when you use the truffle framework. It helps you deploy and test everything from the command line instead of using the Remix IDE.

When you’re done testing, continue with the next part of the tutorial.