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;
}
}
@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