Programming Project - Phase 1

hello! I was able to go further with my dapp. At this point is completed and it seem to work.

The only thing I can’t get to work is this:

after the bet I’d like to get on the page the new value of Balance for example without the need to refresh.

could you help me to get what is wrong?

for example in main.js file I define the getBalance() function

function getBalance(){
contractInstance.methods.balance().call().then(function(res){                                                    // in una blockchain vera createPerson è lenta, e getPerson è veloce

$("#balance_output").text(res);
$("#max_bet").text(res/2.5);
})};

and then I call it after the bet function:

function inputData(){


var config = {
value: web3.utils.toWei("1", "ether")}

var amount = $("#amount").val();

contractInstance.methods.setBet(amount, bet).send({value: web3.utils.toWei(amount, "ether")})
.on("transactionHash", function(hash){
console.log(hash);
})
.on("confirmation", function(confirmationNr){          
console.log(confirmationNr);
})
.on("receipt", function(receipt){
console.log(receipt);
alert("done");
})

getBalance()

}

but still it doesn’t update automatically on the page but only after refresh.

this is the main.js

var web3 = new Web3(Web3.givenProvider);
var contractInstance;

$(document).ready(function() {
    window.ethereum.enable().then(function(accounts){
      contractInstance = new web3.eth.Contract(abi, "0x6623444594c3555F9652AD1ed273f8317a55b35f", {from: accounts[0]});
      console.log(contractInstance);
      getBalance()
      getPlayerBalance()
      getTotGames()
      getTotMoneyBetted()
      getGamesWon()
      getMoneyWon()
      getMinimumBet()
    });

    $("#bet0").click(function(){bet = 0;})
    $("#bet1").click(function(){bet = 1;})

    $("#confirm").click(inputData)
    $("#get_data_button").click(fetchAndDisplay)

    $("#withdraw").click(startWithdraw)
    $("#withdrawPlayer").click(startWithdrawPlayer)
    $("#deposit").click(startDepositFunds)

    $("#set_minimumBet").click(setMinimumBet)

    $("#getAddress").click(startGetAddress)



    //$("#get_balance_button").click(function(){
    //let res = contractInstance.methods.balance().call().then(function(res){                                                    // in una blockchain vera createPerson è lenta, e getPerson è veloce

    //$("#balance_output").text(res);})});

});





function getTotGames(){
contractInstance.methods.TotGames().call().then(function(res){                                                    // in una blockchain vera createPerson è lenta, e getPerson è veloce
$("#TotGames").text(res);
})};
function getTotMoneyBetted(){
contractInstance.methods.TotMoneyBetted().call().then(function(res){                                                    // in una blockchain vera createPerson è lenta, e getPerson è veloce
$("#TotmoneyBetted").text(res);
})};
function getGamesWon(){
contractInstance.methods.TotGamesWon().call().then(function(res){                                                    // in una blockchain vera createPerson è lenta, e getPerson è veloce
$("#TotGamesWon").text(res);
})};
function getMoneyWon(){
contractInstance.methods.TotMoneyWon().call().then(function(res){                                                    // in una blockchain vera createPerson è lenta, e getPerson è veloce
$("#TotMoneyWon").text(res);
})}




function getBalance(){
contractInstance.methods.balance().call().then(function(res){                                                    // in una blockchain vera createPerson è lenta, e getPerson è veloce

$("#balance_output").text(res);
$("#max_bet").text(res/2.5);
})};


function getMinimumBet(){
contractInstance.methods.minBet().call().then(function(res){                                                    // in una blockchain vera createPerson è lenta, e getPerson è veloce

$("#min_bet").text(res);

})};

function getPlayerBalance(){
  contractInstance.methods.getResult().call().then(function(res){          // quando uso un GETTER FUNCTION non devo creare un tx che poi deve essere minata, la blockchain non deve essere cambiata
                                                // in una blockchain vera createPerson è lenta, e getPerson è veloce
  $("#playerBalance_output").text(res.playerBalance);

})}




