Somnia On-Chain 반응성
Source: Dev.to

1. 소개
Web3 개발자들은 자동 반응이 필요한 시스템을 자주 구축합니다.
온체인 게임, PotWar 풀, 예측 시장 등 실제 프로젝트의 예시:
- 타이머가 끝나면 마지막 플레이어가 승리합니다
- 상자를 연 후 자동 보상
- 풀 자동 지급
- NFT가 XP를 얻은 후 레벨업
- DAO 제안 자동 실행
전통적인 스마트 계약에서는 이것을 위해 다음이 필요합니다:
- 백엔드 서버
- 이벤트 인덱서
- 크론 작업
- 추가 사용자 트랜잭션
이로 인해 복잡성, 비용 및 중앙화가 증가합니다.
Somnia On‑Chain Reactivity는 스마트 계약이 온체인에서 완전히 자동으로 이벤트에 반응하도록 함으로써 이를 해결합니다.
2. Somnia 온‑체인 반응성은 무엇인가?
Somnia는 구독된 이벤트가 발생할 때 스마트 계약이 로직을 자동으로 실행하도록 합니다.
Traditional Flow
User Action → Event → Backend Listener → New Tx → State Update
Somnia Reactive Flow
User Action → Event → Validator Detect → _onEvent() → State Update
- 백엔드 없음.
- 추가 사용자 가스 없음.
- 완전 탈중앙화.
3. 왜 이것이 Web3 개발자에게 중요한가
게임, DeFi, 자동화 분야에서 일하는 빌더들을 위해:
- 서버 인프라 불필요
- 지연 시간 감소
- 더 깔끔한 아키텍처
- 향상된 사용자 경험(UX)
- 해커톤 빌드 속도 향상
예를 들어, Last Player Standing에서는 백엔드 타이머가 필요 없으며, 계약 로직이 자동으로 반응할 수 있습니다.
4. 예시: 매직 체스트 반응형 게임
작은 게임을 만들어 보겠습니다.
게임 규칙
- 일반 체스트 → +10 코인
- 희귀 체스트 → +50 코인
- 전설 체스트 → NFT 검
플레이어가 체스트를 열면 → 보상이 자동으로 지급됩니다.
5. Solidity 계약 예시
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;
import { SomniaEventHandler }
from "@somnia-chain/reactivity-contracts/contracts/SomniaEventHandler.sol";
contract MagicChestReactiveGame is SomniaEventHandler {
event ChestOpened(address indexed player, uint256 chestType);
mapping(address => uint256) public coins;
mapping(address => bool) public hasSword;
bytes32 constant CHEST_SIG =
keccak256("ChestOpened(address,uint256)");
uint256 constant COMMON = 1;
uint256 constant RARE = 2;
uint256 constant LEGENDARY = 3;
function openChest(uint256 chestType) external {
emit ChestOpened(msg.sender, chestType);
}
function _onEvent(
address,
bytes32[] calldata topics,
bytes calldata data
) internal override {
require(topics[0] == CHEST_SIG, "Wrong event");
address player =
address(uint160(uint256(topics[1])));
uint256 chestType =
abi.decode(data, (uint256));
if (chestType == COMMON)
coins[player] += 10;
else if (chestType == RARE)
coins[player] += 50;
else if (chestType == LEGENDARY)
hasSword[player] = true;
}
}
6. 반응성 내부 작동 방식
- 플레이어가
openChest()를 호출합니다 - 이벤트가 발생합니다
- Somnia 검증자들이 구독을 감지합니다
_onEvent()가 자동으로 실행됩니다- 상태가 업데이트됩니다
- 추가 트랜잭션이 필요하지 않습니다
반응형 트랜잭션은 다음 검증자 주소에 의해 실행됩니다:
0x0000000000000000000000000000000000000100
7. 이벤트에 대한 구독 생성
import { SDK } from "@somnia-chain/reactivity";
import { privateKeyToAccount } from "viem/accounts";
import { createPublicClient, createWalletClient, http } from "viem";
import { somniaTestnet } from "viem/chains";
import { keccak256, toBytes } from "viem";
const CONTRACT = "0xYourContractAddress";
async function main() {
const account = privateKeyToAccount(
process.env.PRIVATE_KEY as `0x${string}`
);
const publicClient = createPublicClient({
chain: somniaTestnet,
transport: http(),
});
const walletClient = createWalletClient({
account,
chain: somniaTestnet,
transport: http(),
});
const sdk = new SDK({
public: publicClient,
wallet: walletClient,
});
const EVENT_SIG = keccak256(
toBytes("ChestOpened(address,uint256)")
);
const txHash = await sdk.createSoliditySubscription({
handlerContractAddress: CONTRACT,
emitter: CONTRACT,
eventTopics: [EVENT_SIG],
gasLimit: 3_000_000n,
});
const receipt = await publicClient.waitForTransactionReceipt({
hash: txHash,
});
// 👉 Extract subscriptionId
const log = receipt.logs[0];
const subscriptionId = BigInt(log.topics[2]);
console.log("Subscription ID:", subscriptionId.toString());
}
main();
중요한 참고 사항
- 32 STT 잔액이 필요합니다.
- 구독 ID를 저장하세요.
- 이벤트 시그니처는 정확히 일치해야 합니다.
8. 반응성 테스트
import { ethers } from "hardhat";
const CONTRACT = "0xYourContractAddress";
async function main() {
const [user] = await ethers.getSigners();
const game = await ethers.getContractAt(
"MagicChestReactiveGame",
CONTRACT
);
const before = await game.coins(user.address);
console.log("Coins before:", before.toString());
const tx = await game.openChest(1); // 1 = COMMON
await tx.wait();
console.log("Waiting for Somnia reactivity...");
await new Promise(r => setTimeout(r, 5000)); // adjust as needed
const after = await game.coins(user.address);
console.log("Coins after:", after.toString());
if (after > before) {
console.log("✅ Reactivity Working");
} else {
console.log("❌ No Reactivity");
}
}
main();
9. 실제 사용 사례
게임
- 최후의 플레이어 승리
- PotWar 자동 지급
- 전리품 보상
- NFT 업그레이드
예측 시장
- 자동 보상 분배
- 점수 업데이트
디파이
- 청산
- 수익 분배
DAO
- 제안 자동 실행
10. Conclusion
Somnia 온‑체인 반응성은 백엔드 의존성을 제거하고 완전 자율 스마트 계약을 가능하게 합니다.
자동화된 게임 로직, 예측 시장, 또는 DeFi 자동화를 구축하는 개발자에게 이는 확장성과 단순성의 새로운 수준을 열어줍니다.
Web3 앱의 미래는 반응형입니다.
Neeraj Choubisa (Nikku.Dev) – 스마트 계약 개발, Web3 통합 및 소비자 중심 탈중앙화 애플리케이션을 전문으로 하는 풀‑스택 블록체인 엔지니어.
