본문 바로가기

BlockChain Developer/Public Blockchain

[Solditiy] CEI & Mutex Pattern

[소개]

Smart Contract는 코인 또는 토큰을 보관할 수 있으며 배포 후 Verify가 진행되면 누구에게나 열람할 수 있는 권한이 있다. 이에 따라 코드상에 보안 문제가 다양하게 발생할 수 있다. 금일 이야기 해 볼 주제인 CEI 패턴은 "Re-Entrancy Attack(재진입 공격)"을 방지하는 방법 중 하나의 패턴이다. 이에 대응하기위해 Openzeppelin에서 Re-Entrancy Guard 를 사용해 Re-Entrancy Attack을 방법을 주로 채택한다. 스마트컨트랙트를 작성하다보면 GasFee Optimization(가스비 최적화)문제에 자주 맞닥드리게되는데 상기 Re-Entrancy Guard에 비해 CEI 패턴으로 작성된 컨트랙트는 보다 낮은 가스비용을 지출하므로 가스비 최적화에 보다 효율적으로 대응할 수 있다.

 

[참고]

Re-Entrancy Attack에 대한 자세한 내용은 여기를 참조 : https://github.com/BlockMonkeys/MasteringSmartContract/tree/dev/4_reEntrancy

 

GitHub - BlockMonkeys/MasteringSmartContract: R&D For SmartContract

R&D For SmartContract. Contribute to BlockMonkeys/MasteringSmartContract development by creating an account on GitHub.

github.com

 

[CEI Pattern]

CEI Pattern은 Checks Effects Interaction Pattern의 약자로 "Check" -> "Effect" -> "Interaction" 순으로 코드를 작성해야 한다는 패턴을 의미한다. 이렇게 할 경우 Re-Entrancy로 재접근해 함수를 호출해 Interaction을 하기 전에 Checking과 Effect가 진행되기에 재진입 공격을 방지할 수 있다.

function withdraw() external {
	require(!lock, "Currently Locked"); // Check Exceptions
    
    lock = true; // State Effect
    
    payable(msg.sender).call{value : 100 ether}(""); // Interaction
}

 

[Mutex Pattern]

Mutext Pattern은 바로 이전에 함수에서 lock 변수값을 통해 함수에 대한 접근을 제어한 것을 확인할 수 있다. 통상 Re-Entrancy Attack의 방지를 위해 위 CEI Pattern과 함께 사용하는 것이 일반적이다.

contract reEntrancyGuardTest {
	modifier reEntrancyGuard() {
    	require(!lock);
        
        lock = true;
      	_;
        lock = false;
    }
    
    bool lock;
    
    function withdraw() external reEntrancyGuard {
    	  payable(msg.sender).call{value : 100 ether}(""); // Interaction
    }
}