Raptors vs. Cavaliers: Sports Betting DApp

What a DApp is, how the DApp works, and how I built it.

What are DApps?

A DApp is a decentralized application which is run by many users on a decentralized network with trustless protocols. DApps are designed to avoid any single point of failure, which is why it is very difficult for theft, or hackers to attach the network.

Sports Betting DApp

I decided to take this concept and build my own Virtual Sports Betting DApp where each player can bet a certain amount of ethers on a team, and where the smart-contract redistribute the prices to the players who betted on the right team .

How the DApp Works

Essentially, you can try to bet on the Team (Raptors), as I did on the above screenshot with 0.2 ethers. If you fill up the input with the amount you want and click on Bet, a Metamask interface will open up: edit the gas fee to something around 100–200 GWEI and click on confirm. It will take around 15 seconds for the transaction to complete.

The same way, someone can bet on the other team (Cavaliers). Afterwards, the smart contract will be able to redistribute the prices to the players who betted on the winning team.

How I developed the DApp

I used React for developing the front end. The main steps I went through to develop were:

  • Preparing the project environment
  • Writing, testing, and deploying the smart-contract
  • Creating the front-end

Preparing the project environment

For the development of this application, I used node.js to install various packages. I developed our App in React using react-create-app, which generated a simple skeleton for my app. Another framework I used for developing the app was Truffle, which was useful to compile, test & deploy my smart-contract onto an ethereum Blockchain.

Writing, testing, and deploying the smart-contract

I first write & tested my smart-contract on the Remix IDE, which is a light and web Solidity IDE that allows you to write, compile and deploy a smart-contract on any network.

Formulas

To keep the problem simple, you are only able to bet on two options, either the winning or losing team. Each player is able to bet a certain amount of ethereum on a team or another, and following the result, can win back the initial bet and a certain ponderation of the ethers from the losing jackpot.

The winning amount can be represented with this simple formula:

bet / Total bets on your team represent the ponderation of what you will win, that’s why we multiply it with the losing stake to share.

Using solidity and the updated version 0.5.0, the final code of my contract was:

pragma solidity >0.4.99;contract Betting {
address payable public owner;
uint256 public minimumBet;
uint256 public totalBetsOne;
uint256 public totalBetsTwo;
address payable[] public players;
struct Player {
uint256 amountBet;
uint16 teamSelected;
}
// The address of the player and => the user info
mapping(address => Player) public playerInfo;
function() external payable {}

constructor() public {
owner = msg.sender;
minimumBet = 100000000000000;
}
function kill() public {
if(msg.sender == owner) selfdestruct(owner);
}

function checkPlayerExists(address payable player) public view returns(bool){
for(uint256 i = 0; i < players.length; i++){
if(players[i] == player) return true;
}
return false;
}
function bet(uint8 _teamSelected) public payable {
//The first require is used to check if the player already exist
require(!checkPlayerExists(msg.sender));
//The second one is used to see if the value sended by the player is
//Higher than the minimum value
require(msg.value >= minimumBet);
//We set the player informations : amount of the bet and selected team
playerInfo[msg.sender].amountBet = msg.value;
playerInfo[msg.sender].teamSelected = _teamSelected;
//then we add the address of the player to the players array
players.push(msg.sender);
//at the end, we increment the stakes of the team selected with the player bet
if ( _teamSelected == 1){
totalBetsOne += msg.value;
}
else{
totalBetsTwo += msg.value;
}
}
// Generates a number between 1 and 10 that will be the winner
function distributePrizes(uint16 teamWinner) public {
address payable[1000] memory winners;
//We have to create a temporary in memory array with fixed size
//Let's choose 1000
uint256 count = 0; // This is the count for the array of winners
uint256 LoserBet = 0; //This will take the value of all losers bet
uint256 WinnerBet = 0; //This will take the value of all winners bet
address add;
uint256 bet;
address payable playerAddress;
//We loop through the player array to check who selected the winner team
for(uint256 i = 0; i < players.length; i++){
playerAddress = players[i];
//If the player selected the winner team
//We add his address to the winners array
if(playerInfo[playerAddress].teamSelected == teamWinner){
winners[count] = playerAddress;
count++;
}
}
//We define which bet sum is the Loser one and which one is the winner
if ( teamWinner == 1){
LoserBet = totalBetsTwo;
WinnerBet = totalBetsOne;
}
else{
LoserBet = totalBetsOne;
WinnerBet = totalBetsTwo;
}
//We loop through the array of winners, to give ethers to the winners
for(uint256 j = 0; j < count; j++){
// Check that the address in this fixed array is not empty
if(winners[j] != address(0))
add = winners[j];
bet = playerInfo[add].amountBet;
//Transfer the money to the user
winners[j].transfer( (bet*(10000+(LoserBet*10000/WinnerBet)))/10000 );
}

delete playerInfo[playerAddress]; // Delete all the players
players.length = 0; // Delete all the players array
LoserBet = 0; //reinitialize the bets
WinnerBet = 0;
totalBetsOne = 0;
totalBetsTwo = 0;
}
function AmountOne() public view returns(uint256){
return totalBetsOne;
}
function AmountTwo() public view returns(uint256){
return totalBetsTwo;
}
}

Creating the Front-end

Since I used React, the main components I used in the front end were:

  • App.js, which is already the front-page, and this will contain general information about the dApp, and import the other components.
  • TeamA.jsx , will contain the elements for the Team A.
  • TeamB.jsx , will contain the elements for the Team B.

I used Promises as a way for the smart contract to “make a decision”. Promises are asynchronous tasks, and we can chain them to do the tasks wanted on a chosen order.

To view the entire project and files, visit here.

If you enjoyed reading this article, please press the👏 button, and follow me to stay updated on my future articles. Also, feel free to share this article with others!

Follow me on Medium and LinkedIn to stay updated with my progress in Blockchain.

I’m a developer & innovator who enjoys building products and researching ways we can use AI, Blockchain & robotics to solve problems in healthcare and energy!