[TIL] Part4 - DAY59 Project - react+ethers

박동우·2023년 6월 19일

블록체인 스쿨 3기

목록 보기
55/72

[TIL] 2023-06-19 DAY59


Project

GIT 주소
https://github.com/dowoo303/SOLIDITY
https://github.com/dowoo303/hardhat


오늘 배운것들

  1. 복습
    1) hardhat
    2) react+ethers
  2. react+ethers
    1) 계정 or 네트워크 or 잔고가 변화할때마다 자동으로 업데이트 되도록 코딩해보기

각종 팁

  1. 메타마스크 document
    https://docs.metamask.io/wallet/reference/provider-api/#accountschanged

회고




💻 Solidity 코딩

✅ hardhat, react+ethers 복습

hardhat.config.js

require("@nomicfoundation/hardhat-toolbox");

/** @type import('hardhat/config').HardhatUserConfig */

const pvkey =
  "개인키";

module.exports = {
  solidity: "0.8.18",
  etherscan: {
    apiKey: "키",
  },
  networks: {
    goerli: {
      url: `https://goerli.infura.io/v3/키`,
      accounts: [pvkey],
    },
  },
};

npx hardhat verify --network goerli 컨트랙트주소 : verify하는 명령어 -> 생성자 있으면 컨트랙트 주소 뒤에 똑같이 넣어줘야함


✅ react+ethers

npx create-react-app 0619 : react 설치(0619 폴더 생성 후 0619에)

npm i web3

npm run start

npm install --save ethers : ethers 설치

계정 or 네트워크 or 잔고가 변화할때마다 자동으로 업데이트 되도록 코딩해보기


🟥 코드

import React from "react";
import { useEffect, useState } from "react";
import Web3 from "web3";
import { ethers } from "ethers";

function App() {
  const [blockNumber, setBlockNumber] = useState();
  const [balance, setBalance] = useState();
  const [account, setAccount] = useState();
  const [chainId, setChainId] = useState();

  const web3 = new Web3(
    "wss://goerli.infura.io/ws/v3/88cd1369d4b0478b9b44c031a628b0bf"
  );

  // 체인 아이디 가져오기
  async function getChainId() {
    if (window.ethereum) {
      const res = await window.ethereum.request({
        method: "eth_chainId",
      });
      setChainId(res);
    }
  }

  useEffect(() => {
    if (window.ethereum) {
      window.ethereum.on("chainChanged", chainChanged);
    }
  });

  const chainChanged = async () => {
    if (window.ethereum) {
      setAccount(null);
      setBalance(null);
      connect();
    }
  };

  // 계정이 변경될 때
  useEffect(() => {
    if (window.ethereum) {
      window.ethereum.on("accountsChanged", connect);
    }
  });

  // 들어온 사용자 메마에 연결하기
  const connect = async () => {
    if (window.ethereum) {
      try {
        const res = await window.ethereum.request({
          method: "eth_requestAccounts",
        });
        console.log(res);
        setAccount(res[0]);
        const _balance = await window.ethereum.request({
          method: "eth_getBalance",
          params: [res[0].toString(), "latest"],
        });

        //setBalance(Number(_balance)); // wei 단위로 표시
        setBalance(ethers.formatEther(_balance)); // -> 이더 단위로 표시
        getChainId();
      } catch (err) {
        console.error(err);
      }
    } else {
      console.log("Install Metamask");
    }
  };

  connect();

  // 페이지 들어가자마자 블록 업데이트 하기
  useEffect(() => {
    async function getBlock() {
      const blockNumber = await web3.eth.getBlockNumber();
      setBlockNumber(Number(blockNumber));
    }
    getBlock();
  });

  useEffect(() => {
    async function getBalance() {
      if (account) {
        const balance = await web3.eth.getBalance(account);
        setBalance(Number(balance));
      }
    }

    getBalance();

    async function subscribeBlock() {
      const subscription = await web3.eth.subscribe("newHeads");
      subscription.on("data", async (blockHead) => {
        console.log("New block header : ", blockHead);
        setBlockNumber(Number(blockHead.number));
      });
    }

    subscribeBlock();
  });

  return (
    <div>
      <div
        className="App"
        onClick={() => {
          connect();
        }}
      >
        CONNECT WALLET
      </div>
      <li>current Block Number : {blockNumber}</li>
      <li>current address : {account}</li>
      <li>current balance : {balance} eth</li>
      <li>current chainId : {chainId}</li>
    </div>
  );
}

export default App;


profile
HELLO!

0개의 댓글