0

I'm trying to build a decentralized app for a lottery smart contract, deployed on a local ganache ethereum network, for this I have created a project with creat-react-app.

This is the smart contract, it's pretty simple, it has pickWinner, enter and getPlayers functions.

contract Lottery {
    address public manager;
    address payable[] public players;
    uint256 index;

    constructor() payable {
        manager = msg.sender;
    }

    function enter() public payable {
        require(msg.value == .02 ether);
        players.push(payable(msg.sender));
    }

    function random() private view returns (uint256) {
        return
            uint256(
                keccak256(
                    abi.encodePacked(block.difficulty, block.timestamp, players)
                )
            );
    }

    function pickWinner() public restricted {
        index = random() % players.length;
        players[index].transfer(address(this).balance);
        players = new address payable[](0);
    }

    modifier restricted() {
        require(msg.sender == manager);
        _;
    }

    function getPlayers() public view returns (address payable[] memory) {
        return players;
    }
}

On react project, I web3.js file. This is in charged to inject a Web3 object from Metamask, that's the reason I installed web3 module with npm and I imported on this file.

import Web3 from "web3";

const web3 = new Web3(window.web3.currentProvider);

export default web3;

I also have a lottery.js file, this is in charged of loading the smart contract data created after it was deployed on Ganache local network, this data corresponds to the ABI and the contract address.

import web3 from "./web3";

const contractAddress = "0x4fF1731d8eC2776c4202fD2b2145910e4652A500";

const abi = [
    {
        inputs: [],
        stateMutability: "payable",
        type: "constructor",
        payable: true,
    },
    {
        inputs: [],
        name: "manager",
        outputs: [
            {
                internalType: "address",
                name: "",
                type: "address",
            },
        ],
        stateMutability: "view",
        type: "function",
        constant: true,
    },
    {
        inputs: [
            {
                internalType: "uint256",
                name: "",
                type: "uint256",
            },
        ],
        name: "players",
        outputs: [
            {
                internalType: "address payable",
                name: "",
                type: "address",
            },
        ],
        stateMutability: "view",
        type: "function",
        constant: true,
    },
    {
        inputs: [],
        name: "enter",
        outputs: [],
        stateMutability: "payable",
        type: "function",
        payable: true,
    },
    {
        inputs: [],
        name: "pickWinner",
        outputs: [],
        stateMutability: "nonpayable",
        type: "function",
    },
    {
        inputs: [],
        name: "getPlayers",
        outputs: [
            {
                internalType: "address payable[]",
                name: "",
                type: "address[]",
            },
        ],
        stateMutability: "view",
        type: "function",
        constant: true,
    },
];

export default new web3.eth.Contract(abi, contractAddress);

Finally, I have an App.js file. This is in charged of creating the App component and implementing functions and events in order to render the single web page.

import React, { Component } from "react";
import "./App.css";
import lottery from "./lottery";
import web3 from "./web3";

class App extends Component {
    state = {
        manager: "",
        players: [],
        balance: "",
    };

    async componentDidMount() {
        const players = await lottery.methods.getPlayers().call();
        const manager = await lottery.methods.manager().call();
        const balance = await web3.eth.getBalance(lottery.options.address);

        console.log(players);
        this.setState({ manager, players, balance });
    }

    enter = async (event) => {
        event.preventDefault();

        const accounts = await web3.eth.getAccounts();

        console.log(this.state.players);
        await lottery.methods.enter().send({
            from: accounts[0],
            value: web3.utils.toWei("0.02", "ether"),
        });
    };

    pickWinner = async () => {
        const accounts = await web3.eth.getAccounts();

        await lottery.methods.pickWinner().send({
            from: accounts[0],
        });
    };

