Skip to content

Instantly share code, notes, and snippets.

@adilanchian
Last active March 6, 2023 09:37
Show Gist options
  • Star 20 You must be signed in to star a gist
  • Fork 9 You must be signed in to fork a gist
  • Save adilanchian/236fe9f3a56b73751060800cae3a780d to your computer and use it in GitHub Desktop.
Save adilanchian/236fe9f3a56b73751060800cae3a780d to your computer and use it in GitHub Desktop.
Section 4: Update WavePortal to randomly send lucky users waving at you some Ethereum
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;
}
}
@hayongbak
Copy link

Thank you @adilanchian for good job on this, I really enjoyed this.

Here are my suggestions to fix issues:

@CarlosSchell
Copy link

CarlosSchell commented Mar 6, 2022

For me worked with the following declaration (In "ethers": "^5.4.4") :

const provider = new ethers.providers.Web3Provider(window.ethereum)

@lcy101u
Copy link

lcy101u commented Jun 11, 2022

const { ethereum } = window;
What is this line means?

@thepadurean
Copy link

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.

@jamie-hurst
Copy link

Thanks for that explanation, thepadurean.

@zklim
Copy link

zklim commented Dec 1, 2022

What waveCleaned does?

        let wavesCleaned = [];
        waves.forEach(wave => {
          wavesCleaned.push({
            address: wave.waver,
            timestamp: new Date(wave.timestamp * 1000),
            message: wave.message
          });
        });

        setAllWaves(wavesCleaned);

@bigjoefilms
Copy link

yea that is true

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment