Canopy가 무엇을 해결하는 물건인가.
Canopy는 신규 블록체인이 부트스트랩 단계를 건너뛸 수 있게 해주는 재귀적(recursive) 멀티체인 프로토콜이다. 신규 체인(nested chain)은 Canopy의 검증자 위원회(Committee)에서 보안을 빌리고, 준비가 되면 독립할 수 있는 명확한 경로가 설계되어 있다.
합의 엔진 NestBFT는 리더가 중심이 되는 별형 통신 패턴과 BLS 집계 서명으로, 대규모 검증자 집합도 효율적으로 운영할 수 있다. 저장소는 Go 1.24로 작성된 풀스택 노드 구현이다.
11,800+ 스타의 이유 — 기존 체인 대비 무엇이 다른가.
블록체인 생태계에서 새로운 체인을 만들 때 가장 큰 장벽은 "검증자 확보"다. Ethereum, Cosmos, Polkadot 모두 이 문제를 다르게 풀었지만, Canopy는 재귀 구조라는 독특한 접근법을 택했다.
새 체인을 만들면 검증자를 처음부터 모집해야 한다. 초기에는 보안이 취약하고, 토큰 인센티브 없이는 검증자가 참여하지 않는 닭-달걀 문제가 생긴다.
Cosmos IBC는 체인 간 메시지 전달은 해결했지만, 체인이 각자 독립된 검증자 집합을 유지해야 한다. Polkadot Parachain은 슬롯 경매 방식으로 진입 장벽이 높다.
신규 체인은 Canopy의 기존 검증자들로 구성된 Committee(위원회)에서 즉시 보안을 빌린다. 검증자는 동일한 스테이크(CNPY 토큰)로 여러 Committee에 동시 참여할 수 있어 자본 효율이 높다.
준비가 되면 중첩 체인은 독립(graduate)할 수 있는 명확한 로드맵이 프로토콜에 내재되어 있다. "임시 보육원 → 독립 생태계" 패턴이다.
| 특성 | 전통 BFT (PBFT 등) | Tendermint/CometBFT | NestBFT (Canopy) |
|---|---|---|---|
| 통신 패턴 | All-to-All (O(n²)) | All-to-All (O(n²)) | Star 패턴 (O(n)) |
| 서명 집계 | 없음 (개별 서명) | 없음 (개별 서명) | BLS 집계 서명 O(1) |
| 리더 선출 | 결정론적 | 라운드 로빈 | VRF + 지분 가중 추첨 |
| 멀티체인 지원 | 단일 체인 가정 | 단일 체인 (IBC 별도) | 중첩 체인 네이티브 |
| 최종성 | 즉시 | 즉시 | 즉시 |
| 네트워크 가정 | 신뢰 가능한 네트워크 | 부분 동기 모델 | 비신뢰 P2P 환경 설계 |
go.mod와 소스 모듈로 확인한 실제 의존성.
| 모듈 | 역할 | 주요 패키지/기술 |
|---|---|---|
| bft/ | NestBFT 합의 엔진 | VRF 리더 선출, BLS 집계 서명, Pacemaker, QC 생성 |
| fsm/ | 유한 상태 기계 | 트랜잭션 처리, 계좌·검증자·풀·거버넌스 상태 관리 |
| p2p/ | P2P 네트워크 | TCP/IP, 멀티플렉스, ECDH+ChaCha20-Poly1305 암호화, Gossip |
| store/ | 영속성 레이어 | PebbleDB(LSM 트리), Sparse Merkle Tree, Indexer, 중첩 트랜잭션 |
| controller/ | 컴포넌트 조율 허브 | FSM·BFT·P2P·Mempool 통합, 블록 처리, 크로스체인 체크포인트 |
| lib/ | 공용 타입·유틸 | Protobuf 타입, 설정, 로그, VDF, Codec, 암호화 인터페이스 |
| lib/crypto/ | 암호화 모음 | BLS12-381, Ed25519, secp256k1, ECDH, ChaCha20-Poly1305, VDF(class group) |
| cmd/ | CLI · RPC · 자동 업데이트 | Cobra CLI, HTTP/WebSocket RPC, Ethereum 호환 RPC, Next.js 지갑/탐색기 |
| plugin/ | 중첩 체인 SDK | Go·Kotlin·Python·TypeScript·C# 다중 언어 플러그인 인터페이스 |
| 패키지 | 용도 |
|---|---|
| cockroachdb/pebble/v2 | PebbleDB — LSM 트리 기반 고성능 KV 저장소 (BadgerDB에서 교체됨) |
| drand/kyber + kyber-bls12381 | BLS12-381 곡선 위 BLS 집계 서명 |
| decred/secp256k1/v4 | secp256k1 ECDSA (Ethereum 호환 계좌) |
| ethereum/go-ethereum | Ethereum ABI/RLP 호환, KZG 검증 |
| filippo.io/edwards25519 | Ed25519 서명 (노드 인증) |
| oasisprotocol/curve25519-voi | VRF 구현 (리더 선출 랜덤성) |
| gorilla/websocket | WebSocket RPC 서버 |
| prometheus/client_golang | 메트릭 수집 · 모니터링 |
| spf13/cobra | CLI 커맨드 프레임워크 |
| allegro/bigcache/v3 | 인메모리 캐시 (피어 정보 등) |
| julienschmidt/httprouter | 고성능 HTTP 라우터 (RPC 서버) |
| google/protobuf | 직렬화 포맷 (네트워크 메시지·저장 타입) |
cmd/rpc/web/wallet, cmd/rpc/web/explorer 디렉토리에 Next.js 14.2 기반 프론트엔드가 포함되어 있다. Makefile의 build/wallet, build/explorer 타깃이 각각 빌드한다.
노드 내부 구조와 NestBFT 합의 메커니즘.
Canopy의 store/는 자체 최적화된 SMT(희소 머클 트리)를 구현한다. 전통 SMT가 빈 브랜치를 모두 저장하는 것과 달리, 단일 자식 부모 노드를 자식으로 압축하고 닐 리프를 생략해 공간을 절약한다. 상태 루트 해시를 O(log n)으로 갱신할 수 있어 블록마다 전체 상태 재해시가 필요 없다.
Controller는 오케스트라 지휘자다. BFT(합주단), FSM(악보 해석), P2P(음향 시스템), Mempool(대기 중인 악보 더미)이 각자 역할을 맡고, 지휘자가 신호를 주면 함께 움직인다.
NestBFT의 Star 패턴: 100명의 단원이 서로 직접 신호를 주고받으면 9,900번 통신이 필요하지만, 지휘자(리더)를 통하면 200번이면 된다. 그게 O(n²) → O(n)의 차이다.
실제 git clone 결과로 확인한 파일 트리.
이 레포에서 무엇을 배울 수 있는가.
store/txn.go의 중첩 트랜잭션은 DB 수준이 아닌 인메모리 레이어에서 구현되어 있다. RWStoreI 인터페이스를 통해 모든 컴포넌트가 동일한 API로 저장소에 접근하는 패턴을 배울 수 있다.
controller/의 뮤텍스·아토믹 연산 활용으로 스레드 안전한 분산 시스템 설계 관행을 익힐 수 있다.
lib/*.pb.go 파일들은 Protobuf 스키마로 정의된 타입들이다. 블록·인증서·트랜잭션·피어 메시지가 어떻게 직렬화되어 네트워크를 오가는지 실제 코드로 확인할 수 있다.
실습: proto/ 파일을 수정하고 protoc로 재생성해 보면 gRPC/Protobuf 생태계를 손으로 익힐 수 있다.
bft/README.md는 NestBFT 전체 설계 문서로 교과서 수준의 BFT 설명이다. 합의 8단계, Pacemaker, 안전성·활성성 메커니즘, DDoS 방어가 문서와 코드 양쪽으로 제공된다.
BLS 서명 집계(lib/crypto/bls.go), VRF(lib/crypto/vdf.go), Quorum Certificate 생성 코드를 함께 읽으면 현대 BFT의 실제 구현을 파악할 수 있다.
BLS12-381(집계 서명), Ed25519(노드 인증), secp256k1(Ethereum 호환), ECDH(키 교환), ChaCha20-Poly1305(대칭 암호화), VDF(검증 가능 지연 함수)가 모두 Go로 구현되어 있다. 각 파일에 _test.go가 있어 동작 확인이 쉽다.
블록체인 상태를 어떻게 효율적으로 저장·검증하는지, 키 프리픽스로 네임스페이스를 분리하는 패턴, 최신 상태(LSS)와 역사적 상태(HSS)를 파티션으로 나누는 설계를 배울 수 있다. store/README.md는 스토리지 아키텍처 설계 문서로 탁월하다.
노드를 직접 빌드하고 실행하는 방법.
| 항목 | 요구사항 | 비고 |
|---|---|---|
| OS | Linux / macOS | Makefile이 Linux/macOS 분기 지원. Windows 미공식 |
| Go | 1.24 이상 | go.mod 기준 |
| Node.js | 최신 LTS | Next.js 지갑·탐색기 빌드 시 필요 |
| Docker | Docker + Compose | 로컬넷 테스트 환경 구성 시 필요 |
| 메모리 | 최소 4 GB RAM | 검증자 노드는 8 GB 권장 |
| 디스크 | SSD 권장 | PebbleDB(LSM) 특성상 SSD에서 최적 성능 |
# 1. 소스 클론
git clone https://github.com/canopy-network/canopy.git
cd canopy
# 2. 바이너리 빌드 (지갑+탐색기 포함 풀 빌드)
make build/canopy-full
# 3. 노드 실행
canopy start
# Docker로 로컬 테스트넷 실행 (4노드 구성)
make docker/build
make docker/up-fast
make docker/logs
# 유닛 테스트 실행
make test/all
# 특정 모듈만 테스트
go test ./bft/...
go test ./store/...
go test ./lib/crypto/...
# Go 플러그인 기반 중첩 체인 개발
cd plugin/go
cat TUTORIAL.md # 튜토리얼 필독
# Docker로 플러그인 노드 실행
make PLUGIN=go build/plugin
난이도별 3~5개 — 손으로 익혀야 진짜 이해된다.
make docker/up-fast && make docker/logs로 4노드 로컬넷을 실행하고, RPC 엔드포인트(localhost:50002)를 통해 블록이 생성되는 것을 관찰한다.
목표: 블록 높이 증가, 합의 메시지 로그 확인, 기본 RPC 쿼리 (getBlock, getTransaction) 사용법 익히기.
lib/crypto/bls_test.go를 실행하고(go test ./lib/crypto/... -v -run BLS), BLS 서명 생성·집계·검증 과정을 단계별로 추적한다.
목표: 개별 서명 3개를 집계하면 단일 서명이 되고, 그 크기가 원본 서명 하나와 같음을 확인. BLS12-381 곡선에서 서명 집계가 왜 가능한지 이해.
store/ 패키지의 SMT 코드를 읽고 테스트 파일을 참고해, Go 코드로 SMT를 초기화하고 키-값 쌍을 삽입·삭제하면서 루트 해시가 변경되는 것을 확인한다. Merkle Proof 생성과 검증도 직접 실행한다.
목표: 상태 루트가 어떻게 무결성 보장의 핵심이 되는지 체감.
plugin/go/TUTORIAL.md를 따라 간단한 커스텀 중첩 체인을 만든다. 상태 머신 로직을 직접 구현하고, 로컬넷에 연결해 Certificate Result가 루트 체인에 제출되는 것을 확인한다.
목표: 중첩 체인의 상태 관리가 루트 체인과 어떻게 분리·연동되는지 이해. Plugin 양방향 API 구조 파악.
Docker Compose로 4노드 로컬넷을 실행한 후, 노드 1개를 중단(docker stop)하여 Pacemaker(뷰 변경) 메커니즘이 발동되는 과정을 로그로 추적한다. bft/ 소스에서 Round Interrupt → Pacemaker 경로를 코드레벨로 따라간다.
목표: 비잔틴 장군 문제에서 "1/3 장애 허용" 원칙이 실제 로그에서 어떻게 나타나는지 체감.
Canopy를 이해하기 위한 최적 학습 순서.
| 주차 | 주제 | 학습 자료 / 실습 |
|---|---|---|
| 1주 | Go 기초·인터페이스·고루틴 | Tour of Go, "Concurrency in Go" (O'Reilly), 채널·뮤텍스 실습 |
| 2주 | 블록체인 개념 | 비트코인 백서, Nakamoto 합의 vs BFT 차이, Merkle Tree 구조 |
| 3주 | Byzantine Fault Tolerance | Lamport et al. 비잔틴 장군 논문, PBFT 논문 요약, Tendermint 백서 |
| 4주 | BLS 서명 · 암호학 | Stanford BLS 강의 노트, lib/crypto/bls.go 코드 읽기, 서명 집계 실습 |
| 5주 | P2P 네트워킹 | libp2p 개념, gossip protocol, p2p/README.md + encrypted_conn.go 분석 |
| 6주 | LSM 트리 · 스토리지 | PebbleDB/LevelDB 구조, Sparse Merkle Tree 논문, store/README.md 정독 |
| 7주 | Protobuf · gRPC | proto3 공식 문서, lib/*.proto 파일 수정 실습, Go 코드 재생성 |
| 8주 | 멀티체인 · 상호운용성 | IBC 개념 비교, Polkadot Parachain vs Canopy Nested Chain, plugin/go 튜토리얼 |
| 9주 | NestBFT 전체 통합 | bft/README.md 완독, 로컬넷 장애 시뮬레이션, 소스 코드 전체 flow 추적 |
| 10주 | 기여 · 확장 | CONTRIBUTING.md, 이슈 탐색, 작은 버그 픽스 PR 제출 |
이 레포를 읽다 마주치는 용어 정리.
| 용어 | 설명 |
|---|---|
| NestBFT | Canopy 전용 BFT 합의 알고리즘. 별형 통신(O(n))·BLS 집계·VRF 리더 선출·중첩 체인 지원이 특징. |
| BFT (Byzantine Fault Tolerance) | 일부 노드가 악의적으로 행동해도 전체 시스템이 올바르게 동작할 수 있는 성질. 1/3 미만 악의적 노드 허용. |
| Quorum Certificate (QC) | 검증자 2/3 초과가 서명한 합의 증명서. BLS 집계 서명으로 O(1) 크기. |
| BLS 서명 | Boneh-Lynn-Shacham 서명. 여러 서명을 하나로 집계할 수 있어 블록체인 합의에 적합. |
| VRF (Verifiable Random Function) | 개인키로 검증 가능한 난수를 생성. 리더 선출에 사용해 예측 불가능하면서도 검증 가능한 선출 보장. |
| VDF (Verifiable Delay Function) | 일정 시간이 지나야 결과를 얻을 수 있는 함수. 타이밍 공격·장거리 공격 방지에 사용. |
| Nested Chain | Canopy 베이스 체인의 보안·합의를 빌려 동작하는 서브 체인. 독립 경로 내재. |
| Committee | 특정 중첩 체인의 합의를 담당하는 검증자 부분집합. 동일 CNPY 스테이크 재활용 가능. |
| Certificate Result | 리더가 중첩 체인 블록 합의 결과를 루트 체인에 제출하는 트랜잭션. |
| Pacemaker | 합의 실패 시 검증자들을 최고 관찰 라운드로 재동기화하는 복구 메커니즘. |
| Sparse Merkle Tree (SMT) | 희소 키-값 집합을 효율적으로 저장·증명하는 트리. 블록체인 상태 루트 해시 계산에 사용. |
| FSM (Finite State Machine) | 유한 상태 기계. 트랜잭션을 입력으로 받아 블록체인 상태를 결정론적으로 전이. |
| Mempool | 아직 블록에 포함되지 않은 대기 중인 트랜잭션 풀. |
| LSM Tree | Log-Structured Merge-Tree. PebbleDB가 사용하는 쓰기 최적화 저장소 구조. |
| PebbleDB | CockroachDB에서 만든 Go용 LSM 트리 KV 저장소. Canopy의 기본 스토리지 엔진. |
| ECDH | Elliptic Curve Diffie-Hellman. 두 노드가 공유 비밀키를 안전하게 합의하는 키 교환 프로토콜. |
| ChaCha20-Poly1305 | 현대적인 대칭 암호화 AEAD 알고리즘. P2P 연결 암호화에 사용. |
| Plugin SDK | 중첩 체인 소프트웨어를 개발하기 위한 SDK. Go·Kotlin·Python·TypeScript·C# 지원. |
| Sortition | 지분 가중 랜덤 선출. 스테이크 비율에 비례한 리더 선출 확률을 보장. |
| Slashing | 이중 서명 등 비잔틴 행동을 한 검증자의 스테이크를 일부 몰수하는 처벌 메커니즘. |
| Betanet | 메인넷 전 단계 테스트 네트워크. Canopy는 현재 이 단계. |
더 깊이 파고들기 위한 출처.