블록체인 학습
0 XP

종합 실습: 역할 기반 출금 금고

이 차시에서 배운 msg.sender, require, modifier, 커스텀 에러를 모두 합쳐 관리자 전용 출금 금고를 만듭니다.

이번 실습의 핵심은 modifier 안에서 문자열 대신 커스텀 에러로 중단하는 것입니다. error NotOwner(); 를 선언해두고, onlyOwner modifier 에서 msg.sender != owner 이면 revert NotOwner(); 로 트랜잭션을 되돌립니다. 커스텀 에러는 4바이트 셀렉터만 저장하므로 문자열 메시지보다 가스를 적게 씁니다.

deposit() 은 payable 로 선언해 msg.value 로 들어온 이더를 받고, totalLocked() 은 address(this).balance 를 반환합니다. totalLocked() 에 onlyOwner 를 붙이는 것은 modifier 를 view 함수에도 적용해 보는 연습용 예시입니다. 권한 검사(onlyOwner)와 입력 검증(require(msg.value > 0, ...))이 한 컨트랙트 안에서 어떻게 나뉘는지 살펴보세요.

접근 제어로 데이터를 숨길 수는 없습니다. view 함수는 오프체인에서 eth_call 로 호출할 때 from 주소를 마음대로 지정할 수 있고, 컨트랙트 잔액은 애초에 eth_getBalance 로 누구나 읽습니다. totalLocked() 의 onlyOwner 가 실제로 막는 것은 다른 컨트랙트가 온체인에서 호출하는 경로 뿐입니다. 접근 제어는 상태를 바꾸는 함수(출금, 소유권 이전 등)를 막을 때 의미가 있습니다.

해야 할 일:

  1. address public owner 와 mapping(address => uint256) public deposits 를 선언하세요.
  2. error NotOwner() 커스텀 에러를 선언하세요.
  3. constructor 에서 owner = msg.sender 로 설정하세요.
  4. onlyOwner modifier: msg.sender != owner 이면 revert NotOwner(), 아니면 _;.
  5. deposit() 함수(payable): require(msg.value > 0, "zero deposit") 후 deposits[msg.sender] 에 더하세요.
  6. onlyOwner 가 적용된 totalLocked() view 함수: address(this).balance 를 반환하세요.

payable 키워드가 없으면 함수는 이더를 받을 수 없습니다. deposit() 에는 반드시 payable 을 붙이세요.

완성 후 Run 을 눌러 모든 조건을 통과하는지 확인하세요.

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

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