function startDepositFunds(){

var deposit = $("#depositAmount").val();
contractInstance.methods.depositFunds(deposit).send({value: web3.utils.toWei(deposit, "ether")})
.on("transactionHash", function(hash){
  console.log(hash);
})
.on("confirmation", function(confirmationNr){
  console.log(confirmationNr);
})
.on("receipt", function(receipt){
  console.log(receipt);
})

getBalance()
}


function startWithdraw(){

var withdraw = $("#withdrawAmount").val();

contractInstance.methods.withdrawFunds(withdraw).send()
.on("transactionHash", function(hash){                                                              //istanza del contratto. methods(funzioni). funzione createPerson
console.log(hash);                                                                // .send dice di firmarla con metamask e inviarla al contratto all'indirizzo dentro contract instance
})                                                                // in config specifico che devo mandare 1 ether per createPerson
.on("confirmation", function(confirmationNr){          // .on() funzione che quando riceve tx hash esegue una funzione (quando ci da txhash, block confirmation, receipt = quando tx è messa in un blocco per la prima volta)
console.log(confirmationNr);
})
.on("receipt", function(receipt){
console.log(receipt);
alert("done");
})
getBalance()
};

function startWithdrawPlayer(){

var withdraw = $("#withdrawPlayerAmount").val();

contractInstance.methods.withdrawFundsPlayer(withdraw).send()
.on("transactionHash", function(hash){                                                              //istanza del contratto. methods(funzioni). funzione createPerson
console.log(hash);                                                                // .send dice di firmarla con metamask e inviarla al contratto all'indirizzo dentro contract instance
})                                                                // in config specifico che devo mandare 1 ether per createPerson
.on("confirmation", function(confirmationNr){          // .on() funzione che quando riceve tx hash esegue una funzione (quando ci da txhash, block confirmation, receipt = quando tx è messa in un blocco per la prima volta)
console.log(confirmationNr);
})
.on("receipt", function(receipt){
console.log(receipt);
alert("done");
})
getPlayerBalance()
}


function setMinimumBet(){

var config = {value: web3.utils.toWei("1", "ether")}   // definisco config del valore di 1 ether

var amount = $("#minBetAmount").val();

contractInstance.methods.minimumBet(amount).send() // metto input dentro funzione del CONTRATTO
.on("transactionHash", function(hash){                                                              //istanza del contratto. methods(funzioni). funzione createPerson
console.log(hash);                                                                // .send dice di firmarla con metamask e inviarla al contratto all'indirizzo dentro contract instance
})                                                                // in config specifico che devo mandare 1 ether per createPerson
.on("confirmation", function(confirmationNr){          // .on() funzione che quando riceve tx hash esegue una funzione (quando ci da txhash, block confirmation, receipt = quando tx è messa in un blocco per la prima volta)
console.log(confirmationNr);
})
.on("receipt", function(receipt){
console.log(receipt);
alert("done");
})

getMinimumBet()

}

function startGetAddress(){

  contractInstance.methods.TotUniquePlayers().call().then(function(res){                                                    // in una blockchain vera createPerson è lenta, e getPerson è veloce
  $("#unique").text(res)})

var config = {value: web3.utils.toWei("1", "ether")}   // definisco config del valore di 1 ether

var array = $("#address").val();


contractInstance.methods.getAddress(array).call().then(function(res){                                                    // in una blockchain vera createPerson è lenta, e getPerson è veloce

$("#addressResult").text(res);



contractInstance.methods.getStatistics(res).call().then(function(res){


$("#playerGames").text(res.games);
$("#playerMoneyBetted").text(res.moneyBetted);
$("#playerGamesWon").text(res.gamesWon);
$("#PlayerMoneyWon").text(res.moneyWon);

})



})
}

