专业级的比特币转账类库,支持完整的 UTXO 管理、多种地址格式、动态手续费估算、多签、Taproot。
- ✅ 指定数量划转
- ✅ 全部余额划转(自动预留手续费)
- ✅ 自动找零到指定地址
- ✅ 第三方项目友好的 API 设计
- 🔐 多种签名方式:P2PKH (Legacy)、P2WPKH (SegWit)、P2TR (Taproot)
- 🏦 UTXO 智能管理:自动选择最优 UTXO 组合
- 💰 手续费策略:动态估算、自定义费率、批量优化
- 🎯 地址格式全支持:Legacy、SegWit、Native SegWit (Bech32)、Taproot (Bech32m)
- 🔄 RBF 支持:Replace-By-Fee 交易加速
- 👥 多签地址:支持 M-of-N 多签交易(1-of-2, 2-of-3, 3-of-5 等)
- 🔑 HD 钱包支持:BIP39 助记词、BIP44 派生路径、多账户管理
- 🌐 多节点支持:自建节点、第三方 API(Blockstream, Blockchain.com)
- 🧪 测试网支持:Mainnet/Testnet 无缝切换
- 📊 交易追踪:查询交易状态、确认数、区块高度
- 🛡️ 安全特性:交易签名前验证、余额检查、双花检测
- 📝 完整日志:操作审计、错误追踪
- 🚀 Taproot 支持:Schnorr 签名、更小交易、更强隐私
go get github.com/zlabwork/btc-libpackage main
import (
"fmt"
"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/btcutil"
"github.com/btcsuite/btcd/chaincfg"
btc "github.com/zlabwork/btc-lib/pkg"
)
func main() {
network := btc.TestNet
params := &chaincfg.TestNet3Params
// --- 单签地址 ---
privKey, _ := btcec.NewPrivateKey()
wif, _ := btcutil.NewWIF(privKey, params, true)
parsedKey, _, _ := btc.ParsePrivateKey(wif.String(), network)
legacyAddr, _ := btc.GenerateAddress(parsedKey, "legacy", network)
fmt.Printf("P2PKH (Legacy) : %s\n", legacyAddr) // 1... / m... / n...
segwitAddr, _ := btc.GenerateAddress(parsedKey, "segwit", network)
fmt.Printf("P2WPKH (SegWit) : %s\n", segwitAddr) // bc1q... / tb1q...
taprootAddr, _ := btc.GenerateTaprootAddress(parsedKey, network)
fmt.Printf("P2TR (Taproot) : %s\n", taprootAddr) // bc1p... / tb1p...
// --- 多签地址 (2-of-3) ---
priv2, _ := btcec.NewPrivateKey()
wif2, _ := btcutil.NewWIF(priv2, params, true)
priv3, _ := btcec.NewPrivateKey()
wif3, _ := btcutil.NewWIF(priv3, params, true)
wifs := []string{wif.String(), wif2.String(), wif3.String()}
p2shAddr, _, _, _ := btc.CreateMultiSigAddressFromWIFs(2, wifs, network)
fmt.Printf("P2SH (传统多签) : %s\n", p2shAddr) // 3... / 2...
p2wshAddr, _, _, _ := btc.CreateSegWitMultiSigAddressFromWIFs(2, wifs, network)
fmt.Printf("P2WSH (SegWit 多签) : %s\n", p2wshAddr) // bc1q... (64 chars)
}package main
import (
"fmt"
"log"
btc "github.com/zlabwork/btc-lib/pkg"
)
func main() {
// 1. 创建客户端
client := btc.NewClient(&btc.Config{
Network: btc.MainNet,
NodeURL: "https://blockstream.info/api",
LogLevel: btc.InfoLevel,
})
// 2. 执行转账
result, err := client.Transfer(&btc.TransferRequest{
FromPrivKey: "你的WIF私钥",
ToAddress: "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
Amount: 50000, // 50,000 聪
FeeRate: 10, // 10 sat/vB
ChangeAddress: "", // 空则自动使用发送地址
})
if err != nil {
log.Fatal(err)
}
fmt.Printf("✅ 转账成功!\n")
fmt.Printf("TxID: %s\n", result.TxID)
fmt.Printf("手续费: %d sats\n", result.Fee)
}// 1. 创建 2-of-3 多签地址
wifs := []string{"key1", "key2", "key3"}
multiSigAddr, redeemScript, _, err := btc.CreateMultiSigAddressFromWIFs(2, wifs, btc.MainNet)
// 2. 从多签地址转账(使用其中 2 个私钥)
result, err := client.TransferFromMultiSig(&btc.MultiSigTransferRequest{
FromAddress: multiSigAddr,
PrivKeys: []string{"key1", "key2"}, // 只需要 2 个
RedeemScript: redeemScript,
ToAddress: "bc1q...",
Amount: 100000,
FeeRate: 10,
})// 1. 生成 Taproot 地址
privKey, _, _ := btc.ParsePrivateKey("your_wif", btc.MainNet)
taprootAddr, _ := btc.GenerateTaprootAddress(privKey, btc.MainNet)
// 地址格式: bc1p... (使用 Schnorr 签名)
// 2. 从 Taproot 地址转账
result, err := client.TransferFromTaproot(&btc.TaprootTransferRequest{
FromPrivKey: "your_wif",
ToAddress: "bc1q...",
Amount: 200000,
FeeRate: 5, // Taproot 手续费更低
})// 1. 生成 12 词助记词
mnemonic, _ := btc.GenerateMnemonic(btc.Strength128)
// 例如: "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"
// 2. 从助记词创建 HD 钱包
wallet, _ := btc.NewHDWallet(mnemonic, "", btc.MainNet)
// 3. 派生第一个接收地址 (m/44'/0'/0'/0/0)
path := btc.GetDefaultDerivationPath(btc.MainNet, 0, 0)
address, privKey, _ := wallet.DeriveAddress(path, "segwit")
// 4. 批量生成 10 个接收地址
addresses, _ := wallet.GetReceivingAddresses(0, 10, "segwit")
// 5. 生成找零地址 (m/44'/0'/0'/1/0)
changeAddrs, _ := wallet.GetChangeAddresses(0, 5, "segwit")
// 6. 恢复钱包
restoredWallet, _ := btc.RestoreWalletFromMnemonic(mnemonic, btc.MainNet)// 一次交易发送给多个地址(节省手续费)
result, err := client.BatchTransfer(&btc.BatchTransferRequest{
FromPrivKey: "your_wif",
Outputs: []btc.Output{
{Address: "bc1q...", Amount: 10000},
{Address: "bc1q...", Amount: 20000},
{Address: "bc1q...", Amount: 30000},
},
FeeRate: 8,
})type Config struct {
Network NetworkType // MainNet, TestNet
NodeURL string // Bitcoin 节点 RPC 或 API URL
NodeUser string // RPC 用户名(可选)
NodePassword string // RPC 密码(可选)
LogLevel LogLevel // Debug, Info, Warn, Error
Timeout time.Duration // 请求超时
}type TransferRequest struct {
FromPrivKey string // WIF 格式私钥
ToAddress string // 接收地址
Amount int64 // 转账金额(satoshi),0 表示全部转账
FeeRate int64 // 手续费率(sat/vB),0 则自动估算
FeeStrategy FeeStrategy // Fast, Normal, Slow
ChangeAddress string // 找零地址
UTXOs []UTXO // 指定 UTXO(可选)
RBF bool // 启用 Replace-By-Fee
Memo string // OP_RETURN 备注(可选)
}// 创建 M-of-N 多签地址
func CreateMultiSigAddress(m int, pubKeys []*btcec.PublicKey, network NetworkType) (string, []byte, error)
// 从 WIF 私钥列表创建多签地址
func CreateMultiSigAddressFromWIFs(m int, wifs []string, network NetworkType) (string, []byte, []*btcec.PublicKey, error)
// 多签转账请求
type MultiSigTransferRequest struct {
FromAddress string // 多签地址
PrivKeys []string // 至少 M 个私钥
RedeemScript []byte // 赎回脚本
ToAddress string // 接收地址
Amount int64 // 转账金额
FeeRate int64 // 手续费率
}// 生成 Taproot 地址
func GenerateTaprootAddress(privKey *btcec.PrivateKey, network NetworkType) (string, error)
// Taproot 转账请求
type TaprootTransferRequest struct {
FromPrivKey string // WIF 私钥
ToAddress string // 接收地址
Amount int64 // 转账金额
FeeRate int64 // 手续费率
}
// 判断是否为 Taproot 地址
func IsTaprootAddress(address string, network NetworkType) bool// 生成助记词
func GenerateMnemonic(strength MnemonicStrength) (string, error)
// strength: Strength128 (12 词) 或 Strength256 (24 词)
// 验证助记词
func ValidateMnemonic(mnemonic string) bool
// 创建 HD 钱包
func NewHDWallet(mnemonic string, passphrase string, network NetworkType) (*HDWallet, error)
// HD 钱包方法
type HDWallet struct {
// 派生单个地址
DeriveAddress(path *DerivationPath, addressType string) (string, *btcec.PrivateKey, error)
// 批量生成接收地址
GetReceivingAddresses(account uint32, count uint32, addressType string) ([]AddressInfo, error)
// 批量生成找零地址
GetChangeAddresses(account uint32, count uint32, addressType string) ([]AddressInfo, error)
// 获取主公钥 (xpub/tpub)
GetMasterPublicKey() (string, error)
}
// 派生路径
type DerivationPath struct {
Purpose uint32 // 44' (BIP44)
CoinType uint32 // 0' (Bitcoin), 1' (Testnet)
Account uint32 // 账户索引
Change uint32 // 0 (接收), 1 (找零)
AddressIndex uint32 // 地址索引
}
// 恢复钱包
func RestoreWalletFromMnemonic(mnemonic string, network NetworkType) (*HDWallet, error)
// 导出私钥为 WIF
func ExportPrivateKeyWIF(privKey *btcec.PrivateKey, network NetworkType) (string, error)// 查询余额
balance, _ := client.GetBalance("bc1q...")
// 查询 UTXO
utxos, _ := client.GetUTXOs("bc1q...")
// 查询交易状态
tx, _ := client.GetTransaction("txid")
// 估算手续费
feeEstimate, _ := client.EstimateFee()
// feeEstimate.Fast - 快速确认
// feeEstimate.Normal - 正常确认
// feeEstimate.Slow - 慢速确认
// 地址验证
isValid := btc.ValidateAddress("bc1q...", btc.MainNet)
// 地址类型识别
addrType, _ := btc.GetAddressType("bc1q...", btc.MainNet)
// P2PKH, P2SH, P2WPKH, P2WSH, P2TR
// 判断 SegWit 地址
isSegWit := btc.IsSegWitAddress("bc1q...", btc.MainNet)btc-lib/
├── pkg/ # 核心库
│ ├── types.go # 类型定义
│ ├── client.go # 客户端入口
│ ├── transaction.go # 交易构建与签名(P2PKH/P2WPKH)
│ ├── multisig.go # 多签功能
│ ├── taproot.go # Taproot 支持
│ ├── wallet.go # 钱包功能(私钥/地址)
│ ├── address.go # 地址工具
│ ├── node.go # 节点交互(Blockstream API)
│ └── logger.go # 日志系统
├── examples/ # 使用示例
│ ├── basic_transfer.go # 基础转账
│ ├── batch_transfer.go # 批量转账
│ ├── multisig_transfer.go # 多签转账
│ ├── taproot_transfer.go # Taproot 转账
│ └── advanced_features.go # 高级功能
├── tests/ # 单元测试
│ ├── transaction_test.go
│ ├── wallet_test.go
│ ├── multisig_test.go
│ └── taproot_test.go
└── README.md
| 特性 | Legacy (P2PKH) | SegWit (P2WPKH) | Taproot (P2TR) |
|---|---|---|---|
| 地址前缀 | 1... | bc1q... | bc1p... |
| 签名算法 | ECDSA | ECDSA | Schnorr |
| 交易大小 | ~230 bytes | ~140 vBytes | ~110 vBytes |
| 手续费 | 高 | 中 | 低 |
| 隐私性 | 低 | 中 | 高 |
| 多签可见性 | 可见 | 可见 | 不可见 |
| 推荐使用 | ❌ 已过时 | ✅ 推荐 | ✅✅ 强烈推荐 |
// 普通转账 - 推荐使用 SegWit 或 Taproot
client.Transfer(&btc.TransferRequest{
FromPrivKey: "wif_key",
ToAddress: "bc1q...",
Amount: 100000,
})// 2-of-3 多签:需要 3 个管理者中的任意 2 个批准
multiSigAddr, redeemScript, _ := btc.CreateMultiSigAddressFromWIFs(
2, []string{"ceo_key", "cfo_key", "cto_key"}, btc.MainNet)
// 转账时使用其中 2 个私钥
client.TransferFromMultiSig(&btc.MultiSigTransferRequest{
PrivKeys: []string{"ceo_key", "cfo_key"},
// ...
})// 给多个员工发工资 - 一次交易完成
client.BatchTransfer(&btc.BatchTransferRequest{
Outputs: []btc.Output{
{Address: "employee1_addr", Amount: 500000},
{Address: "employee2_addr", Amount: 600000},
{Address: "employee3_addr", Amount: 700000},
},
})// 使用 Taproot - 更小、更快、更隐私
client.TransferFromTaproot(&btc.TaprootTransferRequest{
FromPrivKey: "wif_key",
ToAddress: "bc1p...",
Amount: 1000000,
})// 生成助记词并创建 HD 钱包
mnemonic, _ := btc.GenerateMnemonic(btc.Strength128) // 12 词
wallet, _ := btc.NewHDWallet(mnemonic, "", btc.MainNet)
// 批量生成 100 个接收地址(用户充值地址)
addresses, _ := wallet.GetReceivingAddresses(0, 100, "segwit")
// 只需备份一个助记词,恢复所有地址
restoredWallet, _ := btc.RestoreWalletFromMnemonic(mnemonic, btc.MainNet)# 安装依赖
make install
# 运行所有测试
make test
# 带覆盖率
make test-cover
# 运行示例
make example-basic
make example-batch
make example-multisig
make example-taproot- 永远不要硬编码私钥 - 使用环境变量或密钥管理系统
- 生产环境使用冷钱包签名 - 本库支持离线签名
- 测试先在 Testnet - 确保逻辑正确
- 监控交易状态 - 等待足够确认数(建议 6 confirmations)
- 备份助记词和私钥 - 私钥丢失 = 资产永久丢失
- 小额测试 - 生产环境前先用小金额测试完整流程
- 验证接收地址 - 仔细核对接收地址,交易不可撤销
- 使用 RBF - 启用 RBF 可以在交易拥堵时加速
- ✅ P2PKH (Legacy) 签名 - 完整支持
- ✅ P2WPKH (SegWit) 签名 - 完整支持
- ✅ P2SH 多签 - 完整支持
- ✅ P2TR (Taproot) 签名 - 完整支持
- ✅ BIP39 助记词 - 完整支持
- ✅ BIP44 HD 钱包 - 完整支持
- ✅ P2WSH SegWit 多签 - 完整支持
⚠️ 硬件钱包集成 - 未实现(可扩展)
- ✅ 完整的 P2PKH/P2WPKH 签名实现
- ✅ 多签地址创建与转账(M-of-N)
- ✅ Taproot 支持(Schnorr 签名)
- ✅ BIP39 助记词支持(12/24 词)
- ✅ BIP44 HD 钱包(多账户、多地址派生)
- ✅ 批量转账功能
- ✅ 动态手续费估算
- ✅ RBF 交易加速
- ✅ 完整单元测试
- ✅ Blockstream API 集成
- BIP141 - Segregated Witness
- BIP340 - Schnorr Signatures
- BIP341 - Taproot
- BIP342 - Tapscript
- btcd Documentation
MIT License - 详见 LICENSE 文件
欢迎提交 Issue 和 Pull Request!