Skip to content

A type-safe, template-based blockchain library for C++20 with compile-time validation

Notifications You must be signed in to change notification settings

robolibs/blockit

Repository files navigation

Blockit

Header-first C++20 blockchain toolkit for verifiable data, PoA coordination, storage anchoring, and identity backends.

Development Status

Main implementation plan is tracked in PLAN.md. If your workflow expects a TODO.md, use PLAN.md as the current source of truth in this repository.

Overview

Blockit is a modular C++20 library that combines three practical concerns in one codebase: deterministic ledger structures, persistent file-backed storage, and identity-oriented verification utilities.

At its core, Blockit gives you templated ledger primitives (Transaction<T>, Block<T>, Chain<T>) and a higher-level Blockit<T> facade that keeps blockchain operations and storage commits in sync. This helps when you need both an append-only audit trail and queryable local state.

For consensus-driven deployments, the PoA module adds validator management, proposals, quorum checks, and signature enforcement. For identity workflows, the repository includes both classic DID/VC tooling and a backend-only account-proof path (AccountId, AccountProof, AccountVerifier) that can be consumed by an external DID layer.

Design priorities in this repo are: typed APIs, incremental build/test workflows, clear module boundaries, and data models that serialize cleanly through datapod.

Architecture Diagrams

┌──────────────────────────────────────────────────────────────────────────────┐
│                                  BLOCKIT                                     │
├───────────────────────────────┬──────────────────────────────────────────────┤
│ Ledger Core                   │ Storage Core                                 │
│ - Transaction<T>              │ - FileStore                                  │
│ - Block<T>                    │ - Anchor records                             │
│ - Chain<T>                    │ - Block/tx persistence                       │
│ - MerkleTree                  │ - Continuity checks                          │
├───────────────────────────────┼──────────────────────────────────────────────┤
│ Consensus                     │ Identity                                     │
│ - PoAConfig                   │ - DID/VC types                               │
│ - PoAConsensus                │ - AccountId / AccountProof / AccountVerifier │
│ - Validator lifecycle         │ - eip155 backend hooks                       │
└───────────────────────────────┴──────────────────────────────────────────────┘
                     │                              │
                     └───────────────┬──────────────┘
                                     ▼
                           ┌───────────────────┐
                           │    Blockit<T>     │
                           │  unified facade   │
                           └───────────────────┘
High-level backend interop flow (method-agnostic)

External DID Layer (authbox / custom)
          │
          │ parse did:* externally
          ▼
   CAIP-10 account string
          │
          ▼
blockit::identity::parse_account_id(...)
          │
          ▼
blockit::identity::verify_account_proof(...)
          │
          ▼
   AccountVerifierRegistry
          │
          ▼
      eip155 backend
          │
          ├── keccak256 (keylock)
          ├── secp256k1 recover (keylock)
          └── pubkey -> address (keylock)
Block finalization + anchoring pipeline

App Data
  │
  ├─> Transaction<T> build + sign
  │
  ├─> Block<T> creation
  │
  ├─> Chain<T>::addBlock / addBlockWithPoA
  │
  ├─> FileStore::storeBlock + storeTransaction
  │
  └─> FileStore::createAnchor(content_id, content_hash, tx_ref)

Installation

Repository URL: https://github.com/robolibs/blockit

Quick Start (CMake FetchContent)

include(FetchContent)

FetchContent_Declare(
  blockit
  GIT_REPOSITORY https://github.com/robolibs/blockit
  GIT_TAG main
)

FetchContent_MakeAvailable(blockit)

target_link_libraries(your_target PRIVATE blockit)

Complete Development Environment (Nix + Direnv + Devbox)

  1. Install Nix:
curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install
  1. Install direnv:
sudo apt install direnv

Then add to your shell config:

eval "$(direnv hook bash)"
  1. Install Devbox:
curl -fsSL https://get.jetpack.io/devbox | bash
  1. Enter repo and enable env:
cd blockit
direnv allow
  1. Configure/build/test with provided Makefile:
make config
make build
make test

Build and Test

Primary workflows in this repo are driven by Makefile.

Common targets:

  • make config - generate build files (incremental)
  • make build - format + compile
  • make test - run full test suite
  • make test TEST=test_account_verifier - run one test binary
  • make run - run ./build/main

