메인 콘텐츠로 건너뛰기

목적 및 범위

이 문서는 StableNet 네트워크의 제네시스 블록 생성, 체인 초기화, 검증자 키 구성 방법을 설명합니다. genesis_generator 도구를 사용한 자동 생성과 수동 제네시스 파일 작성을 모두 다룹니다. 관련 문서:

제네시스 파일 구조

제네시스 파일은 블록체인의 초기 상태를 정의하는 JSON 파일로, 체인 구성, 초기 계정 할당, 합의 매개변수를 포함합니다.

핵심 제네시스 필드

Genesis 구조체:
필드타입설명
Config*params.ChainConfig포크 규칙 및 합의 설정을 포함한 체인 구성
Timestampuint64제네시스 블록 타임스탬프
ExtraData[]byteAnzeon 체인에서 WBFT 검증자 정보가 RLP 인코딩되어 포함됨
GasLimituint64초기 블록 가스 상한
Difficulty*big.Int초기 난이도 (Anzeon에서는 1)
Alloctypes.GenesisAlloc사전 할당된 계정 및 배포된 컨트랙트 코드
BaseFee*big.IntEIP-1559 기본 수수료

Anzeon 합의 구성

Anzeon/WBFT 체인의 경우 ChainConfigAnzeon 필드가 포함됩니다. 이 구성에는 두 가지 검증자 세트 정의가 있습니다:
  • Init: 블록 1부터 첫 번째 에포크까지 활성인 검증자 (제네시스 블록의 ExtraData에 하드코딩)
  • SystemContracts.GovValidator: 두 번째 에포크부터 적용되는 검증자 세트 (거버넌스를 통해 변경 가능)
두 세트는 특별한 이유가 없는 한 일치해야 합니다. 에포크 전환 메커니즘에 대한 상세 내용은 Anzeon WBFT 합의 프로토콜을 참조하세요.

시스템 컨트랙트

StableNet은 제네시스에서 5개의 시스템 컨트랙트를 고정 주소에 배포합니다:
컨트랙트주소용도
NativeCoinAdapter0x0000000000000000000000000000000000001000네이티브 코인의 ERC20 래퍼
GovValidator0x0000000000000000000000000000000000001001검증자 세트 관리 및 가스 팁 거버넌스
GovMasterMinter0x0000000000000000000000000000000000001002민터 등록 관리
GovMinter0x0000000000000000000000000000000000001003민트/소각 거버넌스
GovCouncil0x0000000000000000000000000000000000001004블랙리스트/인증 계정 관리 거버넌스
시스템 컨트랙트는 소유자 없이 배포되며, 하드 포크를 통해서만 업그레이드할 수 있습니다. 각 컨트랙트의 상세 초기화 매개변수, 스토리지 슬롯, 의존성 관계는 시스템 컨트랙트 개요를 참조하세요.

제네시스 초기화 매개변수

제네시스에서 반드시 설정해야 하는 주요 매개변수입니다. GovValidator :
매개변수설명기본값
members거버넌스 멤버 주소 (쉼표 구분)필수
validators검증자 주소 (쉼표 구분)필수
blsPublicKeysBLS 공개 키 (0x 접두사, 쉼표 구분)필수
quorum제안 통과에 필요한 최소 투표 수필수
expiry제안 만료 시간 (초)604800 (7일)
memberVersion멤버 세트 버전”1”
maxProposals최대 동시 제안 수 (1-50)3
gasTip의무 가스 팁 (wei)27600000000000 (27600 Gwei)
members, validators, blsPublicKeys는 동일한 순서로 관리되는 병렬 목록이며, 각 목록의 같은 위치에 있는 값들이 하나의 검증자 신원을 구성합니다.
  • 운영자 주소 (members): 거버넌스 투표·검증자 등록/제거에 사용하는 EOA 또는 멀티시그 주소
  • 검증자 주소 (validators): 합의 메시지 서명·coinbase(블록 수수료 수신)에 쓰는 주소. 노드의 nodekey에서 파생
  • BLS 공개 키 (blsPublicKeys): 검증자 키에서 파생된 BLS 공개 키. WBFT PREPARE/COMMIT 집계 서명에 사용
