Programming Project - Phase 2

Hi @dan-i

Yes withdrawMoney should be onlyOwner.

I am thinking of building about 3-4 projects for my github profile. Can you tell me any websites where I can find ideas?

Can you tell me any websites where I can find ideas?

In the blockchain space, ideas are the most valuable “assets” :slight_smile:
Do you have a project that you like?
Do you like decentralised exchanges?

If yes then just play with existing projects and protocols, maybe you can find something interesting to code.

Also check https://gitcoin.co

Keep in mind that this industry is usually extremely open, feel free to join Discord groups and discuss with other devs.

Also make sure you perfectly know web3, write code in js using that library until you master it.

Now you have all the tools you need to read and understand Solidity, take your time, keep study and try to network with valuable people.

Good luck and never give up!

2 Likes

@dan-i @filip

May I know why I cannot call other function within the code inside the __callback(), I have included the Remix screen capture attached.

and here is the github link: https://github.com/kwokkawai/dapp-coinflip.git

contract name: coinflip.sol

Completed phase 2. Code and screen captures are available here: https://github.com/skdev52/CoinFlip_Phase2

I haven’t added much front end checks for now. I hope to work on it on completing ReactJS web development course.

A code review and feedback will be much appreciated.

It has been a great learning experience. Many thanks to everyone in Ivan On Tech Academy for these great courses.

Hey @Paul_Kwok

In both cases value in not defined.

function __callback(bytes32 _queryId,string memory _result,bytes memory _proof) public {

        bool flip;
        
        uint256 randomNumber = uint256(keccak256(abi.encodePacked(_result))) % 2;
        if (randomNumber == 0) {
            flip = true;
        } else {
            flip = false;
        }
        emit generateRandomNumber(bets[_queryId].walletAddress, flip);

        if (bets[_queryId].predictCoinSide == flip) {
            transferToPlayer(msg.sender,value);
            //balance -= value;
            //playerBalance[msg.sender] += value;             
            
            playerRecord[msg.sender].balance = playerBalance[msg.sender];
            playerRecord[msg.sender].countWin += 1;
        } else {
            
            transferToContract(msg.sender,value);
            //balance += value;
            //playerBalance[player] -= value;
            
            playerRecord[msg.sender].balance = playerBalance[msg.sender];
            playerRecord[msg.sender].countLoss += 1;            
        }

        //delete bet from mapping
        delete(bets[_queryId]);        
    }

You need to define value to be able to use it.

Regards,
Dani

Hey @KryptoS

Some things to think about :slight_smile:

function initalDepositToContract()

I am not sure this function is useful.
Also you do not have a deposit function, which means that you are using initalDepositToContract during your migration but it cannot be used to deposit ether because of what the function does:

function initalDepositToContract() public payable{
     contractBalance = address(this).balance;
}

It would be better to write a function deposit and use that one.

function deposit() public payable {
      contractBalance += msg.value;
}

You have a modifier:

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

but then you also require (contractBalance > 2*msg.value); in your function playFlipCoin(), the modifier can be improved:

   modifier costs(uint cost){
        require (contractBalance > 2*msg.value);
        _;
    }

Or if you also want to set a minimum bet amount, you can also include it in your modifier

   modifier costs(uint cost){
        require (contractBalance > 2*msg.value && msg.value >= cost);
        _;
    }

This function:

    function resetPlayerStatus() internal {
        address creator = msg.sender;

            players[creator].countWin = 0;
            players[creator].sumWin = 0;
            players[creator].countLost = 0;
            players[creator].isActive = false;
            players[creator].coinSide = 0;
            players[creator].betAmount = 0;

    }

Can be simplified:

   function resetPlayerStatus() internal {
       delete(players[msg.sender]);
    }

Happy coding and congrats for your 1st dapp :slight_smile:
Dani

1 Like

Hi, my code is here:
https://github.com/ble4h/CoinFlipDapp

Also had some issue with migrating using Truffle on Ropsten so I deployed using Remix. Demo video on GitHub as well.

Btw my JS is still a little noob-ish. :slight_smile:

Thanks.

Hello, here is my project:

https://github.com/ricoto/bet-game-oracle

Even though it took quite a lot of time, it still has lots of edge cases that are not taken into account. I took more heavy focus on code and documentation rather than UI.
Thank you @filip for such a great course. It helped to understand a lot (and understand that there much more to learn).

