* 메타마스크가 브라우저에 설치되어 있는 상태에서 작업 *
window.ethereum
$ npx create-react-app front
제네시스 블럭이 같아도 chainID가 다르면 다른 네트워크로 넘어간다.
제네시스 블럭과 chainID값이 같아야 온전히 같은 블록임.
이더리움 네트워크 상에서 고유한 식별자 역할을 함
chainId는 5글자 안 숫자로.
$ $ npm install -g ganache-cli
$ ganache-cli --chainId 7722
//useWeb3.js
import { useEffect, useState } from "react";
const useWeb3 = () => {
useEffect(()=>{
console.log(window.ethereum)
})
return null
};
export default useWeb3;
import { useEffect, useState } from "react";
const useWeb3 = () => {
const [account,setAccount] = useState(null)
useEffect(() => {
console.log(window.ethereum)
// null이 아니면 메타마스크가 설치된 사람
if(window.ethereum) {
}
});
return [account]
};
export default useWeb3;
프런트에서 메타마스크에 있는 정보를 가져옴.
메타마스크에 연결되어있는 네트워크 정보 -> 0x3
import { useEffect, useState } from "react";
const useWeb3 = () => {
const [account,setAccount] = useState(null)
useEffect(() => {
console.log(window.ethereum)
// null이 아니면 메타마스크가 설치된 사람
// http에서 받는거라 promise로 반환됨 -> axios를 사용하고있으니까
if(window.ethereum) {
window.ethereum.request({
method:'eth_chainId',
})
.then(data =>{
console.log(data)
})
}
});
return [account]
};
export default useWeb3;
account 정보 가져오기
window.ethereum.request({
method:'eth_requestAccounts'
})
.then(data=>{
console.log(data)
})
import { useEffect, useState } from "react";
const useWeb3 = () => {
const [account, setAccount] = useState(null);
// http에서 받는거라 promise로 반환됨 -> axios를 사용하고있으니까
const getChainId = async () => {
const chainId = await window.ethereum.request({
method: "eth_chainId",
});
return chainId;
};
const getRequestAccounts = async () => {
const account = await window.ethereum.request({
method: "eth_requestAccounts",
});
return account
};
useEffect(() => {
const init = async () => {
try {
const chainId = await getChainId();
const account = await getRequestAccounts();
setAccount(account)
} catch (e) {
console.error(e.message);
}
};
if (window.ethereum) {
init();
}
}, []);
return [account]
};
export default useWeb3;
import useWeb3 from "./hooks/useWeb3";
import {useEffect, useState} from "react"
function App() {
const [account] = useWeb3()
const [isLogin, setIsLogin] = useState(false)
useEffect(()=>{
if(account) setIsLogin(true)
},[account])
if(!isLogin) return <div>메타마스크 로그인 후 사용해주세요</div>
return <div className="App">Hello React</div>;
}
export default App;
web3 설치시 생기는 오류 해결법
1. 다른 라이브러리를 설치하는 방법
import Web3 from 'web3/dist/web3.min.js'
// web3 -> nodeJSd에서 사용하는 라이브러리라서 번들링안됨 -> 에러뜸
// 해결방법 : web3/dist/web3.min.js
2. 웹팩을 건드리는 방법
// 방법 1
ejest
// 방법 2
override : 일반적인 방법
// override를 사용하는 여러 방법 중에 하나
$ npm install react-app-rewired
// package.json -> start
// reat-script -> react-app-rewired start로 바꿔주기
// override 먼저 읽고, 파일을 읽고, 파일 위에 덮어씌무면서 실행됨
$ npm install customize-cra
$ npm install http-browserify
// config.overrides.js 생성
```javascript
const {override} = require('customize-cra')
module.exports = override(config => {
config.resolve={
fallback:{
...config.resolve.fallback,
https: require.resolve('http-browserify')
}
}
return config
})
```
$ npm run start
새로운 문법
const a = {
b:'a',
c:{}
}
a.c?.d == null일경우 undefined으로 바꿔줌 --> 새로운 문법
import { useEffect, useState } from "react";
import Web3 from 'web3/dist/web3.min.js'
// web3 -> nodeJSd에서 사용하는 라이브러리라서 번들링안됨 -> 에러뜸
// 해결방법 : web3/dist/web3.min.js
const useWeb3 = () => {
const [account, setAccount] = useState(null);
const [web3,setWeb3] = useState(null)
// http에서 받는거라 promise로 반환됨 -> axios를 사용하고있으니까
const getChainId = async () => {
const chainId = await window.ethereum.request({
method: "eth_chainId",
});
return chainId;
};
const getRequestAccounts = async () => {
const account = await window.ethereum.request({
method: "eth_requestAccounts",
});
return account
};
useEffect(() => {
const init = async () => {
try {
const chainId = await getChainId();
const [account] = await getRequestAccounts(); // 결과물을 배열에 담아주기때문
// 메타마스크에 요청보내기 -> 메타마스크가 만든 객체가 window.ethereum 이니까 가능
const web3 = new Web3(window.ethereum)
setAccount(account)
setWeb3(web3)
} catch (e) {
console.error(e.message);
}
};
if (window.ethereum) {
init();
}
}, []);
return [account,web3]
};
export default useWeb3;
import useWeb3 from "./hooks/useWeb3";
import { useEffect, useState } from "react";
import { Web3 } from "web3/dist/web3.min";
function App() {
const [account, web3] = useWeb3();
const [isLogin, setIsLogin] = useState(false);
const [balance, setBalance] = useState(0);
useEffect(() => {
const init = async () => {
const balance = await web3?.eth.getBalance(account);
setBalance(balance / 10 ** 18);
};
if (account) setIsLogin(true);
init();
}, [account]);
if (!isLogin) return <div>메타마스크 로그인 후 사용해주세요</div>;
return (
<div>
<div>
<h2>{account}님 환영합니다</h2>
<div>Balance : {balance} ETH</div>
</div>
</div>
);
}
export default App;
새로 생긴 기능
메인넷에 들어가더라도 사용해야할 네트워크에 접속하게 하는 방법
import { useEffect, useState } from "react";
import Web3 from "web3/dist/web3.min.js";
// web3 -> nodeJSd에서 사용하는 라이브러리라서 번들링안됨 -> 에러뜸
// 해결방법 : web3/dist/web3.min.js
const useWeb3 = () => {
const [account, setAccount] = useState(null);
const [web3, setWeb3] = useState(null);
// http에서 받는거라 promise로 반환됨 -> axios를 사용하고있으니까
const getChainId = async () => {
const chainId = await window.ethereum.request({
method: "eth_chainId",
});
return chainId;
};
const getRequestAccounts = async () => {
const account = await window.ethereum.request({
method: "eth_requestAccounts",
});
return account;
};
const addNetwork = async (chainId) => {
const network = {
chainId: chainId,
chainName: "ingGanache",
rpcUrls: ["http://127.0.0.1:8545"],
nativeCurrency: {
// 사용하는 통화에 대한 내용
name: "Ethereum", // 풀네임
symbol: "ETH", // 단위는 뭐니
decimals: 18, // 소수 몇자리까지 표현하니
},
};
await window.ethereum.request({
method: "wallet_addEthereumChain",
params: [network],
});
};
useEffect(() => {
const init = async () => {
try {
const targetChainId = "0x1e2a";
const chainId = await getChainId(); //7722
// 현재 너의 메타마스크의 체인아이디가 7722니? 0x1e2a
console.log("너의 체인아이디 : ", chainId);
if (targetChainId !== chainId) {
// 네트워크 추가 코드
addNetwork(targetChainId);
}
const [account] = await getRequestAccounts(); // 결과물을 배열에 담아주기때문
// 메타마스크에 요청보내기 -> 메타마스크가 만든 객체가 window.ethereum 이니까 가능
const web3 = new Web3(window.ethereum);
setAccount(account);
setWeb3(web3);
} catch (e) {
console.error(e.message);
}
};
if (window.ethereum) {
init();
}
}, []);
return [account, web3];
};
export default useWeb3;
import useWeb3 from "./hooks/useWeb3";
import { useEffect, useState } from "react";
import { Web3 } from "web3/dist/web3.min";
function App() {
const [account, web3] = useWeb3();
const [isLogin, setIsLogin] = useState(false);
const [balance, setBalance] = useState(0);
useEffect(() => {
const init = async () => {
const balance = await web3?.eth.getBalance(account);
setBalance(balance / 10 ** 18);
};
if (account) setIsLogin(true);
init();
}, [account]);
if (!isLogin) return <div>메타마스크 로그인 후 사용해주세요</div>;
return (
<div>
<div>
<h2>{account}님 환영합니다</h2>
<div>Balance : {balance} ETH</div>
</div>
</div>
);
}
export default App;
거래를 할 수 있게 메타마스크와 연결하기
import { useEffect, useState } from "react";
import Web3 from "web3/dist/web3.min.js";
// web3 -> nodeJSd에서 사용하는 라이브러리라서 번들링안됨 -> 에러뜸
// 해결방법 : web3/dist/web3.min.js
const useWeb3 = () => {
const [account, setAccount] = useState(null);
const [web3, setWeb3] = useState(null);
// http에서 받는거라 promise로 반환됨 -> axios를 사용하고있으니까
const getChainId = async () => {
const chainId = await window.ethereum.request({
method: "eth_chainId",
});
return chainId;
};
const getRequestAccounts = async () => {
const account = await window.ethereum.request({
method: "eth_requestAccounts",
});
return account;
};
const addNetwork = async (chainId) => {
const network = {
chainId: chainId,
chainName: "ingGanache",
rpcUrls: ["http://127.0.0.1:8545"],
nativeCurrency: {
// 사용하는 통화에 대한 내용
name: "Ethereum", // 풀네임
symbol: "ETH", // 단위는 뭐니
decimals: 18, // 소수 몇자리까지 표현하니
},
};
await window.ethereum.request({
method: "wallet_addEthereumChain",
params: [network],
});
};
useEffect(() => {
const init = async () => {
try {
const targetChainId = "0x1e2a";
const chainId = await getChainId(); //7722
// 현재 너의 메타마스크의 체인아이디가 7722니? 0x1e2a
console.log("너의 체인아이디 : ", chainId);
if (targetChainId !== chainId) {
// 네트워크 추가 코드
addNetwork(targetChainId);
}
const [account] = await getRequestAccounts(); // 결과물을 배열에 담아주기때문
// 메타마스크에 요청보내기 -> 메타마스크가 만든 객체가 window.ethereum 이니까 가능
const web3 = new Web3(window.ethereum);
setAccount(account);
setWeb3(web3);
} catch (e) {
console.error(e.message);
}
};
if (window.ethereum) {
init();
}
}, []);
return [account, web3];
};
export default useWeb3;
import useWeb3 from "./hooks/useWeb3";
import { useEffect, useState } from "react";
import { Web3 } from "web3/dist/web3.min";
function App() {
const [account, web3] = useWeb3();
const [isLogin, setIsLogin] = useState(false);
const [balance, setBalance] = useState(0);
const handleSubmit = async (e) => {
e.preventDefault();
// 메타마스크한테 sendTransaction을 실행할거야
await web3.eth.sendTransaction({
from: account,
to: e.target.recived.value,
value: web3.utils.toWei(e.target.amount.value,'ether'),
// ether단위 숫자를 -> wei 단위로 바꾸는 함수
});
};
useEffect(() => {
const init = async () => {
const balance = await web3?.eth.getBalance(account);
setBalance(balance / 10 ** 18);
};
if (account) setIsLogin(true);
init();
}, [account]);
if (!isLogin) return <div>메타마스크 로그인 후 사용해주세요</div>;
return (
<div>
<div>
<h2>{account}님 환영합니다</h2>
<div>Balance : {balance} ETH</div>
</div>
<div>
<form onSubmit={handleSubmit}>
<input type="text" id="recived" placeholder="받을 계정" />
<input type="number" id="amount" placeholder="보낼 금액" />
<input type="submit" value="전송" />
</form>
</div>
</div>
);
}
export default App;
'프로그래밍 > typescsript' 카테고리의 다른 글
[220630] GETH를 통해 실제 이더리움 네트워크와 연결하기 (0) | 2022.07.06 |
---|---|
[220627] private 네트워크 생성 / GETH (0) | 2022.07.06 |
[타입스크립트] class(클래스) vs interface(인터페이스) (0) | 2022.06.17 |
[220617] 지갑과 블록 네트워크가 소통하는 흐름 (0) | 2022.06.17 |
[220616] 월렛(블록체인 지갑)의 개념과 구조, 직접 월렛 만들기 (0) | 2022.06.16 |
댓글