Header-first C++20 blockchain toolkit for verifiable data, PoA coordination, storage anchoring, and identity backends.
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.
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.
┌──────────────────────────────────────────────────────────────────────────────┐
│ 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)
Repository URL:
https://github.com/robolibs/blockit
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)- Install Nix:
curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install- Install direnv:
sudo apt install direnvThen add to your shell config:
eval "$(direnv hook bash)"- Install Devbox:
curl -fsSL https://get.jetpack.io/devbox | bash- Enter repo and enable env:
cd blockit
direnv allow- Configure/build/test with provided Makefile:
make config
make build
make testPrimary workflows in this repo are driven by Makefile.
Common targets:
make config- generate build files (incremental)make build- format + compilemake test- run full test suitemake test TEST=test_account_verifier- run one test binarymake run- run./build/main
Useful options:
CC=gccorCC=clangBUILD_SYSTEM=cmake|xmake|zig(cmake is default here)BIG_TRANSFER=1for large transfer test paths (when available)
CMake options surfaced by this project include:
BLOCKIT_BUILD_EXAMPLESBLOCKIT_ENABLE_TESTSBLOCKIT_ENABLE_SIMDSHORT_NAMESPACEEXPOSE_ALL
#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;
}#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;
}#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;
}#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;
}// 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
);- 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, anddp::Result. - Diagnostics with echo - structured runtime diagnostics in account verification backend.
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_idproof_typemessagesignaturecreated_at
AccountVerifier runtime model:
- namespace registry
- pluggable backends
- default
verify_account_proof(...)entrypoints - typed backend errors:
invalid_namespaceinvalid_referenceinvalid_addressunsupported_namespacebad_signature
eip155 backend behavior:
- supports raw and EIP-191 message policies
- parses
r,s,vformat from 65-byte signatures - normalizes
v(27/28and0/1) - rejects high-
swhen enabled - computes digest via keccak256
- recovers secp256k1 public key
- derives Ethereum address
- compares derived address against account id address
examples/main.cpp- broad API walkthroughexamples/enhanced_demo.cpp- richer ledger scenariosexamples/farming_demo.cpp- domain-flavored typed payloadsexamples/file_integration_demo.cpp- direct storage integrationexamples/unified_api_demo.cpp- recommendedBlockit<T>flowexamples/complete_stack_demo.cpp- end-to-end app shapeexamples/poa_demo.cpp- PoA orchestrationexamples/did_demo.cpp- DID operationsexamples/robot_identity_demo.cpp- robot DID + VC workflow
- 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.
Blockit can be used in two identity styles:
- Full in-repo DID/VC stack.
- 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.
From PROJECT:
echo0.0.23datapod0.0.51keylock0.0.19doctestv2.4.12(tests)
Deep-dive docs in this repo:
misc/LEDGER.mdmisc/STORAGE.mdmisc/DID.md
Related planning notes:
PLAN.mdxtra/KEYLOCK.md
Suggested local workflow:
make configmake build- run focused tests for touched areas
- run full
make testbefore final review
Keep changes incremental, and prefer module-focused commits where possible.
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.
Blockit is built on the shoulders of:
- datapod
- keylock
- echo
- doctest
and the broader C++ and robotics open-source ecosystem.
