A PoC of a casino roulette implemented in a smart contract
Ethereum Roulette
A conceptual casino roulette deployed in the ropsten network.
Content
Motivation
How to play
An accident
Safety
Clone a repository
Motivation
I decided to learn more about the development of smart contracts, and since I am learning by creating material, I decided to implement roulette for casinos, while the business logic was implemented in Solidity, the language chosen for the development of smart contracts in the Ethereum blockchain.
The interface is a regular html page with a jаvascript web3 library that allows you to interact with the Ethereum blockchain using jаvascript. The web3 library is introduced to the page using the Chrome Metamask extension.
How to play
You will need to use the installed Metamask Chrome extension, have an account on the ropsten network, have some ether (get some here or here) and go to the dapp url:
Each bet has a fixed amount of 0.01 ether (about 6 euros), and you can place a bet by clicking on the playing field:
On a number (from 0 to 36) with a payment of 36;
On a dozen (1-12, 13-24, 25-36), with a payment of 3;
For color (black or red), with a payment of 2;
If the number is even or odd, then the payout will be 2;
In the column (left, middle or right), with a payout of 3.
Roulette accepts a bet only when you have enough funds to pay for it, as well as for any other active bet.
Different people can play at the same time.
One of the players will press the “Spin the Wheel” button, which will generate a random number, and all bets will be distributed accordingly.
When a player wins a bet, the payout is credited to his personal account. The player can click the “Cash out” button at any time and receive his winnings. Keep in mind that at some point roulette may not have enough funds to pay out winnings to all players. Keep reading to understand why this could happen.
An accident
True randomness is not possible in an Ethereum Virtual Machine (EVM) due to the way the virtual machine works. When a smart contract is invoked, each node in the network will have to run code to verify it, and at the end the state should be the same for each node (consensus). If, hypothetically, a true random function were available, then when each node called it, it would give out a different value, which would make it impossible to reach consensus.
So, we have to use the current state of the blockchain to find a fair random number, and the formula I chose was to calculate a hash from several factors and use a reminder to divide this hash by 37. The factors used in the hash are:
The blockchain of the previous block
Timestamp of the current block
Current block difficulty
Last accepted bid
The problem with this approach is that anyone who can see the state of the blockchain can calculate ("guess") a future random number and bet on this number.
Safety
So, the first security measure implemented was to make a random number dependent on the last bid. So, if, for example, an attacker expects that a random number will be 13, then by betting on 13, he will change the result of a random number, making this type of attack ineffective.
But an attacker can make a reverse attack by betting on a number, and then waiting for the state of the blockchain to be such that generates this particular number. For this attack to work, the attacker must fulfill 2 conditions:
be able to control when the wheel is spinning;
be able to accurately guess the next random number.
The first condition is difficult, because anyone can spin the wheel, but there will be moments when the attacker will be the only player in roulette, which makes this possible. With an average time per block of 14.4 seconds and a bet with a payout of 36, on average, the attacker will have to be alone in roulette for 37 * 14.4 / 60 ~= 9 minutes.
The second condition is more complicated. The two factors used in calculating the “random” number relate to the current block, which will only be known when the wheel rotates, making it impossible to guess the “random” number. The problem is that, even unknown, the timestamp values of the current block and complexity are strictly predictable and, even worse, the miner can manipulate them.
In a nutshell, it will be very difficult for an ordinary player to guess a random number, but the system is vulnerable to miner attacks. Therefore, additional security measures were taken.
Balancing cap
Every time the wheel turns and all payouts are credited to the players' accounts, the system checks whether the roulette balance exceeds 2 ether. If so, it sends the surplus to the contract owner (me). Thus, the maximum amount of ether that an attacker can steal is 3 ethers (full roulette with 2 ethers plus 100 bets of 0.01 ether).
Keep in mind that players' personal accounts (their respective winnings) are not taken into account when calculating the balance. In other words, a player may have more than 2 ethers on his winning accounts, but he will not be able to cash them out because there are not enough funds in roulette to pay.
This is done to prevent a Denial of Service attack, in which a player may have all the winning roulette money in his account, which will prevent other players from playing. Players must be aware of this and withdraw money frequently.
Clone a repository
You can clone the repository and run it on your own private network.
What you will need
Ganache: You can download a stand-alone ready-made Ganache binary for your chosen platform by clicking the "Download" button on the Ganache website. After that, run it and keep running, this will lead to the deployment of a private Ethereum network on your computer, port 7545.
npm: follow these instructions to install npm
The Metamask Chrome extension is installed and running
How to run ethereum Roulette on your computer
Whisk the ganache and continue to whisk.
installing ethereum cd-roulette
npm
Place the contract in your personal blockchain (provided by Ganache):
truffle deployment -reset
Start the web server
npm starts dev
Now you have an ethereum roulette on http://localhost:3000 .