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. 지갑 이벤트 핸들링

Web3ProvideruseEffect 훅을 사용하여 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 지갑의 상태 변화에 동적으로 반응하고 사용자에게 최신 정보를 제공할 수 있습니다.