-
-
Save adilanchian/236fe9f3a56b73751060800cae3a780d to your computer and use it in GitHub Desktop.
| import React, { useEffect, useState } from "react"; | |
| import { ethers } from "ethers"; | |
| import './App.css'; | |
| import wavePortal from './utils/WavePortal.json'; | |
| const App = () => { | |
| const [currentAccount, setCurrentAccount] = useState(""); | |
| const [allWaves, setAllWaves] = useState([]); | |
| const contractAddress = "0xd5f08a0ae197482FA808cE84E00E97d940dBD26E"; | |
| const getAllWaves = async () => { | |
| try { | |
| if (window.ethereum) { | |
| const provider = new ethers.providers.Web3Provider | |
| const signer = provider.getSigner(); | |
| const wavePortalContract = new ethers.Contract(contractAddress, wavePortal.abi, signer); | |
| const waves = await wavePortalContract.getAllWaves(); | |
| let wavesCleaned = []; | |
| waves.forEach(wave => { | |
| wavesCleaned.push({ | |
| address: wave.waver, | |
| timestamp: new Date(wave.timestamp * 1000), | |
| message: wave.message | |
| }); | |
| }); | |
| setAllWaves(wavesCleaned); | |
| } else { | |
| console.log("Ethereum object doesn't exist!") | |
| } | |
| } catch (error) { | |
| console.log(error); | |
| } | |
| } | |
| const checkIfWalletIsConnected = async () => { | |
| try { | |
| const { ethereum } = window; | |
| if (!ethereum) { | |
| console.log("Make sure you have metamask!"); | |
| return; | |
| } else { | |
| console.log("We have the ethereum object", ethereum); | |
| } | |
| const accounts = await ethereum.request({ method: 'eth_accounts' }); | |
| if (accounts.length !== 0) { | |
| const account = accounts[0]; | |
| console.log("Found an authorized account:", account); | |
| setCurrentAccount(account) | |
| } else { | |
| console.log("No authorized account found") | |
| } | |
| } catch (error) { | |
| console.log(error); | |
| } | |
| } | |
| const connectWallet = async () => { | |
| try { | |
| const { ethereum } = window; | |
| if (!ethereum) { | |
| alert("Get MetaMask!"); | |
| return; | |
| } | |
| const accounts = await ethereum.request({ method: "eth_requestAccounts" }); | |
| console.log("Connected", accounts[0]); | |
| setCurrentAccount(accounts[0]); | |
| } catch (error) { | |
| console.log(error) | |
| } | |
| } | |
| const wave = async () => { | |
| try { | |
| const { ethereum } = window; | |
| if (ethereum) { | |
| const provider = new ethers.providers.Web3Provider(ethereum); | |
| const signer = provider.getSigner(); | |
| const wavePortalContract = new ethers.Contract(contractAddress, wavePortal.abi, signer); | |
| let count = await wavePortalContract.getTotalWaves(); | |
| console.log("Retrieved total wave count...", count.toNumber()); | |
| const waveTxn = await wavePortalContract.wave(); | |
| console.log("Mining...", waveTxn.hash); | |
| await waveTxn.wait(); | |
| console.log("Mined -- ", waveTxn.hash); | |
| count = await wavePortalContract.getTotalWaves(); | |
| console.log("Retrieved total wave count...", count.toNumber()); | |
| } else { | |
| console.log("Ethereum object doesn't exist!"); | |
| } | |
| } catch (error) { | |
| console.log(error) | |
| } | |
| } | |
| useEffect(() => { | |
| checkIfWalletIsConnected(); | |
| }, []) | |
| return ( | |
| <div className="mainContainer"> | |
| <div className="dataContainer"> | |
| <div className="header"> | |
| 👋 Hey there! | |
| </div> | |
| <div className="bio"> | |
| I am farza and I worked on self-driving cars so that's pretty cool right? Connect your Ethereum wallet and wave at me! | |
| </div> | |
| <button className="waveButton" onClick={wave}> | |
| Wave at Me | |
| </button> | |
| {!currentAccount && ( | |
| <button className="waveButton" onClick={connectWallet}> | |
| Connect Wallet | |
| </button> | |
| )} | |
| {allWaves.map((wave, index) => { | |
| return ( | |
| <div style={{ backgroundColor: "OldLace", marginTop: "16px", padding: "8px" }}> | |
| <div>Address: {wave.address}</div> | |
| <div>Time: {wave.timestamp.toString()}</div> | |
| <div>Message: {wave.message}</div> | |
| </div>) | |
| })} | |
| </div> | |
| </div> | |
| ); | |
| } | |
| export default App |
| const main = async () => { | |
| const waveContractFactory = await hre.ethers.getContractFactory('WavePortal'); | |
| const waveContract = await waveContractFactory.deploy({ | |
| value: hre.ethers.utils.parseEther('0.001'), | |
| }); | |
| await waveContract.deployed(); | |
| console.log('WavePortal address: ', waveContract.address); | |
| }; | |
| const runMain = async () => { | |
| try { | |
| await main(); | |
| process.exit(0); | |
| } catch (error) { | |
| console.error(error); | |
| process.exit(1); | |
| } | |
| }; | |
| runMain(); |
| const main = async () => { | |
| const waveContractFactory = await hre.ethers.getContractFactory('WavePortal'); | |
| const waveContract = await waveContractFactory.deploy({ | |
| value: hre.ethers.utils.parseEther('0.01'), | |
| }); | |
| await waveContract.deployed(); | |
| console.log('Contract addy:', waveContract.address); | |
| let contractBalance = await hre.ethers.provider.getBalance( | |
| waveContract.address | |
| ); | |
| console.log( | |
| 'Contract balance:', | |
| hre.ethers.utils.formatEther(contractBalance) | |
| ); | |
| let waveTxn = await waveContract.wave('A message!'); | |
| await waveTxn.wait(); | |
| contractBalance = await hre.ethers.provider.getBalance(waveContract.addresss); | |
| console.log( | |
| 'Contract balance:', | |
| hre.ethers.utils.formatEther(contractBalance) | |
| ); | |
| let allWaves = await waveContract.getAllWaves(); | |
| console.log(allWaves); | |
| }; | |
| const runMain = async () => { | |
| try { | |
| await main(); | |
| process.exit(0); | |
| } catch (error) { | |
| console.log(error); | |
| process.exit(1); | |
| } | |
| }; | |
| runMain(); |
| // SPDX-License-Identifier: UNLICENSED | |
| pragma solidity ^0.8.0; | |
| import "hardhat/console.sol"; | |
| contract WavePortal { | |
| uint256 totalWaves; | |
| event NewWave(address indexed from, uint256 timestamp, string message); | |
| struct Wave { | |
| address waver; | |
| string message; | |
| uint256 timestamp; | |
| } | |
| Wave[] waves; | |
| constructor() payable { | |
| console.log("We have been constructed!"); | |
| } | |
| function wave(string memory _message) public { | |
| totalWaves += 1; | |
| console.log("%s has waved!", msg.sender); | |
| waves.push(Wave(msg.sender, _message, block.timestamp)); | |
| emit NewWave(msg.sender, block.timestamp, _message); | |
| uint256 prizeAmount = 0.0001 ether; | |
| require( | |
| prizeAmount <= address(this).balance, | |
| "Trying to withdraw more money than they contract has." | |
| ); | |
| (bool success, ) = (msg.sender).call{value: prizeAmount}(""); | |
| require(success, "Failed to withdraw money from contract."); | |
| } | |
| function getAllWaves() public view returns (Wave[] memory) { | |
| return waves; | |
| } | |
| function getTotalWaves() public view returns (uint256) { | |
| return totalWaves; | |
| } | |
| } |
Thank you @adilanchian for good job on this, I really enjoyed this.
Here are my suggestions to fix issues:
-
provider initialization issue
https://gist.github.com/adilanchian/236fe9f3a56b73751060800cae3a780d#file-app-js-L14
const provider = new ethers.providers.Web3Provider(ethereum); -
Load messages on wallet connect
https://gist.github.com/adilanchian/236fe9f3a56b73751060800cae3a780d#file-app-js-L76-L77
InsertgetAllWaves();inconnectWalletfunction -
Add key in message list
https://gist.github.com/adilanchian/236fe9f3a56b73751060800cae3a780d#file-app-js-L137
<div style={{ backgroundColor: "OldLace", marginTop: "16px", padding: "8px" }} key={index}>
For me worked with the following declaration (In "ethers": "^5.4.4") :
const provider = new ethers.providers.Web3Provider(window.ethereum)
const { ethereum } = window;
What is this line means?
const { ethereum } = window; What is this line means?
https://stackoverflow.com/questions/41058569/what-is-the-difference-between-const-and-const-in-javascript - Read this, it is essentially a way of importing a named variable from a module in a shorthand way, in this particular case it imports the ethereum object that was injected by Metamask in the window context.
Thanks for that explanation, thepadurean.
What waveCleaned does?
let wavesCleaned = [];
waves.forEach(wave => {
wavesCleaned.push({
address: wave.waver,
timestamp: new Date(wave.timestamp * 1000),
message: wave.message
});
});
setAllWaves(wavesCleaned);
yea that is true
See updates!
https://gist.github.com/letsgitcracking/ddb27442486dfcc1152e836ad103317f/revisions