Photo by olieman.eth on Unsplash
The Most Expensive Counter APP for Babies [2/2]
using ethers.js, react.js
Prerequisites
- Basics of React โ๏ธ
- Metamask
Create new react project counter-dapp
npx create-react-app counter-dapp
Edit App.js & App.css
Just copy paste,these are basic stuff ๐
App.js
import './App.css'
import { useState } from "react";
function App() {
const [count, setCount] = useState(0);
const increment = () => {
setCount((prevCount) => prevCount + 1);
};
const decrement = () => {
setCount((prevCount) => prevCount - 1);
};
return (
<div className="App">
<button onClick={increment}>Increment</button>
<div>{count}</div>
<button onClick={decrement}>Decrement</button>
</div>
);
}
export default App;
App.css ( Or google how to center a div ๐)
.App {
width: 100vw;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
Run locally and test things out
npm run start
IT WORKS ๐
App -> DAPP ๐
Start off by connecting Metamask
// import useEffect on top first
import { useState, useEffect } from "react";
useEffect(() => {
if (typeof window.ethereum == "undefined") {
alert("You don't have a wallet");
} else {
requestAccount();
}
}, []);
const requestAccount = async () => {
await window.ethereum.request({
method: "eth_requestAccounts",
});
};
Lemme Explain
- MetaMask injects a global API into websites visited by its users at window. ethereum.
- This API allows websites to request user's Ethereum accounts, read data from blockchains the user is connected to, and suggest that the user sign messages and transactions.
- eth_requestAccounts returns a Promise that resolves to an array of a single Ethereum address string
Go to page and try refreshing
Get the count from blockchain ๐
- add
const.js
from previous part to src folder - install ethers
npm i ethers
- import these stuff on top of
App.js
import { ABI, ADDRESS } from "./const"; import { ethers } from "ethers";
- add a new function
getCount()
const getCount = async () => { const provider = new ethers.providers.Web3Provider(window.ethereum); const CounterContract = new ethers.Contract(ADDRESS, ABI, provider); try { const data = await CounterContract.count(); setCount(data.toString()); } catch (err) { console.log("Error:", err); } };
What is Provider??
- provider is abstraction of a connection to the Ethereum network
- We use provider for read only functions,Like getting count(remember blue button on Remix)
What is Contract??
- Contract is an abstraction of code that has been deployed to the blockchain.
- User to interact with deployed contract
- Update
useEffect
useEffect(() => {
if (typeof window.ethereum == "undefined") {
alert("You dont have a wallet");
} else {
requestAccount();
getCount();
}
}, []);
getCount()
now gets called on page loading
Updating increment() and decrement()
const increment = async () => {
const provider = new ethers.providers.Web3Provider(window.ethereum);
const signer = provider.getSigner();
const CounterContract = new ethers.Contract(ADDRESS, ABI, signer);
const txn = await CounterContract.increment();
setCount("๐๐๐");
await txn.wait();
getCount();
};
const decrement = async () => {
const provider = new ethers.providers.Web3Provider(window.ethereum);
const signer = provider.getSigner();
const CounterContract = new ethers.Contract(ADDRESS, ABI, signer);
const txn = await CounterContract.decrement();
setCount("๐๐๐");
await txn.wait();
getCount();
};
What is Signer??
- Signer is an abstraction of an Ethereum Account, which can be used to sign messages and transactions and send signed transactions to the Ethereum Network to execute state changing operations.
- Since increment and decrement function changes state variable count,we need to sign the transaction (remember orange button on Remix)
Lets see the action
The final code looks something like
import "./App.css";
import { useState, useEffect } from "react";
import { ABI, ADDRESS } from "./const";
import { ethers } from "ethers";
function App() {
const [count, setCount] = useState(0);
useEffect(() => {
if (typeof window.ethereum == "undefined") {
alert("You dont have a wallet");
} else {
requestAccount();
getCount();
}
}, []);
const requestAccount = async () => {
await window.ethereum.request({
method: "eth_requestAccounts",
});
};
const getCount = async () => {
const provider = new ethers.providers.Web3Provider(window.ethereum);
const CounterContract = new ethers.Contract(ADDRESS, ABI, provider);
try {
const data = await CounterContract.count();
setCount(data.toString());
} catch (err) {
console.log("Error:", err);
}
};
const increment = async () => {
const provider = new ethers.providers.Web3Provider(window.ethereum);
const signer = provider.getSigner();
const CounterContract = new ethers.Contract(ADDRESS, ABI, signer);
const txn = await CounterContract.increment();
setCount("๐๐๐");
await txn.wait();
getCount();
};
const decrement = async () => {
const provider = new ethers.providers.Web3Provider(window.ethereum);
const signer = provider.getSigner();
const CounterContract = new ethers.Contract(ADDRESS, ABI, signer);
const txn = await CounterContract.decrement();
setCount("๐๐๐");
await txn.wait();
getCount();
};
return (
<div className="App">
<button onClick={increment}>Increment</button>
<div>{count}</div>
<button onClick={decrement}>Decrement</button>
</div>
);
}
export default App;
Woohoo ๐๐ it's finished
You can see the source code here:
If you want to waste some Rinkeby Ether,Come In
Live Link: https://sharathkrml.github.io/counter-dapp/
ย