블록체인

[ethereum] web3와 ethers를 이용하여 메타마스크로 트랜잭션 발생하기

멍개. 2022. 8. 28. 08:18

web3와 ethers으로 메타마스크를 이용하여 트랜잭션을 발생하는 방법을 알아보겠습니다.

확장프로그램 메타마스크가 설치되어 있다면 메타마스크 프로바이더가 window 객체에 ethereum으로 포함되어 있습니다. 근데 vanilaJS로는 window.ethereum 포함된것을 가지고 오기가 좀 까다로우므로 react에서 발생시켜보겠습니다.

window.web3.currentProvider(레거시) 또는 window.ethereum(현재버전)으로 가져오면 됩니다.

● ethers

provider에 메타마스크 프로바이더를 넣어줍니다.

window?.web3?.currentProvider

window.ethereum

import { providers, Wallet, utils, Contract } from "ethers";

function App() {
  
  const clickHandler = async () => {
    const provider = new providers.Web3Provider(
      window.ethereum || 'http://localhost:8545'
    );
    const signer = provider.getSigner(); // 메타마스크에 선택된 지갑으로 트랜잭션 서명을 함
    console.log(signer)
    
    const txHash = await signer.sendTransaction({
      from: signer.address,
      to: '0xAd46355359aE32263EaFE152a408D9D620844eda',
      value: utils.parseUnits('0.1', 'ether').toHexString()
    })

    console.log(txHash)
  }
  return (
    <div className="App">
      <button onClick={clickHandler}>
        클릭
      </button>
    </div>
  );
}

export default App;

· 메타마스크 로그인이 정상적으로 되었을 때

버튼을 누르면 메타마스크로 트랜잭션 발생을 시키기 위해 팝업을 띄웁니다.

· 메타마스크 로그인이 되어있지 않을 때

메타마스크에서 정상적으로 로그인이 되어있지 않았다면 다음과 같이 에러가 발생합니다.

index.ts:261 Uncaught (in promise) Error: unknown account #0 (operation="getAddress", code=UNSUPPORTED_OPERATION, version=providers/5.6.8)
    at Logger.makeError (index.ts:261:1)
    at Logger.throwError (index.ts:273:1)
    at json-rpc-provider.ts:204:1
    at async Promise.all (:3000/index 1)

· 트랜잭션 승인창에서 확인이 아니라 거부를 눌렀을 때

code가 4001인 오브젝트를 exception으로 발생합니다.

