Skip to content

Instantly share code, notes, and snippets.

@adilanchian
Last active February 25, 2023 11:59
Show Gist options
  • Save adilanchian/93fbd2e06b3b5d3acb99b5723cebd925 to your computer and use it in GitHub Desktop.
Save adilanchian/93fbd2e06b3b5d3acb99b5723cebd925 to your computer and use it in GitHub Desktop.
Section 5: Update UI + deploy to an Ethereum testnet so anyone on the internet can wave at you using their
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);
wavePortalContract.on("NewWave", (from, timestamp, message) => {
console.log("NewWave", from, timestamp, message);
setAllWaves(prevState => [...prevState, {
address: from,
timestamp: new Date(timestamp * 1000),
message: message
}]);
});
} 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);
} 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
require('@nomiclabs/hardhat-waffle');
require('dotenv').config();
module.exports = {
solidity: '0.8.0',
networks: {
rinkeby: {
url: process.env.STAGING_ALCHEMY_KEY,
accounts: [process.env.PRIVATE_KEY],
},
mainnet: {
chainId: 1,
url: process.env.PROD_ALCHEMY_KEY,
accounts: [process.env.PRIVATE_KEY],
},
},
};
const main = async () => {
const waveContractFactory = await hre.ethers.getContractFactory('WavePortal');
const waveContract = await waveContractFactory.deploy({
value: hre.ethers.utils.parseEther('0.1'),
});
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('This is wave #1');
await waveTxn.wait();
let waveTxn = await waveContract.wave('This is wave #2');
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;
uint256 private seed;
event NewWave(address indexed from, uint256 timestamp, string message);
struct Wave {
address waver;
string message;
uint256 timestamp;
}
Wave[] waves;
mapping(address => uint256) public lastWavedAt;
constructor() payable {
console.log("We have been constructed!");
}
function wave(string memory _message) public {
require(
lastWavedAt[msg.sender] + 15 minutes < block.timestamp,
"Wait 15m"
);
lastWavedAt[msg.sender] = block.timestamp;
totalWaves += 1;
console.log("%s has waved!", msg.sender);
waves.push(Wave(msg.sender, _message, block.timestamp));
uint256 randomNumber = (block.difficulty + block.timestamp + seed) %
100;
console.log("Random # generated: %s", randomNumber);
seed = randomNumber;
if (randomNumber < 50) {
console.log("%s won!", msg.sender);
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.");
}
emit NewWave(msg.sender, block.timestamp, _message);
}
function getAllWaves() public view returns (Wave[] memory) {
return waves;
}
function getTotalWaves() public view returns (uint256) {
return totalWaves;
}
}
@saqib59
Copy link

saqib59 commented May 13, 2022

This version of the code is different from the one in the lessons.
i.e in App.jsx gaslimit is not applied here with the wave.

@eddsaura
Copy link

eddsaura commented May 23, 2022

This version of the code is different from the one in the lessons. i.e in App.jsx gaslimit is not applied here with the wave.

And also I don't see where the getAllWaves is being used.

@wesleymoliveira
Copy link

You can call "getAllWaves" after check if has an authorized account. After "setCurrentAccount(...". remember wrapping the "checkIfWalletIsConnected" fn into a callback to avoid looping

@Tushitverma99
Copy link

Error: call revert exception [ See: https://links.ethers.org/v5-errors-CALL_EXCEPTION ] (method="getTotalWaves()", data="0x", errorArgs=null, errorName=null, errorSignature=null, reason=null, code=CALL_EXCEPTION, version=abi/5.6.3)
at Logger.makeError (index.ts:261:1)
at Logger.throwError (index.ts:273:1)
at Interface.decodeFunctionResult (interface.ts:427:1)
at Contract. (index.ts:400:1)
at Generator.next ()
at fulfilled (index.ts:1:1)

@Tushitverma99
Copy link

Also the app doesn't looks like the one shown in the first lesson

@nzf210
Copy link

nzf210 commented Jun 12, 2022

hopefully it will be a start for better things

@lcy101u
Copy link

lcy101u commented Jun 13, 2022

So the getAllWaves is not used right?

@vanor89
Copy link

vanor89 commented Jul 3, 2022

Guys. you are supposed to figure out where to put getAllWaves() by yourselves, that's why its not in the gist.

@Bryanmankind
Copy link

Great project, I learnt a good deal of new things. Thanks buildspace for the knowledge.

@lucasbastianik
Copy link

Thanks buildspace.

That's awesome! ✨

@zklim
Copy link

zklim commented Dec 2, 2022

Thanks buildspace!
How amazing buildspace made someone with zero experience about developing like me built a blockchain interactive site.

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