Programming Project - Phase 2

Hey everyone I get this error when I try to run functions inside of truffle for my contract(not just sendTransaction but any function where I send token to contract). Screen Shot 2020-08-25 at 10.27.23 PM

Interesting thing is when I run the same thing in remix, it works fine. Anyone know what is happening?

Here is the link to the contract code:
https://github.com/kedpak/first_dapp/blob/master/contracts/Coinflip.sol

In the code I test it using the “addContractFunds” functions. Same issue with "cannot read property ‘address’ of undefined

@Nikso
Good project.

  1. usage of private, internal, ownership
  2. Great use of events in the frontend

Well done :partying_face:

I have noticed that you haven’t used Oracle, that is provableAPI. Solidity does not have any random() for randomness. And the blockchain architecture prevents randomness to be achieved among nodes. Hence, use Oracle as suggested in the video :slight_smile:
You could add the SafeMath library and a proxy in the future.

Finished phase 2, waiting for your feedback! :slight_smile:

I saw proxies on etherscan somewhere, I am intrigued but not sure where to learn about those?

Please share your github with full code.

2 Likes

Hey dani, oh yeah forgot to add that. I just edited my original post with a link to the contract code :smiley: In the code I test it using the “addContractFunds” functions. Same issue with "cannot read property ‘address’ of undefined

Please have a look,

pragma solidity 0.5.12;

import "./Ownable.sol";
import "./provableAPI.sol";

contract Ethler is Ownable, usingProvable{

    uint256 constant NUM_RANDOM_BYTES_REQUESTED = 1;
    uint contractBalance;

    // uint256 public latestNumber;
    struct Bet{
      address Player;
      uint value;
      uint choice;
    }

    mapping (bytes32 => Bet) public waiting;
    mapping (address => uint) public BalanceSheet;
    mapping (address => bool) public waitingStatus;

    modifier costs(uint value){
      require(msg.value >= value);
      _;
    }

    event statusOfCalledBackPlayer(address indexed Player, bool status);

// part  of callback function
    function updatePlayerBalance(address Player, uint bet)private {
        BalanceSheet[Player] += bet*2;
        contractBalance -= bet;
    }

    constructor()public{
      provable_setProof(proofType_Ledger);
      update();
    }

    function update()public payable returns(bytes32){
      uint256 QUERY_EXECUTION_DELAY = 0;
      uint256 GAS_FOR_CALLBACK = 200000;

      bytes32 queryId = provable_newRandomDSQuery(
          QUERY_EXECUTION_DELAY,
          NUM_RANDOM_BYTES_REQUESTED,
          GAS_FOR_CALLBACK
      );
      return queryId;
    }

// function after the flip button
    function Play(uint Input)public payable costs(0.001 ether){
      require(waitingStatus[msg.sender] == false, "You are already in a game");
      require(Input == 0 || Input == 1, "Input was not valid");

      // updating player status
      waitingStatus[msg.sender] = true;

      Bet memory newbet;
      newbet.Player = msg.sender;
      newbet.value = msg.value;
      newbet.choice = Input;

      // update contract balance
      contractBalance += msg.value;
      bytes32 queryId = update();

      waiting[queryId] = newbet;
    }

    function __callback(bytes32 _queryId, string memory _result, bytes memory _proof) public{
        require(msg.sender == provable_cbAddress());
        if (provable_randomDS_proofVerify__returnCode(_queryId, _result, _proof) == 0) {
          uint256 randomNumber = uint256(keccak256(abi.encodePacked(_result))) % 2;

           // theWaitingPlyer = waiting[_queryId];

          // retrieving data from struct

          bool status = waiting[_queryId].choice == randomNumber;
          address waitingPlayerAddress = waiting[_queryId].Player;
          uint val = waiting[_queryId].value;

          // in case of win update the BalanceSheet
          if(status) updatePlayerBalance(waitingPlayerAddress, val);

          // updating status of the player
          waitingStatus[waitingPlayerAddress] = false;
          delete waiting[_queryId];
          //emitting event
          emit statusOfCalledBackPlayer(waitingPlayerAddress, status);
        }
    }

// Your balance button
    function showBalance() public view returns(uint){
      return BalanceSheet[msg.sender];
    }

// withdraw button
    function withdrawBalance() public payable{
      uint toTransfer = BalanceSheet[msg.sender];
      require(toTransfer >= 100000000000000);
      BalanceSheet[msg.sender] = 0;
      msg.sender.transfer(toTransfer);
    }

// for owner to withdraw the smart contract funds
    function withdrawAll()public isOwned {
      uint toTransfer = address(this).balance;
      contractBalance -= toTransfer;
      msg.sender.transfer(toTransfer);
    }
// for cash deposition by the owner
    function Deosit()public isOwned payable costs(1 ether){
      contractBalance+= msg.value;
    }
}

