블록체인
[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