Programming Project - Phase 1

Here is a video of the project working!
Coin flip betting dapp
And here is the code!
aglawson/CoinFlipDapp_Phase1 at master (github.com)

2 Likes

Hi @a.lwsn, great work!
Just looked at your codebase and I have a doubt.
Isn’t it a bad practice to define your variables when declaring them?
Shouldn’t it be done in the constructor? Maybe I’m just a bit confused with other programming languages :slight_smile:

Hello everyone. I am almost done with the first phase but am having trouble with my withdraw function. The deposit and gamble functions both work as intended however when i click the withdraw function the metamask display comes up, I hit confirm but no value is being transferred. I can see in ganache there is value in the contract. Below is the code for .js interaction and the contract. Am I misdeclaring the function by not listing it as payable?

The contract Code

function withdrawAll() public onlyOwner returns(uint){
      msg.sender.transfer(balance[msg.sender]);
        return balance[msg.sender];
    }

The .js code to call the function

  function withdrawAll() {
    console.log("called"); //written to check if code was being called 
    contractInstance.methods.withdrawAll().send()
    .on("receipt", function(receipt){
    contractInstance.methods.checkBalance().call().then(function(res){
      $("#ETH_output").text(web3.utils.fromWei(res,"ether"));
      console.log("completed");//written to check if function was completed
    });
  });
  }

Thanks

As @filip said not a sexy dapp :sweat_smile:

https://drive.google.com/file/d/1iskKN0_jGZkX77lsBoJI23OvuftDiq4t/view?usp=sharing

1 Like

Wow

pragma solidity 0.5.12;
//pragma abicoder v2;

contract BetContract{
address public owner;
event BetLog(uint amount, address indexed DepositedTo,bool status);
mapping(address => mapping(uint => bool)) approvals;

struct BetLogS{
    uint amount;
    address  receiver;
    bool Status;
    uint id;
}

BetLogS[] BetLogAr;

bytes32 name;

constructor() payable public{
    require(msg.value > 0);
    owner = msg.sender;
}

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

function Bet() public payable{
    require(msg.value > 0);
    BetLogS memory newBet;
    newBet.amount = msg.value;
    newBet.receiver = msg.sender;


    uint amt = random();
    if(amt == 0){
        emit BetLog(msg.value, msg.sender,false);
        newBet.Status = false;
    }else{
        uint BtAmt = msg.value;
        msg.sender.transfer(BtAmt * 2);
        emit BetLog(msg.value, msg.sender, false);
        newBet.Status = false;
    }
    newBet.id = BetLogAr.length;
    BetLogAr.push(newBet);
}

modifier OnlyOwner{
    require(owner == msg.sender ,"You can't view this function");
    _;
}

/*function getTransactionPool() public OnlyOwner view returns(BetLogS[] memory){
    return (BetLogAr);
}*/

}

Am done with the app

2 Likes

Hey @cge5009

Because the function is not ‘view’ you have to use send() instead of call().

contractInstance.methods.withdrawAll().send({from: accounts[0]})

Cheers,
Dani

Ready for phase two :clap:

1 Like

Good job @chim4us :slight_smile: See you in phase two!

dan-i,
Thanks for your help and I made the change from call to send and it still won’t work. See my updated code below. Metamask is still throwing an error saying “ALERT: Transaction Error. Exception thrown in contract code.” Im at a bit of a loss here as this seems as though it should be straightforward.

Sol code

mapping (address => uint256) public balance;

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

JS code

function withdrawAll() {
    contractInstance.methods.withdrawAll().send({from: accounts[0]})
    .on("receipt", function(receipt){
    contractInstance.methods.checkBalance().call().then(function(res){
      $("#ETH_output").text(web3.utils.fromWei(res,"ether"));
      console.log("completed");//written to check if function was completed
    });
  });
  }

Hey @cge5009 Does that code compile?

mapping (address => uint256) public balance;

function withdrawAll() public payable returns(uint){
      msg.sender.transfer(balance[msg.sender]);
      balance[msg.sender] == 0; <<<---- this is an error
        return balance[msg.sender];
    }

In order to bind a value to a variable you have to use only one =

Also the function does not have to be payable as you are not sending ether to it.

Change these two things and retry, if it does not work please push your code on GitHub and give me the link, I will take a look.

Happy coding,
Dani

Thank you! @NamaWho
I think you’re right actually! I’ll have to keep that in mind for the future, thank you for the advice :slight_smile:

2 Likes

@dan-i that code did compile but did not work. I updated it but am still having issues with that function. I posted my GitHub link below. I believe it is the mapping that is causing me problems. I tried adding in the provable function since everything else worked, but when I added mapping for that I am also having trouble getting that settled.

GitHub link to Code

I know, i know, not so pretty, maybe in the future I will make it more fashion, now I’m too curious of the next step

1 Like

Hey @cge5009

I tried to withdraw from your contract and I was able to do it (I did not have any ether to withdraw but the function worked correctly)
TX: https://ropsten.etherscan.io/tx/0xbefc07d7698073df0e4e56a4fb67c9ac4b2ead2963fc2251c6940b50f79f09f1

