Event Logs

Overview

Event는 스마트 컨트랙트 상에서 정의되는 상속 가능한 멤버로서, 컨트랙트 내의 특정 액션의 발생을 이더리움 네트워크에 전파하기 위해 사용됩니다. 트랜잭션을 통해 발생한 Event는 Emit시점에 전달된 Argument들과 함께 해당 트랜잭션 Log객체 내부에 기록되기 때문에, 블록체인 상에서 조회가 가능합니다. 이렇게 기록된 Log는 블록체인에 접근 가능한 모든 엔티티들에 의해 조회될 수 있기 때문에, 특정 액션의 발생 여부 및 컨트랙트의 상태 변경 여부에 대한 실시간 모니터링 및 투명한 관리를 가능하게 합니다.

Event는 스마트 컨트랙트 내에서 다음과 같은 형태로 정의 및 선언됩니다. 아래 코드는 ERC20 토큰 인터페이스 컨트랙트 내의 Transfer Event 선언 예시로, from, to,tokens 의 세 argument를 전달받아 기록하는 Event입니다. from 주소로부터 to 주소로 tokens만큼의 수량이 전송되었음을 전파하기 위해 사용합니다.

contract IERC20 {
    ...
    event Transfer(address indexed from, address indexed to, uint tokens);
    ...
}

위와 같이 선언된 Event는 해당 컨트랙트를 상속받아 구현한 모든 컨트랙트에서 사용 가능합니다. 아래 예시는 위에서 Event를 정의한 IERC20 컨트랙트를 상속받아 구현한 ERC20 컨트랙트 내의 transfer function내에서 Transfer event를 emit하는 예시입니다. 토큰을 전송하기 위한 function 내에서 실제 전송에 필요한 구현을 마친 후, 최종 단계에서 전송 액션이 발생했음을 전파하기 위해 Event를 emit합니다.

contract ERC20 is IERC20 {
    ... 
      
	  function transfer(address recipient, uint amount) external returns (bool) {
        balanceOf[msg.sender] -= amount;
        balanceOf[recipient] += amount;
        emit Transfer(msg.sender, recipient, amount);
        return true;
    }  
    ...
}

이렇게 emit된 Transfer Event는 transfer function을 호출한 트랜잭션의 Receipt 내의 Event Log 영역에 아래와 같이 기록됩니다. logs 객체 내부의 topics배열에서 0번 인덱스의 값은 Transfer Event에 대한 sigature를, 1번 인덱스의 값은 해당 Event에서 indexed로 정의된 첫번째 Argument인 from 값을, 2번 인덱스의 값은 해당 Event에서 indexed로 정의된 두번째 Argument인 to 값을 의미합니다. 이처럼 Event의 Emission을 통해 특정한 액션이 발생했음을 트랜잭션 모니터링만으로 판단할 수 있습니다.

...
"receipt": {
            "from": "0x21e30f293f646ad7db02f009762d5f69b0c577df",
            "to": "0xdac17f958d2ee523a2206206994597c13d831ec7",
            "gasUsed": "0xf6dd",
            "logs": [
                {
                    "blockHash": "0x66bada263b77234f04df2db8f94a9373ec6cde5a3cc8164193be2a22180b68ca",
                    "address": "0xdac17f958d2ee523a2206206994597c13d831ec7",
                    "logIndex": 278,
                    "data": "0x0000000000000000000000000000000000000000000000000000000003567e00",
                    "removed": false,
                    "topics": [
                        "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
                        "0x00000000000000000000000021e30f293f646ad7db02f009762d5f69b0c577df",
                        "0x0000000000000000000000001473fc8c12d17767c0246ced0a0401f0444ea1cc"
                    ],
                    "blockNumber": 16692256,
                    "transactionIndex": 139,
                    "transactionHash": "0x5667e278da3675081e981a94987aecb416ceeb2b174efbc496fe69038446d5b9"
                }
            ],
            "cumulativeGasUsed": "0xa8c5d3",
            "effectiveGasPrice": "0xb4905f7a1",
            "contractAddress": null,
            "transactionIndex": 139,
            "transactionHash": "0x5667e278da3675081e981a94987aecb416ceeb2b174efbc496fe69038446d5b9"
        }
...

Usecases

  • GET searchEvent
    • 지정한 범위의 블록에서 발생한 특정 Event Log를 조회합니다.
    • Event 검색을 위해서는 해당 Event의 정의, 즉 Signature가 필요하기 때문에, 대상 컨트랙트의 ABI를 입력해야합니다.

Domain

Event

PropertyTypeDescriptionRequired
contractstring대상 컨트랙트의 주소required
namestringEvent 이름required
signaturestringEvent Signaturerequired
transactionobject해당 Event가 발생한 트랜잭션 정보 객체required
transaction.hashstring트랜잭션의 해시값required
blockobject관련 트랜잭션이 포함된 블록 정보 객체required
block.hashstring블록의 해시값required
block.numberinteger블록의 Numberrequired
topicarray:stringEvent에 기록된 관련 Topic 정보required
datastringData 항목required
logsobjectEvent에 기록된 Logs 객체required
indexinteger트랜잭션 내에서 해당 Event의 순번required