function inputData(){


var config = {
value: web3.utils.toWei("1", "ether")}

var amount = $("#amount").val();

contractInstance.methods.setBet(amount, bet).send({value: web3.utils.toWei(amount, "ether")})
.on("transactionHash", function(hash){
console.log(hash);
})
.on("confirmation", function(confirmationNr){          
console.log(confirmationNr);
})
.on("receipt", function(receipt){
console.log(receipt);
alert("done");
})

getBalance()

}




  function fetchAndDisplay(){    // deve prendere i dati dalla blockchain e poi deve mostrarli
  contractInstance.methods.getResult().call().then(function(res){          // quando uso un GETTER FUNCTION non devo creare un tx che poi deve essere minata, la blockchain non deve essere cambiata
                                                // in una blockchain vera createPerson è lenta, e getPerson è veloce

$("#amount_output").text(res.amount);
$("#bet_output").text(res.bet);
$("#message_output").text(res.message);
$("#result_output").text(res.result);
$("#playerBalance_output1").text(res.playerBalance);

$("#yourGames").text(res.games);
$("#yourMoneyBetted").text(res.moneyBetted);
$("#yourGamesWon").text(res.gamesWon);
$("#YourMoneyWon").text(res.moneyWon);

getBalance()
getPlayerBalance()
getGamesWon()
getMoneyWon()

})
  }



this is the html:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <title>People</title>
    <script src="https://code.jquery.com/jquery-3.4.1.min.js"
      integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
      crossorigin="anonymous"></script>
    <script type="text/javascript" src="./web3.min.js"></script>
    <script type="text/javascript" src="./abi.js"></script>
    <script type="text/javascript" src="./main.js"></script>

    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">

  </head>
  <body>
    <div class="jumbotron jumbotron-fluid">
      <div class="container">
        <h1 class="display-4">Welcome to Coinchain</h1>
        <p class="lead">Make your bet safely through blockchain </p>
      </div>
    </div>
    <div class="container">


      <div>
        Total games played: <span id="TotGames"></span>
      </div>
      <div>
        Total money betted: <span id="TotmoneyBetted"></span>
      </div>
      <div>
        Total wins: <span id="TotGamesWon"></span>
      </div>
      <div>
        Total money won: <span id="TotMoneyWon"></span>
      </div>

      <br>

      <br>
      <h2>CONTRACT INFOS</h2>
      <div>
        Contract balance: <span id="balance_output"></span>
      </div>
      <div>
        Maximum Bet: <span id="max_bet"></span>
      </div>
      <div>
        Minimum Bet: <span id="min_bet"></span>
      </div>
      <div>
        Player balance: <span id="playerBalance_output"></span>
      </div>

