반응형
오늘은 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 토큰의 잔액을 가져오는 기능을 제공하는 컨트랙트
- uniswapRouter 및 tokens 변수: 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 |