event vs 상태 변수 비교
블록체인에 이력을 남기는 방법은 두 가지입니다. 상태 변수(storage) 에 저장하거나, 이벤트(로그) 로 발행하는 것입니다. 둘은 비슷해 보여도 목적과 비용, 접근 방식이 전혀 다릅니다.
상태 변수와 이벤트의 차이
| 구분 | 상태 변수 (storage) | 이벤트 (로그) |
|---|---|---|
| 저장 위치 | 컨트랙트 스토리지 | 트랜잭션 로그 |
gas 비용 | 비쌈 (슬롯당 20,000+) | 저렴함 |
| 컨트랙트에서 읽기 | 가능 | 불가능 |
| 외부 앱에서 조회 | getter 호출 | 로그 구독·필터 |
스토리지에 값을 새로 쓰면 슬롯 하나당 수만 gas 가 들지만, 이벤트 발행은 그보다 한참 저렴합니다. 그래서 "두고두고 다시 계산에 써야 하는 값"이 아니라면 이벤트 쪽이 경제적입니다.
왜 이벤트는 컨트랙트에서 못 읽는가?
이벤트 로그 는 EVM의 실행 상태(state)가 아니라 트랜잭션 영수증에만 기록되는 별도 영역 입니다. 컨트랙트 코드가 접근할 수 있는 것은 스토리지와 메모리뿐이고, 로그 는 노드가 외부에 공개하는 데이터입니다. 그래서 방금 emit 한 값조차 같은 컨트랙트 안에서 다시 읽지 못합니다.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract Counter {
uint256 public count; // 로직에서 다시 읽어야 함 → 상태 변수
event Incremented(uint256 newCount); // 외부 알림용 → 이벤트
function increment() public {
count += 1; // 다음 호출에서 또 써야 하므로 storage
emit Incremented(count); // 외부 알림이므로 로그
}
}컨트랙트 로직이 다시 읽어야 하는 값은 상태 변수 에 저장하고, 외부에 알리거나 이력으로만 남길 내용은 이벤트로 발행합니다.
실무에서는 둘을 함께 씁니다. 잔액 같은 핵심 값은 상태 변수 로 보관하고, "입금 발생"이라는 사건은 이벤트로 남겨 dApp이 그 로그 를 듣고 화면을 갱신하게 합니다.