본문 바로가기

코인/코인 개발

Solidity(솔리디티): 이벤트(event) 방출(emit) 하고 안하고 차이?

Solidity 개발을 처음 시작할 때 궁금한 것들 중 하나는 이벤트(event)에 대한 것일 텐데요. 이벤트가 왜 있는지, 이벤트를 발생시키면 어떤 차이가 발생하는지를 간단한 예제로 알아보도록 하겠습니다. 다음은 이벤트에 대해 알아보기 위한 예제 컨트랙트입니다.

 

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

contract EventTestContract {
    
    mapping(address => uint256) private _counts;
    
    event Increase(address indexed addr, uint256 oldValue, uint256 newValue);
    
    function increaseWithEvent() public returns (bool) {
        uint256 oldValue = _counts[msg.sender];
        _increase();
        uint256 newValue = _counts[msg.sender];
        emit Increase(msg.sender, oldValue, newValue);
        return true;
    }
    
    function increaseWithoutEvent() public returns (bool) {
        _increase();
        return true;
    }
    
    function _increase() private {
        _counts[msg.sender] += 1;
    }
    
    function count() public view returns (uint256) {
        return _counts[msg.sender];
    }
    
}

 

 

increaseWithoutEventincreaseWithEvent, count 등 3개의 외부에서 호출 가능한 함수가 있습니다. increaseWithoutEvent와 increaseWithEvent 함수 모두 하는 일은 내부에 mapping으로 주소별로 저장되는 count를 증가시키는 것입니다. count함수는 증가된 count를 확인하기 위한 함수입니다. 차이는 increaseWithEvent에서만 Increase 이벤트를 방출(emit) 하는 것인데요. 두 함수를 호출한 뒤 어떤 차이가 있는지를 알아보도록 하겠습니다. 먼저 Remix에서 컴파일하고 Rinkeby 테스트넷에 배포해서 호출해보았습니다. 다음은 Rinkeby Etherscan에서 확인해 본 호출 별 결과입니다.

 

increaseWithoutEvent 호출 결과

 

increaseWithEvent 호출 결과

 

increaseWithEvent 호출 결과에서만 Logs 탭을 확인할 수 있는데, Logs 탭을 눌러보면 다음과 같은 상세 내용을 확인하실 수 있습니다.

 

increaseWithEvent 호출에 대한 이벤트 로그

 

Data 부분에서 1에서 2로 증가한 값(increaseWithoutEvent 다음에 호출했기 때문에 초기값이 1)을 확인할 수 있고, Increase 이벤트에 addr 매개 변수는 indexed로 지정되어 있어 etherscan에서 검색 시 필터로 사용이 가능합니다.

 

다른 차이는 increaseWithEvent 함수가 gas를 약간 더 사용하는 것인데, opcodes가 조금이라도 더 많으니 어쩔 수 없는 부분이겠습니다. 따라서, event는 로그를 남기기 위해서 반드시 사용해야 하지만, 사용자에게 불필요한 gas를 부담시키지 않으려면 꼭 필요한 부분에만 사용하는 것이 바람직하겠습니다.