<br>

      <div>
        <h2>Set your stake</h2>
        <div class="input-group mb-3">
          <input type="text" class="form-control" id="amount" placeholder="Set your stake" >

          <input type="button" value="0" id="bet0" placeholder="0" >
          <input type="button" value="1" id="bet1" placeholder="1" >



        </div>

        <button type="button" id="confirm" class="btn btn-primary">CONFIRM AMOUNT</button>

        <div class="container">
          <p class="lead">Make your bet safely through blockchain </p>
        </div>





      <div>
        <h2>LAST BET</h2>
        <div>
          Amount: <span id="amount_output"></span>
        </div>
        <div>
          What did you bet: <span id="bet_output"></span>
        </div>
        <div>
          YOU: <span id="message_output"></span>
        </div>
        <div>
          coin flip was: <span id="result_output"></span>
        </div>

        <div>
          Your balance: <span id="playerBalance_output1"></span>
        </div>

        <h2>YOUR STATISTICS</h2>


        <div>
          Games played: <span id="yourGames"></span>
        </div>
        <div>
          Money betted: <span id="yourMoneyBetted"></span>
        </div>
        <div>
          Games won: <span id="yourGamesWon"></span>
        </div>
        <div>
          Money won: <span id="YourMoneyWon"></span>
        </div>



        <button type="button" id="get_data_button" class="btn btn-primary">Get Data</button>
      </div>


      <br>
      <div>
      <input type="text" class="form-control" id="withdrawPlayerAmount" placeholder="amount to withdraw Player" >
      <button type="button" id="withdrawPlayer" class="btn btn-primary">WITHDRAW PLAYER</button>
      </div>

      <br>

      <div>
        <h2>PLAYER STATISTICS</h2>

        <div class="input-group mb-3">
          <input type="text" class="form-control" id="address" placeholder="Input address" >
          <button type="button" id="getAddress" class="btn btn-primary">GET ADDRESS</button>

        </div>
        <div>
          Number of unique players: <span id="unique"></span>
          <br>
          Address: <span id="addressResult"></span>
        </div>
        <div>
          Games: <span id="playerGames"></span>
        </div>
        <div>
          Money betted: <span id="playerMoneyBetted"></span>
        </div>
        <div>
          Games won: <span id="playerGamesWon"></span>
        </div>
        <div>
          Money Won: <span id="PlayerMoneyWon"></span>
        </div>

      <br>

      <div class="input-group mb-3">
        <input type="text" class="form-control" id="minBetAmount" placeholder="Set minimum bet" >
        <button type="button" id="set_minimumBet" class="btn btn-primary">SET MINIMUM BET</button>

      </div>







<br>

<div>
<input type="text" class="form-control" id="depositAmount" placeholder="amount to deposit" >
<button type="button" id="deposit" class="btn btn-primary">DEPOSIT FUNDS</button>
</div>
<br>

  <div>
<input type="text" class="form-control" id="withdrawAmount" placeholder="amount to withdraw" >
  <button type="button" id="withdraw" class="btn btn-primary">WITHDRAW</button>
  </div>
<br>


  </body>
</html>

thanks a lot!

Hi @enrico

In your code I do not see events handling.
In order to automatically update the balance, you should listen for events so that you can call your function getBalance() as soon as you get the bet result back.

Regards,
Dani

Hi @dan-i

I was just trying to add more functionalities as below: :point_down:

Instead of using one Button , i added two Buttons
Head and Tails

Both lead to the same function flipCoin();

But when i click on Head it directs me to Metamask and my Transaction goes through , but when i click on Tails, it doesn’t go through which is quite strange :roll_eyes:

Below Code :point_down:



    <div class="container">
      <div>
        <h2>Now time to Bet</h2>


        <div class="input-group mb-3">
          <input type="text" class="form-control" id="bet_input" placeholder="Enter amount in ether less than Contract Balance"/>
        </div>
        <button type="button" id="flip_button" class="btn btn-primary">Head</button>
        <button type="button" id="flip_button1" class="btn btn-primary">Tails</button>
      </div>
    </div>
var web3 = new Web3(Web3.givenProvider);
var contractInstance;

