bitcoinlib
bitcoinlib is a comprehensive Python library for handling Bitcoin and other cryptocurrencies. It provides functionalities for creating and managing wallets, keys, addresses, scripts, and transactions, supporting various networks like mainnet, testnet, and regtest. The current stable version is 0.7.8, with updates typically focusing on bug fixes, performance improvements, and feature enhancements as the underlying protocols evolve.
Common errors
-
bitcoinlib.exceptions.WalletError: No wallet with name 'my_wallet'
cause Attempting to load a wallet that has not been created yet, or trying to load it from a different database path than where it was originally saved.fixBefore loading, ensure the wallet has been created using `Wallet.create('my_wallet', ...)` at least once. If you use custom database URIs, ensure you're providing the correct `db_uri` when instantiating the Wallet. -
bitcoinlib.exceptions.InvalidKeyError: Invalid private key format
cause The string provided for a private key (e.g., WIF, hex) is not correctly formatted, is an incorrect length, or uses an unsupported encoding.fixDouble-check the private key string. Ensure it's a valid Wallet Import Format (WIF) string, a correct 64-character hexadecimal string, or the specific format expected by the `Key` constructor you are using. -
bitcoinlib.exceptions.InsufficientFundsError: Insufficient funds
cause The wallet does not contain enough unspent transaction outputs (UTXOs) to cover the amount you are trying to send plus the transaction fee.fixVerify the wallet's balance using `wallet.get_balance()`. Ensure that the funds are confirmed on the blockchain. Reduce the transaction amount or add more funds to the wallet. -
ModuleNotFoundError: No module named 'bitcoinlib.wallets'
cause Incorrect import path used for the `Wallet` class, possibly due to outdated code or a typo.fixUse the correct import statement: `from bitcoinlib.wallets import Wallet`. Similar issues might arise for `keys`, `transactions`, or `networks` modules if using incorrect paths.
Warnings
- breaking Major refactoring occurred in version 0.7.x, particularly affecting Wallet and Network management. Older import paths, object instantiation, and network configuration methods from 0.6.x are likely to break.
- gotcha By default, `bitcoinlib` often assumes the Bitcoin mainnet ('bitcoin') if no network is explicitly specified during wallet or transaction creation. This can lead to unexpected behavior if you intend to work on testnets or regtest.
- gotcha Wallets in `bitcoinlib` are persistent and stored in an underlying database (defaulting to SQLite). Changes made to a wallet (e.g., new keys, transactions) are not automatically saved until `wallet.close()` is called.
- gotcha Handling private keys directly in code, especially for display or logging, is a significant security risk. `bitcoinlib` provides tools to manage keys, but ultimate security is the user's responsibility.
- gotcha Creating transactions without proper fee calculation can lead to transactions getting stuck or being rejected by the network. While `bitcoinlib` can estimate fees, it requires careful consideration.
Install
-
pip install bitcoinlib
Imports
- Wallet
from bitcoinlib.wallets import Wallet
- Key
from bitcoinlib.keys import Key
- Transaction
from bitcoinlib.transactions import Transaction
- Script
from bitcoinlib.scripts import Script
- Network
from bitcoinlib.networks import Network
- Mnemonic
from bitcoinlib.mnemonic import Mnemonic
Quickstart
from bitcoinlib.wallets import Wallet
from bitcoinlib.networks import Network
# Define the network (e.g., 'testnet', 'regtest', or 'bitcoin' for mainnet)
# Explicitly set for safety and clarity.
network_name = 'testnet'
# Create a new wallet or load an existing one
# Wallets are persistent and stored in a database (default SQLite).
wallet_name = 'my_first_bitcoinlib_wallet'
try:
wallet = Wallet(wallet_name, network=network_name)
print(f"Loaded existing wallet '{wallet_name}' on {network_name}.")
except Exception:
wallet = Wallet.create(wallet_name, network=network_name)
print(f"Created new wallet '{wallet_name}' on {network_name}.")
# Generate a new address for the wallet
key = wallet.get_key()
address = key.address
print(f"New address: {address}")
print(f"Private key (WIF): {key.wif}") # CAUTION: Handle private keys securely!
# Close the wallet to ensure all changes are saved
wallet.close()
print("Wallet closed.")