Skip to content

Architecture ​

BKC is one binary, BKCd, assembled from four codebases:

ComponentRepositoryWhat BKC changes
Applicationbkc-chainThe chain itself: the x/bkc module, ML-DSA-only transaction policy, wrapped EVM calls, genesis allocation and staking-reward emission
Cosmos SDKbkc-cosmos-sdk (fork)ML-DSA-65 consensus keys in staking, mempool and proposal fixes
CometBFTbkc-cometbft (fork)ML-DSA-65 validator keys, votes and the tendermint.crypto.PublicKey oneof
EVMbkc-cosmos-evm (fork of cosmos/evm)Synthetic receipts for wrapped calls, fee reporting
ML-DSA-65 backendbkc-mldsa65v3The pq-crystals C implementation linked through cgo, with an AVX2 build
text
                ┌──────────────────────────── BKCd ────────────────────────────┐
  P2P 26656 ───▶│ CometBFT (fork)   ML-DSA-65 votes, ~1 s blocks               │
                │      │ ABCI                                                  │
                │ Cosmos SDK (fork) auth · bank · staking · gov · distribution │
                │      │            x/bkc: ML-DSA policy, MsgExecuteEvmCall,   │
                │      │                   staking-reward emission             │
                │ cosmos/evm (fork) EVM · feemarket · precompiles (0x…0900)    │
                └──────────────────────────────────────────────────────────────┘
       JSON-RPC 8545 · WS 8546 · CometBFT RPC 26657 · REST 1317 · gRPC 9090

One account, two views ​

The Cosmos side and the EVM see the same account. A BKC address is 20 bytes; bkc1… is its bech32 spelling and 0x… its hex spelling. Native BKC is one balance whether you query it through the bank module (/cosmos/bank/v1beta1/balances/bkc1…) or the EVM (eth_getBalance(0x…)). The bank denom bkc has 18 decimals, so 1 BKC = 10¹⁸ bkc = 10¹⁸ wei.

How a write reaches the EVM ​

text
 your code (ethers / Hardhat)
     │  eth_sendTransaction-shaped request
     ▼
 BKC signer (SDK or Hardhat plugin)
     │  builds /bkc.bkc.v1.MsgExecuteEvmCall, signs it with ML-DSA-65 (SIGN_MODE_DIRECT)
     ▼
 CometBFT RPC  broadcast_tx_sync
     │
 ante handler  ML-DSA-only policy · fee · sequence
     │
 x/bkc         call_nonce == sequence − 1 · gas limit ≤ Cosmos gas
     │
 cosmos/evm    executes the call, emits ethereum_tx event + logs
     ▼
 JSON-RPC      eth_getTransactionReceipt(<EVM hash>) → status, logs, contractAddress

Reads skip all of this: eth_call, eth_getLogs, eth_getBalance go straight to the EVM JSON-RPC.

Consensus ​

  • CometBFT BFT consensus: a block commits when validators holding more than 2/3 of the voting power sign it. With three equally weighted validators, all three must be online; four tolerate one failure.
  • Each vote carries a 3,309-byte ML-DSA-65 signature, so a commit is roughly 3.4 KB per validator.
  • timeout_commit is 0.5 s; blocks land about once a second under load.

Node roles ​

RoleSigns blocksServes public RPCTypical config
Validatoryesno — RPC bound to 127.0.0.1indexer off, only P2P exposed
Full node (RPC)noyesindexer kv, JSON-RPC/REST/gRPC on 0.0.0.0, CORS open

Keeping public RPC off validators matters on BKC: query load competes for the same CPU that builds and verifies ML-DSA-heavy blocks.

BKC testnet is unaudited. Do not hold value on it.