$(document).ready(function(){
  window.ethereum.enable().then(function(accounts){
    contractInstance = new web3.eth.Contract(abi, web3.utils.toChecksumAddress("0xdDf78ed37690D2B8dB21C4d89736491C8E501DD9"), {from : accounts[0]});
    console.log(contractInstance);
    console.log(`Use Contract address: ${contractInstance._address}`)
    });

    $("#flip_button").click(function() {
      flipCoin();
    });
    $("#flip_button1").click(function(){
      flipCoin();
    });
    $("#get_balance").click(fetchAndDisplay);
    $("#fund_contract_button").click(fundContract);
    $("#withdraw_funds").click(withdrawAll);

    function flipCoin(){
        var bet = $("#bet_input").val();
        var config = {
            value: web3.utils.toWei(bet,"ether")
        }
        contractInstance.methods.flipCoin().send(config)
        .on("transactionHash", function(hash){
            console.log(hash);
        })
        .on("confirmation", function(confirmationNr){
            console.log(confirmationNr);
        })
        .on("receipt", function(receipt){
            console.log(receipt);
            if(receipt.events.betPlaced.returnValues[2] === false){
                alert("You lost " + bet + " Ether!");
            }
            else if(receipt.events.betPlaced.returnValues[2] === true){
                alert("You won " + bet + " Ether!");
            }
        })

      };


      function fetchAndDisplay(){
          contractInstance.methods.getBalance().call().then(function(res){
            $("#jackpot_output").text("The Contract has : " + web3.utils.fromWei(res[1], "ether") + "Ether");

          })
      };


      function fundContract(){
        var fund = $("#fund_contract").val();
        var config = {
          value : web3.utils.toWei(fund, "ether")
        }
        contractInstance.methods.fundContract().send(config)
        .on("transactionHash", function(hash){
          console.log(hash);
        })
        .on("confirmation", function(confirmationNr){
          console.log(confirmationNr);
        })
        .on("receipt", function(receipt){
          console.log(receipt);

        })

      }
});


function withdrawAll(){
  contractInstance.methods.withdrawAll().send();
}

Can you please explain me where I am going wrong???

Also, another question:

