[solidity] Fallback

wooz3k.eth·2022년 12월 23일
0
post-custom-banner

Fallback

fallback 이라는 단어의 의미는 대비책이다.

solidity로 작성된 smart contract에 함수를 호출할 때 해당 smart contract에 호출한 함수가 존재하지 않을 경우 대비책으로 fallback 함수가 실행되게 된다.

Solidity 6.0 버전 이전에는 fallback 함수 1개만 존재하였었는데 6.0 버전 이후에 fallback과 receive로 나눠지게 됐다.

형태

// 6.0 이전 fallback
function() external payable {
    
}
// 6.0 이후
fallback() external payable {
   
  }

receive() external payable{
    
}

목적

  • 존재하지 않는 함수 호출이 들어왔을 때 처리할 사항이 있을 경우
  • 이더를 받기 위해 구현 해야 하고, 이더를 받았을 때 동작을 구현 가능
    fallback이 구현되어있지 않고, payable 함수가 없을 경우 해당 컨트렉트는 이더를 받을 수 없음 ( selfdestruct를 이용하여 강제로 전송 가능 )

receive, fallback

  • solidity 6.0 이후로 나뉘어짐
  • receive 함수는 이더를 받을 때만 동작
  • fallback 함수는 이더를 받을 수도 있고, 존재하지 않는 함수가 호출될 때 실행될 수도 있음

다음은 foundry를 이용하여 receive, fallback이 둘 다 구현되어있을 때 어떤 상황에서 둘 중에 어떤 fallback이 호출되는지 확인해보는 간단한 테스트코드이다.

// Fallback.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;

import "forge-std/Test.sol";

contract Target
{
    constructor()
    {
        
    }

    receive() external payable
    {
        console.log("receive");
    }

    fallback() external payable
    {
        console.log("fallback");
    }
    
}
// fallback.t.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;

import "forge-std/Test.sol";
import "../src/fallback.sol";

contract fallbacktest is Test 
{
    Target public target;
    
    address public user = address(0x11);
    
    function setUp() public
    {
        target = new Target();
    }

    function test_receive1() public
    {
        vm.deal(user, 1 ether);
        vm.prank(user);
        address(target).call{value: 0.1 ether}("");
    }

    function test_receive2() public
    {
        vm.deal(user, 1 ether);
        vm.prank(user);
        address(target).call("");
    }

    function test_fallback1() public
    {
        vm.deal(user, 1 ether);
        vm.prank(user);
        address(target).call{value: 0.1 ether}("12312312");
    }

    function test_fallback2() public
    {
        address(target).call("1231231232131");
    }
}

실행결과

이 예제를 통해서 receive, fallback 각각 어느 상황에서 실행되는지 확인할 수 있었다.

profile
Theori ChainLight Web3 Researcher
post-custom-banner

0개의 댓글