본문으로 건너뛰기

StateCell

StateCell은 Nigo 원장의 최소 상태 단위입니다. Nigo는 하나의 전역 account object를 제자리에서 덮어쓰는 대신, 의미가 분리된 StateCell을 소비하고 생성해 상태 변화를 표현합니다.

StateCell 모델은 UTXO의 명시적 input/output 추적성과 EVM의 slot 기반 상태 실행을 동일한 원장 상태와 commitment 위에 결합하기 위한 기반입니다.

StateCell의 구성

하나의 StateCell은 네 필드로 구성됩니다.

필드형식의미
idversioned binary StateCellId원장 안에서 셀을 식별하는 canonical key
owner20-byte address셀의 소유 또는 접근 주체
schemaHash32-byte hash값의 구조와 타입을 식별하는 structural hash
valueprimitive value실제로 저장되는 단일 primitive payload

지원되는 primitive type은 다음과 같습니다.

UINT8, UINT64, UINT256, INT64, INT256,
ADDRESS, BOOL, BYTES4, BYTES32, BYTES, STRING

StateCell 하나에는 일반적인 구조체나 배열 객체 전체를 넣지 않습니다. Schema-backed 복합 상태는 여러 primitive leaf로 분해하고, EVM storage는 Solidity가 계산한 최종 256-bit slot 하나를 UINT256 StateCell 하나로 저장합니다.

StateCell ID V1

StateCellId는 표시용 이름이 아니라 versioned binary protocol address입니다.

UINT8 formatVersion = 0x01
UINT8 domain
UINT8 subtype
BYTES body

ID의 전체 길이는 3~255 bytes이고 subtype 0은 할당하지 않습니다. Canonical hex 표현에는 version, domain, subtype을 포함한 전체 바이트가 들어갑니다.

0x 01 | domain | subtype | body...

RPC가 제공하는 사람이 읽기 쉬운 ID나 metadata는 표시용 projection입니다. Transaction hash, DB key와 state commitment에는 canonical binary ID만 사용합니다.

Domain

DomainCode소유 영역
GENERIC0x00protocol-neutral ID와 Direct Cell output
NATIVE_ASSET0x01NIGO를 포함한 Native Asset output과 supply state
NATIVE_SYSTEM0x02Native Program identity, revision, activation과 runtime
NATIVE_PROGRAM_STATE0x03Native Program이 소유하는 persisted state
EVM0x04EVM storage slot, canonical nonce와 code reference
PROTOCOL0x05fee, consensus 등 chain-wide canonical configuration

Domain code를 등록하는 것과 domain의 업무 규칙을 검증하는 것은 별개입니다. nigo-state-cell은 canonical ID shape를 보존하고, allowance·asset supply·EVM slot·fee policy 같은 의미는 각 실행 소유 모듈이 검증합니다.

세 가지 대표 상태 패턴

Schema-backed 상태

일반적인 구조체와 배열은 schema를 따라 primitive leaf로 분해됩니다.

AccountProfile
├── owner: ADDRESS -> StateCell A
├── enabled: BOOL -> StateCell B
└── limit: UINT256 -> StateCell C

필드 하나가 바뀌면 전체 객체를 다시 저장하지 않고 변경된 leaf만 교체합니다. 구조화 상태를 읽을 때는 필요한 leaf를 batch로 가져오고 schema와 완전성을 검증한 뒤 원래 값으로 복원합니다.

EVM storage

EVM storage는 schema-backed decomposer를 사용하지 않습니다.

EvmStorageCellId(contractAddress, slot256)
-> UINT256 StateCell

Solidity struct, mapping과 array의 layout은 compiler와 EVM이 최종 slot으로 계산합니다. Nigo는 그 slot을 다시 논리 필드로 분해하지 않으므로 SLOADSSTORE 의미를 중복 정의하지 않습니다.

Native Asset