    render() {
        var rows = [];

        for (var i = 0; i < this.state.players.length; i++) {
            rows.push(
                <label>
                    {" "}
                    <br />
                    Player {i + 1} - {this.state.players[i]}{" "}
                </label>
            );
        }

        return (
            <div className="App">
                <h2 align="center">Lottery Contract</h2>

                <p>
                    This contract is managed by <b>{this.state.manager}</b>. All players
                    are competing to win{" "}
                    <b>{web3.utils.fromWei(this.state.balance, "ether")}</b> ether!
                </p>

                <hr />

                <p>
                    All {this.state.players.length} players are {rows}
                </p>

                <hr />

                <h4>Want to try your luck?</h4>
                <button
                    className="button"
                    style={{ height: 40, width: 150, borderRadius: 10, fontSize: 15 }}
                    onClick={this.enter}
                >
                    {" "}
                    <b>Enter</b>
                </button>

                <hr />

                <h4>Ready to pick a winner?</h4>
                <button
                    className="button"
                    style={{ height: 40, width: 150, borderRadius: 10, fontSize: 15 }}
                    onClick={this.pickWinner}
                >
                    <b>Pick Winner</b>
                </button>

                <hr />
            </div>
        );
    }
}

export default App;

When I run npm start, I got all these errors:

Compiled with problems:X

ERROR in ./node_modules/cipher-base/index.js 3:16-43

Module not found: Error: Can't resolve 'stream' in '/home/user/lottery-frontend/lottery/node_modules/cipher-base'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
    - add a fallback 'resolve.fallback: { "stream": require.resolve("stream-browserify") }'
    - install 'stream-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
    resolve.fallback: { "stream": false }


ERROR in ./node_modules/eth-lib/lib/bytes.js 9:193-227

Module not found: Error: Can't resolve 'crypto' in '/home/user/lottery-frontend/lottery/node_modules/eth-lib/lib'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
    - add a fallback 'resolve.fallback: { "crypto": require.resolve("crypto-browserify") }'
    - install 'crypto-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
    resolve.fallback: { "crypto": false }


ERROR in ./node_modules/ethereumjs-util/dist.browser/account.js 39:31-48

Module not found: Error: Can't resolve 'assert' in '/home/user/lottery-frontend/lottery/node_modules/ethereumjs-util/dist.browser'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
    - add a fallback 'resolve.fallback: { "assert": require.resolve("assert/") }'
    - install 'assert'
If you don't want to include a polyfill, you can use an empty module like this:
    resolve.fallback: { "assert": false }


ERROR in ./node_modules/ethereumjs-util/dist.browser/address.js 14:31-48

Module not found: Error: Can't resolve 'assert' in '/home/user/lottery-frontend/lottery/node_modules/ethereumjs-util/dist.browser'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
    - add a fallback 'resolve.fallback: { "assert": require.resolve("assert/") }'
    - install 'assert'
If you don't want to include a polyfill, you can use an empty module like this:
    resolve.fallback: { "assert": false }


ERROR in ./node_modules/ethereumjs-util/dist.browser/object.js 14:31-48

Module not found: Error: Can't resolve 'assert' in '/home/user/lottery-frontend/lottery/node_modules/ethereumjs-util/dist.browser'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
    - add a fallback 'resolve.fallback: { "assert": require.resolve("assert/") }'
    - install 'assert'
If you don't want to include a polyfill, you can use an empty module like this:
    resolve.fallback: { "assert": false }


ERROR in ./node_modules/web3-eth-accounts/lib/index.js 31:74-91

Module not found: Error: Can't resolve 'crypto' in '/home/user/lottery-frontend/lottery/node_modules/web3-eth-accounts/lib'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
    - add a fallback 'resolve.fallback: { "crypto": require.resolve("crypto-browserify") }'
    - install 'crypto-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
    resolve.fallback: { "crypto": false }


ERROR in ./node_modules/web3-eth-accounts/node_modules/eth-lib/lib/bytes.js 7:193-227

Module not found: Error: Can't resolve 'crypto' in '/home/user/lottery-frontend/lottery/node_modules/web3-eth-accounts/node_modules/eth-lib/lib'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
    - add a fallback 'resolve.fallback: { "crypto": require.resolve("crypto-browserify") }'
    - install 'crypto-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
    resolve.fallback: { "crypto": false }


ERROR in ./node_modules/web3-providers-http/lib/index.js 30:11-26

Module not found: Error: Can't resolve 'http' in '/home/user/lottery-frontend/lottery/node_modules/web3-providers-http/lib'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
    - add a fallback 'resolve.fallback: { "http": require.resolve("stream-http") }'
    - install 'stream-http'
If you don't want to include a polyfill, you can use an empty module like this:
    resolve.fallback: { "http": false }


