메인 콘텐츠로 건너뛰기

목적 및 범위

이 문서는 StableNet 블록체인의 블록 및 헤더 구조, 인코딩 방식, 해시 계산, 머클 루트 구성, 그리고 WBFT 합의에 특화된 Extra 데이터 구조를 설명합니다.
블록이 어떻게 구성되고 검증되며, 합의 과정에서 어떤 데이터가 헤더에 포함되는지를 중심으로 다룹니다.
관련 문서:

블록 구조 개요

블록은 메타데이터를 포함하는 헤더, 트랜잭션을 포함하는 본문, 선택적 인출(withdrawals) 목록과 엉클(uncles) 목록으로 구성됩니다.
StableNet(WBFT 기반)에서는 엉클을 사용하지 않으며, 항상 비어 있습니다.

Block 타입

Block 구조체(core/types/block.go)의 주요 필드:
필드타입설명
header*Header메타데이터 및 머클 루트를 포함한 블록 헤더
transactionsTransactions블록에 포함된 트랜잭션 목록
uncles[]*Header엉클 블록 헤더 (사용안함)
withdrawalsWithdrawals인출 목록 (Shanghai 이후 선택적)
hashatomic.Value캐시된 블록 해시
sizeatomic.Value캐시된 RLP 인코딩 크기
블록은 생성 이후 불변(immutable) 객체로 취급됩니다. 내부 데이터는 생성 시 복사되며, 해시와 크기 캐시는 이후 변경되지 않습니다.

헤더 구조

Header는 블록의 핵심 메타데이터로, 블록 내용과 실행 결과에 대한 암호학적 커밋을 포함합니다.

핵심 헤더 필드

필드타입설명
ParentHashcommon.Hash부모 블록 헤더 해시
UncleHashcommon.Hash엉클 목록 해시 (StableNet에서는 EmptyUncleHash)
Coinbasecommon.Address블록 수수료 수령 주소(검증자 주소)
Rootcommon.Hash블록 실행 후 상태 trie 루트
TxHashcommon.Hash트랜잭션 머클 루트
ReceiptHashcommon.Hash영수증 머클 루트
BloomBloom로그 블룸 필터
Difficulty*big.Int블록 난이도 (WBFT: 항상 1)
Number*big.Int블록 번호
GasLimituint64블록 가스 한도
GasUseduint64사용된 총 가스
Timeuint64블록 생성 시각
Extra[]byteWBFT 합의 데이터 (RLP 인코딩)
MixDigestcommon.HashPoW 필드 (WBFT에서는 사용되지 않음)
NonceBlockNoncePoW 필드 (WBFT에서는 사용되지 않음)
StableNet 특이사항:
  • Difficulty는 항상 1로 설정되어 WBFT 블록임을 식별합니다
  • Coinbase는 검증자의 합의 서명 주소이며 운영자 주소와 다를 수 있습니다
  • Extra에는 WBFT 합의 라운드 정보, 집계 서명, 가스 팁, 에포크 정보가 포함됩니다
  • GasLimit은 체인 파라미터에 의해 고정된 값으로 운영됩니다

포크별 선택적 필드

다음 필드들은 특정 포크 이후에만 존재하며, nil이 아닌 경우에만 RLP 인코딩에 포함됩니다.
필드EIP포크설명
BaseFeeEIP-1559London블록 기본 수수료
WithdrawalsHashEIP-4895Shanghai인출 머클 루트
BlobGasUsedEIP-4844Cancunblob 가스 사용량
ExcessBlobGasEIP-4844Cancun초과 blob 가스
ParentBeaconRootEIP-4788Cancun비콘 체인 부모 루트

본문 구조

블록 본문은 실제 실행 데이터로 구성됩니다.
  • Transactions: 트랜잭션 목록
  • Uncles: 엉클 헤더 목록 (사용 안함)
  • Withdrawals: 인출 목록 (해당 포크 이후)

RLP 인코딩

블록과 헤더는 모두 Recursive Length Prefix(RLP) 인코딩을 사용합니다.

블록 인코딩

블록은 다음과 같은 RLP 리스트로 인코딩됩니다.
[header, transactions, uncles, withdrawals]
Shanghai 이전 블록에서는 withdrawals 항목이 존재하지 않습니다.

