Skip to main content

Web3 통합 상세 (Web3 Integration Details)

이 문서는 프론트엔드 애플리케이션에서 Web3 지갑(MetaMask)과 상호작용하고 블록체인 데이터를 가져오는 방법에 대해 상세히 설명합니다.

1. Web3Provider의 역할 (frontend-autopromaker-ai/src/providers/Web3Provider.tsx)​

Web3Provider는 애플리케이션의 Web3 관련 상태를 중앙에서 관리하고, useWeb3 훅을 통해 이 상태를 모든 컴포넌트에 제공합니다.

  • 관리하는 주요 상태:
    • publicAddress: 현재 연결된 지갑의 공개 주소.
    • isConnected: 지갑 연결 여부.
    • network: 현재 연결된 블록체인 네트워크의 이름과 체인 ID.
    • balance: 연결된 지갑의 네이티브 토큰(예: ETH) 잔액.
    • usdtBalance: 연결된 지갑의 USDT (ERC-20 토큰) 잔액.

2. ethers.js를 활용한 블록체인 데이터 조회​

Web3Provider 내부의 getWeb3Info 함수는 ethers.js 라이브러리를 사용하여 다양한 블록체인 데이터를 조회합니다.

2.1. ethers.BrowserProvider​

MetaMask와 같은 브라우저 확장 지갑을 통해 블록체인과 상호작용하기 위한 Provider 인스턴스를 생성합니다.

const provider = new ethers.BrowserProvider(window.ethereum);

2.2. 네트워크 정보 조회​

provider.getNetwork()를 호출하여 현재 연결된 네트워크의 정보를 가져옵니다. 이 정보에는 네트워크 이름(예: homestead for Ethereum Mainnet)과 체인 ID가 포함됩니다.

const networkData = await provider.getNetwork();
setNetwork({ name: networkData.name, chainId: Number(networkData.chainId) });

2.3. 네이티브 토큰 (ETH) 잔액 조회​

provider.getBalance(address)를 호출하여 특정 주소의 네이티브 토큰 잔액을 BigNumber 형태로 가져옵니다. ethers.formatEther()를 사용하여 사람이 읽기 쉬운 ETH 단위로 변환합니다.

const balanceWei = await provider.getBalance(address);
setBalance(ethers.formatEther(balanceWei));

2.4. ERC-20 토큰 (USDT) 잔액 조회​

USDT와 같은 ERC-20 토큰의 잔액을 조회하려면 해당 토큰의 스마트 컨트랙트와 상호작용해야 합니다.

  1. USDT 컨트랙트 주소 정의:
    const USDT_ADDRESS = '0xdAC17F958D2ee523a2206206994597C13D831ec7'; // 이더리움 메인넷 기준
  2. ERC-20 ABI 정의: balanceOf 함수 호출에 필요한 최소한의 ABI를 정의합니다.
    const ERC20_ABI = [
    'function balanceOf(address owner) view returns (uint256)',
    'function decimals() view returns (uint8)',
    'function symbol() view returns (string)',
    ];
  3. 컨트랙트 인스턴스 생성: ethers.Contract를 사용하여 USDT 컨트랙트 인스턴스를 생성합니다.
    const usdtContract = new ethers.Contract(USDT_ADDRESS, ERC20_ABI, provider);
  4. balanceOf 함수 호출 및 단위 변환: usdtContract.balanceOf(address)를 호출하여 잔액을 가져오고, ethers.formatUnits(usdtBalanceWei, 6)를 사용하여 USDT의 소수점 단위(일반적으로 6)에 맞춰 변환합니다.
    const usdtBalanceWei = await usdtContract.balanceOf(address);
    setUsdtBalance(ethers.formatUnits(usdtBalanceWei, 6));

3. 지갑 이벤트 핸들링​

Web3Provider는 useEffect 훅을 사용하여 MetaMask에서 발생하는 주요 이벤트들을 구독하고 처리합니다.

3.1. accountsChanged 이벤트​

사용자가 MetaMask에서 계정을 변경할 때 발생합니다. 이 이벤트가 발생하면 publicAddress를 업데이트하고, 새로운 주소에 대한 Web3 정보를 다시 조회합니다.

window.ethereum.on('accountsChanged', (accounts: string[]) => {
if (accounts.length > 0) {
setPublicAddress(accounts[0]);
setIsConnected(true);
getWeb3Info(accounts[0]);
} else {
disconnectWallet(); // 계정이 없으면 연결 해제
}
});

3.2. chainChanged 이벤트​

사용자가 MetaMask에서 네트워크(체인)를 변경할 때 발생합니다. 이 이벤트가 발생하면 현재 publicAddress를 사용하여 Web3 정보를 다시 조회하여 네트워크 및 잔액 정보를 업데이트합니다.

window.ethereum.on('chainChanged', () => {
if (publicAddress) {
getWeb3Info(publicAddress);
}
});

이러한 이벤트 핸들링을 통해 애플리케이션은 MetaMask 지갑의 상태 변화에 동적으로 반응하고 사용자에게 최신 정보를 제공할 수 있습니다.