Skip to content

Instantly share code, notes, and snippets.

@danicuki
Last active August 18, 2024 23:05
Show Gist options
  • Save danicuki/4fce48bc881766115370dbe2913b44fc to your computer and use it in GitHub Desktop.
Save danicuki/4fce48bc881766115370dbe2913b44fc to your computer and use it in GitHub Desktop.
Seção 4: Interface UI + deploy na testnet Ethereum e projeto completo
import React, { useEffect, useState } from "react";
import { ethers } from "ethers";
import './App.css';
import abi from "./utils/WavePortal.json"
export default function App() {
const [currentAccount, setCurrentAccount] = useState("");
const [allWaves, setAllWaves] = useState([]);
const contractAddress = "0xd289A2e424dE94E9dcfFE03Ae050961Df70a4474";
const contractABI = abi.abi;
const getAllWaves = async () => {
const { ethereum } = window;
try {
if (ethereum) {
const provider = new ethers.providers.Web3Provider(ethereum);
const signer = provider.getSigner();
const wavePortalContract = new ethers.Contract(contractAddress, contractABI, signer);
const waves = await wavePortalContract.getAllWaves();
const wavesCleaned = waves.map(wave => {
return {
address: wave.waver,
timestamp: new Date(wave.timestamp * 1000),
message: wave.message,
};
});
setAllWaves(wavesCleaned);
} else {
console.log("Objeto Ethereum inexistente!");
}
} catch (error) {
console.log(error);
}
};
/**
* Escuta por eventos emitidos!
*/
useEffect(() => {
let wavePortalContract;
const onNewWave = (from, timestamp, message) => {
console.log("NewWave", from, timestamp, message);
setAllWaves(prevState => [
...prevState,
{
address: from,
timestamp: new Date(timestamp * 1000),
message: message,
},
]);
};
if (window.ethereum) {
const provider = new ethers.providers.Web3Provider(window.ethereum);
const signer = provider.getSigner();
wavePortalContract = new ethers.Contract(contractAddress, contractABI, signer);
wavePortalContract.on("NewWave", onNewWave);
}
return () => {
if (wavePortalContract) {
wavePortalContract.off("NewWave", onNewWave);
}
};
}, []);
const checkIfWalletIsConnected = async () => {
try {
const { ethereum } = window;
if (!ethereum) {
console.log("Garanta que possua a Metamask instalada!");
return;
} else {
console.log("Temos o objeto ethereum", ethereum);
}
const accounts = await ethereum.request({ method: "eth_accounts" });
if (accounts.length !== 0) {
const account = accounts[0];
console.log("Encontrada a conta autorizada:", account);
setCurrentAccount(account)
getAllWaves();
} else {
console.log("Nenhuma conta autorizada foi encontrada")
}
} catch (error) {
console.log(error);
}
}
/**
* Implemente aqui o seu método connectWallet
*/
const connectWallet = async () => {
try {
const { ethereum } = window;
if (!ethereum) {
alert("MetaMask encontrada!");
return;
}
const accounts = await ethereum.request({ method: "eth_requestAccounts" });
console.log("Conectado", 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, contractABI, signer);
let count = await wavePortalContract.getTotalWaves();
console.log("Recuperado o número de tchauzinhos...", count.toNumber());
/*
* Executar o aceno a partir do contrato inteligente
*/
const waveTxn = await wavePortalContract.wave("esta é uma mensagem");
console.log("Minerando...", waveTxn.hash);
await waveTxn.wait();
console.log("Minerado -- ", waveTxn.hash);
count = await wavePortalContract.getTotalWaves();
console.log("Total de tchauzinhos recuperado...", count.toNumber());
} else {
console.log("Objeto Ethereum não encontrado!");
}
} catch (error) {
console.log(error)
}
}
useEffect(() => {
checkIfWalletIsConnected();
}, [])
return (
<div className="mainContainer">
<div className="dataContainer">
<div className="header">
👋 Olá Pessoal!
</div>
<div className="bio">
Eu sou o danicuki e já trabalhei com música, sabia? Legal, né? Conecte sua carteira Ethereum wallet e me manda um tchauzinho!
</div>
<button className="waveButton" onClick={wave}>
Mandar Tchauzinho 🌟
</button>
{/*
* Se não existir currentAccount, apresente este botão
*/}
{!currentAccount && (
<button className="waveButton" onClick={connectWallet}>
Conectar carteira
</button>
)}
{allWaves.map((wave, index) => {
return (
<div key={index} style={{ backgroundColor: "OldLace", marginTop: "16px", padding: "8px" }}>
<div>Endereço: {wave.address}</div>
<div>Data/Horário: {wave.timestamp.toString()}</div>
<div>Mensagem: {wave.message}</div>
</div>)
})}
</div>
</div>
);
}
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("Endereço do WavePortal: ", waveContract.address);
};
const runMain = async () => {
try {
await main();
process.exit(0);
} catch (error) {
console.error(error);
process.exit(1);
}
};
runMain();
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("Endereço do contrato:", waveContract.address);
let contractBalance = await hre.ethers.provider.getBalance(
waveContract.address
);
console.log(
"Saldo do contrato:",
hre.ethers.utils.formatEther(contractBalance)
);
/*
* Vamos tentar acenar 2 vezes agora
*/
const waveTxn = await waveContract.wave("tchauzinho #1");
await waveTxn.wait();
const waveTxn2 = await waveContract.wave("tchauzinho #2");
await waveTxn2.wait();
contractBalance = await hre.ethers.provider.getBalance(waveContract.address);
console.log(
"Saldo do contrato:",
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;
/*
* Este é um endereço => uint mapping, o que significa que eu posso associar o endereço com um número!
* Neste caso, armazenarei o endereço com o últimoo horário que o usuário tchauzinhou.
*/
mapping(address => uint256) public lastWavedAt;
constructor() payable {
console.log("Contrato construido!");
/*
* Define a semente inicial
*/
seed = (block.timestamp + block.difficulty) % 100;
}
function wave(string memory _message) public {
/*
* Precisamos garantir que o valor corrente de timestamp é ao menos 15 minutos maior que o último timestamp armazenado
*/
require(
lastWavedAt[msg.sender] + 15 minutes < block.timestamp,
"Espere 15m"
);
/*
* Atualiza o timestamp atual do usuário
*/
lastWavedAt[msg.sender] = block.timestamp;
totalWaves += 1;
console.log("%s tchauzinhou!", msg.sender);
waves.push(Wave(msg.sender, _message, block.timestamp));
/*
* Gera uma nova semente para o próximo usuário que acenar
*/
seed = (block.difficulty + block.timestamp + seed) % 100;
if (seed <= 50) {
console.log("%s venceu!", msg.sender);
uint256 prizeAmount = 0.0001 ether;
require(
prizeAmount <= address(this).balance,
"Tentando sacar mais dinheiro que o contrato possui."
);
(bool success, ) = (msg.sender).call{value: prizeAmount}("");
require(success, "Falhou em sacar dinheiro do contrato.");
}
emit NewWave(msg.sender, block.timestamp, _message);
}
function getAllWaves() public view returns (Wave[] memory) {
return waves;
}
function getTotalWaves() public view returns (uint256) {
return totalWaves;
}
}
@clacerda
Copy link

Animal!!! Adorei esse bootcamp, valeu mesmo pessoal!

@leonardotkimura
Copy link

Foi excelente!!

@marcusvinicius178
Copy link

Muito bacana!

@tahlly
Copy link

tahlly commented Apr 17, 2024

Muito bom!! Adorei esse bootcamp!

@flpmtts
Copy link

flpmtts commented Aug 18, 2024

muito bom!! valeu galera!

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