Programming Project - Phase 1

Hi Dani-

Ok, I have modified the files in my repository, and made the following changes. Can you take a look and let me know how it looks?:

  1. I added a function to fund the contract (so the contract has enough to payout winners at first) and I also attempted to fund the contract during migration in the coinflip migration .js file. Can you take a look and let me know if that is correct?

  2. I changed the guess variable from string to uint.

  3. I changed the bet input to ether and converted to wei in main.js before sending the parameter to the flipAndPay function.

  4. Also, I am still getting the 404 page not found error when clicking the “flip” button. If you can take a look at that and let me know why that may be happening, I would appreciate it.

Thanks!

Randy

heres part 1 of the flip app assignment:
link: https://github.com/yochess2/Flip-Dapp

TODO:

  • [ ] Testing
  • [ ] HTML/bootstrap design
1 Like

Hey @Flaflaflohi

When a user clicks on ‘flip’ look at the result in the URL bar:

Schermata 2020-09-23 alle 11.29.04
Schermata 2020-09-23 alle 11.29.25

What is failing is something related to action_page.php as shown in the address bar.

The issue in your HTML is this:

<form action="/action_page.php">

This form tag has never been closed.
If you use this action_page.php, then you need to close the form tag, otherwise you can just remove it.

Cheers,
Dani

1 Like

Hey @yochess

Well done!

I notice that in your function function flip() public payable you do not ask for any parameter, so a user wins if random == 1 and loses otherwise.
Would not be better to give the user the possibility to choose the side (0 or 1)?

Happy coding,
Dani

2 Likes

Finally managed to finish my attempt on the first project. Has been quite a ride.
If you are interested find below the link to a video recording made of the project.


The front end is very basic but it works. It took my quit long to figure out some issues I ran into with the contract hence why I did not focus too much on the front end.

As you can see in the video I ran several times in a “rpc payload error” which was holding me up since the first steps with the project, until I found some information that this may be related to Ganache. Should anyone have a nice hint how this could be avoided in general I would be very happy.

1 Like

Hi guys, I got stuck and need your help.
Doing my Coin flip project and I don’t understand why on Remix my flip() function doesn’t send money to player account in case of winning… can anyone help me?
here is my code: https://github.com/Ulakal/Coin-Flip-Project

Thanks Dani!

  1. I have removed this line which I believe is leftover from the template that Filip provided. Now, when I click the flip_button, nothing happens at all.

  2. Also, when my dApp loads, I am now getting this error message in the console:

main.js:30 Uncaught TypeError: Cannot read property 'methods' of undefined
    at main.js:30

I have verified that the contract has been deployed and that I am using the correct address in my contractInstance variable. Also, when I type “contractInstance” into the console, I am seeing the contract with methods.

Here is my git repository again:

Thanks!
Randy

  $("#get_balance_button").click(fetchBalance);
  $("#bet_button").click(placeBet).click(fetchBalance);

How can I have the balance of the contract updated after the placeBet function executed?
In the code above, when bet_button selector button is pressed, fetchBalance function shows balance before and not after.

Thanks for the suggestion Dani

I have changed my code and implemented the logic to allow the user to select heads or tails.

link: https://github.com/yochess2/Flip-Dapp

1 Like

Hey @rkindle

Well done with your project. Now ready for phase two :slight_smile:

That error with payload is really annoying I agree.
You can try the following every time it pops up.

Metamask > Settings > Advanced > Reset Account.

If you remove the errors.

Cheers,
Dani

1 Like

Hi @Ula

    function setAbet(uint myCoinSide, uint myBetValue) public payable {
        
        Bet memory newbet;
        
        newbet.coinside = myCoinSide;
        newbet.betvalue = myBetValue;
        bettings[msg.sender] = newbet;
    }

You are setting uint myBetValue as bet amount.
What happens if a user sends 0 ether to this function but sends 1 ether as parameter of this function?

You should remove the parameter uint myBetValue and instead use msg.value as value amount:

    function setAbet(uint myCoinSide) public payable {
        
        Bet memory newbet;
        
        newbet.coinside = myCoinSide;
        newbet.betvalue = msg.value;
        bettings[msg.sender] = newbet;
    }

Also you need to consider the following:

  • Your flip() function should check if there are enough Ether in your contract before allowing a user to play.
  • If your contract has 0 ether and the user bets 1 Ether and wins, you will not have enough money to pay the user back.
else {
            msg.sender.transfer(0);
            return result = false;
        }
  • No need to transfer 0, if the user lost the game just return false.

Fix these things and keep going :slight_smile:

Happy leaning,
Dani

Hey @Flaflaflohi

There are some errors. Take some time to review what the console tells you, it’s really important to learn :slight_smile:

  • You are migrating your contract by sending 100 Ether, is this you intention of just a typo?
  • Look at your main.js file, check where you have closed the function sendBet().
  • Your var config did not include any sender accounts. Keep in mind that you have to specify the sender and the amount to send when using web3.
  • You did not update your contract abi, so all the modification you did in your smart contract were not included in contractInstance.

Below your main.js. I strongly advise you not to copy it, just read at my suggestions above and spend some time by fixing it yourself. You have no rush and the goal is to learn.
Ps. remember to update the abi

var web3 = new Web3(Web3.givenProvider);
var contractInstance;
var user;
$(document).ready(function() {
    window.ethereum.enable().then(function(accounts){
      contractInstance = new web3.eth.Contract(abi, "0xd7B679BAd796e0cf9faa0db162a20456046bE7a6", {from: accounts[0]});
      user = accounts[0];
    });
  $("#flip_button").click(sendBet)
});

