Taproot User Guide
This guide explains how to use Taproot (BIP341/BIP86) addresses in the go-crypto-wallet system.
Table of Contents
- What is Taproot?
- Why Use Taproot?
- Prerequisites
- Configuration
- Getting Started
- Workflow Examples
- Migration Guide
- Best Practices
- FAQ
- Troubleshooting
What is Taproot?
Taproot is Bitcoin's latest major upgrade (activated November 2021) that introduces a new address format and signature scheme:
- Address Format: P2TR (Pay-to-Taproot) using bech32m encoding
- Address Prefix:
bc1pfor mainnet,tb1pfor testnet/signet - Signature Scheme: Schnorr signatures (BIP340) instead of ECDSA
- Derivation Path: BIP86 (
m/86'/0'/account'/0/index)
Technical Improvements
- Privacy: All Taproot spends look identical on-chain (single-sig and multisig indistinguishable)
- Efficiency: Smaller transaction sizes = lower fees (30-50% reduction)
- Smart Contracts: Script path spending enables complex conditions
- Signature Aggregation: Multiple signatures can be combined (MuSig2)
Why Use Taproot?
Benefits
✅ Lower Transaction Fees - 30-50% smaller transaction sizes ✅ Enhanced Privacy - All spends look the same on-chain ✅ Future-Proof - Latest Bitcoin address standard ✅ Faster Validation - Schnorr signatures verify faster than ECDSA ✅ Better Multisig - More efficient than traditional multisig
When to Use Taproot
- ✅ New wallets and addresses
- ✅ When transaction fee savings matter
- ✅ When privacy is important
- ✅ For multisig setups (more efficient)
When NOT to Use Taproot
- ⚠️ If you need compatibility with services that don't support Taproot yet
- ⚠️ If you're using Bitcoin Core older than v22.0
- ⚠️ If you need to support very old wallet software
Prerequisites
Required Software Versions
Bitcoin Core v22.0 or later (for Taproot/Schnorr support)
bashbitcoin-cli --version # Should output: Bitcoin Core version v22.0.0 or highergo-crypto-wallet v5.0.0 or later
bash./keygen --version ./watch --version ./sign --versionMySQL 5.7 or later (for address/transaction storage)
Recommended Setup
- Operating System: Linux, macOS, or Windows
- Network: Bitcoin Mainnet, Testnet3, or Signet
- Disk Space: Varies by network (Mainnet requires significant space)
Configuration
Step 1: Configure Key Type and Address Type
Edit your wallet configuration file to enable Taproot:
Keygen Wallet (config/wallet/btc/keygen.yaml):
# BIP86 is required for Taproot
key_type: bip86 # bip44, bip49, bip84, bip86, musig2
# Set address type to taproot
address_type: taproot # legacy, p2sh-segwit, bech32, taproot
bitcoin:
host: 127.0.0.1:18332
user: your_rpc_user
pass: your_rpc_password
network_type: testnet3 # mainnet, testnet3, regtest, signetWatch Wallet (config/wallet/btc/watch.yaml):
address_type: taproot
bitcoin:
host: 127.0.0.1:18332
user: your_rpc_user
pass: your_rpc_password
network_type: testnet3Sign Wallet (config/wallet/btc/sign1.yaml):
address_type: taproot
bitcoin:
host: 127.0.0.1:20332
user = "your_rpc_user"
pass = "your_rpc_password"
network_type = "testnet3"Step 2: Verify Bitcoin Core Configuration
Ensure Bitcoin Core is configured correctly:
# Check Bitcoin Core version (must be v22.0+)
bitcoin-cli --version
# Check if Taproot is activated (mainnet)
bitcoin-cli getblockchaininfo | grep -A 5 taproot
# Create wallet with descriptor support (recommended)
bitcoin-cli createwallet "taproot_wallet" false false "" false trueStep 3: Verify Database Schema
Ensure your database has the taproot_address column:
-- Check if taproot_address column exists
DESCRIBE account_key;
-- Should show:
-- taproot_address varchar(255) NULLIf missing, run the migration script (already included in Phase 1a).
Getting Started
Quick Start Example
This example walks through creating a Taproot wallet from scratch:
# Config paths
KEYGEN_CONF=./config/wallet/btc/keygen.yaml
WATCH_CONF=./config/wallet/btc/watch.yaml
ACCOUNT_CONF=./config/wallet/account/account.yaml
# 1. Generate seed (Keygen wallet - OFFLINE)
./keygen --config $KEYGEN_CONF --coin btc create seed
# 2. Generate Taproot keys (Keygen wallet - OFFLINE)
./keygen --config $KEYGEN_CONF --coin btc create hdkey --account client --count 10
# 3. Export addresses (Keygen wallet - OFFLINE)
./keygen --config $KEYGEN_CONF --coin btc export address --account client
# Output: ./data/address/btc/client_1234567890.csv
# 4. Import addresses to Watch wallet (Watch wallet - ONLINE)
./watch --config $WATCH_CONF --coin btc import address --account client \
--filepath ./data/address/btc/client_1234567890.csv
# 5. Check imported addresses
./watch --config $WATCH_CONF --coin btc api getaddressesbylabel --label clientExpected Output
After generating Taproot keys, you should see addresses like:
Mainnet: bc1p5cyxnuxmeuwuvkwfem96lqzszd02n6xdcjrs20cac6yqjjwudpxqkedrcr
Testnet: tb1pqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvsesf3hn0cTaproot Address Characteristics:
- Prefix:
bc1p(mainnet) ortb1p(testnet/signet) - Length: 62 characters
- Encoding: bech32m (lowercase only)
Workflow Examples
Example 1: Receiving Funds to Taproot Address
Scenario: Customer deposits funds to your Taproot address
# Config paths
KEYGEN_CONF=./config/wallet/btc/keygen.yaml
WATCH_CONF=./config/wallet/btc/watch.yaml
# 1. Generate client account Taproot addresses (Keygen - OFFLINE)
./keygen --config $KEYGEN_CONF --coin btc create hdkey --account client --count 100
# 2. Export addresses (Keygen - OFFLINE)
./keygen --config $KEYGEN_CONF --coin btc export address --account client
# Output: ./data/address/btc/client_1234567890.csv
# 3. Transfer address file to Watch wallet (secure transfer)
# Copy client_1234567890.csv to Watch wallet system
# 4. Import addresses (Watch - ONLINE)
./watch --config $WATCH_CONF --coin btc import address --account client \
--filepath ./data/address/btc/client_1234567890.csv
# 5. Monitor for incoming transactions
./watch --config $WATCH_CONF --coin btc monitor transaction
# 6. Create deposit transaction when funds are confirmed
./watch --config $WATCH_CONF --coin btc create transaction --account deposit
# Output: ./data/tx/btc/deposit_1_unsigned_0_1234567890.txExample 2: Sending Funds from Taproot Address (Single-Sig)
Scenario: Send funds from deposit account to payment account
# Config paths
KEYGEN_CONF=./config/wallet/btc/keygen.yaml
WATCH_CONF=./config/wallet/btc/watch.yaml
# 1. Create unsigned transaction (Watch - ONLINE)
./watch --config $WATCH_CONF --coin btc create transaction --account deposit
# Output: ./data/tx/btc/deposit_1_unsigned_0_1234567890.tx
# 2. Transfer transaction file to Keygen wallet (secure transfer)
# Copy deposit_1_unsigned_0_1234567890.tx to Keygen system
# 3. Sign transaction with Schnorr signature (Keygen - OFFLINE)
./keygen --config $KEYGEN_CONF --coin btc sign \
--file ./data/tx/btc/deposit_1_unsigned_0_1234567890.tx
# Output: ./data/tx/btc/deposit_1_signed_0_1234567890.tx
# 4. Transfer signed transaction back to Watch wallet
# 5. Send transaction (Watch - ONLINE)
./watch --config $WATCH_CONF --coin btc send transaction --account deposit \
--file ./data/tx/btc/deposit_1_signed_0_1234567890.txExample 3: Multisig Taproot Transaction
Scenario: Send funds from payment account (requires 2-of-3 signatures)
# Config paths
KEYGEN_CONF=./config/wallet/btc/keygen.yaml
SIGN_CONF=./config/wallet/btc/sign1.yaml
WATCH_CONF=./config/wallet/btc/watch.yaml
# 1. Create unsigned transaction (Watch - ONLINE)
./watch --config $WATCH_CONF --coin btc create transaction --account payment
# Output: ./data/tx/btc/payment_5_unsigned_0_1234567890.tx
# 2. First signature (Keygen - OFFLINE)
./keygen --config $KEYGEN_CONF --coin btc sign \
--file ./data/tx/btc/payment_5_unsigned_0_1234567890.tx
# Output: ./data/tx/btc/payment_5_unsigned_1_1234567890.tx (still unsigned - needs more sigs)
# 3. Second signature (Sign wallet - OFFLINE)
./sign --config $SIGN_CONF --coin btc sign \
--file ./data/tx/btc/payment_5_unsigned_1_1234567890.tx
# Output: ./data/tx/btc/payment_5_signed_0_1234567890.tx (now fully signed)
# 4. Send transaction (Watch - ONLINE)
./watch --config $WATCH_CONF --coin btc send transaction --account payment \
--file ./data/tx/btc/payment_5_signed_0_1234567890.txExample 4: Creating Payment Request with Taproot
# Config path
WATCH_CONF=./config/wallet/btc/watch.yaml
# 1. Create payment request (Watch - ONLINE)
./watch --config $WATCH_CONF --coin btc create payment-request \
--address bc1p5cyxnuxmeuwuvkwfem96lqzszd02n6xdcjrs20cac6yqjjwudpxqkedrcr \
--amount 0.001
# 2. Monitor payment status
./watch --config $WATCH_CONF --coin btc monitor transactionMigration Guide
Migrating from Legacy Addresses to Taproot
Important: You cannot convert existing addresses to Taproot. You must generate new addresses and migrate funds.
Step 1: Generate New Taproot Addresses
# Update configuration
sed -i 's/address_type = "bech32"/address_type = "taproot"/' \
config/wallet/btc/keygen.yaml
sed -i 's/key_type = "bip84"/key_type = "bip86"/' \
config/wallet/btc/keygen.yaml
# Generate new Taproot addresses
./keygen --coin btc create hdkey --account client --count 100
./keygen --coin btc export address --account clientStep 2: Import to Watch Wallet
# Import new Taproot addresses
./watch --coin btc import address --account client \
--filepath ./data/address/btc/client_1234567890.csvStep 3: Gradual Migration Strategy
Option A: Immediate Migration
- Stop using old addresses immediately
- Transfer all funds from old addresses to new Taproot addresses
- Update all systems to use new addresses
Option B: Gradual Migration
- Start issuing new Taproot addresses to new users
- Keep accepting payments to old addresses
- Periodically consolidate old address balances to Taproot addresses
- Phase out old addresses over 6-12 months
Step 4: Update External Systems
# Export new Taproot addresses for integration
./keygen --coin btc export address --account client
# Update:
# - Payment processors
# - Customer databases
# - Invoicing systems
# - Exchange integrationsCompatibility Matrix
| Address Type | Your Wallet | Bitcoin Core | Network | Status |
|---|---|---|---|---|
| Taproot (bc1p) | v5.0.0+ | v22.0+ | All | ✅ Full Support |
| Bech32 (bc1q) | All | v0.16.0+ | All | ✅ Compatible |
| P2SH-SegWit (3) | All | v0.13.1+ | All | ✅ Compatible |
| Legacy (1) | All | All | All | ✅ Compatible |
Best Practices
Security
Keep Keygen/Sign Wallets Offline
- Never connect Keygen or Sign wallets to the internet
- Use air-gapped systems or hardware security modules (HSMs)
- Transfer files via USB or QR codes only
Secure File Transfers
bash# Encrypt transaction files gpg --encrypt --recipient your@email.com transaction.tx # Verify checksums sha256sum transaction.txBackup Seed Phrases
- Store seed phrases in multiple secure locations
- Use hardware wallets for seed storage
- Test wallet recovery before storing funds
Performance
Batch Operations
bash# Generate addresses in batches ./keygen --coin btc create hdkey --account client --count 1000Monitor Transaction Pool
bash# Check mempool before sending bitcoin-cli getmempoolinfoOptimize Fee Estimation
- Taproot transactions are smaller = lower fees
- Use dynamic fee estimation based on mempool
Operational
Test on Testnet First
bash# Always test new workflows on testnet ./keygen --config ./config/wallet/btc/keygen_testnet.yaml --coin btc ...Keep Audit Logs
bash# Log all wallet operations ./keygen --coin btc create hdkey --account client --count 10 \ 2>&1 | tee -a keygen_audit.logRegular Backups
bash# Backup database mysqldump -u user -p wallet_db > backup_$(date +%Y%m%d).sql # Backup address files tar -czf addresses_backup_$(date +%Y%m%d).tar.gz data/address/
FAQ
General Questions
Q: Can I receive funds to Taproot addresses from any wallet? A: Yes, most modern wallets support sending to Taproot addresses. However, some older wallets may not recognize bc1p addresses.
Q: Are Taproot addresses case-sensitive? A: No, Taproot addresses use bech32m encoding which is case-insensitive. However, they should always be displayed in lowercase.
Q: Can I convert my existing bech32 (bc1q) addresses to Taproot (bc1p)? A: No, you must generate new Taproot addresses. Each address type has a different derivation path and key structure.
Q: Do I need to upgrade my entire system at once? A: No, you can run Taproot and legacy address types side-by-side. Migrate gradually.
Technical Questions
Q: What is the difference between bech32 and bech32m? A: Bech32m is an improved version that fixes a checksum issue in the original bech32 encoding. Taproot uses bech32m.
Q: Can I use Taproot for multisig? A: Yes, but traditional multisig (multiple keys, threshold signing) works the same way. True Taproot multisig (MuSig2 key aggregation) is more efficient but not yet implemented in this wallet.
Q: How much smaller are Taproot transactions? A: Typical savings:
- Single-sig: 30-40% smaller
- 2-of-3 multisig: 40-50% smaller
- Larger multisig: Even greater savings
Q: Do I need to change my backup procedures? A: No, seed phrases work the same way. However, ensure you note the derivation path (BIP86) for recovery.
Q: Can I mix Taproot and legacy UTXOs in one transaction? A: Yes, you can spend from multiple address types in a single transaction.
Troubleshooting Questions
Q: Why do I get "fail to call NewAddressTaproot()" errors? A: This usually means:
- Bitcoin Core version is older than v22.0
- Bitcoin Core is not properly configured
- RPC connection issue
Q: Why are my Taproot addresses not showing up? A: Check:
- Configuration:
address_type = "taproot"andkey_type = "bip86" - Database schema has
taproot_addresscolumn - Address import completed successfully
Q: Transaction signatures failing? A: Ensure:
- Bitcoin Core v22.0+ is running
- Transaction file includes previous transaction data
- Correct wallet is unlocked in Bitcoin Core
Troubleshooting
Issue: "Address type not supported"
Symptoms:
Error: address type 'taproot' not recognizedSolutions:
Verify configuration file:
bashgrep "address_type" config/wallet/btc/keygen.yaml # Should show: address_type = "taproot"Check wallet version:
bash./keygen --version # Should be v5.0.0 or later
Issue: "Bitcoin Core RPC connection failed"
Symptoms:
Error: could not connect to Bitcoin Core RPCSolutions:
Verify Bitcoin Core is running:
bashbitcoin-cli getblockchaininfoCheck RPC credentials in config:
toml[bitcoin] host = "127.0.0.1:18332" user = "your_rpc_user" pass = "your_rpc_password"Test RPC connection:
bashcurl --user your_rpc_user:your_rpc_password \ --data-binary '{"jsonrpc": "1.0", "id": "test", "method": "getblockchaininfo", "params": []}' \ -H 'content-type: text/plain;' \ http://127.0.0.1:18332/
Issue: "Taproot address not generated"
Symptoms:
- Keys generated but no Taproot addresses in output
- Database shows NULL for
taproot_addresscolumn
Solutions:
Verify
key_typeis set tobip86:bashgrep "key_type" config/wallet/btc/keygen.yaml # Should show: key_type = "bip86"Check database schema:
sqlDESCRIBE account_key; -- Should include: taproot_address varchar(255) NULLRegenerate keys with correct configuration
Issue: "Transaction signature invalid"
Symptoms:
Error: non-mandatory-script-verify-flag (Signature must be zero for failed CHECK(MULTI)SIG operation)Solutions:
Ensure Bitcoin Core v22.0+:
bashbitcoin-cli --versionVerify transaction file includes previous outputs:
bashcat ./data/tx/btc/payment_5_unsigned_0_*.tx # Should contain: hex,encoded_prevs_addrsCheck wallet is properly configured for Taproot
Issue: "Database migration required"
Symptoms:
Error: column 'taproot_address' does not existSolutions:
Run database migration:
sqlALTER TABLE account_key ADD COLUMN taproot_address VARCHAR(255) NULL AFTER bech32_address;Restart wallet services
Getting Help
If you encounter issues not covered here:
Check Logs:
bash# Keygen wallet tail -f keygen.log # Watch wallet tail -f watch.logEnable Debug Logging:
toml[logger] level = "debug" # change from "info" to "debug"Verify Configuration:
bash# Validate TOML syntax python3 -c "import toml; toml.load('config/wallet/btc/keygen.yaml')"Test with Signet:
- Signet is easier to test than testnet
- Free test coins available
- Faster block times
Report Issues:
- GitHub Issues: https://github.com/hiromaily/go-crypto-wallet/issues
- Include: version, config (redact secrets), error messages, steps to reproduce
Additional Resources
Documentation
- Taproot Testing Guide - For developers running tests
- BIP341 - Taproot - Technical specification
- BIP86 - Key Derivation - Derivation path standard
- BIP340 - Schnorr Signatures - Signature scheme
Tools
- Bitcoin Core - Full node software
- Bitcoin Explorer - View transactions on-chain
- Mempool.space - Fee estimation and mempool monitoring
Community
- Bitcoin-dev mailing list
- Bitcoin Stack Exchange
- Bitcoin Core development
Document Version: Phase 1h Last Updated: 2025-12-27 Related Issue: #89 - Implement Taproot Support (Phase 1) Minimum Wallet Version: v5.0.0 Minimum Bitcoin Core Version: v22.0.0