Bitcoin cryptography in Python, written to be read.
btclib is a Python type annotated library intended for teaching, learning and using bitcoin, focused on elliptic curve cryptography and bitcoin's blockchain. It began as a teaching tool for Ferdinando Ametrano's Bitcoin and Blockchain Technology course — taught at the Università di Milano-Bicocca, Politecnico di Milano, Università Statale di Milano, and ESSEC (Paris) — and is used in production today. It is still marked beta, because it is still refactored whenever that makes it clearer.
What the projects here have in common is a preference for the explicit
one: a public function that validates what it is handed, a docstring that
states the contract rather than restating the name, and a py.typed in
every package, so a caller's own type checker reads the same annotations
mypy is held to here. Where behaviour comes from a BIP, an RFC or a Bitcoin Core
function, the code says so and cites it; where these libraries deviate,
they say that too.
- btclib — elliptic curve cryptography and bitcoin's blockchain, from modular arithmetic up through ECDSA, BIP340 Schnorr, addresses, scripts, transactions and blocks. Not limited to secp256k1: the curve arithmetic serves SEC, NIST, Brainpool and low-cardinality test curves alike.
- btclib-wallet — the wallet built on btclib: BIP32 keys, BIP39 and SLIP39 mnemonics, output descriptors, PSBT and the signers for it, transaction building and coin selection, and a wallet that reads a Bitcoin Core node or an explorer.
- btclib-secp256k1 — cffi bindings to libsecp256k1, Bitcoin Core's optimized C library. btclib delegates to them for secp256k1 and validates its own Python arithmetic against them: consensus code is what says the right answer.
- bitcoin-core-rpc
— a standalone JSON-RPC client for a Bitcoin Core node: a package of
modules with nothing but the standard library behind it, annotated and
shipping
py.typed. It installs beside anything without bringing a dependency tree with it. - btclib-benchmarks — timings against the packages these are usefully compared with. Its own repository on purpose: the comparands are third-party libraries, and measuring them from inside btclib would put them in the lock file of a library that never imports them.
- btclib-node — a bitcoin node, consensus and network code in Python, built on btclib. Its author reports it downloading and validating the whole chain.
- bitcoin-node-tests — a conformance suite for any bitcoin node: Bitcoin Core's functional tests rewritten on btclib, bitcoind the oracle and btclib-node the first target.
- bbt — the course the library came out of: spreadsheets illustrating finite fields and elliptic curves, notebooks, scripts, and a regtest lab.
- portanode — Bitcoin Core and Electrum on a portable external disk, shared between macOS, Windows and Linux.
- .github — this page, and the standard every repository of the organization is built and kept to. Its issue tracker is where a repository's drift from that standard is filed, since a divergence between two repositories belongs to neither.
- btclib-org.github.io — the organization site: this page, served at btclib.org from a copy generated out of the repository above.
A test suite that only agrees with itself proves that the code does what it does. These libraries answer to vectors their authors published: the BIPs' and the SLIPs' own, Bitcoin Core's script, transaction, sighash and key-encoding files, HWI's, Trezor's for BIP39 and SLIP39, and Appendix A.2 of RFC 6979. Each vendored file is pinned to the upstream commit it was copied from, with a weekly job asking whether the two still agree.
Coverage is gated at 100%, so a line no test reaches is a red build rather than a number that drifts down. Everything else the repositories here are held to — one lint gate that CI runs verbatim, strict type checking, signed commits, one commit per pull request — is written down, with the reasoning and the rejected alternatives, in the repository standard.
Questions and patches: the issues and pull requests of each repository.
Its own README says where the package and the documentation are, and its
CONTRIBUTING.md how a change is proposed.
What every one of them asks for is the same, and none of it waits for CI to say so: the lint gate clean, the suite passing with its coverage, a signed commit, and a changelog entry wherever a user would notice the difference.
Everything here is MIT licensed.
The btclib organization and its projects are actively supported by DGI and CheckSig.