When i put the withdrawAll() inside the window.ethereum.enable().then(function(accounts) {

function withdrawAll(){
contractInstance.methods.withdrawAll().send();
}
)

It doesn’t work.

And when i put it outside the window.ethereum.enable() {} ,

It Magically works…

I cannot grasp my Head around this?
Can you explain ??

I want to get into the Phase 2 after I understand all the basics conceptually well enough so my mind doesn’t waiver Later.

Thanks and Regards

Su.kal Crypto

Hello thanks,

I tried to set the function getBalance() inside the receipt and it works

function inputData(){


var config = {
value: web3.utils.toWei("1", "ether")}

var amount = $("#amount").val();

contractInstance.methods.setBet(amount, bet).send({value: web3.utils.toWei(amount, "ether")}) // così evito di scrivere 1000000000000
.on("transactionHash", function(hash){
console.log(hash);
})
.on("confirmation", function(confirmationNr){
console.log(confirmationNr);
})
.on("receipt", function(receipt){
console.log(receipt);
getBalance();
getPlayerBalance();
getTotGames();
getTotMoneyBetted();
getGamesWon();
getMoneyWon();
})
}

anyway I think is not clear to me how to use my own event.

in the contract I defined the event “betEvent” which emit the result of the bet after the “setBet” function is called.event betEvent(uint bet);

to use this in the main.js file I tried to do the following after the function that start the bet function:

function inputData(){


var config = {
value: web3.utils.toWei("1", "ether")}

var amount = $("#amount").val();

contractInstance.methods.setBet(amount, bet).send({value: web3.utils.toWei(amount, "ether")})
.on("transactionHash", function(hash){
console.log(hash);
})
.on("confirmation", function(confirmationNr){          
console.log(confirmationNr);
})
.on("receipt", function(receipt){
console.log(receipt);
alert("done");
})
.on("bet", getBalance)

}

and also

function inputData(){


var config = {
value: web3.utils.toWei("1", "ether")}

var amount = $("#amount").val();

contractInstance.methods.setBet(amount, bet).send({value: web3.utils.toWei(amount, "ether")})
.on("transactionHash", function(hash){
console.log(hash);
})
.on("confirmation", function(confirmationNr){          
console.log(confirmationNr);
})
.on("receipt", function(receipt){
console.log(receipt);
alert("done");
})

.contractInstance.events.betEvent().on("bet", getBalance);

}


neither are working.

can you please tell me how to use this correctly?

thanks

Hi @Su.kal.Crypto

I saw that you have added two buttons (head and tail), but what’s the difference between them?
They both call the same function. How does the function know if the user choice is head or tail?
You have to code the different behaviours (functions accept parameters)

Also the functions need to be outside the windows.eth.enable, as that’s a function used to connect metamask.

Kind regards,
Dani

Hi @enrico

I have wrote an FAQ about events: FAQ - How to listen for events

Happy coding,
Dani

Hey @filip @dan-i,

I am currently working on setting up an event listener for the result of the random function if the result was what the user chose else if it wasn’t correct.

I’m trying to alert() the response of the listener and am getting an error of main.js:50 Uncaught (in promise) ReferenceError: outcome is not defined in my javascript file -

await alert(contractInstance.events.Outcome(outcome)); //(outcome) is where the error is showing up at

Outcome is the name of the listener and outcome is the name of the events string variable. I feel like I have the line correct for the most part but am thinking I am accessing the event variable incorrectly.

I also initially had it just as this -

await alert(contractInstance.events.Outcome);

I was getting an alert at that point but it was just showing this:
function () { [native code] }
And the alert seemed to be showing up before the ‘coin flip’ actually happened.

Here is my main.js code:

var web3 = new Web3(Web3.givenProvider);
var contractInstance;

$(document).ready(function() {
    window.ethereum.enable().then(function(accounts){
        contractInstance = new web3.eth.Contract(abi, "0x315f7861Fe614133c804bD1D2e901fA40Fd49B50", {from: accounts[0]});
        console.log(contractInstance);
    });
    $("#add_bet_button").click(inputData);
    $("#get_current_bet_btn").click(fetchAndDisplay);
    $("#flip_coin_btn").click(pickChoiceAndFlipCoin);

});

function inputData() {

    let bet = $("#bet_input").val().toString()


    let config = {
        value: web3.utils.toWei(bet, "ether")
    }

    contractInstance.methods.setBet(bet).send(config)
    .on("transactionHash", function(hash){
        console.log(hash);
    })
    .on("confirmation", function(confirmationNr){
        console.log(confirmationNr);
    })
    .on("receipt", function(receipt){
        console.log(receipt);
    })

};

function fetchAndDisplay() {
    contractInstance.methods.getBetAmount().call().then(function(res){
        $("#current_bet_output").text(res);
    });
};

async function pickChoiceAndFlipCoin() {
    let selectedValue = $('input[name=answer]:checked').val(); 
    await contractInstance.methods.random(selectedValue).send();
    await alert(contractInstance.events.Outcome(outcome));
};

Here is my contracts code as well:

pragma solidity 0.7.6;

contract CoinFlip {

    mapping (address => uint) balance;

    uint256 betAmount;
    uint256 minimumBet;
    string outcome;

	event Outcome(string outcome);

	constructor() {
		minimumBet = 1;
	}


	function addBalance() public payable returns(uint){
		balance[msg.sender] += msg.value;
		return balance[msg.sender];
	}

	function getBalance() public view returns(uint){
	    return balance[msg.sender];
	}

    function setBet(uint256 amount) public payable returns(uint256, uint256){
        require(minimumBet <= amount, "Minimum bet should be at least 1 ether");
        balance[msg.sender] -= amount;
        betAmount = amount;
        return(balance[msg.sender], betAmount);
    }

    function getBetAmount() public view returns(uint256){
        return betAmount;
    }

	function random(uint256 choice) public payable returns(string memory){
	    require(choice == 0 || choice == 1);
		uint256 result = block.timestamp % 2;
		if(result == choice){
		    balance[msg.sender] += betAmount * 2;
		    betAmount = 0;
		    emit Outcome("congrats, you win!");
		}
		else{
		    betAmount = 0;
		    emit Outcome("sorry you lost, try again.");
		}
	}

}

I feel like I’ve somewhat hit a snag now. Thank you for the help!

Hi @Paul_Mun

async function pickChoiceAndFlipCoin() {
    let selectedValue = $('input[name=answer]:checked').val(); 
    await contractInstance.methods.random(selectedValue).send();
    await alert(contractInstance.events.Outcome(outcome));
};

This outcome is not declared in your function indeed therefore your code does not know what to alert.
You first have to declare a variable, bind a value then alert it.

function test () {
    console.log(outcome);
}

Would product outcome is not definied.

let outcome = 5;
console.log(outcome);

Will display the number 5 in your console.

You always have to declare a variable before using it.

Regards,
Dani

Struggling to figure out how to get the contract to pay out to the better after a win. This should be functional in the phase of the project, correct? If so, can you give me a hint as to how to make the payout happen?

Thank you!

I was able to figure it out. msg.transfer did the trick for me on the contract side. However, on the js side, I had to use .send({value: 0, from: contractInstance.address}). Is this the best way to handle that? Regardless, attached are the screenshots that show the dapp in action.

Home Screen/Original State

Create Bet (1 ETH)

Settle Bet/Generates pseudo random number/determines win or loss

Transaction + alert if you won.


Alert if you lost.

Thanks Dani
I understood and resolved the issue.
Meanwhile, I am stuck at another point : How to listen to ? and how to console.log the events ?

Please have a look at the below code in my Github Repository and kindly let me know where I am going wrong :point_down:
https://github.com/Suveett/coinFlip-Dapp.git

Anyways, I am also just enclosing below the main.js function where I am trying to get an alert created for the event, but it’s not showing as the alert after execution of function. And the surprising part also is that there no errors being thrown in the console while executing this function :point_down:


      function fetchAndDisplay(){
          contractInstance.methods.getBalance().call().then(function(res){
            $("#jackpot_output").text("The Contract has : " + web3.utils.fromWei(res[1], "ether") + "Ether");

          })
      };


      function fundContract(){
        var fund = $("#fund_contract").val();
        var config = {
          value : web3.utils.toWei(fund, "ether")
        }
        contractInstance.methods.fundContract().send(config)
        .on("transactionHash", function(hash){
          console.log(hash);
        })
        .on("confirmation", function(confirmationNr){
          console.log(confirmationNr);
        })
        .on("receipt", function(receipt){
          console.log(receipt);
          receipt.events.contractFunded(function(error, result){
            alert(`The Contract has now been funded by  + ${result.returnValues.amount(web3.utils.fromWei(amount, "ether"))} + Ether`);
        })
        })
      };


Can you guide me where am I going wrong ?

Thanks and Regards
Su.kal Crypto

1 Like

Ahh ok I see what you mean!! What is the difference between accessing a global variable through a getter function vs just setting the variable to public then accessing it thorough the getter function that is automatically created for it? Is one way more superior or more safer to use than the other?

Hey everyone, @dan-i @filip @thecil

I hope all is well with you! I have recently gotten stuck on the project on the Coin Flipp Dapp Project.

I have started to receive an error when trying to interact with my dapp through the localhost server and Ganache. I am getting some error that seems to be pertaining to Ganache. Here is the following error message that I am receiving. Everything was working fine until this point.

MetaMask - RPC Error: Error: [ethjs-query] while formatting outputs from RPC '{"value":{"code":-32603,"data":{"message":"VM Exception while processing transaction: revert","code":-32000,"data":{"0x561ecfe8301c8c7c2724531363728afeaf555613467b10462f470cf869d16d36":{"error":"revert","program_counter":273,"return":"0x"},"stack":"RuntimeError: VM Exception while processing transaction: revert\n at Function.RuntimeError.fromResults (/tmp/.mount_ganachwb0RIt/resources/static/node/node_modules/ganache-core/lib/utils/runtimeerror.js:94:13)\n at BlockchainDouble.processBlock (/tmp/.mount_ganachwb0RIt/resources/static/node/node_modules/ganache-core/lib/blockchain_double.js:627:24)\n at runMicrotasks (<anonymous>)\n at processTicksAndRejections (internal/process/task_queues.js:93:5)","name":"RuntimeError"}}}}' {code: -32603, message: "Error: [ethjs-query] while formatting outputs from…/task_queues.js:93:5)","name":"RuntimeError"}}}}'"}

