종합 실습: 역할 기반 출금 금고
이 차시에서 배운 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 가 실제로 막는 것은 다른 컨트랙트가 온체인에서 호출하는 경로
뿐입니다. 접근 제어는 상태를 바꾸는 함수(출금, 소유권 이전 등)를 막을 때 의미가 있습니다.
해야 할 일:
address public owner와mapping(address => uint256) public deposits를 선언하세요.error NotOwner()커스텀 에러를 선언하세요.constructor에서owner = msg.sender로 설정하세요.onlyOwnermodifier:msg.sender != owner이면revert NotOwner(), 아니면_;.deposit()함수(payable):require(msg.value > 0, "zero deposit")후deposits[msg.sender]에 더하세요.onlyOwner가 적용된totalLocked()view 함수:address(this).balance를 반환하세요.
payable 키워드가 없으면 함수는 이더를 받을 수 없습니다. deposit() 에는 반드시 payable 을
붙이세요.
완성 후 Run 을 눌러 모든 조건을 통과하는지 확인하세요.