헤더 인코딩

헤더는 정의된 필드 순서대로 RLP 인코딩되며, 선택적 필드는 값이 존재할 때만 포함됩니다.

블록 및 헤더 해싱

표준 해싱

블록 해시는 헤더만을 기준으로 계산됩니다.
block_hash = keccak256(rlp(header))
계산된 해시는 캐시되어 반복 계산을 방지합니다.

WBFT 전용 헤더 해싱

WBFT에서는 합의 서명이 헤더의 Extra 필드에 포함되므로, 서명 대상 해시 계산 시 서명 자체를 제외해야 합니다. 이를 위해 WBFTFilteredHeader()가 사용됩니다.
  • PreparedSeal, CommittedSeal 제거
  • 라운드 번호, 에포크 정보, 가스 팁은 유지
  • Difficulty == 1인 경우에만 적용
이로 인해 서명과 해시 간 순환 의존성이 발생하지 않습니다.

라운드 포함 해시

WBFT 합의 라운드에서는 라운드 번호를 포함한 별도의 해시를 사용하여, 동일 블록 제안이라도 라운드별로 다른 서명 대상이 됩니다.

WBFT Extra 데이터 구조

WBFT 합의 데이터는 헤더의 Extra 필드에 RLP 인코딩되어 저장됩니다.

WBFTExtra 구조

필드타입설명
VanityData[]bytevanity 데이터
RandaoReveal[]byte랜덤성용 BLS 서명
PrevRounduint32이전 합의 라운드
PrevPreparedSeal*WBFTAggregatedSeal이전 prepare 집계 서명
PrevCommittedSeal*WBFTAggregatedSeal이전 commit 집계 서명
Rounduint32현재 합의 라운드
PreparedSeal*WBFTAggregatedSeal현재 prepare 집계 서명
CommittedSeal*WBFTAggregatedSeal현재 commit 집계 서명
GasTip*big.Int거버넌스가 결정한 가스 팁
EpochInfo*EpochInfo다음 에포크 정보 (에포크 블록에서만 포함)
nil인 필드는 RLP 인코딩에서 제외됩니다.

WBFTAggregatedSeal

여러 검증자의 BLS 서명을 하나로 집계한 구조입니다.
필드타입설명
SealersSealerSet서명한 검증자 비트맵
Signature[]byte집계된 BLS 서명

EpochInfo

에포크 블록에만 포함되며, 다음 에포크의 검증자 세트를 정의합니다.
필드타입설명
Candidates[]*Candidate모든 검증자 후보
Validators[]uint32활성 검증자 인덱스
BLSPublicKeys[][]byte검증자 BLS 공개 키

머클 루트 계산

TxHash

트랜잭션 목록을 Merkle Patricia Trie로 구성하여 계산됩니다.
빈 목록은 EmptyTxsHash를 사용합니다.

ReceiptHash

영수증 목록으로 동일한 방식으로 계산되며, 블룸 필터는 영수증에서 파생됩니다.

UncleHash

엉클 헤더 목록의 해시이며, StableNet에서는 항상 EmptyUncleHash입니다.

WithdrawalsHash

Shanghai 이후 블록에서 인출 목록에 대해 계산됩니다.

블록 구성

NewBlock 함수

NewBlock()은 다음 절차로 블록을 생성합니다.
  1. 헤더 복사
  2. 트랜잭션 머클 루트 계산
  3. 영수증 루트 및 블룸 계산
  4. 엉클 해시 계산
  5. 본문 데이터 결합
WBFT 블록의 경우:
  • Difficulty = 1
  • Extra에 WBFTExtra 인코딩
  • 에포크 블록에서만 EpochInfo 포함
Shanghai 이후에는 NewBlockWithWithdrawals()를 사용합니다.

헤더 무결성 검사

Header.SanityCheck()는 비정상 입력으로 인한 DoS를 방지합니다.
필드제한
Number64비트 범위
Difficulty합리적 비트 길이
Extra최대 크기 제한
BaseFeeuint256 범위

블록 크기 계산

블록 크기는 RLP 인코딩된 전체 크기이며, Block.Size()로 조회합니다.
Blob 트랜잭션이 포함된 경우 사이드카 데이터도 크기에 포함됩니다.