Programming Project - Phase 1

Hi everyone.
I’m still confused about a relation of a contract, player, and game master…
Could anyone tell me the answer of these questions?

  1. Is a contract “owner” equal to each player?
  2. Is a deployed address equal to a game master?
  3. Should I keep each player’s info like we did in a people project with “mapping”?
  4. Are there any drawbacks to make one function handles “get betting info” -> “get results” -> “transfer ETH if a player won” -> “return result of game”?
  5. Should I assign one user (=game master) account as a base balance for paying ETH?

I finished the coding part. Implementation pretty simple. Just a button to place bet and flip the coin. First, you select the bet amount between 0.1 ETH to 1 ETH with the radio buttons
Second, you click button “Flip that coin!”
Third, sign the transaction
Fourth, browser alerts you whether you won or lost
Fifth, your money is payed out automatically to your wallet.

1 Like

It’s not much to look at:

1 Like

@Rafael21
Amazing work!

You can also send your code for review :slight_smile:

1 Like

What is the best way to have a dapp detect an account balance change without need to poll for the balance?

Turning Programming Project - Phase 1…

HI @azu

I ll try to :slight_smile:

  1. the contract owner is just a variable. Usually you are setting the variable "owner " to be equal to the contract creator. Then you are checking in sensitive function if the address which is calling this contract is the owner of the contract
  2. What do you mean ? The address who deployed the contract or the address of the contract itself. What is a game master for you ?
  3. Yes
  4. You can only use one function for that.
  5. Do you mean allowing only a specific user to provide liquidity to your contract ?
    You can yes, in this case you can create a “game_master” variable set this variable with an address and only allow this address to do specific actions (game master action)
3 Likes

Hi @gabba, Thank you for answering!
I’m starting to understand.

For #5, that means you can, but not necessary? If any specific address was not assigned at the beginning, does the contract keep the betted ETH from players?
I’m wondering if a player continued winning or betted a big amount and won, who actually pay for that. Could I assume there is an unlimited ETH to pay or should I set a limit for betting if there was not enough balance to pay?

@Daveed
The best way to detect balance is with the use of event :slight_smile:

With events you can detect anything because events are only executed when the transaction on the EVM is successful.
In case of failure, you can use require() or assert()

also check
error handling in solidity : https://solidity.readthedocs.io/en/v0.5.3/control-structures.html#error-handling-assert-require-revert-and-exceptions

1 Like

Thanks for the reply reply! Which event do I listen to specifically to detect account balance updates?

here is the GitHub link!

Some Experience worth sharing:

  1. When you see an RPC-payload error, import another address from Ganache(there you have a total of 10 addresses), and try to use that as a client.
  2. If you run out of addresses, just uninstall, and reinstall ganache, and you have 10 new addresses.
  3. Say, you still have the same error, turn off the wifi of your pc, then when metamask says to confirm the Tx, just edit the gas limit, and gas prices, going to the advanced option.

And another thing, I have tried to bring randomness some other way. In the smart contract I have written a function that takes two numbers as input, when the two numbers are same, the function will transfer the msg.sender double money, else nothing willbe given back.

Now in the main.js file I have created a random number, either 0 or 1 (because javascript can produce random numbers ( try Math.random() ) ), and have taken an input from the user, which is also either 0 or 1. Then have sent these two numbers as arguments to the contractInstance.methods.gamble() function.

Will be happy to receive feedback :sweat_smile:

With solidity you can use events to listen (log) any update.

example for account balance:

pragma solidity ^0.6.0;

contract Example {
    //create mapping for balance
    mapping (address => uint) public balance;

    // Log event to print the balance
    event Log(uint balance);

    function CheckBalance(address _address) public {
        //execute the event
        emit Log(balance[_address]);
    }
};

source : https://solidity.readthedocs.io/en/v0.5.3/contracts.html#events

P.S. you can use the event wherever you like to check the updated balance in the contract

1 Like

@Daveed
Amazing work!
You can share your code for further review :slight_smile:

1 Like

I would like to implement a withdrawal function though I know it was not requested in the assignment. I’ve written it as follows and have unit tested it which appears to work

   function withdrawAll() public returns(uint) { 
        uint toTransfer = balance;
        balance = 0;
        msg.sender.transfer(toTransfer);
        return toTransfer;
    }

I do realize it is not checking for who is extracting the funds but I wanted to keep it simple for now. When I implement this function in the dApp, it’ll return the correct balance but the funds are not removed from the contract. I am I missing something?

Yes it’s not necessary, you can let other player add liquidity too, it depends the complexity of your smart contract for example you can:

  1. Only the owner is sending ETH to the contract (he is the bank) and player are betting againt him

  2. Player can also send funds in other bank and player can bet against an other player bank.

This question is more related to game mechanism than code imo.

The contract continue to pay the player if there is ETH on it

You should of course add a require a the beginning of your function and check that the msg.value is smaller than the contract balance

2 Likes

That makes sense!

How about just generally speaking? Imagine a dapp that isn’t relying on any particular contract’s event. Is there a way to detect changes to the current account (the account selected by the web3 provided (Metamask))? Perhaps there’s a way to hook into Metamask to detect changes to the account balance. Hopefully my question makes sense.

Sure thing! I don’t have any smart contract tests written yet :). I’ll do that for the 2nd part of the assignment.

Hello All,

Starting to work on phase 1 of this project and looking for a bit of direction on where to start with the smart contract portion… I scrolled up and read some of the prior comments but most of those are further along then I am at this point.

I’ve watched the videos and I understand what we are trying to achieve. I guess I need some help breaking down the overall goal into simpler steps so I can figure out how to build this out. If anyone can point me to a prior post with some of this info or point me in the right direction it would be greatly appreciated. I’m looking forward to the challenge of this project and hope to become more comfortable with the development process with more practice.

Thanks in advance!

-Cody

@Taha

Looking at some previous peoples posts, I;ve created the code below so far:

pragma solidity 0.5.12;

import "./safeMath.sol";

contract CoinFlip is Ownable {

    mapping (address => uint) public balance;

    function getContractBalance() public view returns(uint) {
        return address(this).balance;
    }

    function flipCoin (uint) public payable returns (string memory, address) {
      require(msg.sender balance >= msg.value, "The users bet cannot be more than users balance");

        if (random() == 0) {
          //Winning
            uint win = safeMath.mul(msg.value, 2);
            msg.sender.transfer(win);
        } else {
            uint lose = msg.value;
            this.transfer(lose);
        }
    }

    function withdrawAll() public onlyOwner returns(uint) {
        uint toTransfer = balance;
        balance = 0;
        msg.sender.transfer(toTransfer);
        return toTransfer;
    }

    function random() private view returns (uint) {
        return block.timestamp % 2;
    }


}

I will start by saying that I feel as though I dont know as much as I should at this point which is somewhat frustrating for me personally. Looking at what I’ve created so far, which i know doesn’t totally work yet… I have the following questions:

  • If the user loses, how do I transfer msg.sender.value to the contract itself?

  • How do you determine what the functions modifiers should be and what/if it should return anything
    For example, I saw different people have different inputs and returns for the coinflip function and i dont understand the differences or why you would chose to do it one way versus a different way.

I love that we are building something on our own and forced to figure it out because i feel that really helps you to learn and understand what you are learning, however I do wish there was a basic outline( create mapping for x, then create function to do y, etc.) even if its purposely vague, but at least making you think out the problem a bit more.

Would love some feedback/guidance from the community here. I’m going to keep trying to improve this in the meantime.

Hi @Daveed
Metamask changes and updates will be logged/listened by using web3.

You can create an instance of the contract and check mapping balance variable for updates.

Example:

 // instance of the contract
  var instance = contract.at("0xB2dAaeEb856d1E9CC69d7F5d74aeDa8f1C5FE018");

//TO show Balance of End-user Wallet
  function showGetBalance() {
  web3.eth.getAccounts((err, res) => {
    var output = "";
    if (!err) {
      // if there are more than one account like in Private Ethereum i.e. ganache
      for (i=0; i< res.length; i++){
        var account = res[i];

        web3.eth.getBalance(account, (err2, res2) => {
          if (!err2) {
            // web3.eth.getBalance(res[i]) returns an instanceof BigNumber
            output += "Account: "+ account +",<br/ > Balance: " + res2 + " (wei), "+ web3.fromWei(res2, 'ether').toFixed(2) +" (ether)<br />";

          } else {
            output = "Please Install Metamask Plug in Extension";
          }
          $('#result').html("<b>Balance of all accounts </b> <br />" + output + "<br />");
        })
      }

    } else {
      output = "Please Install Metamask Plug in Extension";
    }
    $('#result').html("<b>Balance of all accounts</b> <br />" + output + "<br />");
  })
}
1 Like