I’ve spend 2 days trying to figure this out and look this up. With my current knowledge I have been unable to figure it out. Would anyone happen to know what would be causing me to get this error?

Things I’ve already tried:

  1. Resetting my MM
  2. Reinstalling MM
  3. Resetting my computer
  4. Clearing Cache
  5. Switching from port number 7545 to 8545
  6. Deleting CoinFlip.json file and re-migrating
  7. Going over my code

I think there may have been another student with a similar issue as well as I noticed the same question as mine posted on Ethereum Stack Exchange from 6 days ago for a coin flip dapp. Here is my github as well: https://github.com/Paul-Munley/CoinFlipDapp

Thank you for the help!

I had a similar issues.

  1. For the Revert error : Surely there is a RevertError in the code (@dan-i) can check code and revert.
  2. Also, I had to open up a new workplace in Ganache and Miraculously everything worked Ok after that (do not forget to copy the new contract address in main.js)
    Thanks and Cheers and Happy Coding

Su.kal Crypto

2 Likes

Hey @Su.kal.Crypto

  1. Ya I was thinking it had to be something in my code but and having a difficult time diagnosing it. I know for sure the contract code should be ok.

  2. Unfortunately I already tried that and didn’t seem to have much luck. It’s good to know that I haven’t been the only one with this issue though.

