본문 바로가기
  • 개발 / 공부 / 일상
BlockChain

(BlockChain) MetaMask와 Front(React) 연결

by JJeongHyun 2023. 3. 3.
반응형

일단 작업할 폴더에 React 환경을 설치해주자

 

설정이 완료되면 쓸 때 없는 기본 제공되는 효과들은 지워주자

 

그리곤 입력한 값에 따라 최초 0이었던 수가 사칙연산에 따라 변하도록 하는 solidity contract 코드를 작성하자

 

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;

contract InputCalc{
    int private result;

    constructor(){
        result = 0;
    }

    function getResult() public view returns (int){ 
        return result;
    }   
   function add(int _input) public {
    result += _input;
  }

  function minus(int _input) public {
    result -= _input;
  }
   function multiply(int _input) public {
    result *= _input;
  }

  function division(int _input) public {
    result /= _input;
  }
}

컴파일과 배포 명령어를 통해 해당 컨트랙트에 대한 JSON 파일이 생성되었다면

 

복사해서 React 환경에도 contracts 폴더를 생성하고 붙여 넣자

 

붙여넣기~!

다음은 커스텀 훅을 하나 만들자!!!

 

기존의 존재하는 훅(Hook)이 아닌 입맛대로 훅을 하나 생성해서 사용해 보자

 

그 훅에는 메타마스크가 설치되어 있지 않는다면 그냥 아무것도 종료 ( 실행되는 게 없다 )

 

있다면 web3 통신으로 메타마스크를 연결하고 연동되어 있는 계정들을 반환하는 Hook을 만들어 보도록 하자~!!!!!

 

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

const useWeb3 = ()=>{
    const [web3, setWeb3] = useState();
    const [account, setAccount] =useState();

    useEffect(()=>{
        (async () =>{
            if(window.ethereum) return;
            const [address] = await window.ethereum.request({
                method:"eth_requestAccounts",
            })
            setAccount(address);

            const _web3 = new Web3(window.ethereum);
            setWeb3(_web3);
        })()
    },[])
    return [web3,account];
    
}

export default useWeb3;

 

이렇게 커스텀 훅 까지 잘 만들었다면

 

아까 truffle compile 후 migration명령어로 ganache와 정상적으로 연결 후에 나온 CA와 contract의 abi로 새로운 Contract

 

를 생성하여 solidity 파일의 메서드들을 연결해보려고 한다

 

useEffect(() => {
    (async () => {
      if (deployed) return;
      const _deployed = new web3.eth.Contract(
        InputCalcContract.abi,
        "0xb02d46c5d6dbaeE6F47f855b4443C5adb1ECA5f8"
      );
      setDeployed(_deployed);

      const _result = await _deployed.methods.getResult().call();
      setResult(parseInt(_result));
    })();
  }, []);
  • 즉시실행함수를 선언하여서 정상적으로 배포하고 난 후의 CA를 그리고 Contract의 abi를 이용하여 solidity 내 get함수를 실행시켜 result값을 재정의 해준다

 

정상적으로 result값이 떴다면 사칙연산에 대한 각각의 함수를 만들어서 solidity내 생성된 메서드에 접근하는 선언 해보자

  const add = async (_input) => {
    const data = await deployed.methods.add(_input).send({ from: account });
    if (!data) return;
    const _result = await deployed.methods.getResult().call();
    setResult(_result);
  };
  const minus = async (_input) => {
    const data = await deployed.methods.minus(_input).send({ from: account });
    if (!data) return;
    const _result = await deployed.methods.getResult().call();
    setResult(_result);
  };
  const multiply = async (_input) => {
    const data = await deployed.methods
      .multiply(_input)
      .send({ from: account });
    if (!data) return;
    const _result = await deployed.methods.getResult().call();
    setResult(_result);
  };
  const division = async (_input) => {
    const data = await deployed.methods
      .division(_input)
      .send({ from: account });
    if (!data) return;
    const _result = await deployed.methods.getResult().call();
    setResult(_result);
  };

함수를 선언하고 호출할 HTML 객체들 또한 만들어 준다

 

<div>
      <input
        type="number"
        value={inputValue}
        placeholder={"연산할 수를 입력하세요"}
        onInput={(e) => {
          setInput(e.target.value);
        }}
      />
      <button
        onClick={() => {
          add(inputValue);
        }}
      >
        더하기
      </button>
      <button
        onClick={() => {
          minus(inputValue);
        }}
      >
        빼기
      </button>
      <button
        onClick={() => {
          multiply(inputValue);
        }}
      >
        곱하기
      </button>
      <button
        onClick={() => {
          division(inputValue);
        }}
      >
        나누기
      </button>
      <div>Result : {result}</div>
    </div>

 

이제 여기까지 정상적으로 오타 없이 잘 만들었다면

 

최상위 App.js에서 커스텀 훅과 컴포넌트를 하나로 합쳐 준다

 

import useWeb3 from "./Hooks/useWeb3";

import NumberCalc from "./components/NumberCalc";

function App() {
  const [web3, account] = useWeb3();

  if (!account) return <div>No MetaMask || disconnected Accounts</div>;
  return (
    <div>
      <div>Now Account : {account}</div>
      <NumberCalc web3={web3} account={account} />
    </div>
  );
}

export default App;

 

다음 시간에는 express 까지 연결하는 코드를 올려볼까 합니다 ~

 

항상 감사합니다 ~