반응형

 

 

오늘은 MultiCall에 대해 코드예제와 함께 정리해보겠다.

블록체인에서 MultiCall이란 한 번의 트랜잭션으로 여러 스마트 컨트랙트 함수를 호출하여 블록체인 네트워크에 효율적으로 처리할 수 있는 방법을 제공하는 것이다. 이와 같이 블록체인 지갑등에서 자신의 잔고를 확인하거나 체크하는 용도로 많이 쓰이고 있다. 아래 멀티콜 예제를 보면 하나하나 어떤 내용이 있는지 확인해보자.

 

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface IERC20 {
    function balanceOf(address account) external view returns (uint256);
}

interface Multicall {
    function aggregate(
        call[] calldata calls
    ) external returns (uint256 blockNumber, bytes[] memory returnData);
}

struct call {
    address target;
    bytes callData;
}

contract UniswapMulticallExample {
    address public uniswapRouter;  // Uniswap Router contract address
    address[] public tokens;       // ERC-20 token addresses

    constructor(address _uniswapRouter, address[] memory _tokens) {
        uniswapRouter = _uniswapRouter;
        tokens = _tokens;
    }

    function getBalances(address user) external view returns (uint256[] memory balances) {
        balances = new uint256[](tokens.length);

        for (uint256 i = 0; i < tokens.length; i++) {
            // Encode the balanceOf function call for the ERC-20 token
            bytes memory data = abi.encodeWithSelector(IERC20(tokens[i]).balanceOf.selector, user);
            
            // Add the call to the Multicall data
            Multicall.call memory tokenBalanceCall = Multicall.call({
                target: tokens[i],
                callData: data
            });

            // Aggregate the results in a single call to Multicall
            (, bytes[] memory results) = Multicall(uniswapRouter).aggregate([tokenBalanceCall]);

            // Decode the result and store the balance
            balances[i] = abi.decode(results[0], (uint256));
        }

        return balances;
    }
}

 

 

  • 코드 해석
    • SPDX-License-Identifier: 컨트랙트의 라이선스를 지정하는 부분
    • pragma solidity ^0.8.0;: Solidity 컴파일러 버전을 지정
    • IERC20 인터페이스: ERC-20 토큰 표준을 따르는 balanceOf 함수를 정의한 인터페이스
    • Multicall 인터페이스: aggregate 함수를 정의한 인터페이스로, 여러 호출을 집계하여 실행
    • function aggregate가 여러 call들을 집계하여 배열형태로 한 번에 처
    • call 구조체: 호출할 대상 주소와 호출할 데이터를 담는 구조체
    • UniswapMulticallExample 컨트랙트: ERC-20 토큰의 잔액을 가져오는 기능을 제공하는 컨트랙트
    • uniswapRoutertokens 변수: Uniswap 라우터 주소와 ERC-20 토큰 주소 배열을 저장
    • constructor: 컨트랙트를 배포할 때 Uniswap 라우터 주소와 ERC-20 토큰 주소 배열을 초기화
    • getBalances 함수: 사용자의 주소를 받아와 각 ERC-20 토큰의 잔액을 조회하는 함수
    • for 루프: tokens 배열의 각 토큰에 대해 잔액을 조회
    • abi.encodeWithSelector: balanceOf 함수를 호출하기 위해 함수 시그니처와 사용자 주소를 인코딩
    • **Multicall**을 사용하여 여러 호출을 집계하고 결과를 얻음
    • abi.decode: 결과를 해석하여 해당 토큰의 잔액을 가져옴
    • return balances;: 각 토큰의 잔액을 반환
    • 부록
      • view 또는 pure 키워드를 사용하면 함수가 스마트 계약의 상태를 변경하지 않고 데이터를 읽기만 하는 데 사용됨을 나타냄. 이러한 함수는 외부로부터 호출되어도 블록체인의 상태를 변경하지 않으므로 가스 비용이 들지 않는다. 이러한 함수의 실행은 로컬 노드에서 처리되며, 블록체인 트랜잭션을 생성하지 않으므로 가스비용이 발생하지 않는다.
      • view 및 pure 함수는 블록체인의 무언가를 기록하거나 변경하지 않고 단순히 데이터를 반환하는 데 사용된다. 이 경우 getBalances 함수가 external view returns를 사용하기 때문에 블록체인 상태를 변경하지 않고 사용자의 잔액을 읽기만 하므로 호출 시 가스비용이 발생하지 않는다.

위와 같이 코드들의 함수를 살펴보면서 각각의 함수들이 어떠한 기능들을 하는지 알아보았다. 멀티콜의 경우 스왑을 하거나 나의 잔고를 모두 가져올 때 많이 사용될 것 같다는 생각이 들었다. 멀티콜 기능을 통해 다음에는 유니스왑 v2를 구현해 보도록 하겠다. 

반응형

'블록체인' 카테고리의 다른 글

토큰을 만들어보자!  (0) 2023.11.24
블록체인 블록의 구조  (0) 2021.09.27
블록체인 용어정리  (0) 2021.07.27
P2P 네트워크 와 블록체인 네트워크 설계  (0) 2021.07.19
데이터베이스와 분산원장?  (0) 2021.07.08

+ Recent posts