Thank you for the response, I really appreciate it! :slightly_smiling_face: :+1:

I’ve now narrowed this down to I think this code as being the issue but can’t figure out what is wrong with this. It seems to be throwing the error in regards to the config being passed into the send. Any ideas?

function inputBetData() {
    let bet = $("#bet_input").val();

    let config = {
        value: web3.utils.toWei(bet, "ether")
    }
    console.log(config);

    contractInstance.methods.setBet(bet).send(config)
    .on("transactionHash", function(hash){
        console.log(hash);
    })
    .on("confirmation", function(confirmationNr){
        console.log(confirmationNr);
    })
    .on("receipt", function(receipt){
        console.log(receipt);
    })
};

This code above will take the input for the bet amount and subtract it from the contract balance that was added to the page. It is meant to take in an ether amount from the user and send it to the contract.

Hi @Haysoose

I had to use .send({value: 0, from: contractInstance.address}). Is this the best way to handle that?

The payout should not be handled in the js file, it should be done from your contract directly.
Keep in mind that your contract must be 100% independent from the front end.

If you want to push money to the user in case he wins (not safe), you can use msg.sender.transfer().

if (userGuess == now %2) msg.sender.transfer etc…

I suggest you to keep track of the user balance and code a withdraw function instead.

Regards,
Dani

1 Like

Hi @Su.kal.Crypto

I wrote a basic faq about events, this will give you a general idea that you can of course improve: FAQ - How to listen for events

In the faq you will find a link to the web3 documentation, always check there as it contains examples and explanations that will surely help you :slight_smile:

Happy learning,
Dani

Hi @Paul_Mun

Ahh ok I see what you mean!! What is the difference between accessing a global variable through a getter function vs just setting the variable to public then accessing it thorough the getter function that is automatically created for it? Is one way more superior or more safer to use than the other?

A public variable can be read and used from other contracts, while a private variable can only be accessed if you code a getter function.
It really depends if you want that variable to be accessed by other contracts.

1 Like

Hi @Paul_Mun

I agree with @Su.kal.Crypto, I think that your code is hitting a revert.
Your function random() has a require:

function random(uint256 choice) public payable returns(uint){
	    require(choice == 0 || choice == 1);

Are you sending 0 or 1 as parameter?

Also please give us more context, when does this error pops up?
Which function are you calling?
You can also add a revert error and check if that is returned, for example you could do something like this:

    require(choice == 0 || choice == 1, "invalid choice");