Chris Pollett > Students >
Ajinkya

    ( Print View)

    [Bio]

    [Blog]

    [CS297 Proposal]

    [Overview on IPFS and SWARM - PDF]

    [Deliverable 1]

    [Deliverable 2]

    [Deliverable 3]

    [Solidity Overview - PDF]

    [Deliverable 4]

    [CS297 Report - PDF]

    [CS298 Proposal]

    [CS298 Final Report-PDF]

    [CS298 Defense Slides-PDF]

Deliverable 4: Smart Contracts: Solidity

Description: Solidity is a programming language invented for authoring smart contracts. It uses the Solidity compiler to generate two executable files namely the Byte code and the Application Binary Interface. ABI is useful to interact with the deployed contracts. This deliverable includes a 5 player gambling game created and deployed using Solidity. For this I have made use of the Remix development environment which provides test accounts and networks with 100 ether assigned to each account. Remix provides a UI to interact with the deployed contract and test it using different users.

Gambling game rules: In the game 5 players are allowed to bet on a number of their choice with some amount which should be greater than 500000 Wei (Wei is a unit of ether). The contract generates a random number and the 2 player who guessed the number closest to the contract generated value win some amount. The winner gets 70% of the remaining balance and the runner up gets 30%. 50K is given to the account which deploys the contract and 250k to the 5th player who enters the game as a lot of gas is used to run the gamble function which is initiated when the 5th player enters.

The Remix UI

UI image

Multiple accounts

accounts screenshot

The deployed contract

contract screenshot

Parameters

paramaters screenshot

Logs for one transaction

logs screenshot
// solidity compiler version
pragma solidity ^0.5.0;

// defines a new contract - similar to a class
contract Gamble{
    // storage variable - instance variable
    address public dealer;
    address public lastPlayer;
    address[] public players;
    address[] public gameWinners;
    struct rankPlayers{
        uint diff;
        address addr;
    }
    mapping(address => uint) public playerBets;
    event winner(address[] winner); 
    event log(string log);
    // sunction syntax - function name params function type return type
    // constructor - functions associated with contracts
    constructor() public {
        dealer = msg.sender;
    }

    function enterPlayerBet(uint num) public checkIfPlayersCanEnter payable{
        // will give an error if sent lesser ether and not push the player
        require(msg.value > 500000 wei);
        require(gameWinners.length==0);
       // only enter one player once
        if(playerBets[msg.sender]==0){
            players.push(msg.sender);
            playerBets[msg.sender] = num;
        }
        if(players.length==5){
            lastPlayer = msg.sender;
            gamble();
            emit winner(gameWinners);
        }else{
            emit log('Waiting for more players');
        }
    }

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

    function random() public view returns (uint){
        
        uint rand = uint(keccak256(abi.encodePacked(now,block.difficulty, players)));
        // difficulty going to give how difficult its going to be to seal or solve the block
        return rand;
    }

    function firstWinfunc() public view returns (uint){
        
        uint firstWin = (address(this).balance*70)/100;
        
        // difficulty going to give how difficult its going to be to seal or solve the block
        return firstWin;
    }

    function secondWinfunc() public view returns (uint){
        
        uint secWin = (address(this).balance*30)/100;
        
        // difficulty going to give how difficult its going to be to seal or solve the block
        return secWin;
    }


    function gamble() private {
        require(players.length==5);
        uint winnerTicket = random();
        //address[] memory winners =checkRankings(winnerTicket);
        // reinitialize the game with a new dynamic empty players array with an initial size of 0
        gameWinners = checkRankings(winnerTicket);
        // reinitialize all playerBets keys and players array
        for(uint i =0; I< players.length;i++){
            playerBets[players[i]]=0;
        }
        players = new address[](0);
    }

    function transferWinnings() public payable{
        uint remainingAmount = (address(this).balance - 300000 wei);
        uint firstWin = (remainingAmount*70)/100;
        uint secondWin = (remainingAmount - firstWin);
        address payable win1 = address(uint(gameWinners[0]));
        win1.transfer(firstWin);
        address payable win2 = address(uint(gameWinners[1]));
        win2.transfer(secondWin);
        address payable tranAmount = address(uint(lastPlayer));
        tranAmount.transfer(250000 wei);
        address payable dealerShare = address(uint(dealer));
        dealerShare.transfer(50000 wei);
        gameWinners = new address[](2);
    }

    function checkRankings(uint randomGen) private view returns (address[] memory){
        
        rankPlayers memory r1 =  rankPlayers({
            diff:randomGen - playerBets[players[0]],
            addr: players[0]
        });
        
        rankPlayers memory r2 =  rankPlayers({
            diff:randomGen-playerBets[players[1]],
            addr: players[1]
        });
        
        rankPlayers memory r3 =  rankPlayers({
            diff:playerBets[players[2]] - randomGen,
            addr: players[2]
        });
       
        rankPlayers memory r4 =  rankPlayers({
            diff:playerBets[players[3]] - randomGen,
            addr: players[3]
        });
    
        rankPlayers memory r5 =  rankPlayers({
            diff:playerBets[players[4]] - randomGen,
            addr: players[4]
        });
        rankPlayers[] memory arr = new rankPlayers[](5);

        arr[0] = r1;
        arr[1] = r2;
        arr[2] = r3;
        arr[3] = r4;
        arr[4] = r5;

        for(uint i =0; i < arr.length-1;i++){
            for(uint j =0; j < arr.length-1;j++){
                if(arr[j].diff > arr[j+1].diff){
                    rankPlayers memory temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                }
            }
        }
        
        address[] memory ret = new address[](2);
        ret[0] = arr[0].addr;
        ret[1] = arr[1].addr;
        return ret;
    }

    function checkNumberOfPlayers() public view returns(uint) {
        return players.length;
    }
    // code resue to restric functions to dealers
    modifier restrictedToDealer(){
        require(msg.sender == dealer);
        // underscore is where all the functions code will be executed
        _;
    }

    modifier checkIfPlayersCanEnter(){
        require(players.length < 5);
        _;
    }

    function playersNumbers() public restrictedToDealer view returns(uint[] memory) {
        uint[] memory ret = new uint[](5);
        for(uint i =0; i < players.length;i++){
            ret[i] = playerBets[players[i]];
        }

        return ret;
    }

  
    
}