Home [Solidity] modifier 와 _; 그리고 Condition-Orientated Programming
Post
Cancel
Preview Image

[Solidity] modifier 와 _; 그리고 Condition-Orientated Programming

개요

요즘 Solidity를 공부하고 있다. 왜 갑자기 Solidity를 공부하냐면 이유따위는 없다.

그래서 이것저것 코드를 작성해보면서 Solidity에 익숙해지고 있는데, modifier에서 이상한 라인을 확인하게 되었다.

modifier 함수의 마지막에 꼭 _; 를 넣어줘야 한다는 것이다.

아니 이 하찮은(?) _; 를 왜 꼭 넣어줘야 하는것인가?

알고보니 중요한 친구였고 역할이 있었다.

_; 은 functional modifiers 에서 쓰이는 특수한 character 다

_; 역할은 다음과 같다.

function modifier 이란 함수가 실행할 때 사용되는 modifier 인데,

이 function modifier A가 function B에 붙은 경우

  1. function B가 실행되기전 function modifier A 먼저 _; 전까지 실행
  2. function B의 body를 실행
  3. function B의 body가 다 끝나면 function modifier A에서 _; 뒷 부분을 실행

하게 된다.

이런 스타일의 코딩을 Condition-Orientated Programming (COP) 이라고 한다.

Condition-Orientated Programming (COP)

COP란 무엇일까?

여기서는 간단히만 정리해보겠다.

  • COP는 contract-orientated programming 의 서브도메인이다.
    • (contract-orientated programming 도 cop이나 여기서는 풀네임으로 쓰겠다.)
  • 함수형 프로그래밍과 명령형 프로그래밍의 하이브리드 방식
  • 특정 문법(particular syntax)보다는 느스한 방법론(loose methodology)에 가깝다.
  • function modifiers 와 events가 있는, Solidity에게는 매우 적합한 방식.

COP의 주요 목표는 하나다.

Function bodies should have no conditional paths.

함수 본문에는 조건부 경로가 없어야 합니다.

또는

Never mix transitions with conditions.

전환(transitions)을 조건(conditions)과 혼합하지 마십시오.

COP는 프로그래머가 그러한 모든 조건을 명시적으로 열거하도록 요구함으로써 이 문제를 해결한다.

논리는 비조건부 상태 트랜잭션(non-conditional state-transactions)으로 평면화(flattened)된다.

그런 다음 조건 단편(condition fragments)을 적절하게 문서화하고, 재사용하고, 추론하고, 요구 사항과 의미를 부여할 수 있다.

예시

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// https://docs.soliditylang.org/en/v0.8.13/contracts.html#function-modifiers
contract Mutex {
    bool locked;
    modifier noReentrancy() {
        require(
            !locked,
            "Reentrant call."
        );
        locked = true;
        _;
        locked = false;
    }

    /// This function is protected by a mutex, which means that
    /// reentrant calls from within `msg.sender.call` cannot call `f` again.
    /// The `return 7` statement assigns 7 to the return value but still
    /// executes the statement `locked = false` in the modifier.
    function f() public noReentrancy returns (uint) {
        (bool success,) = msg.sender.call("");
        require(success);
        return 7;
    }
}

f() 는 다음과 같이 실행된다.

  1. noReentrancy function modifier가 붙어있으므로, noReentrancy 에서 _; 전까지를 수행한다.
    1. locked = true; 상태
  2. f() 본문(body) 를 실행한다.
  3. noReentrancy 에서 _; 다음을 수행한다.

References

This post is licensed under CC BY 4.0 by the author.

[Kotlin] 한 줄로 swap 하는 방법

[Clojure] Do Things: A Clojure Crash Course - Functions