Native Asset은 소비 가능한 output과 supply state로 표현됩니다. NIGO는 별도 ID namespace가 아니라 NATIVE_ASSET domain의 zero asset ID를 사용합니다. Asset별 controller와 Native Program은 소유권, 수량 보존, mint/burn 또는 관리형 이전 정책을 검증합니다.

상태 생명주기

StateStore의 핵심 전이는 spend와 create입니다.

논리적인 값 변경도 내부 객체를 직접 수정하는 대신 기존 셀을 spend하고 replacement를 생성합니다.

before
Cell ID X -> value 10

transition
spentIds: [X]
createdCells: [Cell ID X -> value 11]

after
Cell ID X -> value 11

동일 ID가 spent와 created 목록에 각각 한 번 존재하면 replacement입니다. 새 ID를 사용하면 이전 output과 새 output의 lineage가 명시적으로 분리됩니다.

applyBatch(spentIds, createdCells)은 검증된 spend와 create를 하나의 상태 전이로 원자 적용합니다. 이미 active인 ID의 중복 생성, 존재하지 않거나 이미 소비된 ID의 spend와 batch 안의 중복 ID는 거부됩니다.

Overlay와 StateDelta

Transaction과 block 실행은 실제 저장소를 즉시 변경하지 않고 BufferedStateStore overlay에서 진행합니다.

성공한 child overlay만 부모에 병합되고 실패한 실행은 폐기됩니다. Overlay의 최종 결과는 canonical ID 순서의 StateDelta로 정규화됩니다.

StateDelta
spentIds
createdCells

Overlay 안에서 생성한 뒤 다시 spend한 Cell은 최종 delta에 나타나지 않습니다. State commitment 계층은 전체 active state를 다시 읽는 대신 이 delta를 이전 root에 적용합니다.

Transaction lineage

Receipt는 실행 중 읽거나 소비한 input, 생성된 output과 spent ID를 기록합니다. 이를 통해 상태 관계를 다음과 같이 해석할 수 있습니다.

관계의미
CREATING이전에 없던 StateCell이 transaction 결과로 생성됨
SPENDING기존 StateCell이 소비되어 더 이상 active하지 않음
MUTATINGEVM 실행에서 같은 StateCell ID가 소비되고 replacement로 다시 생성됨

Cell transaction은 선언된 input을 소비하고 output을 생성하는 관계로 기록합니다. EVM storage update는 같은 slot ID의 spend와 replacement가 함께 나타날 수 있으므로 mutation으로 분류할 수 있습니다.

StateCell과 결정론적 병렬 실행

명시적인 StateCell ID는 transaction의 read/write 집합을 분석하는 단위가 됩니다. 서로 독립적인 StateCell에만 접근하는 transaction은 같은 frozen state view에서 실행할 수 있고, 충돌하거나 접근 범위를 완전히 증명할 수 없는 transaction은 canonical 순서로 실행합니다.

병렬 worker 수와 scheduling 전략은 node-local 최적화입니다. 최종 StateDelta, receipt와 state root는 같은 block을 순차 실행한 결과와 동일해야 합니다.

Protocol limit

항목현재 한도
StateCell ID최대 255 bytes
StateCell value최대 16 MiB
Schema depth최대 64
Schema node최대 4,096
Struct field최대 1,024
Array length최대 100,000
Structured state leaf최대 100,000

이 값은 합의 안전을 위한 상한입니다. 실제 배포 profile은 더 낮은 업무·운영 한도를 둘 수 있습니다.

StateCell이 의미하지 않는 것

  • 모든 StateCell이 금융 자산 UTXO라는 의미는 아닙니다.
  • EVM account와 storage 의미가 없어지는 것이 아닙니다. EVM 상태를 StateCell로 영속화합니다.
  • owner만으로 모든 접근 권한이 결정되는 것은 아닙니다. Domain별 Core/VM 규칙이 추가로 적용됩니다.
  • 사람이 읽는 friendly ID는 canonical identity가 아닙니다.
  • StateCell 구현만으로 전체 storage lifecycle, pruning 또는 production 운영 승인이 완료되는 것은 아닙니다.

다음 문서