아키텍처
백서의 엔지니어링 동반 문서입니다 — 참조 노드가 설계를 어떻게 실현하는지, 그리고 그 뒤에 있는 결정들. 규범적이 아니라 설명적입니다.
프로토콜은 파라미터 파일과 골든 벡터에, 그리고 이름 붙은 규칙들이 정의된 곳 어디에나 있습니다. 와이어 명세는 피어 계층의 요구사항을 담고 있습니다. 이 페이지는 그 표면을 설명하고 그 뒤에 있는 결정들을 기록합니다. 이 페이지가 규범적 표면과 어긋날 때는 규범적 표면이 이기며 이 글이 수정됩니다. 전체 엔지니어링 동반 문서는 docs/ARCHITECTURE.md입니다.
두 개의 술어, 두 개의 엔진#
인증서(certificate)의 일생, 처음부터 끝까지.
wallet or sequencer network every full node
+-------------+ gossip +--------------+ +---------------------+
| build cert | ---------> | cert topic | ------------> | STATELESS PIPELINE |
| (reads, | | (TLS gossip) | | V-rules, strict |
| writes, | +--------------+ | Ed25519, program |
| sigs, fee, | | re-execution |
| deposit) | | -> mark VALID |
+-------------+ +----------+----------+
| mempool
v
miner (any node) +---------------------+
+----------------------+ block | FOLD (sequential) |
| order the hash list, | ---------> | per certificate: |
| append forced certs, | gossip | APPLIED / SKIPPED / |
| RandomX solve | | FORCED_FAILED / |
+----------------------+ | DROPPED -> state |
+---------------------+
유효성은 상태와 무관하고 병렬적입니다. 노드마다 인증서(certificate)마다 한 번씩, 블록보다 앞서 블록과 무관하게 실행됩니다. 적용 가능성은 상태에 의존하고 순차적입니다. 인증서가 커밋된 위치에서 폴드(fold) 안에서 실행됩니다. 채굴자는 건네받은 것을 아무것도 실행하지 않습니다. 이미 검증된 것을 본 해시들의 순서를 정하고 작업증명을 풀거나, Era 2에서 지분증명으로 전환한 뒤에는 자신이 추첨된 슬롯에 서명할 뿐입니다. 채굴자가 하는 유일한 실행은 Era 1부터의 강제 경로의 실행입니다. 채굴자는 자기 블록 끝의 상태에 대해 오픈 인텐트를 실행하고 그 결과를 블록당 최대 16개까지 덧붙일 수 있으며, 모든 노드는 그것을 다른 인증서와 똑같이 검사합니다. 폴드는 메모리에 있는 작업 집합 위를 도는 촘촘한 루프이며 — 비교하고, 더하고, 씁니다 — 아무것도 실행하지 않습니다.
엔지니어링 원칙#
| 원칙 | |
|---|---|
| P1 | 폴드(fold)는 신성합니다. 상태 전이 함수는 I/O도, 시계도, 고루틴도, 맵 순회도, 부동소수점도 없는 하나의 순수 패키지 안에 있습니다. 사후에 버그를 고칠 수 없는 유일한 코드입니다. 노드의 나머지는 전부 교체 가능한 배관입니다. |
| P2 | 결정론이 성능을 이깁니다. 비결정성을 초래할 위험이 있는 최적화는 합의 코드에서 기각됩니다. 성능은 안전한 곳, 즉 상태 없는 파이프라인의 몫입니다. |
| P3 | 관리자 키도, 특권 RPC도 없습니다. 어떤 키로도 일시 정지하거나, 업그레이드하거나, 발행하거나, 재구성할 수 있는 코드 경로가 없습니다. 폴드(fold) 규칙에 없는 것은 존재하지 않습니다. |
| P4 | 합의 표면은 작게. core/는 표준 라이브러리 밖의 어떤 것도 임포트하지 않습니다. 노드의 나머지는 생태계 라이브러리를 써도 되지만, 코어는 안 됩니다. |
| P5 | 명세가 먼저. 골든 벡터가 곧 프로토콜입니다. Go 코드는 하나의 참조 구현입니다. 이 벡터를 통과하는 독립 구현은 포크가 아니라 피어입니다. 이것이 언젠가 관리자가 특별한 누구도 아니게 되는 것을 가능하게 합니다. |
| P6 | v0.1부터 재현 가능. 고정된 Go 툴체인, -trimpath, 고정된 의존성. 신뢰가 바이너리에서 코드로 옮겨 가며, 그것이 익명의 저자가 제공할 수 있는 유일한 신뢰입니다. |
| P7 | 하나의 바이너리, 높이로 제한됩니다. 머신, 시퀀서 장치, 강제 경로는 모든 릴리스에 컴파일되어 들어 있으며 활성화 높이 h1_vm(mainnet에서 80,640) 아래에서는 거부됩니다. Validate는 이 높이가 에포크 경계에 놓이도록 요구합니다. Era 1은 운영자에게 업그레이드를 요청해서가 아니라 체인이 어떤 숫자에 도달했기 때문에 도래합니다. 그 이후의 에라는 바이너리에 들어 있지 않습니다. 각 에라는 하드 포크를 통해 자체 릴리스로 배포됩니다. |
회의적인 독자가 가장 강하게 따져 물어야 할 원칙은 P3이며, 따져 물을 곳은 트레저리(treasury)입니다. 제네시스 블록에는 키도, 지출 경로도 전혀 없으므로, 보유하거나 위임하거나 훔칠 특권이 없습니다. 트레저리는 높이 259,200 이전에는 지출할 수 없으며, 그것을 여는 규칙이 무엇이든 합의 변경으로 도착합니다 — 다른 모든 변경과 같은 사회적 메커니즘이고, 같은 거부의 대상이며, 그때조차 정확히 하나의 셀(cell)만 움직일 수 있습니다. 창립자 몫은 키가 아니라 입금입니다. 각 보조금의 3%가 높이 3,153,600까지 파라미터 파일에 고정된 한 주소로 가며, Era 2는 이 높이를 에포크 1,095로 읽습니다. 그 주소는 코인을 보유할 뿐 다른 어떤 것에도 닿지 않습니다. 관리자 키란 누구도 동의하기 전에 존재하면서 모든 것에 닿는 키입니다.
암호 기본 요소#
| 역할 | 선택 | 이유 |
|---|---|---|
| 서명 | Ed25519 | 일괄 검증(GPU로 가는 진입로), 가변성 없음, 작은 키. 제네시스 블록에서 고정된 엄격한 규칙이 있습니다. 공개 키와 R에 대한 정규 인코딩 요구, 공개 키가 비틀림이 없고 낮은 위수가 아닐 것, 그리고 검증은 여인수 없이 수행할 것. |
| 해싱 | BLAKE3 | 인증서(certificate)와 블록의 id, 주소, 상태 루트에 쓰입니다. 중계 회선 속도로 해싱할 만큼 빠르고, 에포크 상태 루트에 대해 병렬화하기 좋습니다. |
| 작업증명 | RandomX | CPU에 최적화되어 있습니다. 트리 안의 유일한 cgo이며, 빌드 태그 뒤에 있고, 태그 없이 빌드하면 아예 없습니다. pow_engine은 합의 루트 안에 있으므로, 잘못된 엔진을 담은 바이너리는 잘못된 증명을 받아들이는 대신 시작을 거부합니다. |
| 도메인 분리 | 필수 | 모든 해시는 blake3(tag ‖ payload)입니다. 서명은 체인 id 와 합의 루트에 대해 이루어지며, 이는 네트워크들 사이의 재생과 한 네트워크의 두 화신 사이의 재생을 모두 막습니다. |
일괄 경로를 안전하게 만들어 주는 것이 바로 비틀림 배제입니다. 혼합 위수 키는 낮은 위수가 아니므로 어떤 차단 목록에도 걸리지 않으며, 여인수를 쓰는 일괄 검증기와 여인수를 쓰지 않는 단건 검증기가 어긋나는 지점이 정확히 거기입니다. 키와 R이 소수 위수 부분군 안에 있으면 둘은 증명 가능하게 동등합니다 — 따라서 일괄 검증기는 일괄 처리 전에 동일한 인코딩 및 비틀림 규칙을 적용한다는 조건에서 여인수를 써도 됩니다. 그 의무가 이 선택의 대가이며, 일괄 검증기는 아직 존재하지 않습니다.
정규 인코딩과 식별자#
모든 합의 객체는 SSZ 컨테이너입니다. 정규 바이트 인코딩이 하나뿐이고, 맵 순서도 없고, 선택적 필드로 인한 모호함도 없으며, 값싼 부분 파싱을 위한 고정 오프셋과 기본 제공되는 머클화를 갖추고 있습니다.
cert_id = blake3("zcd/certid/v1" || ssz(certificate with an empty signature list))
cert_exemplar = blake3("zcd/cert/v1" || ssz(certificate))
block_id = blake3("zcd/block/v1" || ssz(header))
앞의 둘은 서로 다른 질문에 답하는 서로 다른 다이제스트이며, 한쪽이 있어야 할 자리에 다른 쪽을 쓰는 구현은 금전적으로 망가진 것입니다. id는 이 인가에 대해 청구가 이루어졌는가에 답하고, 실체(exemplar) 해시는 이 바이트들이 그것을 증명하는가에 답합니다. 둘은 결코 키를 공유하지 않습니다.
서명이 id의 원상 바깥에 있는 것은 서명이 무작위화된 시연이기 때문입니다. 서명자가 nonce를 고르고, 모든 nonce가 같은 본문에 대한 또 하나의 유효한, 완벽하게 정규적인 서명을 만들어 내며, 어떤 검증자도 어느 것이 쓰였는지 확인할 수 없습니다. 서명이 안에 있었다면 하나의 인가가 무한히 많은 id를 갖게 되고, 각각이 청구 가능하며, 각각을 필요한 서명자 중 어느 하나가 다른 서명자들의 권한을 빌려 만들어 낼 수 있게 됩니다.
id 바깥의 입찰가는 전송 중인 누구든 다시 쓸 수 있는 입찰가입니다 — 기본 수수료를 통해 서명자의 잔액을 태우려고 부풀릴 수도 있고, 인증서(certificate)를 어떤 블록에도 넣지 못하게 하려고 0으로 만들 수도 있습니다. 인증서가 얼마를 내는지는 그 서명자가 인가한 것의 일부이므로, 그것은 해싱되고 서명됩니다. 나중에 "중계 유연성을 위해 수수료를 서명된 본문 밖으로 옮기는" 인코딩 변경은 최적화처럼 보이겠지만 절도 경로가 될 것입니다.
여기서 따라 나오는 규칙은 파싱하되 두 번 검증하지 말라입니다. 디코딩이 정규 형식을 강제하므로, 디코딩된 객체는 구조적으로 유효한 것이 보장되고 규칙 엔진은 형태를 다시 검사하지 않습니다.
셀(cell) 모델#
셀(cell)은 슬롯에 담긴 값입니다. 셀의 값은 32바이트에 빅엔디언으로 저장되는 부호 없는 256비트 정수입니다. 없는 셀은 0으로 읽힙니다 — 0은 부재입니다. 이는 구현상의 편의가 아니라 합의 요구사항입니다. 상태 루트가 상태를 만들어 낸 이력의 함수가 아니라 상태 자체의 함수로 남게 해 주기 때문입니다.
이와 별개로, 프로토콜은 사용된 주소 레지스트리를 유지합니다. 서명 권한이 소각된 일회성 주소들의 영구적인 합의 집합입니다.
Addr = version || blake3("zcd/addr/v1" || version || payload)[:31]
| 버전 | 종류 | 차변 인가 |
|---|---|---|
0x01 | 일회성 사용자 | 소유자 서명. 차변을 발생시키는 인증서(certificate)는 명시적인 MARK_SPENT도 함께 지녀야 합니다. 그것이 적용되고 나면 그 주소 아래의 모든 읽기와 쓰기가 영원히 실패합니다. |
0x02 | 영구 사용자 | 소유자 서명. 영원히 재사용할 수 있습니다. 사용된 주소 레지스트리에 결코 들어갈 수 없습니다. |
0x03 | 자산 | 그 자산의 불변 권한 셀(cell)들이 다스립니다. |
0x00 | 프로토콜 | 폴드(fold) 전용입니다. 에포크 비컨, 기본 수수료 셀(cell), coinbase 성숙 기간 링, 트레저리(treasury) 셀, 시퀀서 카운터. |
0x05 | 컨트랙트 | 키로는 아무도 없습니다. 어떤 키도 이 주소로 해시되지 않습니다. 컨트랙트의 코드와 폴드 규칙이 결정합니다. |
0x04 | 정의되지 않음 | 그 아래에는 어떤 셀도 존재하지 않습니다. 그런 주소를 지목하는 인증서는 유효하지 않습니다. |
병렬성은 타입이 지정된 접근에서 나옵니다. 읽기는 자신이 셀(cell)을 어떻게 제약하는지
선언하고 — EXACT, 또는 가드 GUARD_GE, GUARD_LE,
GUARD_EQ 중 하나 — 쓰기는 자신이 무엇을 하는지 선언합니다.
SET, DELTA_ADD, DELTA_SUB 또는 MARK_SPENT입니다.
오직 EXACT만 계산에 들어가며, 셀이 움직일 때 낡아지는 것도 오직 EXACT뿐입니다.
가드는 아무것도 반환하지 않고 델타는 아무것도 읽지 않으므로, 재실행은 정확한 읽기의 순수 함수로
남고, 하나의 슬롯에 대한 가드된 차변과 대변은 몇 개가 되든 교환 가능합니다. 인증서 하나에서 슬롯 하나에는
하나의 규율만 적용됩니다. 설정(set)과 델타는 결코 슬롯을 공유하지 않습니다. 0을 쓰면 셀이 삭제되므로,
한 번도 쓰이지 않은 슬롯과 0이 쓰인 슬롯은 같은 슬롯입니다.
일회성 대 영구는 두 개의 원장이 아니라, 주소 비트로 드러나는 지갑 정책입니다. 지갑은 기본적으로 들어오는 결제마다 새 일회성 주소를 쓰며, 이것이 경합 없는 경로입니다. 계정을 원하는 사람은 영구 버전을 씁니다. 채굴 보상은 영구 주소에 들어가야 합니다. 합의는 어느 종류든 지급 주소로 받아들이지만, 일회성 주소는 지출되는 순간 그 안에 있는 모든 보상을 소각하므로, 노드는 일회성 주소를 지급 주소로 쓰기를 거부합니다.
레지스트리 항목은 결코 압축되지 않습니다. 사용된 주소 아래의 셀(cell) 값은 되돌리기 지평 이후에 정리될 수 있지만, 그 주소가 사용되었음을 기록하는 항목은 그 주소가 되살아나는 것을 막는 장치입니다. 이는 추가만 가능한 합의 상태로, 주소당 약 33바이트씩 영원히 남습니다 — 이 프로토콜이 정직하게 밝히는 미해결 문제이며, 모든 널리파이어 집합 설계가 구조적으로 함께 지고 있는 문제입니다.
상태 없는 유효성, 그리고 청구 법칙#
V-규칙은 모든 인증서에 대해, 병렬로, 멤풀 수용 전과 블록 검증 중에 실행되며 상태가 전혀 필요 없습니다. 정규 형식과 체인 id, 그리고 모든 목록이 한도 안에 있을 것. 모든 서명이 서명 루트에 대해 엄격한 Ed25519로 검증되고, 서명 집합이 충분할 뿐 아니라 최소일 것. 선언된 읽기에 대한 프로그램의 재실행이 선언된 쓰기를 정확히 만들어 낼 것. 인가가 필요한 모든 쓰기에 대한 인가, 그리고 예치 셀에 대한 서명은 무조건. 예치금이 사용자 주소의 네이티브 잔액이며 인증서의 최악의 경우를 감당할 것. 자기 일관성, 즉 어떤 쓰기도 같은 슬롯의 읽기와 모순되지 않고, 차변이 발생한 어떤 일회성 주소도 사용됨 표시를 피하지 못할 것. 프로토콜 셀에 대한 쓰기가 없을 것. 지목된 모든 주소에 정의된 버전 바이트가 있을 것. 그리고 시퀀서 키가 0이 아닌 컨트랙트에서는 정확한 경로에 그 키의 서명이 있을 것.
이 시스템의 청구 법칙은 한 문장이며, 붙들어야 할 것이 바로 그것입니다.
하나의 서명에는 많아야 한 번의 청구, 그리고 결코 그 서명자가 피할 수 없었던 위치에서는 아닙니다.
폴드는 블록을 세 부류로 정렬하며 생산자에게 재량을 남기지 않습니다. 먼저 fill이
자신이 속한 시퀀서 파이프라인의 순서대로, 그다음 그 밖의 모든 인증서가 (deposit address, Seq, id)
순서로, 마지막으로 강제
인증서가 id 순서로 옵니다. 그러면 각 인증서는 네 가지 결과 중 정확히 하나를 가지며,
골든 벡터가 그 결과들의 이름을 붙입니다.
| 결과 | 조건 | 지불하는 쪽 |
|---|---|---|
APPLIED | 선언된 모든 읽기가 성립합니다. | 예치자가 실제 비용으로 지불합니다. 기본 수수료는 소각되고, 우선 수수료는 생산자에게 갑니다. |
SKIPPED_STALE, SKIPPED_OVERFLOW | 어떤 읽기가 더 이상 성립하지 않거나, 델타가 [0, 2²⁵⁶)를 벗어나게 됩니다. 아무것도 쓰이지 않습니다. | 예치자가 고정된 건너뜀(skip) 수수료를 내며, 그 수수료는 소각됩니다. fill의 경우에는 시퀀서가 냅니다 — 결코 사용자가 아닙니다. |
FORCED_FAILED | 호출이 revert되었거나 한도를 어긴 강제 인증서. | 그 지불 주소들이 냅니다. 그 밖에는 아무것도 쓰이지 않습니다. |
DROPPED | 예치금을 예약할 수 없습니다. 셀에 잔액이 없거나 이미 사용되었습니다. | 아무도 내지 않습니다. 확인 집합(seen set)에 표시되지 않으므로, 잔액이 있는 예치금을 붙여 다시 제출할 수 있습니다. |
적용된 인증서, 건너뜀(skip) 처리된 인증서, 강제 실패한 인증서는 모두 확인 집합(seen set)에 표시되며, 이미 확인된 인증서, 만료된 인증서, 또는 입찰가가 모자란 인증서를 포함하면 블록이 유효하지 않게 되므로, 어떤 생산자도 다른 사람의 인증서를 다시 포함하거나 지연시켜 그 예치금을 거둬들일 수 없습니다. 청구할 대상이 없는 실패 — 파이프라인 카운터의 순서가 어긋났거나 펜스 카운터가 움직인 fill, 읽기가 성립하지 않는 강제 인증서 — 는 대신 블록을 유효하지 않게 만듭니다. 자신이 보유한 상태로부터 블록을 만든 생산자가 그것을 알 수 있었던 당사자이기 때문입니다.
에라(Era) 관문#
활성화 높이는 spec/params.json에 있습니다. h1_vm = 80,640이
Era 1을 엽니다. cEVM과 미리 배포된 라이브러리, 시퀀서 키·관리자·펜스 카운터를 가진 컨트랙트 기록,
인텐트와 fill, 시퀀서 디렉터리, 그리고 강제 경로입니다. 이 에라 자체의 상수들 — 8블록의 인텐트 창,
블록당 16개이고 각각 4,000 유도 단위(derivation unit)인 강제 인증서, 공지 인증서의 TTL 이후 259,200블록인
디렉터리 항목의 수명 — 은 파라미터 파일에 실리지 않고 컴파일되어 들어갑니다. 파라미터를 추가하면
운영 중인 모든 네트워크의 제네시스 블록 id가 바뀌기 때문입니다. 관문 블록이 이 상수들을 프로토콜 셀에
기록하므로, 그때부터는 상태 루트가 그것들에 구속됩니다.
h1_bond는 mainnet과 공개 testnet에서 h1_vm과 같으므로, 그곳에서 본딩
연산은 결코 열리지 않습니다. Era 1에는 지분 본딩이 없습니다. 트리에는 여전히 v1.0의 인수(underwriting),
임대, 강제 큐 규칙이 들어 있으며, 그것들은 개발 네트워크에서만, 그 h1_vm 위이자 자체 v1
관문 아래의 256블록 창 안에서만 유효합니다. 이 창은 그 장치를 기록한 벡터들이 그것이 유효한 네트워크를
계속 갖도록 하기 위해 존재합니다. h2_pos = 1,576,800은 지분증명을 위해 예약되어 있으며,
제네시스 블록에서 고정되고 어떤 규칙도 읽지 않습니다. Era 2, 지분증명은 하드 포크를 통해 자체 릴리스로
배포되며, 그 상수는 Era 1의 것처럼 컴파일됩니다. 높이에 따라 에포크 182에 본딩을 열고, 활성 지분이
30 에포크 동안 공급량의 10%를 유지하면, 또는 늦어도 에포크 273에 램프 구간을 시작하며, 램프 구간이
완료되면 5초 슬롯으로 전환합니다. 전환부터는 실제로는 기간인 모든 제네시스 블록 상수를 그것이 측정하는
단위로 읽으므로, 파라미터 파일은 바뀌지 않습니다.
저장소 구조#
zycord/
spec/ parameter sets, golden vectors, library images <- THE PROTOCOL
core/ consensus-critical; standard library only (P4)
types/ crypto/ ssz/ u256/ state/ validity/ fold/ params/ genesis/
cevm/ the certificate-adapted EVM; vendored interpreter, pure Go
stdlib/ the pre-deployed library, its addresses and code hashes
pow/randomx/ the mainnet engine: vendored C++, cgo, behind a build tag
node/ storage/ chain/ verify/ mempool/ miner/ p2p/ sync/ rpc/ stratum/
wallet/ key management, certificate builders (reference; not consensus)
contracts/ the reference contracts, in Solidity
sim/ simulator, fuzz harnesses, differential refold, chaos soak
cmd/ zycordd, zcd
desktop/ the wallet in a native window — a separate Go module
docs/ architecture, protocol, operating guide, whitepaper
의존성 화살표는 안쪽으로만 향합니다 — node → core,
wallet → core이며 그 반대는 결코 없습니다 — 그리고 core/
안의 어떤 것도 core/와 표준 라이브러리 바깥에 손을 뻗지 않습니다. 명시되고 강제되는
예외가 하나 있습니다. core/pow/randomx는 트리 안의 유일한 cgo이며 빌드 태그 아래에서만
컴파일되므로, 태그 없는 모든 빌드는 여전히 표준 라이브러리만 쓰고 C 툴체인이 필요 없습니다. 이를
강제하는 검사는 CI가 실행합니다. 서드파티 검사는 모듈 경로를 grep하는데 cgo에는 모듈 경로가 없어서
— 이 검사가 추가되기 전까지 그 규칙은 아무도 강제하지 않고 있었습니다.
어떻게 테스트하는가#
- 골든 벡터. 모든 폴드(fold), 블록, 유효성 규칙에 대해
(pre-state, block) → (post-state | invalid, outcomes, fees)형태의 긍정 사례와 부정 사례가 있습니다. 이 모음이 독립 구현을 위한 호환성 계약입니다. - 괴롭힘 모음. 적용된 인증서(certificate)와 건너뜀(skip) 처리된 인증서의 재포함, 만료된 포함, 낮은 입찰가 포함, 제안자 셔플 아래의 의존 사슬, 소각-환불 순환, 제3자 대변 폭풍, 발행 상한 경계 경합.
- 속성 기반. 제안자 순서 치환 아래에서의 폴드(fold) 결정론, 델타 교환성, ABA 내성, 그리고 보존 — 진행 중인 예치금, 성숙 링, 트레저리(treasury) 셀(cell)까지 포함해서입니다. 트레저리를 빠뜨린 보존 검사는 모든 블록이 가치를 만들어 낸다고 보고하기 때문입니다.
- 차이 검사. 속도가 아니라 명료함을 위해 쓴, 일부러 순진하게 만든 두 번째 폴드(fold) 구현을 진짜 구현에 대해 퍼징합니다. 결과가 갈라지면 릴리스가 막힙니다.
- 적대적 시뮬레이션. 건너뜀(skip) 폭풍, 예치금 고갈 경합, 폐기(drop)로 채워 넣는 채굴자, 재구성 고문, 타임스탬프 조작, 경량 이클립스 중계 시나리오. 시나리오 설정은 커밋되어 있고, 실행은 시드로 재현할 수 있습니다.
- 동시성, 의도적으로. 고루틴 하나보다 많은 것이 건드리는 모든 구성 요소에는 프로세스가 실제로 쓰는 형태 그대로 실제로 동시적인 테스트가 있습니다. 고루틴 하나짜리 테스트 모음에
-race를 걸면 아무것도 측정하지 못한 채 성공을 보고합니다. - 카오스 침수 시험. 지연, 지터, 손실, 분할을 주입하는 프록시 뒤에서 실제 소켓 위로 실제 노드 프로세스를 돌리며, 노드를 무작위로
SIGKILL로 죽입니다. 이것이-race모음 전체가 놓친 데이터 경합을 찾아낸 표면입니다.
제네시스 블록은 의식이 아니라 산출물입니다#
zcd genesis는 제네시스 블록 — 빈 상태, 초기화된 비컨 셀(cell), 빈 사용된 주소
레지스트리, 어떤 종류의 배분도 없음 — 과 그 id를 내놓습니다. 출시는 미리
코드 태그, 파라미터 해시, 제네시스 블록 id, 출시 시각에 구속되었고, 파라미터 집합은 블록 1이 그 다이제스트를
드러내야 했던 출시 메시지에 대한 커밋먼트를 담고 있었으므로, 공표된 시작 전에는 아무도 체인을 채굴할 수
없었습니다. 누구든 앞의 넷을 소스로부터, 어떤 컴퓨터에서든, 밀리초 단위로 다시 만들어 볼 수 있습니다.
그 밖에 신뢰할 것은 아무것도 없습니다.