ERROR in ./node_modules/web3-providers-http/lib/index.js 32:12-28

Module not found: Error: Can't resolve 'https' in '/home/user/lottery-frontend/lottery/node_modules/web3-providers-http/lib'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
    - add a fallback 'resolve.fallback: { "https": require.resolve("https-browserify") }'
    - install 'https-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
    resolve.fallback: { "https": false }


ERROR in ./node_modules/web3-providers-ws/lib/helpers.js 11:12-26

Module not found: Error: Can't resolve 'url' in '/home/user/lottery-frontend/lottery/node_modules/web3-providers-ws/lib'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
    - add a fallback 'resolve.fallback: { "url": require.resolve("url/") }'
    - install 'url'
If you don't want to include a polyfill, you can use an empty module like this:
    resolve.fallback: { "url": false }


ERROR in ./node_modules/xhr2-cookies/dist/xml-http-request.js 37:11-26

Module not found: Error: Can't resolve 'http' in '/home/user/lottery-frontend/lottery/node_modules/xhr2-cookies/dist'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
    - add a fallback 'resolve.fallback: { "http": require.resolve("stream-http") }'
    - install 'stream-http'
If you don't want to include a polyfill, you can use an empty module like this:
    resolve.fallback: { "http": false }


ERROR in ./node_modules/xhr2-cookies/dist/xml-http-request.js 39:12-28

Module not found: Error: Can't resolve 'https' in '/home/user/lottery-frontend/lottery/node_modules/xhr2-cookies/dist'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
    - add a fallback 'resolve.fallback: { "https": require.resolve("https-browserify") }'
    - install 'https-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
    resolve.fallback: { "https": false }


ERROR in ./node_modules/xhr2-cookies/dist/xml-http-request.js 41:9-22

Module not found: Error: Can't resolve 'os' in '/home/user/lottery-frontend/lottery/node_modules/xhr2-cookies/dist'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
    - add a fallback 'resolve.fallback: { "os": require.resolve("os-browserify/browser") }'
    - install 'os-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
    resolve.fallback: { "os": false }


ERROR in ./node_modules/xhr2-cookies/dist/xml-http-request.js 43:10-24

Module not found: Error: Can't resolve 'url' in '/home/user/lottery-frontend/lottery/node_modules/xhr2-cookies/dist'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
    - add a fallback 'resolve.fallback: { "url": require.resolve("url/") }'
    - install 'url'
If you don't want to include a polyfill, you can use an empty module like this:
    resolve.fallback: { "url": false }

I've solved them by doing what the messages suggested. So I installed these packages: stream-browserify, https-browserify, os-browserify, crypto-browserify, stream-http, url, assert. After that, I changed the webpack.config.js from the path node_modules>>react-scripts>>config>>webpack.config.js by adding the below:

...
module.exports = function (webpackEnv) {
  ...
  return {
   ...
        resolve: {
      fallback: {"stream": require.resolve("stream-browserify"), "crypto": require.resolve("crypto-browserify"), "assert": require.resolve("assert/"), "http": require.resolve("stream-http"), "https": require.resolve("https-browserify"), "url": require.resolve("url/"), "os": require.resolve("os-browserify/browser"), "url": require.resolve("url/")},
     ...
    }
  }
}
...