function sendBet(){
var bet = $("#bet_amount").val();
var playerChoice = $("#sides").val();

var guess;
if(playerChoice == "heads"){
  guess = 0;
}
else{
  guess = 1;
}

var config = {
  from: user,
  value: web3.utils.toWei(bet, 'ether')
}


contractInstance.methods.flipAndPay(guess).send(config)

.on("transactionHash", function(hash){
    console.log(hash);
  })
  .on("confirmation", function(confirmationNr){
    console.log(confirmationNr);
  })
  .on("receipt", function(receipt){
    console.log(receipt);
    alert("Done");
  })

.then(function(res){

      $("#result_output").text(res.flip_result);
      $("#payout_output").text(res.payout);

});
}; 

Happy learning,
Dani

1 Like

I have figured it out:

$(document).ready(function() {
    window.ethereum.enable().then(function(accounts){
      contractInstance = new web3.eth.Contract(abi, "0xe9BEB94D634F9B126898f8Ca8dC23ECc4C298DC0", {from: accounts[0]});
      fetchBalance();
      console.log(contractInstance);
    })

    $("#bet_button").click(placeBet);

});

And I have also placed fetchBalance(); function into my placeBet() function.

My coinflip() function that has to return uint type returns undefined

function placeBet(){
  var bet = $("#bet_input").val();

  var bet_to_ether = {
    value: web3.utils.toWei(bet, "ether")
  }

  contractInstance.methods.coinflip().send(bet_to_ether)
  .on("transactionHash", function(hash){
    console.log(hash);
  })
  .on("confirmation", function(confirmationNr){
    console.log(confirmationNr);
  })
  .on("receipt", function(receipt){
    console.log(win_loose);
  }).then(function(res){
    alert("The result is: " + res.win_loose);
    $("#win_output").text(res.win_loose);

    fetchBalance();
  })
}

What am I missing?

Also, here is the part of my code from the coinflip function. Maybe the problem somewhere in the smartcontract itself. Please take a look.

function coinflip() public payable costs(100000000000 wei) returns(uint){
        require(msg.value >= 100000000000 wei);
        require(msg.value <= balance);
        uint betBalance = msg.value;
        uint toTransafer = 0;
        uint luck = random();

        if(luck == 1){
            win_loose = 1;
            toTransafer = betBalance *2;
            balance -= betBalance;
            msg.sender.transfer(toTransafer);
        }
        else{
            win_loose = 0;
            toTransafer = 0;
            balance += betBalance;
        }

        emit coinFlipped(balance, win_loose);
        return win_loose;
  }

Thank you Dani for your help and time! I have implemented the changes.
Now facing new challenges… As long as my contract works perfectly fine on Remix, it gives me chills while deploying it on ganache and local server…

  1. Flip a coin! button and flip() function - it asks my metamask for 0 eth transaction
  2. when the result is negative it displays my alert(“You lost a bet”), in some cases RPC error ocurs, it never a case that “You won”

here is my repository: https://github.com/Ulakal/Coin-Flip-Project/tree/master/Coin%20Flip%20Project

I have spent hours trying to solve it, heeelp! :wink:

EDIT: I’ve changed code in main.js file from this:

function flipAcoin() {

contractInstance.methods.flip().send().then(function(res){
    if (res==1) {
        alert("You won!");
    }
    else {
        alert("you lost a bet");
    }
})

}
to this:

function flipAcoin() {

contractInstance.methods.flip().send().then(function(res){

    contractInstance.methods.showResult().call().then(function(result){

        if (result==true) { alert("You won!"); }

        else alert("You lost a bet.");

    })

})

}

and it seems to be working correctly, I dont understand why, but guess its about send() and call() functions…

Still… is it ok that metamask is throwing a transaction 0 eth for flip() function?

Sorry for such a long post… Going to finish with unit tests

1 Like

Hey Dani,

thank you for that. Was trying resetting the account but seems not to help in every case but at least it does improve.
On my way to the next challange.

Cheers,
Ralf

1 Like

Hi,

I’m starting out on this project and was curious what the best way to check the balance and make sure there is enough ETH in the user’s wallet? I’m seeing variations of “this.balance” and “address(this).balance” but not sure which one I can use?

Thank you!

Hey @Ula

I have tested your contract and I won :smiley:

Migrate your contract again (truffle migrate --reset) then take the contract abi from CoinFlip.json and paste it into your ABI file.

Reset Metamask: Settings > Advanced > Reset account.
!Schermata 2020-09-26 alle 14.05.58

Schermata 2020-09-26 alle 14.06.28

Retry your dapp and let me know.

Happy learning,
Dani

2 Likes

Thanks Dani! That was so helpful, and I learned a lot. Next obstacle I am facing is displaying the results. I changed it to emitting an event rather than returning results, but I still cannot get the results to display after the bet. Can you take a look?

Thanks!

Randy

I am also getting this error quite a bit, but not consistently. Can you tell me how to avoid this? Thanks!

inpage.js:1 MetaMask - RPC Error: Error: [ethjs-rpc] rpc error with payload {"id":9300923051282,"jsonrpc":"2.0","params":["0xf893808504a817c800836170d49449efe51b8c23760e50ea389c5b2081a9328be12b880de0b6b3a7640000a48399515c0000000000000000000000000000000000000000000000000000000000000000822d45a0f56b8d57583c7d6aad9a985ad092bfea67b8abecef8594ed2b05850d861df2eaa04c1c6535267fe980dfd55540dc58abe9a073779be2dd1a355fa6eeb84db85bfe"],"method":"eth_sendRawTransaction"} [object Object]