- Bitcoin software overview
- Bitcoin wallets and security
- Bitcoin Development Kit (BDK) and technical concepts
Daniela Brozzoni offers a comprehensive overview of the Bitcoin Layer 1 software stack, explaining the layers that comprise the foundation of Bitcoin's protocol (ie. Bitcoin nodes and Bitcoin wallets) and how to build Bitcoin software with an introduction to Bitcoin libraries and a deep dive into Bitcoin Development Kit (BDK).
Bitcoin software overview
Bitcoin's software stack is fundamental to its operation and is composed of various elements, including nodes and wallets. A critical part of this ecosystem is the Bitcoin Development Kit (BDK), which we will explore in detail later. First, let's focus on the role of nodes within the Bitcoin network.
Bitcoin nodes
Bitcoin nodes are the backbone of the Bitcoin network. They connect to each other, exchange transactions and blocks, and validate incoming data. There are different types of nodes, each serving a unique purpose:
-
Full nodes: These nodes store the entire blockchain and validate all transactions and blocks. They provide a high level of security and are essential for the network's decentralization.
- Archival nodes: A subset of full nodes, archival nodes retain all blockchain data, making them valuable for historical analysis and debugging.
- Pruned nodes: Pruned nodes save disk space by keeping only a portion of the blockchain, eliminating older data that is no longer needed for validation.
Bitcoin Core
Bitcoin Core is the most widely used full node implementation. It performs dual functions as both a full node and a wallet. Key aspects of Bitcoin Core include:
- Usability: It can be utilized via a Command Line Interface (CLI) and a graphical user interface (GUI).
- Open-source nature: The code is open-source, allowing developers to contribute and scrutinize its workings.
- Language: Written in C++ with tests in Python, ensuring robust performance and reliability.
Exploring bitcoin core
To get hands-on experience with Bitcoin Core, one can compile and run tests using Git. This process involves:
- Compiling the codebase to create an executable version. bitcoin github access to doc/build-*.md for instructions.
./autogen.sh ./configure make # use "-j N" for N parallel jobs make install # optional
- Running tests to ensure everything functions correctly. Instructions can be found here
make check #individual tests can be run directly calling the test script e.g: test/functional/feature_rbf.py #run all possible tests test/functional/test_runner.py
- Creating and executing a test in Python to validate specific functionality. The file example.py is a heavily commented example of a test case that uses both the RPC and P2P interfaces.
Alternative node implementations
Beyond Bitcoin Core, there are several alternative node implementations:
- Bitcoin knots: It offers more advanced features than Bitcoin core, taking more space and memory.
- LibBitcoin: A flexible and modular implementation.
- btcd: Written in Go, it offers different design philosophies.
Implementing these alternatives comes with its own risks, particularly regarding the consensus rules. Deviating from established validation rules can lead to forks or inconsistencies. The Bitcoin Kernel project seeks to mitigate these risks by centralizing consensus code, ensuring uniformity across implementations.
Bitcoin wallets and security
Bitcoin wallets are crucial for managing your Bitcoin holdings securely. They come in various forms, each with distinct features and security considerations.
Types of Bitcoin wallets
-
Custodian vs. non-custodian:
- Custodian wallets: Managed by third parties, offering convenience but requiring trust in the custodian.
- Non-custodian wallets: Controlled by users, providing higher security and privacy.
-
Desktop vs. mobile:
- Desktop wallets: Typically more feature-rich and secure.
- Mobile wallets: Offer convenience and portability.
-
On-chain vs. lightning:
- On-chain wallets: Interact directly with the Bitcoin blockchain.
- Lightning wallets: Facilitate faster and cheaper transactions off-chain.
-
Cold wallets vs. hot wallets:
- Cold wallets: Not connected to the internet, providing superior security against hacks.
- Hot wallets: Connected to the internet, offering more accessibility but less security.
Cold wallet security
Cold wallets are revered for their security. By remaining offline, they are inherently resistant to online hacks. However, it is crucial to ensure that transactions performed through cold wallets are secure and accurate to prevent inadvertently sending Bitcoin to malicious actors.
Watch-only wallets
Watch-only wallets contain only public keys, allowing users to receive Bitcoin and monitor their balance without the ability to spend. This feature adds an extra layer of security for those who need to keep a close eye on their holdings.
Basic functions of a Bitcoin wallet
Regardless of type, every Bitcoin wallet performs three fundamental functions:
- Receive Bitcoin: Generate addresses and monitor for incoming transactions.
- Send Bitcoin: Create and broadcast transactions to the network.
- Display balance: Show the current balance of the wallet.
Role of Bitcoin wallets
- Bitcoin wallets act as keychains, holding and generating cryptographic keys.
- They monitor the blockchain for incoming transactions.
- Create transactions by selecting unspent transaction outputs (UTXOs), setting inputs and outputs, and optimizing for privacy and fees.
Reusability of wallet logic
Given that all Bitcoin wallets share similar functions, rewriting wallet logic repeatedly is inefficient. This is where the Bitcoin Development Kit (BDK) comes into play.
Bitcoin Development Kit (BDK) and technical concepts
The Bitcoin Development Kit (BDK) is a library designed to simplify the creation and management of Bitcoin wallets.
Overview of BDK
BDK simplifies wallet creation by providing higher-level functionality built on top of Rust Bitcoin. It supports multiple programming languages through bindings, including Kotlin, Swift, and Python.
Other Bitcoin libraries
Numerous Bitcoin libraries cater to different programming languages, such as Python, JavaScript, Java, Go, and C. These libraries offer diverse tools for Bitcoin development.
Key technical concepts
- Descriptors: Descriptors describe how to derive Bitcoin scripts and addresses from keys, allowing for more flexible and powerful wallet functionalities.
- PSBT (Partially Signed Bitcoin Transactions): PSBT is a format for transactions that require multiple signatures, facilitating collaborative transactions and enhanced security.
- Rust syntax: Key concepts in Rust, such as
Optionfor null safety and theResulttype for error handling, are integral to understanding and using BDK effectively.
Creating and managing transactions
BDK streamlines the process of building, signing, and broadcasting transactions:
- Build transactions: Specify recipients, amounts, and fees.
- Sign transactions: Use PSBT to gather signatures.
- Broadcast transactions: Send finalized transactions to the network.
Example workflow in BDK
- Set up wallet: Initialize a wallet with descriptors.
use bdk::{Wallet, SyncOptions}; use bdk::database::MemoryDatabase; use bdk::blockchain::ElectrumBlockchain; use bdk::electrum_client::Client; use bdk::bitcoin; fn main() -> Result<(), bdk::Error> { let wallet = Wallet::new( "tr(tprv8ZgxMBicQKsPf6WJ1Rr8Zmdsr6MaACS5K3tHw3QDQmFbkEsdnG3zAZzhjEgEtetL1jwZ5VAL85UaaFzUpAZPrS7aGkQ3GdM75xPu4sUxSiF/*)", None, bitcoin::Network::Testnet, MemoryDatabase::default(), )?; Ok(()) }
- Generate addresses: Create new addresses to receive Bitcoin from a testnet faucet.
//import AddressIndex outside the main function use bdk::wallet::AddressIndex; //Function to add isnide main function let address = wallet.get_address(AddressIndex::New)?;
- Check balance: Monitor the wallet's balance, first by connecting to electrum, syncing wallet and getting the balance from the wallet.
//connect to Electrum server and save the blockchain let client = Client::new("ssl://electrum.blockstream.info:60002")?; let blockchain = ElectrumBlockchain::from(client); //sync wallet to the blockchain received wallet.sync(&blockchain, SyncOptions::default())?; //get the balance from your wallet let balance = wallet.get_balance()?; println!("This is your wallet balance: {}", balance);
- Build, sign, and broadcast transactions: Construct and finalize transactions, then broadcast them to the network.
//Add to the imports use bdk::bitcoin::Address; use bdk::{SignOptions}; use std::str::FromStr; use bdk::blockchain::Blockchain; //build a transaction psbt let mut builder = wallet.build_tx(); let recipient_address = Address::from_str("tb1qlj64u6fqutr0xue85kl55fx0gt4m4urun25p7q").unwrap(); builder .drain_wallet() .drain_to(recipient_address.script_pubkey()) .fee_rate(FeeRate::from_sat_per_vb(2.0)) .enable_rbf(); let (mut psbt, tx_details) = builder.finish()?; println!("This is our psbt: {}", psbt); println!("These are the details of the tx: {:?}", tx_details); //Sign the PSBT let finalized = wallet.sign(&mut psbt, SignOptions::default())?; println!("Is my PSBT Signed? {}", finalized); println!("This is my PSBT finalized: {}", psbt); let tx = psbt.extract_tx(); let tx_id = tx.txid(); println!("this is my Bitcoin tx: {}", bitcoin::consensus::encode::serialize_hex(&tx)); println!("this is mny tx id: {}", tx_id); //Broadcast the transaction blockchain.broadcast(&tx)?;
Print TXID and broadcast transaction
Assigning and printing the Transaction ID (TXID) allows monitoring on platforms like mempool.space. Broadcasting the transaction can be accomplished using the
Blockchain.broadcast method, and verifying the transaction's details and status is crucial for ensuring successful propagation.BDK utility and privacy considerations
The BDK is invaluable for simplifying Bitcoin wallet development. For enhanced privacy, tools like Electrum, Explora, and personal Bitcoin Core nodes are recommended.
Programming languages
When developing Bitcoin projects, Rust is often preferred due to its safety and efficiency. However, the choice of language may vary based on specific project requirements and developer expertise.
BDK dependencies
BDK relies on several key dependencies, including Rust-Bitcoin and Rust-Miniscipt. Additional libraries may be employed for database management and cryptography.
By understanding these components, from Bitcoin nodes and wallets to the Bitcoin Development Kit (BDK), you can navigate the Bitcoin ecosystem with greater confidence and competence. This knowledge empowers you to develop robust and secure Bitcoin applications, contributing to the ongoing evolution of this revolutionary technology.