자세한 키 역할·파생·운영 방법은 검증자 작업을 참고하세요. NativeCoinAdapter :
매개변수설명기본값
name토큰 이름”WKRC”
symbol토큰 심볼”WKRC”
decimals소수점 자릿수”18”
currency법정화폐 표시”KRW”
masterMinterGovMasterMinter 컨트랙트 주소0x...1002
mintersGovMinter 컨트랙트 주소0x...1003
minterAllowed민터당 최대 민트 가능량10^28

검증자 키 준비

네트워크 초기화 전에 각 검증자의 키를 생성해야 합니다.

노드키 생성

bootnode 유틸리티를 사용하여 노드키를 생성합니다:
# 노드키 생성
bootnode -genkey nodekey

# 생성된 노드키에서 주소 및 BLS 키 확인
bootnode -nodekey nodekey -writeaddress
노드키에서 파생되는 값:
파생 항목함수용도
검증자 주소crypto.PubkeyToAddress(nodeKey.PublicKey)블록 서명 주소 (coinbase)
BLS 개인 키bls.DeriveFromECDSA(nodeKey)합의 메시지 서명
BLS 공개 키blsKey.PublicKey().Marshal()제네시스 구성에 등록 (48바이트, hex 인코딩)
검증자 키 보안, 키 교체, 멀티시그 운영 키에 대한 상세 지침은 검증자 운영을 참조하세요.

genesis_generator 도구

genesis_generator는 시스템 컨트랙트가 올바르게 설정된 제네시스 파일을 생성하는 CLI 도구입니다.

빌드

cd go-stablenet
make genesis_generator

# 바이너리 위치: build/bin/genesis_generator

대화형 모드

인자 없이 실행하면 대화형 모드로 동작합니다:
./build/bin/genesis_generator
대화형 모드에서는 다음을 입력합니다:
  1. 합의 엔진 선택: Anzeon(WBFT) 선택
  2. 노드 수: 단일 노드 또는 다중 노드 선택
  3. 노드키 경로: 각 검증자의 노드키 파일 경로 (기본값: ./nodekey)
  4. 쿼럼 설정: 다중 노드 시 거버넌스 쿼럼 (최소 2, 최대 = 검증자 수)
  5. 체인 ID: 네트워크 고유 식별자 (미지정 시 랜덤 생성)
도구는 노드키에서 검증자 주소와 BLS 키를 자동으로 파생합니다.

명령줄 플래그

비대화형 모드로 사용할 수도 있습니다 (cmd/genesis_generator/genesis_generator.go 50-100):
플래그타입설명기본값
--chainIdint네트워크 체인 ID랜덤
--validatorsstring검증자 주소 (쉼표 구분)-
--blsKeysstringBLS 공개 키 (쉼표 구분)-
--membersstring거버넌스 멤버 주소 (쉼표 구분)-
--quorumint거버넌스 쿼럼-
--epochLengthint에포크당 블록 수10
--blockPeriodint목표 블록 시간 (초)1
--gasLimituint64제네시스 블록 가스 상한-
--outputstring출력 파일 경로genesis.json

생성 예시

단일 검증자 네트워크:
./build/bin/genesis_generator \
  --chainId 9999 \
  --validators 0xaa5f...1234 \
  --blsKeys 0xaec4...5678 \
  --members 0xaa5f...1234 \
  --quorum 1 \
  --output genesis.json
다중 검증자 네트워크:
./build/bin/genesis_generator \
  --chainId 9999 \
  --validators 0xaa5f...1234,0x294f...5678 \
  --blsKeys 0xaec4...abcd,0x91b2...efgh \
  --members 0xaa5f...1234,0x294f...5678 \
  --quorum 2 \
  --epochLength 10 \
  --blockPeriod 1 \
  --output genesis.json

