kokonut

Kokonut πŸ₯₯

High-Performance Modular Blockchain Framework Powered by Kotlin with Proof of Stake

DeepWiki Docker FullNode Docker FuelNode

Kokonut is a lightweight and scalable blockchain framework written in Kotlin. Designed for educational and research purposes, it implements Proof of Stake (PoS) consensus with core blockchain principles (Staking, Validation, Wallets) using an intuitive multi-module architecture.

🌟 Key Features

πŸ“š Project Structure

This project is organized as a Gradle multi-module project, where each module plays a distinct role in the blockchain network.

1. :library (Core Framework)

Contains the core blockchain framework with a clean, minimal architecture:

library/src/main/kotlin/kokonut/
β”œβ”€β”€ core/           # Core blockchain data structures
β”‚   β”œβ”€β”€ Block.kt
β”‚   β”œβ”€β”€ BlockChain.kt
β”‚   β”œβ”€β”€ Data.kt
β”‚   β”œβ”€β”€ FuelNodeInfo.kt
β”‚   β”œβ”€β”€ NetworkRules.kt
β”‚   β”œβ”€β”€ NodeHandshake.kt
β”‚   β”œβ”€β”€ Policy.kt
β”‚   β”œβ”€β”€ Transaction.kt
β”‚   β”œβ”€β”€ Validator.kt
β”‚   └── ValidatorOnboardingInfo.kt
β”œβ”€β”€ state/          # State management
β”‚   β”œβ”€β”€ NodeState.kt
β”‚   └── ValidatorState.kt
└── util/           # Utilities and API
    β”œβ”€β”€ API.kt
    β”œβ”€β”€ FullNode.kt
    β”œβ”€β”€ GenesisGenerator.kt
    β”œβ”€β”€ NodeType.kt
    β”œβ”€β”€ Router.kt
    β”œβ”€β”€ SQLite.kt
    β”œβ”€β”€ Utility.kt
    β”œβ”€β”€ ValidatorPool.kt
    β”œβ”€β”€ ValidatorSession.kt
    └── Wallet.kt

Key Components:

2. :fuelnode (Bootstrap Node)

Acts as the network entry point and provides Node Discovery services.

3. :fullnode (Main Node)

The core node that maintains and operates the actual blockchain network.

4. :lightnode (Wallet Client)

A desktop wallet application for users (built with Compose Desktop).


πŸš€ Getting Started

Prerequisites

Requirement: Kokonut requires Java 17 or higher.

Build

Run the following command in the project root to build the entire project.

# Windows
./gradlew.bat build

# Mac/Linux
./gradlew build

How to Run

Each node can be run individually. The recommended order is Fuel Node β†’ Full Node (Multiple) β†’ Light Node.

1. Run Fuel Node

./gradlew.bat :fuelnode:run

2. Run Full Node

./gradlew.bat :fullnode:run

Full Nodes must join an existing network:

Optional:

3. Run Light Node (Wallet)

./gradlew.bat :lightnode:run

πŸ“‘ API Reference

Full Nodes and the Fuel Node interact via HTTP APIs.

Full Node API

Method Endpoint Description
GET / Node status and information dashboard (HTML)
POST /handshake Client handshake (returns network info)
GET /getLastBlock Get the last block of the current chain
GET /getChain Get the entire blockchain data
GET /getBalance?address= Get wallet balance for a given address (returns JSON)
GET /isValid Check the integrity of the local blockchain
GET /getTotalCurrencyVolume Get the total supply of KNT
GET /getReward Get the current reward policy value
GET /getValidators Get the current validator set
POST /stakeLock Lock stake to stakeVault (creates on-chain STAKE_LOCK block)
POST /startValidating Register a validator session (requires stake >= minimum)
POST /stopValidating Stop validating session
POST /addBlock Submit a validated block (network propagation)

Fuel Node API

Method Endpoint Description
GET /getGenesisBlock Download the Genesis Block data
POST /heartbeat Full Node heartbeat registration (discovery)
GET /getFullNodes Get the list of active Full Nodes
GET /getPolicy Get protocol/version policy
GET /getChain Get the blockchain data

🎁 Validator Onboarding Reward (1-time)

On the first successful Light Node connect (POST /handshake from a LIGHT client), the Full Node appends a VALIDATOR_ONBOARDING block to the chain and records two onboarding transactions:

These payouts are funded by the treasury (KOKONUT_TREASURY_ADDRESS).

Persistence: This onboarding event is stored in kovault.db (SQLite). If you keep kovault.db via Docker volume mounts, the 1-time rule survives container rebuilds.


πŸ”’ Staking (stakeVault lock)

To become an active validator, you must lock at least the network minimum stake (currently 1 KNT) to the stakeVault address.

Chain Integrity: All blocks maintain strict timestamp consistency between blocks and their embedded transactions, ensuring hash validation integrity across the network.

Note: In the current model, validator stake and rewards are derived from the blockchain history (the chain is the source of truth).


πŸ›  Tech Stack

🀝 Contributing

  1. Fork this repository.
  2. Create a new branch (git checkout -b feature/amazing-feature).
  3. Commit your changes (git commit -m 'Add some amazing feature').
  4. Push to the branch (git push origin feature/amazing-feature).
  5. Open a Pull Request.

Development Guidelines

πŸ”§ Recent Updates (January 2026)

Version Upgrades

Blockchain Improvements

Light Node Enhancements

Governance & Security (New)


License This project is licensed under the MIT License. See the LICENSE file for details.

🐳 Docker Hub & Usage

Official Docker images are available on Docker Hub.

Running with Docker

To ensure data persistence (blockchain data, keys), you must mount a volume to /data.

These images set KOKONUT_DATA_DIR=/data, so kovault.db will be created under the mounted /data directory.

1. Run Fuel Node

The Fuel Node acts as the network bootstrapper.

# -p 80:80 : Bind container port 80 to host port 80
# -v ./data:/data : Persist blockchain data to host's ./data directory
docker run -d \
  --name knt_fuelnode \
  -p 80:80 \
  -v $(pwd)/data_fuel:/data \
  volta2030/knt_fuelnode

2. Run Full Node

Full Nodes connect to the network. You can specify a peer to connect to using KOKONUT_PEER.

# -e KOKONUT_PEER : Address of a known node (e.g., Fuel Node or another Full Node)
# -v ./data_full:/data : Use a separate data directory for the Full Node
docker run -d \
  --name knt_fullnode \
  -p 8080:80 \
  -e KOKONUT_PEER="http://<FUEL_NODE_IP>:80" \
  -v $(pwd)/data_full:/data \
  volta2030/knt_fullnode

Critical Note: Full Nodes MUST configure KOKONUT_PEER to join an existing network. If KOKONUT_PEER is omitted or the target peer is unreachable, the Full Node will fail to start (throw an exception). This mechanism prevents accidental network splitting (Split Brain). Only the Fuel Node is allowed to start without a peer to generate the Genesis Block.

Note: Replace <FUEL_NODE_IP> with the actual IP address or domain of your Fuel Node. If running on the same machine, use the host’s local network IP.