-
-
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();
inconnectWallet
function -
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