제네시스 검증

genesis_generator가 생성 시 자동으로 수행하는 검증 항목 :
  1. Init.ValidatorsInit.BLSPublicKeys 배열 길이 일치 확인
  2. 각 BLS 공개 키가 올바른 hex 인코딩 및 길이(96바이트)인지 검증
  3. 모든 검증자 및 멤버 주소가 유효한 Ethereum 주소 형식인지 확인
  4. 에포크 길이, 블록 주기, 타임아웃 값의 범위 확인
  5. 시스템 컨트랙트 주소가 예상 주소와 일치하는지 검증

체인 초기화

gstable init 실행

제네시스 파일로 체인 데이터베이스를 초기화합니다:
# 기본 데이터 디렉터리에 초기화
gstable init genesis.json

# 커스텀 데이터 디렉터리 지정
gstable init genesis.json --datadir /data/gstable
초기화 시 수행되는 작업 :
  1. 제네시스 파일 로드 및 Anzeon 구성 검증
  2. 초기 검증자 세트로 WBFT ExtraData 생성
  3. InjectContracts()를 통해 시스템 컨트랙트 배포
  4. 제네시스 블록을 데이터베이스에 커밋
기존 데이터베이스가 있는 경우, 제공된 제네시스가 저장된 제네시스와 일치하는지 검증합니다. 불일치 시 GenesisMismatchError가 발생합니다.

초기화 후 노드 시작

# 검증자 노드 시작
gstable --datadir /data/gstable \
  --networkid 9999 \
  --mine \
  --nodekey /path/to/nodekey \
  --syncmode full \
  --port 30303

# 부트노드 지정 시
gstable --datadir /data/gstable \
  --networkid 9999 \
  --bootnodes "enode://pubkey@ip:port"
노드 실행 옵션의 상세 내용은 노드 구성을 참조하세요.

두 단계 검증자 초기화

StableNet은 검증자 세트를 두 단계로 관리합니다: 1단계: 첫 번째 에포크 (블록 1 ~ epochLength)
  • Anzeon.Init.Validators에 정의
  • 제네시스 블록의 ExtraData에 하드코딩됨
  • 거버넌스를 통해 변경 불가
2단계: 두 번째 에포크 이후
  • SystemContracts.GovValidator.Params에 정의
  • 에포크 블록에서 GovValidator 컨트랙트 상태를 읽어 검증자 세트 갱신
  • 거버넌스 투표를 통해 수정 가능
이 설계를 통해 체인이 최소 검증자 세트로 부트스트랩한 후, 거버넌스 주도로 검증자 세트를 변경할 수 있습니다. 검증자 거버넌스 프로세스에 대한 상세 내용은 검증자 거버넌스를 참조하세요.

네트워크별 구성

Mainnet

  • 체인 ID: 8282
  • 네트워크 플래그: --mainnet
  • 부트노드: 자동 설정 (params.StableNetMainnetBootnodes)
  • 제네시스: 바이너리에 내장 (별도 init 불필요)
# Mainnet 노드 시작 (제네시스 자동 로드)
gstable --mainnet --syncmode full --datadir /data/gstable

Testnet

  • 체인 ID: 8283
  • 네트워크 플래그: --testnet
  • 부트노드: 자동 설정 (params.StableNetTestnetBootnodes)
  • 제네시스: 바이너리에 내장 (별도 init 불필요)
# Testnet 노드 시작
gstable --testnet --syncmode full --datadir /data/gstable

프라이빗 네트워크

프라이빗 네트워크는 커스텀 제네시스 파일이 필요합니다. 설정 절차:
  1. 각 검증자의 노드키 생성 (bootnode -genkey)
  2. genesis_generator로 제네시스 파일 생성
  3. 모든 노드에서 gstable init genesis.json 실행
  4. 노드 시작 시 --networkid--bootnodes 지정
