Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

언본딩 완료 추적

언본딩 기간이 완료되면 프로토콜은 시스템 트랜잭션을 통해 StableSystem 사전 컴파일러 (0x0000000000000000000000000000000000009999)를 통해 UnbondingCompleted 이벤트를 내보냅니다. 이를 통해 dApp은 사용자 지정 인덱서를 실행하거나 REST 엔드포인트를 폴링하지 않고도 사용자에게 알리고 실시간으로 잔액을 업데이트할 수 있습니다.

전제 조건

  • 시스템 트랜잭션에 대한 이해.
  • 스테이킹, 특히 undelegate 및 언본딩 프로세스에 대한 숙지.
  • 표준 web3 라이브러리 (예: ethers.js v6)를 사용한 컨트랙트 이벤트 구독 및 필터링 경험.

개요

  • 컨트랙트 인스턴스 설정: StableSystem 사전 컴파일러에 대한 컨트랙트 인스턴스를 생성합니다.
  • 애플리케이션에서 이벤트 처리: 애플리케이션 로직에 따라 실시간 이벤트를 구독하거나 과거 데이터를 쿼리합니다.
  • 연결 문제 처리: 지속적인 WebSocket 구독을 위한 재연결 로직을 구현합니다.

1단계: 컨트랙트 인스턴스 설정

UnbondingCompleted 이벤트 ABI를 사용하여 StableSystem 사전 컴파일러에 대한 컨트랙트 인스턴스를 생성합니다.

// config.ts
import { ethers } from "ethers";
 
export const STABLE_SYSTEM_ADDRESS =
  "0x0000000000000000000000000000000000009999";
 
export const STABLE_SYSTEM_ABI = [
  "event UnbondingCompleted(address indexed delegator, address indexed validator, uint256 amount)",
];
 
export const provider = new ethers.JsonRpcProvider("https://rpc.testnet.stable.xyz");
export const stableSystem = new ethers.Contract(
  STABLE_SYSTEM_ADDRESS,
  STABLE_SYSTEM_ABI,
  provider
);

2단계: 애플리케이션에서 이벤트 처리

애플리케이션 로직에 따라 실시간 이벤트를 구독하거나 과거 데이터를 쿼리하거나 둘 다 수행합니다.

실시간 구독

언본딩이 완료될 때 실시간 알림을 위해 UnbondingCompleted 이벤트를 구독합니다. 잔액 업데이트 트리거, 알림 전송 또는 대시보드 통계 새로고침에 유용합니다.

// subscribeBasic.ts
import { stableSystem } from "./config";
 
stableSystem.on("UnbondingCompleted", (delegator, validator, amount, event) => {
  console.log("Unbonding completed:");
  console.log("  Delegator:", delegator);
  console.log("  Validator:", validator);
  console.log("  Amount:", ethers.formatEther(amount), "tokens");
  console.log("  Block:", event.log.blockNumber);
  console.log("  Tx Hash:", event.log.transactionHash);
});

사용자별 필터링

특정 위임자 주소에 대한 이벤트만 수신하려면 인덱싱된 이벤트 매개변수를 사용하여 필터를 생성합니다.

// subscribeByUser.ts
import { ethers } from "ethers";
import { stableSystem } from "./config";
 
const userAddress = "0xabcd...";
const filter = stableSystem.filters.UnbondingCompleted(userAddress);
 
stableSystem.on(filter, (delegator, validator, amount, event) => {
  refreshUserBalance(userAddress);
  showNotification(
    `Your unbonding of ${ethers.formatEther(amount)} tokens completed!`
  );
});

검증인별 필터링

// subscribeByValidator.ts
import { stableSystem } from "./config";
 
const validatorAddress = "0x1234...";
const validatorFilter = stableSystem.filters.UnbondingCompleted(
  null,
  validatorAddress
);
 
stableSystem.on(validatorFilter, (delegator, validator, amount) => {
  updateValidatorStats(validator, amount);
});

과거 쿼리

dApp에서 과거 언본딩 완료 기록을 표시해야 하는 경우 블록 범위가 있는 이벤트 필터를 사용하여 과거 이벤트를 쿼리합니다.

// queryHistory.ts
import { ethers } from "ethers";
import { provider, stableSystem } from "./config";
 
async function getUnbondingHistory(
  userAddress: string,
  fromBlock: number,
  toBlock: number
) {
  const filter = stableSystem.filters.UnbondingCompleted(userAddress);
  const events = await stableSystem.queryFilter(filter, fromBlock, toBlock);
 
  return events.map((event) => ({
    delegator: event.args.delegator,
    validator: event.args.validator,
    amount: ethers.formatEther(event.args.amount),
    blockNumber: event.blockNumber,
    txHash: event.transactionHash,
  }));
}
 
const currentBlock = await provider.getBlockNumber();
const history = await getUnbondingHistory(
  "0xabcd...",
  currentBlock - 1000,
  currentBlock
);

3단계: 연결 문제 처리

이벤트 구독은 지속적인 WebSocket 연결에 의존합니다. 프로덕션 dApp을 위한 재연결 로직을 구현합니다.

// subscribeWithReconnection.ts
import { ethers } from "ethers";
import { STABLE_SYSTEM_ADDRESS, STABLE_SYSTEM_ABI } from "./config";
 
let reconnectAttempts = 0;
const MAX_RECONNECT_ATTEMPTS = 5;
 
function handleUnbonding(delegator: string, validator: string, amount: bigint) {
  console.log("Unbonding completed:", { delegator, validator, amount });
}
 
function setupEventListener() {
  const wsProvider = new ethers.WebSocketProvider("wss://rpc.testnet.stable.xyz");
 
  wsProvider.on("error", (error) => {
    console.error("Provider error:", error);
    if (reconnectAttempts < MAX_RECONNECT_ATTEMPTS) {
      reconnectAttempts++;
      setTimeout(() => setupEventListener(), 5000);
    }
  });
 
  const stableSystem = new ethers.Contract(
    STABLE_SYSTEM_ADDRESS,
    STABLE_SYSTEM_ABI,
    wsProvider
  );
 
  stableSystem.on("UnbondingCompleted", handleUnbonding);
}
 
setupEventListener();

다음 권장 사항