Useful options:

  • CC=gcc or CC=clang
  • BUILD_SYSTEM=cmake|xmake|zig (cmake is default here)
  • BIG_TRANSFER=1 for large transfer test paths (when available)

CMake options surfaced by this project include:

  • BLOCKIT_BUILD_EXAMPLES
  • BLOCKIT_ENABLE_TESTS
  • BLOCKIT_ENABLE_SIMD
  • SHORT_NAMESPACE
  • EXPOSE_ALL

Usage

1) Minimal Ledger Flow

#include <blockit/blockit.hpp>

struct Event {
    std::string kind;
    std::string payload;
    auto to_string() const { return kind + ":" + payload; }
};

int main() {
    auto crypto = std::make_shared<chain::Crypto>("node-secret");

    chain::Chain<Event> chain(
        "demo-chain",
        "genesis",
        Event{"init", "hello"},
        crypto
    );

    chain::Transaction<Event> tx("tx-1", Event{"sensor", "temp=22"}, 100);
    tx.signTransaction(crypto);

    chain::Block<Event> block({tx});
    auto added = chain.addBlock(block);
    if (!added.is_ok()) return 1;

    auto ok = chain.isChainValid();
    return (ok.is_ok() && ok.value()) ? 0 : 2;
}

2) Unified Ledger + Storage (Blockit<T>)

#include <blockit/blockit.hpp>

struct SensorRecord {
    std::string robot_id;
    std::string hash;
    auto to_string() const { return robot_id + ":" + hash; }
};

int main() {
    blockit::Blockit<SensorRecord> store;
    auto crypto = std::make_shared<blockit::Crypto>("fleet-key");

    auto init = store.initialize(
        "./data",
        "sensor-chain",
        "genesis",
        SensorRecord{"system", "init"},
        crypto
    );
    if (!init.is_ok()) return 1;

    std::vector<blockit::u8> content = {1, 2, 3, 4};
    auto created = store.createTransaction(
        "tx-42",
        SensorRecord{"r1", "sha256:abcd"},
        "content-42",
        content,
        100
    );
    if (!created.is_ok()) return 2;

    auto pending = store.getChain().getPendingTransactions();
    auto block_res = store.addBlock(pending);
    if (!block_res.is_ok()) return 3;

    auto verified = store.verifyContent("content-42", content);
    return (verified.is_ok() && verified.value()) ? 0 : 4;
}

3) PoA Consensus Path

#include <blockit/blockit.hpp>

using namespace blockit;

int main() {
    PoAConfig cfg;
    cfg.initial_required_signatures = 2;

    PoAConsensus poa(cfg);

    auto v1 = Key::generate().value();
    auto v2 = Key::generate().value();
    auto v3 = Key::generate().value();

    poa.addValidator("v1", v1);
    poa.addValidator("v2", v2);
    poa.addValidator("v3", v3);

    auto proposal = poa.createProposal("upgrade-window", "v1");
    if (!proposal.is_ok()) return 1;

    return 0;
}

4) Account Backend (CAIP-10 + Proof Verification)

#include <blockit/identity/identity.hpp>

using namespace blockit;

int main() {
    identity::Eip155VerificationOptions opts;
    opts.message_policy = identity::Eip155MessagePolicy::personal_sign;
    opts.enforce_low_s = true;
    opts.required_reference = "1";

    identity::register_eip155_backend(opts);

    auto account = identity::parse_account_id("eip155:1:0x0123456789abcdef0123456789abcdef01234567");
    if (!account.is_ok()) return 1;

    dp::Vector<dp::u8> message = {'h', 'e', 'l', 'l', 'o'};
    dp::Vector<dp::u8> signature(65, 0);

    auto verified = identity::verify_account_proof(
        account.value(),
        message,
        signature,
        identity::AccountProofType::eip191_personal_sign
    );

    // verified is dp::Result<bool, AccountIdentityError>
    return 0;
}

5) External DID Layer Contract (backend-only integration)

// Pseudocode from an external DID/method package

// 1) Parse did:* outside blockit
std::string caip10 = parse_did_to_caip10(did_string);

// 2) Parse account in blockit
auto account = blockit::identity::parse_account_id(caip10.c_str());