I was also able to deposit 1 ether: https://ropsten.etherscan.io/tx/0xd1ec91f5b2777ee5fb6eb2b63a636610e7124f04bfe7c485d0676fe353edc6c6

And to play (and win :slight_smile:): https://ropsten.etherscan.io/tx/0x06059f255e470aa99387468d32bb178e071d1d91dba9e6d5e0ae5511a585c140

I was also able to withdraw the ether I deposited: https://ropsten.etherscan.io/tx/0xd421d2ab43831b95fb98c96df55841939138c819bf46ea85e9ee3c73a2d448ea

I deposited 1 ether, I player once and I won, and I was able to withdraw 1 ether, there is a logic issue here :slight_smile:
Because I played once and I won, I should be able to withdraw more than I deposited.

Are you sure about this line in your function update()?

betsPlaced[_queryID].amountGambled = amountGambled;

Think about it, fix it and deploy a new contract, I will be happy to check again.

Also add a button or just some text in your html page so that the user knows how much ether owns (this will update every time the user play and win or lose).

Cheers,
Dani

1 Like

See you in the next phase!

@dan-i

Hey Danielle, I have a question. I am designing the smart contract for the coin flip but I have some troubles.

I have defined the following objects:

  struct Bet {
      address payable userAddress;
      uint size;
      uint side;
      bool win;
      bool finished;
  }
  
  uint contractBalance;
  
  mapping(address => Bet) userBetting;
  mapping(address => uint) userBalances;

I then define some functions - fundContract, fundUserBalance, withdrawFromContract, withdrawUserBalance and others. When I fund contract or fundUserBalance I just change “the number in a mapping” where it says balance, but I don’t / can’t do the actual transfer to the contract (by using address(this).transfer(_deposit) like I wanted to).

When I withdraw on the other hand I do use .transfer like written below.

  function fundContract(uint _deposit) public payable onlyOwner {
      contractBalance += _deposit;
  }
  
  function fundUserBalance(uint _addCash) public payable {
      require(msg.sender.balance >= _addCash);
      userBalances[msg.sender] += _addCash;

  function withdrawFromContract() public onlyOwner {
      require(contractBalance > 0, "No funds to wtihdraw");
      uint toWithdraw = contractBalance;
      msg.sender.transfer(toWithdraw);
  } 
  
  function withdrawUserBalance(uint _toWithdraw) public {
      require(userBalances[msg.sender] > _toWithdraw, "Not enough funds");
      userBalances[msg.sender] -= _toWithdraw;
      msg.sender.transfer(_toWithdraw);
  }

My questions now are:

  • is this correct and if so, why? Is it because I will send ether to the contract via Web3 in main.js file? And does that mean .transfer is used only for transfering funds that are on the contract?

  • if it is not correct I would believe I have to use .transfer when funding the contract at least. But address(this).transfer(_deposit) does not work, it says I can’t deposit to address(this).

Thanks.

@dan-i found some trouble about main.js file after I start python server my main.js doesn’t update.
https://drive.google.com/file/d/1TizgHm98bxLDC-YMTwZyu14_aEdPqv5h/view?usp=sharing

This is my phase1
https://drive.google.com/file/d/1FKiN8GAJE99TEPIDieeVr83A1lY6AZe9/view?usp=sharing

1 Like

Hi,

I have a question. When I set up a python website (localhost: 8000) for the PeopleProject, everything works fine. I type into Powershell the following: python -m http.server. Then, when I type in “localhost:8000” into my browser, the webpage gets pulled up.

However, when I do the same for my project that I am working on, I get the four choices below (see screenshot). If I click on “webSite.html”, then my website comes up. Why is my website not coming up automatically (like with the PeopleProject website)? I can’t figure it out, and is it a problem?

image

Hi @ZigaP

  • is this correct and if so, why? Is it because I will send ether to the contract via Web3 in main.js file? And does that mean .transfer is used only for transfering funds that are on the contract ?

That is correct.
.transfer is a solidity method that allows your contract to send ether to an address.

In order to send funds to a contract you need:

  • A function in your contract that accepts ether, therefore it will be declared as payable;
  • A front end that allows a user to send funds (this is not strictly necessary but it is how you allow non-developers to interact with your contract).

Here an example of Solidity and backend that will hopefully clarify your ideas.

Solidity code of a deposit function:

    function deposit () public payable {
        
    }

A deposit function does not need anything more than what I wrote before, of course inside you can add as much code as you want (depending on what you want to do) but you will be able to deposit Ether in your contract only by writing that statement above.

Now you need to code a js function that allows a user to deposit.
Whenever you want to send ether to a function (using web3) you have to use the method .send()

function deposit() {
  contract.methods.deposit().send({ from: *here the sender address*, value: 10 ** 18 });
}

In the function above I am calling the method deposit() and I am sending 1 ether (10 ** 18).

Make sure to always specify a sender address otherwise the function will not work.

Here a simple contract I wrote, check it out if you want :slight_smile: https://github.com/dani69654/CoinFlip

Let me know if you have questions.

Cheers,
Dani

1 Like