Last active
August 18, 2024 23:05
-
-
Save danicuki/4fce48bc881766115370dbe2913b44fc to your computer and use it in GitHub Desktop.
Seção 4: Interface UI + deploy na testnet Ethereum e projeto completo
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> | |
); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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], | |
}, | |
}, | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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; | |
} | |
} |
Foi excelente!!
Muito bacana!
Muito bom!! Adorei esse bootcamp!
muito bom!! valeu galera!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Animal!!! Adorei esse bootcamp, valeu mesmo pessoal!