본문 바로가기
Blockchain

[Solidity] 7. 접근 제어 패턴과 `modifier`

by clolee 2025. 4. 18.

 

✅ 7. 접근 제어 패턴과 modifier

Solidity에서 보안과 권한 제어의 핵심 기능

  • 오직 owner만 자금을 인출하게 만들기
  • 특정 조건을 만족해야만 실행되게 만들기
  • 공통 로직(예: require) 중복 방지

📌 1. 접근 제어란?

스마트컨트랙트의 민감한 기능을 특정 조건을 만족하는 사용자만 실행할 수 있도록 제한하는 구조입니다.


✅ 대표적인 실무 패턴

패턴 이름 설명
onlyOwner 소유자만 호출 가능
onlyAdmin 관리자 전용 기능
whenNotPaused 정지 상태일 때 호출 차단
validAmount 조건을 만족해야 실행 가능

📌 2. modifier란?

함수 실행 전후에 조건 검사 로직을 삽입하는 재사용 가능한 코드 블록입니다.

✅ 문법

modifier onlyOwner() {
    require(msg.sender == owner, "Not the owner");
    _;
}
  • _; ← 이 부분이 함수 본문이 들어갈 위치
  • require() 등의 조건 검사 로직을 캡슐화

📌 3. modifier 사용 예시

address public owner;

constructor() {
    owner = msg.sender;
}

modifier onlyOwner() {
    require(msg.sender == owner, "Only owner");
    _;
}

function withdraw(uint amount) public onlyOwner {
    payable(msg.sender).transfer(amount);
}
  • withdraw()를 실행하려면 onlyOwner()의 조건을 먼저 통과해야 함
  • 실패하면 함수 본문(_)으로 진입하지 못하고 revert 발생

📌 4. modifier에 인자 전달도 가능

modifier greaterThan(uint x, uint y) {
    require(x > y, "x must be greater");
    _;
}

function check(uint a) public view greaterThan(a, 10) returns (bool) {
    return true;
}

📌 5. 중복 로직 제거 효과

🔁 중복 예

function f1() public {
    require(msg.sender == owner);
    ...
}

function f2() public {
    require(msg.sender == owner);
    ...
}

modifier로 리팩토링

modifier onlyOwner() {
    require(msg.sender == owner);
    _;
}

→ 함수는 이렇게 간결하게:

function f1() public onlyOwner { ... }
function f2() public onlyOwner { ... }

📌 6. 실무 예: Pausable 패턴

✅ 상태 변수

bool public paused = false;

✅ 제어자(modifier)

modifier whenNotPaused() {
    require(!paused, "Paused");
    _;
}

✅ 사용 예

function transfer() public whenNotPaused {
    // 전송 로직
}

✅ 실전 예제: Modifier + 소유자 패턴

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

contract Vault {
    address public owner;
    bool public paused;

    constructor() {
        owner = msg.sender;
    }

    modifier onlyOwner() {
        require(msg.sender == owner, "Only owner");
        _;
    }

    modifier whenNotPaused() {
        require(!paused, "Paused");
        _;
    }

    function togglePause() public onlyOwner {
        paused = !paused;
    }

    function withdraw(uint amount) public onlyOwner whenNotPaused {
        payable(msg.sender).transfer(amount);
    }

    receive() external payable {}
}

🧠 실무 팁 정리

항목
modifier는 중복 제거에 매우 유용 require를 함수마다 적지 않아도 됨
onlyOwner, whenNotPaused는 필수 수준 대부분의 스마트컨트랙트에서 사용됨
modifier 안에서 revert() 사용 가능 조건 불충족 시 명확한 메시지 반환
보안 강화에 핵심 역할 권한 없는 사용자 차단 가능
modifier에 인자 전달 가능 동적 조건 표현 가능 (require(x > threshold))

✅ [7단계 요약]

개념 설명
modifier 함수 실행 전 조건 검사 블록
_ 실제 함수 본문이 들어갈 위치
onlyOwner, whenNotPaused 가장 흔히 쓰이는 패턴
modifier + require 보안, 접근 제어 구현 핵심
중복 제거 효과 코드 가독성 + 재사용성 향상

댓글