And I got the webpack compiled but I got nothing renders on localhost:3000, 22 warnings and failures at parsing source maps, like this (the log is so long so I'm just showing some of it):

Compiled with warnings.

Failed to parse source map from '/home/user/lottery-frontend/lottery/node_modules/@ethersproject/abi/src.ts/_version.ts' file: Error: ENOENT: no such file or directory, open '/home/user/lottery-frontend/lottery/node_modules/@ethersproject/abi/src.ts/_version.ts'

Failed to parse source map from '/home/user/lottery-frontend/lottery/node_modules/@ethersproject/abi/src.ts/abi-coder.ts' file: Error: ENOENT: no such file or directory, open '/home/user/lottery-frontend/lottery/node_modules/@ethersproject/abi/src.ts/abi-coder.ts'

...

Search for the keywords to learn more about each warning.
To ignore, add // eslint-disable-next-line to the line before.

assets by path static/js/*.js 4.96 MiB
  asset static/js/bundle.js 4.95 MiB [emitted] (name: main) 1 related asset
  asset static/js/node_modules_web-vitals_dist_web-vitals_js.chunk.js 6.92 KiB [emitted] 1 related asset
asset index.html 1.67 KiB [emitted]
asset asset-manifest.json 458 bytes [emitted]
cached modules 4.62 MiB [cached] 591 modules
runtime modules 31.5 KiB 17 modules
javascript modules 8.85 KiB
  ./src/App.js 6.56 KiB [code generated]
  ./src/lottery.js 2.28 KiB [built] [code generated]

WARNING in ./node_modules/@ethersproject/abi/lib.esm/_version.js
Module Warning (from ./node_modules/source-map-loader/dist/cjs.js):
Failed to parse source map from '/home/user/lottery-frontend/lottery/node_modules/@ethersproject/abi/src.ts/_version.ts' file: Error: ENOENT: no such file or directory, open '/home/user/lottery-frontend/lottery/node_modules/@ethersproject/abi/src.ts/_version.ts'
 @ ./node_modules/@ethersproject/abi/lib.esm/fragments.js 6:0-37 7:26-33
 @ ./node_modules/@ethersproject/abi/lib.esm/index.js 3:0-117 6:0-204 6:0-204 6:0-204 6:0-204 6:0-204 6:0-204
 @ ./node_modules/web3-eth-abi/lib/index.js 28:21-59 30:16-55
 @ ./node_modules/web3-eth/lib/index.js 47:10-33
 @ ./node_modules/web3/lib/index.js 34:10-29
 @ ./src/web3.js 3:0-24 4:17-21
 @ ./src/App.js 30:0-26 44:29-49 48:15-31 53:29-49 63:26-45 106:20-38
 @ ./src/index.js 7:0-24 11:33-36
...

22 warnings have detailed information that is not shown.
Use 'stats.errorDetails: true' resp. '--stats-error-details' to show it.

webpack 5.70.0 compiled with 22 warnings in 2515 ms

One last thing, for injecting the web3 object, I use Metamask.

I wonder what the problem is and how can I make my app renders on localhost:3000.

TylerH
  • 20,799
  • 66
  • 75
  • 101
0x55b1E06FF
  • 538
  • 1
  • 9
  • 24
  • it cra issue: https://github.com/facebook/create-react-app/pull/11752 try to set up a webpack – Yilmaz Mar 12 '22 at 23:34
  • @Yilmaz, it works adding ```... "scripts": { "start": "GENERATE_SOURCEMAP=false react-scripts start", },``` on package.json in order to rid of warning messages. But the application continues without rendering on http://localhost:3000/. I should see something like this: https://drive.google.com/file/d/1uLICxoruwaaSBQKdTBlSA_kbLVne6B43/view?usp=sharing – 0x55b1E06FF Mar 13 '22 at 00:22
  • can you check console. sometimes webpack does not show error, but console shows issue – Yilmaz Mar 13 '22 at 00:24
  • @Yilmaz, do you mean to this:https://drive.google.com/file/d/1j47Lb3d_xF8V1zM3s-impRiMTV_iraxI/view?usp=sharing, (sorry for showing an image for the console log, but I thought this was better to show like this on a comment) – 0x55b1E06FF Mar 13 '22 at 00:32
  • Nope, chrome developer tools. CTRL + SHIFT +C then click on console tab – Yilmaz Mar 13 '22 at 00:36
  • @Yilmaz, ok sure! https://drive.google.com/file/d/1gwyc0UuXLAm0RvOsBM81B43yC8jXVHfG/view?usp=sharing – 0x55b1E06FF Mar 13 '22 at 00:43
  • 1
    your webpack set up has issue. either check this for webpack https://stackoverflow.com/questions/70559396/webpack-breaking-change or this for cra https://stackoverflow.com/questions/70472965/web3-issue-react-application-not-compiling/70512623#70512623 – Yilmaz Mar 13 '22 at 00:44
  • @Yilmaz, thanks. This finally works! https://github.com/ChainSafe/web3.js#troubleshooting-and-known-issues – 0x55b1E06FF Mar 13 '22 at 01:40
  • great. good luck. – Yilmaz Mar 13 '22 at 01:46

0 Answers0