실습: Ether 송신하기
앞 실습에서 Ether 를 받는 법을 익혔다면, 이번에는 받은 Ether 를 다시 내보내는 법을
연습합니다. 송금 방법 중 오늘날 권장되는 call 을 직접 사용해, 원하는 주소로 정확한 금액을
보내는 컨트랙트를 완성해 봅시다.
받을 대상은 일반 address 가 아니라 송금이 가능한 address payable 타입이어야 합니다.
그리고 call 은 실패해도 자동으로 revert 하지 않고 성공 여부를 bool 로 반환만 하므로, 그
결과를 반드시 require 로 확인해야 합니다. 이 검증을 빠뜨리면 송금이 실패했는데도 코드가 정상인
척 넘어가는 위험한 버그가 생깁니다.
해야 할 일:
Sender컨트랙트를 선언하세요.deposit이라는payable함수로 Ether 를 받을 수 있게 하세요.sendTo함수를 만들어, 매개변수로 받은address payable to에게amount만큼call로 Ether 를 보내세요.call의 성공 여부(bool ok)를require로 검증하세요.
call 로 Ether 를 보내는 문법은 (bool ok, ) = to.call{value: amount}("");
입니다. 반환된 ok 가 false 면 전송이 실패한 것이므로 require 로 막아야 합니다.
이 실습의 sendTo 는 저수준 call 문법에만 집중한 예제라 접근 제어가 전혀 없습니다.
public 이고 권한 검사가 없으므로 누구나 sendTo(공격자주소, 전액) 을 호출해 컨트랙트 자금을
통째로 빼갈 수 있습니다. 실제 서비스에서는 Chapter 11 에서 배운 것처럼 require(msg.sender == owner, "only owner") 또는 onlyOwner modifier 로 송금 함수의 권한을 반드시 제한하세요. 여기에
더해 call 은 재진입(reentrancy) 공격에도 노출되므로, 송금 전에 상태를 먼저 갱신하는
Checks-Effects-Interactions 패턴을 함께 적용해야 안전합니다.
완성 후 Run 을 눌러 모든 조건을 통과하는지 확인하세요.