블록체인 학습
0 XP

실습: Ether 송신하기

앞 실습에서 Ether 를 받는 법을 익혔다면, 이번에는 받은 Ether 를 다시 내보내는 법을 연습합니다. 송금 방법 중 오늘날 권장되는 call 을 직접 사용해, 원하는 주소로 정확한 금액을 보내는 컨트랙트를 완성해 봅시다.

받을 대상은 일반 address 가 아니라 송금이 가능한 address payable 타입이어야 합니다. 그리고 call 은 실패해도 자동으로 revert 하지 않고 성공 여부를 bool 로 반환만 하므로, 그 결과를 반드시 require 로 확인해야 합니다. 이 검증을 빠뜨리면 송금이 실패했는데도 코드가 정상인 척 넘어가는 위험한 버그가 생깁니다.

해야 할 일:

  1. Sender 컨트랙트를 선언하세요.
  2. deposit 이라는 payable 함수로 Ether 를 받을 수 있게 하세요.
  3. sendTo 함수를 만들어, 매개변수로 받은 address payable to 에게 amount 만큼 call 로 Ether 를 보내세요.
  4. 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 을 눌러 모든 조건을 통과하는지 확인하세요.

Code Editor
에디터를 불러오는 중...
실행 결과

Run 버튼을 눌러 코드를 실행하세요.