I am getting the same error again and again. Have tried,

  1. Deleting existing infura project, creating a new one, and using the new ids.
  2. My meta mask wallet has enough test net ether for deployment also.
    But I can not deploy the contract if I wish to keep the constructor, as you suggested.
    Thanks😅

Here is the migration file,

const contract = artifacts.require("Ethler");

module.exports = function(deployer) {
  deployer.deploy(contract, {value: web3.utils.toWei("1","ether"), gas:6000000});
};

in truffle-config.js file,
ropsten{…gas:6000000,…}

Hey @loksaha1310

Change your migration file to this one:

const contract = artifacts.require("Ethler");

module.exports = function(deployer) {
  deployer.deploy(contract);
};

1 Like

For further reference, we fixed the issue by using an old node version, precisely: https://nodejs.org/download/release/v11.12.0/

Screen Shot 2020-08-25 at 10.27.23 PM

1 Like

That worked!!! Thank you! :sweat_smile: Can you explain,why it didn’t work when I was trying to send some initial balance to my contract?

Hey @loksaha1310

You can send ether to your contract by using your migration file and setting the constructor payable.

Test (using your migration): https://ropsten.etherscan.io/address/0xf20d039F3A434b0e85701a2A257e1Fc47B268957

1 Like

Hi @Nikso
Check this out for proxy upgradable smart contracts.

Our forum: Full Smart Contract Upgradeability Discussion

link 1: https://medium.com/@adilharis/upgradeable-smart-contracts-made-easy-4134bb72fe6
link 2: https://medium.com/@blockchain101/the-basics-of-upgradable-proxy-contracts-in-ethereum-479b5d3363d6

1 Like

I dont seem to be getting the event from the __callback function on the FE. Im listening using the following code in my JS file.

contractInstance.events.generateRandomNumber({
            fromBlock: 0
        }, (err, event) => {
            console.log('event ', event)
            console.log('err ', err);
        }).on('data', (event) => {
            console.log('event2 ', event);
            console.log('contractinstance ', contractInstance);

            let finalResult = res.events.coinFlipped.returnValues.result;
            let amount = web3.utils.fromWei(res.events.winPayout.returnValues.betAmount, "ether");

            if (finalResult === "0") {
                $("#bet-winnings").text("Congrats! You won " + amount + " Ether!");
            } else {
                $("#bet-winnings").text("Sorry you lost!");
            }
        }).on('error', console.error)

I can’t even tell if the __callback is ever being called. I know that my “update” function is called as the “LogNewProvableQuery” event is emitting. What is going wrong. The provable api is provableAPI_0.5.sol from the github repo.

Hi all, I got a question. I’m 99% finished but I can’t figure out how to get the emit from the call back function when the payment has gone through.

Here is my code. The callback function is on line 40.

Thanks

John

There seems to be an issue with Ropsten at the moment because the __callback() is not triggered.
It works on Rinkeby.
Ropsten test
Rinkeby test

Update:

1 Like

@JohnW
Amazing to see you complete the project.
I suppose you are using Ropsten network and there seems to be an issue with Ropsten at the moment because the __callback() is not triggered.
It works on Rinkeby.

Check out this answer:Programming Project - Phase 2

1 Like

Here is result of my work.
I’ve made flip-coin dapp, UI is built with React, Material-UI, Typescript. Oracle random result is used to determine win or lost bet.Tested it with Ropsten network in a days when __callback method on provableAPI worked, lately with Rinkeby testnet, enjoy.

Github: https://github.com/tito6666/flip-coin



1 Like

This issue has been solved and the oracleApi works again on Ropsten.

3 Likes

having issues running my local app against contract deployed ropsten. My ropsten acc looks well funded. I deployed it fine. I did a ‘truffle networks’ to get the contract address and then pasted that into main.js. Also copied the abi stuff.
On page load I get an error:


heres my repo : https://github.com/walshe/betting-dapp

Hey @Emmett

The error is related to this function in main.js function getMyBalance().
Because nobody is sending a call to your contract it returns an invalid result.

Chnage this function in your contract so that it accepts an address as argument

function getUserBalance(address _user) public view returns (uint256) {
        return playerBalances[_user];
}

Now change your function in main.js as follow

  function getMyBalance() {
    web3.eth.getAccounts((err, res) => {
      contractInstance.methods.getUserBalance(res[0]).call().then(function(myBalance){
        console.log(myBalance);
        $("#balance").html(myBalance);
        enableWithdrawButton(parseInt(myBalance));
      })
    })
  }

Now it works.

Happy coding,
Dani

1 Like