// 3) Verify proof in blockit
auto verdict = blockit::identity::verify_account_proof(
    account.value(),
    message_bytes,
    signature_bytes,
    blockit::identity::AccountProofType::eip191_personal_sign
);

Features

  • Typed Ledger Primitives - Transaction<T>, Block<T>, Chain<T> with compile-time constraints.
  • Merkle Utilities - transaction integrity and proof helpers.
  • Proof-of-Authority - quorum-driven block authorization with validator lifecycle controls.
  • Persistent File Storage - block, transaction, anchor, validator, DID and credential records.
  • Unified Facade - Blockit<T> keeps chain and storage commits coordinated.
  • Identity Stack - DID/VC data model and registry APIs for decentralized identity workflows.
  • Backend Account Proof Path - AccountId, AccountProof, and pluggable namespace verifiers.
  • eip155 First-Class Backend - policy-aware digesting, signature structure checks, recovery and address matching.
  • dp-Oriented Data Models - extensive use of dp::String, dp::Vector, and dp::Result.
  • Diagnostics with echo - structured runtime diagnostics in account verification backend.

Account Identity Backend Details

AccountId model:

  • fields: namespace, reference, address
  • canonical rendering: namespace:reference:address
  • parser with strict structure checks
  • namespace/reference/address validation hooks
  • eip155-specific chain-reference numeric checks
  • normalization modes:
    • lowercase
    • checksummed (policy mode)
    • permissive (policy mode)

AccountProof model:

  • account_id
  • proof_type
  • message
  • signature
  • created_at

AccountVerifier runtime model:

  • namespace registry
  • pluggable backends
  • default verify_account_proof(...) entrypoints
  • typed backend errors:
    • invalid_namespace
    • invalid_reference
    • invalid_address
    • unsupported_namespace
    • bad_signature

eip155 backend behavior:

  • supports raw and EIP-191 message policies
  • parses r,s,v format from 65-byte signatures
  • normalizes v (27/28 and 0/1)
  • rejects high-s when enabled
  • computes digest via keccak256
  • recovers secp256k1 public key
  • derives Ethereum address
  • compares derived address against account id address

Example Programs in This Repo

  • examples/main.cpp - broad API walkthrough
  • examples/enhanced_demo.cpp - richer ledger scenarios
  • examples/farming_demo.cpp - domain-flavored typed payloads
  • examples/file_integration_demo.cpp - direct storage integration
  • examples/unified_api_demo.cpp - recommended Blockit<T> flow
  • examples/complete_stack_demo.cpp - end-to-end app shape
  • examples/poa_demo.cpp - PoA orchestration
  • examples/did_demo.cpp - DID operations
  • examples/robot_identity_demo.cpp - robot DID + VC workflow

Performance and Portability Notes

  • C++20 is required.
  • SIMD can be enabled/disabled via CMake option.
  • x86 paths use AVX/AVX2/FMA flags by default when enabled.
  • ARM paths support NEON configuration in build flags.
  • Data models are designed for compact binary serialization with datapod.

Interop Boundaries

Blockit can be used in two identity styles:

  1. Full in-repo DID/VC stack.
  2. Backend-only account proof service consumed by an external DID parser/resolver.

For method-specific DID syntax, keep parsing and DID document synthesis in the external layer, then call blockit backend functions for account parsing and proof verification.

Dependencies

From PROJECT:

  • echo 0.0.23
  • datapod 0.0.51
  • keylock 0.0.19
  • doctest v2.4.12 (tests)

Documentation

Deep-dive docs in this repo:

  • misc/LEDGER.md
  • misc/STORAGE.md
  • misc/DID.md

Related planning notes:

  • PLAN.md
  • xtra/KEYLOCK.md

Contributing Notes

Suggested local workflow:

  1. make config
  2. make build
  3. run focused tests for touched areas
  4. run full make test before final review

Keep changes incremental, and prefer module-focused commits where possible.

License

This repository currently does not include a LICENSE file. If you distribute or consume this project in production, add and review a license file explicitly in your fork or deployment pipeline.

Acknowledgments

Blockit is built on the shoulders of:

  • datapod
  • keylock
  • echo
  • doctest

and the broader C++ and robotics open-source ecosystem.

About

A type-safe, template-based blockchain library for C++20 with compile-time validation

Resources

Stars

Watchers

Forks

Packages

No packages published