Thanks,
Stan!

1 Like

hey @dan-i hope you are good i am trying to compile the code through node js but but sutck in one error hope you can help

here is my code:

// imports & defines

const path = require('path');
const solc = require('solc');
const fs = require('fs-extra');

// Functions

/**
 * Makes sure that the build folder is deleted, before every compilation
 * @returns {*} - Path where the compiled sources should be saved.
 */
function compilingPreperations() {
    const buildPath = path.resolve(__dirname, 'build');
    fs.removeSync(buildPath);
    return buildPath;
}

/**
 * Returns and Object describing what to compile and what need to be returned.
 */
function createConfiguration() {
    return {
        language: 'Solidity',
        sources: {
            'test.sol': {
                content: fs.readFileSync(path.resolve(__dirname, 'contracts', 'test.sol'), 'utf8')
            },/*
            'AnotherFileWithAnContractToCompile.sol': {
                content: fs.readFileSync(path.resolve(__dirname, 'contracts', 'AnotherFileWithAnContractToCompile.sol'), 'utf8')
            }*/
        },
        settings: {
            outputSelection: { // return everything
                '*': {
                    '*': ['*']
                }
            }
        }
    };
}

/**
 * Compiles the sources, defined in the config object with solc-js.
 * @param config - Configuration object.
 * @returns {any} - Object with compiled sources and errors object.
 */
function compileSources(config) {
    try {
        return JSON.parse(solc.compile(JSON.stringify(config)));
    } catch (e) {
        console.log(e);
    }
}


/**
 * Writes the contracts from the compiled sources into JSON files, which you will later be able to
 * use in combination with web3.
 * @param compiled - Object containing the compiled contracts.
 * @param buildPath - Path of the build folder.
 */
function writeOutput(compiled, buildPath) {
    fs.ensureDirSync(buildPath);

    for (let contractFileName in compiled.contracts) {
        const contractName = contractFileName.replace('.sol', '');
        console.log('Writing: ', contractName + '.json');
        fs.outputJsonSync(
            path.resolve(buildPath, contractName + '.json'),
            compiled.contracts[contractFileName][contractName]
        );
    }
}

// Workflow

const buildPath = compilingPreperations();
const config = createConfiguration();
const compiled = compileSources(config);
errorHandling(compiled);
writeOutput(compiled, buildPath);

and here is the output:

Hi @Ritesh_Verma

Follow this FAQ: FAQ - How to downgrade Node.Js

Regards,

still getting the same error when downgraded the nodejs to 10.21.0
my solidity version is 0.6.2

please open your terminal and type node -v. Post a screenshot here :slight_smile:

delete the folder build and node-modules then compile and retry.
If still fails push your code on GitHub and post the link here

Hey @ble4h

Congrats for your first dapp!
Some considerations for you :slight_smile:

uint public rate;
Is this used to exclude fees from the user bet?
If that is the case, there is a method you can call that returns the exact fees required to call the oracle.
provable_getPrice("random")

In your function __callback() you are not checking the proof sent by the oracle.
This is something you can easily implement and that would make your contract much safer.

  function placeBet (uint input, uint amount) public returns (bool) {
    require (minBet <= amount && balance[msg.sender] >= amount && amount <= maxBet);

What happens if your contract balance is 1 ether, the user bets 1 ether and wins? Will your contract be able to pay the user?

You can find the docs here: https://docs.provable.xyz
You can take a look at my project example here: https://github.com/dani69654/CoinFlip/blob/master/contracts/CoinFlip.sol

Well done once again!
Dani

https://github.com/aryaparas/testsolwithnodejs

done everything as you said still error isn’t resolved yet please help

Thank you, Dan. but I cannot add the value argument in the __callback function. Can you advise how I can read the value from the UI inside the __callback function? I cannot use the msg.value as well, because it does not allow me to use msg.value if the __callback function is not payable.

Thanks @dan-i for review feedback. Will note them as improvements in future projects. :slight_smile:

1 Like

You are more than welcome! If you need suggestions just let us know.

1 Like

Hi @Ritesh_Verma

I checked your repo and I see that you are not using Truffle.
Have you taken the Solidity 201 course? If not you can start from this video: https://academy.ivanontech.com/products/ethereum-smart-contract-programming-201/categories/1993907/posts/6668001

Happy learning,
Dani