반응형

Solidity를 하다보면, onlyOwner라는 이름의 modifier가 많이 쓰인다. 그냥 항상 송금/출금 등의 함수에서 당연히 붙이는거니까~ 하면서 쓰고있었는데, 정확한 문법에 대한 이해가 필요할 듯 해 정리해보려고 한다.

    modifier onlyOwner() {
        require(msg.sender == owner, "caller is not the owner");
        _;
    }
    
    function withdraw() public onlyOwner {
        payable(owner).transfer(address(this).balance);
    }

 

줄마다 보면서 해석해봐야할 것 같다.

1. modifier 함수변경자의 의미

modifier는 "함수변경자, 제어자" 라는 이름으로도 불린다. 즉, 함수의 기능에 있어 특정 기능을 제한/변경할 수 있다는 것이다. 

맨 위의 코드를 한번 보자. 

modifier onlyOwner()

onlyOwner라는 이름의 modifier를 만들어준다. 

onlyOwner는 기본적으로 함수에 이 modifier를 추가해주면, 오직 컨트랙트의 소유자만이 해당 함수를 호출할 수 있게 된다.

정확한 내용을 살펴보자.

 

require(msg.sender == owner, "caller is not the owner");
_;

msg.sender의 주소가 owner의 주소와 같지 않다면, 에러메시지 "caller is not the owner"를 출력하고, 함수의 실행을 막는다. 여기까진 오케이. 그 다음에 등장하는 "_;"는 대체 무엇일까?

 

이는, 다시 modifier를 호출한 함수로 돌아가라는 말이다.

이게 무슨 말이지?

 

다시 맨 위의 코드를 보자.

위 코드에서 withdraw() 함수의 위치에서 onlyOwner modifier가 사용되었고, 그 즉시 컨트랙트는 onlyOwner modfier가 선언된 곳으로 가서 해당 함수를 호출한 사람의 주소와 컨트랙트 소유자의 주소가 같은지를 비교한다. 

비교를 한 이후, '_;'부분은, 이제 onlyOwner를 호출한 함수의 나머지 부분을 실행하라는 말이다 즉, 위 코드는 다음과 같다고 할 수 있다.

    function withdraw() public {
    	require(msg.sender == owner, "caller is not the owner");
        payable(owner).transfer(address(this).balance);
    }

이와 똑같은 코드라고 생각하면 된다.

그래서, '_;'는 모든 modifier의 마지막에 항상 넣어준다고 생각하면 된다.

 

그럼, 저렇게 쓰면 되는데 왜 굳이 modifier라는걸 만들어서 사용하지..?

확장성을 위함이겠지..ㅎ

 

2. onlyOwner는 왜 있을까?

onlyOwner는 ownable이라는 컨트랙트에 내장되어있다. 

이렇게까지 라이브러리화 하여 사용하는 이유가 있을까?

 

그 이유는, 블록체인이라는 기술의 특성에 있다.

모두 알겠지만, 블록체인의 중요한 특성 중 하나는 바로, 그 기록들의 '불변성'이다.

이게 무슨말이냐면, 제아무리 컨트랙트를 직접 만든 개발자라고 하더라도, 그 코드를 맘대로 바꿀 수는 없다는 것이다. 

 

EVM(Ethereum Virtual Machine)은 그 구조적 특성상, 컨트랙트 코드의 컴파일 결과물인 바이트코드는 EVM 내의 불변의 영역인 'Storage'에 들어가있다. 때문에 미리 정의된 코드는 그 내용을 절대 바꿀 수 없게 된다.

 

이로 인해서, 솔리디티 코드를 작성할 때 가장 중요한 것은 보안 다음으로, 유지보수성이다. 즉, 지금 짠 코드를 나중에 어떠한 일이 생겼을 때 언제든 바꿀 수 있어야 한다는 것이다. 

따라서 modifier와 같은 제어자 또한 사용해주고, constructor 등의 메서드, 상수 사용의 최소화 등을 해야 한다.

 

말을 하다 보니 onlyOwner의 필요성은 좀 뒷전으로 하긴 했는데, 이렇게 변수의 사용이 자주 바뀔 수 있게 되다 보니 (owner 등의 변수 포함) 컨트랙트의 ownership 또한 중요하기도 하고, 토큰을 거래하는 데 주로 초점이 맞추어져있는 solidity의 특성 상, 송금 또는 출금을 하는 함수도 많다보니 편리성을 위해 존재하기도 하는, 아주 요긴한 녀석이다.

반응형

+ Recent posts