Programming Project - Phase 2

The two js code examples posted each print some data to the console. Your project must be running both of these. It looks like one is run during the steps of execution where the other is run after events are triggered. If you’re only looking for one, comment the other out.

About the .call() versus .send()
–> .call() is used when you do not modify data on-chain. viewable functions like getters.
–> .send() is used when there is some change to modify the on-chain data.

I also came across this problem doing mine. I hope that helps. Good Luck.

1 Like

Hi guys,
finally here is my project, it’s not perfect, but I’m learning from scratch:)

here is my repo: https://github.com/Ulakal/Coin-Flip-phase-2
Also any suggestions are very welcome! :slightly_smiling_face:

2 Likes

Thanks for the .call() vs .send() information. That makes a lot of sense now.

I’m hoping that maybe I can find a way to avoid that second gas fee payment box for the user though. Maybe somehow increase the gas price for the first bet transaction and use it to pay for the second?

Just seems weird to make the player pay a gas fee to finish a losing bet transaction (i.e. mark them no longer playing and delete their failed bet information).

The reason you are having to pay gas twice is the second function is changing the state of the contract. Getters are free but setters cost money. Think of a transaction in terms of data, not money, when you call handleFlippedResult() you are updating the contract with information (transacting data) and this requires computation and therefore computer resources are being used which you have to pay for with gas.
If you want a better user experience, you need to find a way to have all of the state changes of your contract occur from one contract interaction. For example you might have a flipCoin() function, which sends off to the oracle, then when the number comes in to the __callback() function , you could handle your state changes there or call your handleFlippedResult() from within the callback function. This should result in one interaction and therefore you should only have to pay gas the one time. Good luck

2 Likes

Hey @Nicksta

That is an issue with Ropsten, unfortunately I also got that message sometimes.
When that happens, try to migrate to Rinkeby or another testnet.

The ETH mainnet works really good, the testnets have issues sometimes (which is something to keep in mind when using every kind of testnet).

Let me know and happy coding!

Hey @Billy

I took a look at your contract, well done!
Couple of suggestions:

require(msg.value <= balance, "You can't bet more than the bank has!!!");
Lets assume that msg.value is 1 ether and the contract balance is 1 ether.
The user will be able to play, but will your contract be able to pay him back if he wins?

Something to think about :slight_smile:

Happy learning,
Dani

1 Like

Hey @CrazyCanadia,

I want to suggest you this lecture, it is a Medium article really well written about pseudo randomness in Solidity and why it does not work.
https://medium.com/dedaub/bad-randomness-is-even-dicier-than-you-think-7fa2c6e0c2cd

Check it out and please let me know if you have questions.
I really like that you are diving deep into these topics, which are really important for a blockchain dev.

1 Like

Oh, I forgot about the gas fee! oops. Good spot!

Awesome… Thanks for the info. :+1:

1 Like

Beautiful suggestion to call handleFlippedResult() from the callback function. That worked marvelously. I feel somewhat ashamed that I didn’t think of that, lol.

Much thanks.

2 Likes

Hey @Billy

I did not mean the gas fees.
When you pay a win you send msg.value * 2, if the user bets 1 and wins, you send back two eth

Ah, but you also see that when the user bets 1 ETH he also sends the 1 ETH. So the contract pays (sends) that 1 ETH back and 1 ETH winnings!

Hi there. Here is a link to my completed Phase 2 project files.

I’m putting a Dropbox link here because not sure if you appreciate that not everyone knows how to navigate their way around Github. Would be nice to include some basic training on Github in one of the courses!!

https://www.dropbox.com/sh/4x21dux4gfcvos7/AABZxGThAA9WQoUjXayHJUsha?dl=0

And here’s a short video of it in action:
https://youtu.be/8bGn3b8KkKk

UPDATE:

OK, so I started on a GitHub course over at packtpub.com. I now have my repo set up for this project here: https://github.com/CryptoEatsTheWorld/CoinFlip

1 Like

Hey @Billy

Ah, but you also see that when the user bets 1 ETH he also sends the 1 ETH. So the contract pays (sends) that 1 ETH back and 1 ETH winnings!

Lets assume the following:

user_balance = 1 ether;
bank_balance = 0 ether;

The user bets 1 ether on head.

user_balance = 0 ether;
bank_balance = 1 ether;

The user wins:

      if (isHeads) { //they won! pay out their stake + winnings
          uint toTransfer = bet.betAmount * 2;
          balance -= toTransfer;
          require(balance >= 0, "Oops! Balance < 0 !!!"); // INVARIANT OR WE HAVE MUCKED UP
          bet.addr.transfer(toTransfer);

the contract would not have enough amount to process this tx will revert.

Let me know if I am missing something :slight_smile:
Dani

https://github.com/ortegarod/coin-flip-dapp

1 Like
coinFlip() ... {
  require(msg.value <= balance, "You can't bet more than the bank has!!!");

This is the check that the punter doesn’t bet more that’s in the bank. Now, it does occur to be me now that I didn’t have any checks to ensure that all the outstanding bets could be paid out in the event they all won! Woops. Sounds like Fractional Reserve Banking, doesn’t it!? :slight_smile:

1 Like

The two js code examples posted each print some data to the console. Your project must be running both of these. It looks like one is run during the steps of execution where the other is run after events are triggered. If you’re only looking for one, comment the other out.

Circling back to this now. The events that double up are all in Solidity. They are the debugPrintUInt calls in triggerCoinFlip() and handleFlippedResult(). This functions should only be called once so I’m not sure why those traces show up twice (sometimes even 5 or 6 times per actual function call). The logging that occurs in Javascript seems to only print once so this is still a mystery to me.

are you still calling your handleFlipped from the Javascript as well as from the callback still?

I’ve never called handleFlippedResult() more than once per transaction. It’s always either been in the Javascript or the callback but never both.

1 Like

Hey @Warphine

Check your private message I will dm :slight_smile:

1 Like