Architecture
Package Structure
go-blockchain/
config/ Chain parameters (mainnet/testnet), hardfork schedule
crypto/ CGo bridge to libcryptonote (ring sigs, BP+, Zarcanum, stealth)
types/ Core data types: Block, Transaction, Address, KeyImage
wire/ Binary serialisation (consensus-critical, bit-identical to C++)
p2p/ Levin TCP protocol, peer discovery, handshake
rpc/ Daemon and wallet JSON-RPC client + server
chain/ Blockchain storage, block/tx validation, mempool
wallet/ Key management, output scanning, tx construction
difficulty/ PoW + PoS difficulty adjustment (LWMA variant)
consensus/ Hardfork rules, block reward, fee policy
Dependency Diagram
+------------+
| consensus |
+------+-----+
|
+------------+------------+
| |
+-----+-----+ +-----+-----+
| chain | | difficulty |
+-----+------+ +-----------+
|
+--------+---------+
| | |
+----+--+ +---+---+ +---+---+
| p2p | | rpc | | wallet|
+----+--+ +---+---+ +---+---+
| | |
+--------+---------+
|
+----+----+
| wire |
+----+----+
|
+-------+-------+
| |
+---+---+ +-----+-----+
| types | | config |
+---+---+ +-----------+
|
+---+---+
| crypto | <-- CGo boundary
+--------+
Key relationships
- config and types are leaf packages with no internal dependencies (stdlib only).
- wire depends on types for struct definitions and config for version-specific serialisation rules.
- crypto wraps the C++ library via CGo; it is used by wire (for hashing), chain (for signature verification), and wallet (for key derivation and tx signing).
- p2p, rpc, and wallet are higher-level packages that depend on wire-level serialisation.
- chain is the central coordinator: it validates blocks using consensus rules, adjusts difficulty, and stores state.
CGo Bridge Boundary
The crypto/ package is the only package that crosses the CGo boundary. All other packages are pure Go.
Go side C++ side (libcryptonote)
+---------+ +------------------------+
| crypto/ | --- CGo calls ---> | cn_fast_hash() |
| | | generate_key_derivation|
| | | derive_public_key |
| | | generate_key_image |
| | | check_ring_signature |
| | | CLSAG_GG_verify |
| | | CLSAG_GGX_verify |
| | | CLSAG_GGXXG_verify |
| | | bulletproof_plus_verify |
| | | zarcanum_verify |
| | | chacha8_encrypt |
+---------+ +------------------------+
Build tags
The crypto package uses build tags to allow compilation without CGo for testing of non-crypto packages:
//go:build cgo
package crypto
When CGo is disabled, stub implementations return errors, allowing the rest of the codebase to compile and run tests that do not require real cryptographic operations.
Design Principles
-
Consensus-critical code must be bit-identical to the C++ implementation. The
wire/package produces exactly the same binary output as the C++ serialisation for the same input. -
No global state. Chain parameters are passed via
config.ChainConfigstructs, not package-level globals.MainnetandTestnetare pre-defined instances. -
Interfaces at boundaries. The
chain/package defines interfaces for storage backends, allowing LMDB, Pebble, or in-memory stores to be swapped. -
Test against real chain data. Wherever possible, tests use actual mainnet block and transaction hex blobs as test vectors, ensuring compatibility with the C++ node.