Bitcoin Kernel API
A stable C API for Bitcoin Core's consensus validation engine. Build block explorers, alternative node implementations, research tools, and more — in any language.
What Can You Do
The Bitcoinkernel library exposes Bitcoin Core's validation logic through a stable C API. It is a stateful and capable of full block validation, UTXO management, and chain state operations.
Block Validation
Validate blocks using the exact same consensus rules as Bitcoin Core. Process blocks against the current chain state with full contextual checks.
Script Verification
Verify transaction scripts including P2SH, SegWit, and Taproot spend paths. For now, the script verification requires no context.
Block and Header Data Access
Read block data, undo data, and iterate over the UTXO set. Retrieve block indices by height or hash for chain traversal. Create and validate block header of a block.
Chain Management
Initialize and manage chain state from a data directory. Supports mainnet, testnet, signet, and regtest chains.
Validation Callbacks
Receive asynchronous notifications about validation events — block connected, block disconnected, error conditions, and progress updates.
FFI Bindings
The C ABI makes it straightforward to create bindings for any language with C interop. Official bindings exist for C++, Rust, JDK, Python, Go and dotnet.
Architecture Overview
The library follows an opaque-pointer pattern. All kernel objects are created through factory functions and destroyed with corresponding destroy functions. Objects are represented as opaque btck_* pointers — you never access internal fields directly.
The lifecycle for most operations follows this pattern: create a Context (with optional configuration), create a ChainstateManager for chain state operations, then use the manager to validate blocks or read data. When finished, destroy objects in reverse order.
// 1. Create context with options btck_ContextOptions* opts = btck_context_options_create(); btck_context_options_set_chainparams(opts, btck_chain_parameters_create(btck_CHAIN_MAINNET)); btck_Context* ctx = btck_context_create(opts); // 2. Create chainstate manager btck_ChainstateManagerOptions* cm_opts = btck_chainstate_manager_options_create( ctx, data_dir, data_dir_len, blocks_dir, blocks_dir_len); btck_ChainstateManager* chainman = btck_chainstate_manager_create(ctx, cm_opts); // 3. Use the manager — validate blocks, read data, etc. btck_chainstate_manager_process_block(ctx, chainman, block, &accepted); // 4. Tear down in reverse order btck_chainstate_manager_destroy(chainman, ctx); btck_chainstate_manager_options_destroy(cm_opts); btck_context_destroy(ctx); btck_context_options_destroy(opts);
Core C API
The foundational API defined in bitcoinkernel.h. All language bindings ultimately call through this C interface. See the full C API reference for complete documentation.
Context & Configuration
ChainstateManager
Script Verification
btck_ScriptPubkey* spk = btck_script_pubkey_create(script_bytes, script_len); btck_Transaction* tx = btck_transaction_create(raw_tx, raw_tx_len); btck_ScriptVerifyStatus status; int ok = btck_script_pubkey_verify( spk, amount, tx, spent_outputs, n_outputs, input_idx, btck_SCRIPT_FLAGS_VERIFY_ALL, &status); btck_transaction_destroy(tx); btck_script_pubkey_destroy(spk);
Validation Callbacks
void on_block_tip(void* user_data, btck_SynchronizationState state, const btck_BlockIndex* index) { printf("New tip at height: %d\n", btck_block_index_get_height(index)); } btck_ValidationInterfaceCallbacks cbs = { .block_tip = on_block_tip, .user_data = my_app_state, }; btck_context_options_set_validation_interface(opts, cbs);
Language Bindings
Current language bindings documented here in this site.
#include <bitcoinkernel_wrapper.hpp> btck::ContextOptions opts{}; opts.SetNotifications(std::make_shared<MyNotifications>()); btck::Context ctx{opts}; btck::ChainMan cm{ctx, {ctx, data_dir, blocks_dir}}; cm.ImportBlocks({}); for (auto entry : cm.GetChain().Entries()) std::cout << entry.GetHeight() << "\n";
try (BitcoinKernel kernel = new BitcoinKernel( ChainType.MAINNET, Path.of(home, ".bitcoin"), Path.of(home, ".bitcoin", "blocks"), System.out::println)) { ChainstateManager csm = kernel.getChainstateManager(); csm.ImportBlocks(new String[]{}); for (BlockTreeEntry e : csm.getChain()) System.out.println("Height: " + e.getHeight()); }
Error Handling
The C API returns NULL or false on failure. For script verification, a btck_ScriptVerifyStatus output parameter provides detailed error info. Always register a fatal_error callback — if it fires, halt immediately.
Memory Management
Every btck_*_create has a matching btck_*_destroy. Destroy in reverse creation order. Language bindings handle this automatically — Rust uses Drop, JDK uses AutoCloseable, C++ uses RAII handles.