메인 콘텐츠로 건너뛰기

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.

월드 스테이트는 StableNet의 모든 계정에 대한 완전한 스냅샷입니다. 모든 트랜잭션은 이를 변경하거나 정확히 그대로 유지합니다 — 부분 업데이트는 없습니다.

월드 스테이트가 담고 있는 것

StableNet의 모든 주소는 다섯 개의 필드를 가집니다:
필드타입설명
nonceuint64전송된 트랜잭션 수 (EOA) 또는 생성된 컨트랙트 수 (컨트랙트)
balanceuint256wei 단위 WKRC 잔액 — WKRC.balanceOf(address)와 동일
codeHashbytes32컨트랙트 바이트코드의 Keccak-256; EOA는 keccak256("")
storageRootbytes32계정 스토리지 트라이의 루트
extrauint64StableNet 정책 플래그 (블랙리스트, 인증됨) — GovCouncil이 설정
WKRC를 받거나 트랜잭션을 보낸 적 없는 주소는 스테이트에 존재하지 않습니다 — “빈 계정” 항목이 없습니다.

트랜잭션이 상태를 변경하는 방법

각 트랜잭션은 현재 상태의 스냅샷을 기반으로 실행됩니다. 변경 사항은 발생하는 대로 저널에 기록됩니다. 실행이 성공하면 변경 사항이 커밋됩니다. revert되면 저널이 되감겨져 상태가 호출 이전과 동일해집니다.
tx 이전:  StateDB 스냅샷 생성
tx 중:    잔액 / 논스 / 스토리지 변경이 메모리 저널에 기록
revert 시: 저널 되감기 → 상태 변경 없음
성공 시:  변경 사항 확정 → 새 상태 루트 계산
이는 모든 호출 깊이에서 적용됩니다. 컨트랙트 A가 컨트랙트 B를 호출하는 최상위 트랜잭션에서 — B가 revert되면 B의 변경 사항만 롤백됩니다. 그 시점까지 A의 변경 사항은 유지됩니다 (A도 revert하지 않는 한).

컨트랙트 스토리지

각 컨트랙트는 고유한 스토리지 트라이를 가집니다 — 32바이트 슬롯 번호로 키를 지정하는 별도의 키-값 저장소입니다. Solidity 변수는 레이아웃 규칙에 따라 스토리지 슬롯에 매핑됩니다. 한 번도 쓰지 않은 슬롯을 읽으면 bytes32(0)이 반환됩니다. 점유된 슬롯에 bytes32(0)을 쓰면 슬롯이 해제됩니다 (가스 환불에 중요).
// 스토리지 트라이에서 읽기
uint256 public counter;          // 슬롯 0
mapping(address => uint256) bal; // 슬롯 1 (키는 슬롯 번호와 함께 해시됨)
트랜잭션 없이 컨트랙트 스토리지를 읽으려면 eth_getStorageAt을 사용하세요:
const value = await provider.getStorage(contractAddress, slotIndex);

상태 루트와 블록 최종성

각 블록 끝에서 모든 보류 중인 상태 변경이 커밋되고 계정 트라이에서 새 상태 루트가 계산됩니다. 이 루트는 블록 헤더에 포함됩니다 — 블록 검증은 이 루트가 예상 사후 상태와 일치하는지 확인하는 것입니다. StableNet은 결정론적 최종성을 가진 Anzeon WBFT를 사용하기 때문에, 블록 N의 상태 루트는 해당 블록이 커밋되는 순간 최종 확정됩니다. 동일한 블록 번호에 대해 다른 상태 루트를 생성할 수 있는 포크가 없습니다.

extra 필드

StableNet은 GovCouncil이 관리하는 extra 필드로 표준 이더리움 계정 구조를 확장합니다:
비트의미효과
블랙리스트GovCouncil이 설정이 주소와 관련된 모든 전송 차단
인증됨GovCouncil이 설정거버넌스 가스 팁 적용 면제
컨트랙트는 extra를 직접 읽을 수 없습니다. EVM이 투명하게 이를 적용합니다 — 블랙리스트 주소로의 전송은 컨트랙트가 아무것도 하지 않아도 revert됩니다.

개발자 이점

  • 원자적 상태 변경 — 트랜잭션은 완전히 적용되거나 아무 효과가 없음
  • 완전한 revert — require() 실패는 상태를 호출 이전과 동일하게 유지
  • 컨트랙트 스토리지는 주소별로 격리 — 컨트랙트 간 네임스페이스 충돌 없음
  • eth_getStorageAt으로 트랜잭션 없이 모든 스토리지 슬롯 검사 가능

관련 문서