프라이빗 네트워크 권장 매개변수:
매개변수개발용프로덕션용
chainId공용 네트워크와 미충돌하는 고유 값동일
epochLength5~10 (빠른 검증자 변경)100+
blockPeriod1초1~3초
quorum1 (단일 노드)검증자 수의 2/3 이상
gasLimit기본값네트워크 요구사항에 맞게 조정
프라이빗 네트워크 시작 예시:
# 1. 노드키 생성
bootnode -genkey nodekey1
bootnode -genkey nodekey2

# 2. 제네시스 생성 (대화형 모드 권장)
./build/bin/genesis_generator

# 3. 각 노드에서 초기화
gstable init genesis.json --datadir /data/node1
gstable init genesis.json --datadir /data/node2

# 4. 첫 번째 노드 시작
gstable --datadir /data/node1 \
  --networkid 9999 \
  --mine \
  --nodekey nodekey1 \
  --syncmode full \
  --port 30303

# 5. 두 번째 노드 시작 (첫 번째 노드를 부트노드로 지정)
gstable --datadir /data/node2 \
  --networkid 9999 \
  --mine \
  --nodekey nodekey2 \
  --syncmode full \
  --port 30304 \
  --bootnodes "enode://<node1-pubkey>@<node1-ip>:30303"
프로덕션 네트워크 배포 체크리스트, Docker 배포, Debian 패키지 배포에 대해서는 네트워크 배포를 참조하세요.

초기화 검증

네트워크 초기화 후 다음 항목을 확인합니다:
# 노드에 연결
gstable attach /data/gstable/gstable.ipc

# 체인 ID 확인
> eth.chainId()

# 제네시스 블록 확인
> eth.getBlock(0)

# 검증자 세트 확인 (시스템 컨트랙트 호출)
> eth.call({to: "0x0000000000000000000000000000000000001001", data: "0x..."})

# 피어 연결 확인
> admin.peers.length

# 마이닝 상태 확인 (검증자 노드)
> eth.mining

# 블록 생성 확인
> eth.blockNumber

일반적인 초기화 문제 및 해결

제네시스 불일치 오류

오류: GenesisMismatchError: database contains incompatible genesis 원인: 기존 데이터베이스와 일치하지 않는 제네시스로 초기화를 시도함. 해결 방법:
# 방법 1: 기존 체인 데이터 삭제 후 재초기화
rm -rf /data/gstable/gstable/chaindata
gstable init genesis.json --datadir /data/gstable

# 방법 2: 기존 체인과 일치하는 올바른 genesis.json 사용

검증자 수 불일치

오류: Invalid genesis config: validator count mismatch 원인: Init.ValidatorsInit.BLSPublicKeys 배열의 길이가 다름. 해결 방법: 두 배열이 동일한 길이를 가지는지 확인하세요. members, validators, blsPublicKeys는 모두 같은 수의 항목을 가져야 합니다.

시스템 컨트랙트 배포 실패

오류: Failed to inject system contracts 원인: 잘못된 컨트랙트 초기화 매개변수 또는 누락된 컨트랙트 바이트코드. 해결 방법: 시스템 컨트랙트 매개변수가 예상 형식과 일치하는지 확인하세요. 특히 주소 형식(0x 접두사, 40자 hex)과 쉼표 구분 리스트의 형식을 점검하세요.

BLS 키 형식 오류

오류: Invalid BLS public key format 원인: BLS 키가 올바르게 hex 인코딩되지 않았거나 길이가 잘못됨. 해결 방법: BLS 공개 키는 0x 접두사를 포함하여 정확히 98자 (0x + 96바이트 hex 인코딩 = 0x + 192자 hex 문자) 문자열이어야 합니다. bootnode -nodekey 명령으로 올바른 형식을 확인할 수 있습니다.

Init과 GovValidator 검증자 불일치 경고

Init.ValidatorsSystemContracts.GovValidator.Params.validators가 다를 경우, 첫 번째 에포크에서 두 번째 에포크로 전환될 때 검증자 세트가 변경됩니다. 의도적인 경우가 아니라면 두 세트를 일치시키세요.