Documentation Index
Fetch the complete documentation index at: https://docs.stablenet.network/llms.txt
Use this file to discover all available pages before exploring further.
WebSocket 구독과 로그 쿼리를 사용해 StableNet에서 새 블록과 컨트랙트 이벤트를 실시간으로 수신합니다.
배우는 내용
이 튜토리얼을 완료하면 다음을 할 수 있습니다:
- WebSocket으로 새 블록 헤더 구독
- 토픽 필터에 맞는 컨트랙트 이벤트 구독
eth_getLogs로 컨트랙트 과거 로그 조회
사전 준비
- Node.js ≥ 18
npm install ethers (v6)
- 이벤트를 발생시키는 배포된 컨트랙트 (예: Foundry로 배포하기의
WKRCPayment 컨트랙트)
WebSocket으로 연결
eth_subscribe는 지속적인 WebSocket 연결이 필요합니다. HTTP 엔드포인트는 구독을 지원하지 않습니다.
import { ethers } from "ethers";
const wsProvider = new ethers.WebSocketProvider(
"wss://api.test.stablenet.network/ws"
);
새 블록 헤더 구독
새 블록이 생성될 때마다 헤더 이벤트가 발생합니다. 체인 진행 상황 추적이나 폴링 로직 트리거에 활용합니다.
wsProvider.on("block", async (blockNumber) => {
const block = await wsProvider.getBlock(blockNumber);
console.log(`Block ${block.number} — hash: ${block.hash}`);
});
Block 1234567 — hash: 0xabc...
Block 1234568 — hash: 0xdef...
컨트랙트 이벤트 구독
특정 컨트랙트의 이벤트를 수신하려면 컨트랙트의 ABI와 주소로 ethers.Contract 인스턴스를 생성합니다. 아래 예시는 WKRCPayment 컨트랙트의 Payment 이벤트를 구독합니다.
const CONTRACT_ADDRESS = "0xYourDeployedContract";
const ABI = [
"event Payment(address indexed from, address indexed to, uint256 amount)"
];
const contract = new ethers.Contract(CONTRACT_ADDRESS, ABI, wsProvider);
contract.on("Payment", (from, to, amount, event) => {
console.log(`Payment from ${from} to ${to}: ${ethers.formatEther(amount)} WKRC`);
console.log(` tx: ${event.log.transactionHash}`);
});
Payment from 0xSender to 0xRecipient: 1.0 WKRC
tx: 0xabc...
토픽으로 이벤트 필터링
특정 발신자의 이벤트만 수신하려면 토픽 필터를 추가합니다. EVM 토픽 필터에서 null은 와일드카드입니다.
// 특정 주소가 보낸 결제만 수신
const filter = contract.filters.Payment("0xSpecificSender");
contract.on(filter, (from, to, amount) => {
console.log(`Filtered payment: ${ethers.formatEther(amount)} WKRC`);
});
eth_getLogs로 과거 로그 조회
지속적인 연결 없이 과거 이벤트를 조회하려면 eth_getLogs를 사용합니다. 블록 범위와 토픽 필터를 지정합니다.
const httpProvider = new ethers.JsonRpcProvider(
"https://api.test.stablenet.network"
);
const logs = await httpProvider.getLogs({
address: CONTRACT_ADDRESS,
fromBlock: 1200000,
toBlock: "latest",
topics: [
ethers.id("Payment(address,address,uint256)") // 이벤트 시그니처의 keccak256
],
});
for (const log of logs) {
const parsed = contract.interface.parseLog(log);
console.log(
`Block ${log.blockNumber}: ${ethers.formatEther(parsed.args.amount)} WKRC`
);
}
Block 1234500: 1.0 WKRC
Block 1234512: 0.5 WKRC
구독 정리
더 이상 필요하지 않을 때 이벤트 리스너를 제거해 메모리 누수를 방지합니다.
// 특정 리스너 제거
contract.off("Payment", listenerFunction);
// 이벤트의 모든 리스너 제거
contract.removeAllListeners("Payment");
// WebSocket 연결 종료
await wsProvider.destroy();
토픽 매칭 규칙
토픽은 indexed 이벤트 파라미터에 매핑됩니다. 한 위치에 여러 값을 지정하면 OR 조건, 값이 없는 위치는 와일드카드입니다.
| 위치 | 의미 |
|---|
topics[0] | 이벤트 시그니처 해시 (항상 필수) |
topics[1] | 첫 번째 indexed 파라미터 (from) |
topics[2] | 두 번째 indexed 파라미터 (to) |
어떤 위치든 null | 모든 값에 매칭 |
최대 4개의 토픽 위치를 지원합니다.
다음 단계
Foundry로 배포하기
이벤트를 발생시키는 컨트랙트를 배포합니다.
RPC API 레퍼런스
eth_subscribe, eth_getLogs, 필터 메서드 전체 레퍼런스.
온체인 데이터 읽기
잔액, 스토리지 슬롯, 컨트랙트 상태를 조회합니다.
수수료 위임
별도 계정이 사용자 대신 가스를 납부하게 합니다.