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{
}
다음은 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 각각 어느 상황에서 실행되는지 확인할 수 있었다.