{
    "code": 4001,
    "message": "MetaMask Tx Signature: User denied transaction signature."
}
{
    "code": 4001,
    "message": "MetaMask Tx Signature: User denied transaction signature.",
    "stack": "{\n  \"code\": 4001,\n  \"message\": \"MetaMask Tx Signature: User denied transaction signature.\",\n  \"stack\": \"Error: MetaMask Tx Signature: User denied transaction signature.\\n    at new i (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-2.js:1:308657)\\n    at new o.EthereumProviderError (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-2.js:1:309172)\\n    at c (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-2.js:1:311507)\\n    at Object.userRejectedRequest (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-2.js:1:312738)\\n    at y.<anonymous> (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/background-4.js:1:30538)\\n    at Object.l (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-3.js:10:9069)\\n    at u (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-7.js:3:1144)\\n    at a.emit (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-7.js:3:1680)\\n    at y._setTransactionStatus (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/background-4.js:1:76051)\\n    at y.setTxStatusRejected (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/background-4.js:1:74238)\\n    at z.cancelTransaction (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/background-4.js:1:46625)\\n    at s.<anonymous> (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/background-4.js:22:11434)\\n    at l (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-1.js:20:210820)\\n    at s.emit (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-1.js:20:213815)\\n    at w (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-7.js:1:41385)\\n    at v (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-7.js:1:41200)\\n    at b.push (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-7.js:1:42014)\\n    at t.exports._write (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-6.js:8:435312)\\n    at b (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-7.js:1:54430)\\n    at chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-7.js:1:57614\\n    at y.write (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-7.js:1:57641)\\n    at e.exports.m (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-7.js:1:46585)\\n    at l (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-1.js:20:210820)\\n    at s.emit (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-1.js:20:213815)\\n    at w (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-7.js:1:41385)\\n    at v (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-7.js:1:41200)\\n    at b.push (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-7.js:1:42014)\\n    at e.exports._onMessage (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-3.js:10:14413)\\n    at chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-3.js:10:14260\"\n}\n  at new i (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-2.js:1:308657)\n  at new o.EthereumProviderError (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-2.js:1:309172)\n  at c (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-2.js:1:311507)\n  at Object.userRejectedRequest (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-2.js:1:312738)\n  at y.<anonymous> (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/background-4.js:1:30538)\n  at Object.l (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-3.js:10:9069)\n  at u (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-7.js:3:1144)\n  at a.emit (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-7.js:3:1680)\n  at y._setTransactionStatus (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/background-4.js:1:76051)\n  at y.setTxStatusRejected (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/background-4.js:1:74238)\n  at z.cancelTransaction (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/background-4.js:1:46625)\n  at s.<anonymous> (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/background-4.js:22:11434)\n  at l (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-1.js:20:210820)\n  at s.emit (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-1.js:20:213815)\n  at w (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-7.js:1:41385)\n  at v (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-7.js:1:41200)\n  at b.push (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-7.js:1:42014)\n  at t.exports._write (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-6.js:8:435312)\n  at b (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-7.js:1:54430)\n  at chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-7.js:1:57614\n  at y.write (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-7.js:1:57641)\n  at e.exports.m (chrome-extension://nkbihfbeogaeaoehlefnkodbef

 

● web3js

리엑트 최신 버전에서는 web3가 정상적으로 임포트되지 않습니다.

provider에 메타마스크 프로바이더를 넣어줍니다.

window?.web3?.currentProvider

window.ethereum

import Web3 from 'web3';

function App() {

  const clickHandler = async () => {

    const web3 = new Web3(
      window.ethereum || 'http://localhost:8545'
    );
    const accounts = await web3.eth.requestAccounts(); // 메타마스크에 선택된 지갑으로 트랜잭션 서명을 함 
    console.log(accounts);

    const tx = await web3.eth.sendTransaction({
      from: accounts[0],
      to: '0xAd46355359aE32263EaFE152a408D9D620844eda',
      value: web3.utils.toWei('0.1', 'ether'),
      data: ''
    })
    console.log(tx)
  }

  return (
    <div className="App">
      <button onClick={clickHandler}>클릭</button>
    </div>
  );
}

export default App;

· 메타마스크 로그인이 정상적으로 되었을 때

· 메타마스크 로그인이 되어있지 않을 때

web3의 경우는 메타마스크 로그인창을 띄웁니다.

여기서 로그인을 하게되면 다음과 같이 트랜잭션 확인창을 띄워줍니다.

· 트랜잭션 승인창에서 확인이 아니라 거부를 눌렀을 때

code가 4001인 오브젝트를 exception으로 발생합니다.

{
    "code": 4001,
    "message": "MetaMask Tx Signature: User denied transaction signature."
}
{
    "code": 4001,
    "message": "MetaMask Tx Signature: User denied transaction signature.",
    "stack": "{\n  \"code\": 4001,\n  \"message\": \"MetaMask Tx Signature: User denied transaction signature.\",\n  \"stack\": \"Error: MetaMask Tx Signature: User denied transaction signature.\\n    at new i (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-2.js:1:308657)\\n    at new o.EthereumProviderError (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-2.js:1:309172)\\n    at c (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-2.js:1:311507)\\n    at Object.userRejectedRequest (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-2.js:1:312738)\\n    at y.<anonymous> (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/background-4.js:1:30538)\\n    at Object.l (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-3.js:10:9069)\\n    at u (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-7.js:3:1144)\\n    at a.emit (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-7.js:3:1680)\\n    at y._setTransactionStatus (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/background-4.js:1:76051)\\n    at y.setTxStatusRejected (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/background-4.js:1:74238)\\n    at z.cancelTransaction (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/background-4.js:1:46625)\\n    at s.<anonymous> (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/background-4.js:22:11434)\\n    at l (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-1.js:20:210820)\\n    at s.emit (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-1.js:20:213815)\\n    at w (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-7.js:1:41385)\\n    at v (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-7.js:1:41200)\\n    at b.push (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-7.js:1:42014)\\n    at t.exports._write (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-6.js:8:435312)\\n    at b (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-7.js:1:54430)\\n    at chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-7.js:1:57614\\n    at y.write (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-7.js:1:57641)\\n    at e.exports.m (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-7.js:1:46585)\\n    at l (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-1.js:20:210820)\\n    at s.emit (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-1.js:20:213815)\\n    at w (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-7.js:1:41385)\\n    at v (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-7.js:1:41200)\\n    at b.push (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-7.js:1:42014)\\n    at e.exports._onMessage (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-3.js:10:14413)\\n    at chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-3.js:10:14260\"\n}\n  at new i (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-2.js:1:308657)\n  at new o.EthereumProviderError (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-2.js:1:309172)\n  at c (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-2.js:1:311507)\n  at Object.userRejectedRequest (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-2.js:1:312738)\n  at y.<anonymous> (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/background-4.js:1:30538)\n  at Object.l (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-3.js:10:9069)\n  at u (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-7.js:3:1144)\n  at a.emit (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-7.js:3:1680)\n  at y._setTransactionStatus (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/background-4.js:1:76051)\n  at y.setTxStatusRejected (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/background-4.js:1:74238)\n  at z.cancelTransaction (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/background-4.js:1:46625)\n  at s.<anonymous> (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/background-4.js:22:11434)\n  at l (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-1.js:20:210820)\n  at s.emit (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-1.js:20:213815)\n  at w (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-7.js:1:41385)\n  at v (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-7.js:1:41200)\n  at b.push (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-7.js:1:42014)\n  at t.exports._write (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-6.js:8:435312)\n  at b (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-7.js:1:54430)\n  at chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-7.js:1:57614\n  at y.write (chrome-extension://nkbihfbeogaeaoehlefnkodbefgpgknn/common-7.js:1:57641)\n  at e.exports.m (chrome-extension://nkbihfbeogaeaoehlefnkodbef