Node.js中用send-crypto通过WIF密钥发BTC遇ECPair错误求解决
解决WIF私钥转十六进制适配send-crypto库及
ECPair.fromWIF is not a function报错问题 一、修复现有send-crypto代码方案
你遇到的ECPair.fromWIF is not a function报错,是因为新版ecpair库需要依赖tiny-secp256k1初始化工厂实例,不能直接调用静态方法。同时send-crypto要求私钥为十六进制字符串,需要将WIF转换后的Buffer转为hex格式。
步骤1:安装依赖
npm install ecpair tiny-secp256k1
步骤2:修改代码
const bitcoin = require('bitcoinjs-lib'); const { ECPairFactory } = require('ecpair'); const tinysecp = require('tiny-secp256k1'); const CryptoAccount = require("send-crypto"); // 初始化ECPair工厂 const ECPair = ECPairFactory(tinysecp); /* Load account from private key */ const privateKeyWIF = "L3fKJ..."; const keyPair = ECPair.fromWIF(privateKeyWIF); // 将Buffer转为十六进制字符串,适配send-crypto要求 const privateKeyHex = keyPair.privateKey.toString('hex'); console.log(privateKeyHex); const account = new CryptoAccount(privateKeyHex); async function start() { console.log(await account.address("BTC")); console.log(await account.getBalance("BTC")); console.log(await account.getBalance("BTC", {address:"bc1qe6..."})); const balance = await account.getBalance("BTC"); await account.send("bc1qe6...", balance, "BTC", { subtractFee: true, }); }; start();
二、无需send-crypto的替代方案(直接用bitcoinjs-lib实现转账)
如果不想依赖send-crypto,可以直接用bitcoinjs-lib构建交易并通过公开区块链API广播,更灵活可控:
代码示例
const bitcoin = require('bitcoinjs-lib'); const axios = require('axios'); const { ECPairFactory } = require('ecpair'); const tinysecp = require('tiny-secp256k1'); const ECPair = ECPairFactory(tinysecp); const privateKeyWIF = "L3fKJ..."; const keyPair = ECPair.fromWIF(privateKeyWIF); const targetAddress = "bc1qe6..."; // 主网API地址,测试网替换为https://blockstream.info/testnet/api const API_BASE = "https://blockstream.info/api"; async function getUtxos(address) { const response = await axios.get(`${API_BASE}/address/${address}/utxo`); return response.data; } async function getFeeRate() { // 获取半小时确认的费率(sat/vB) const response = await axios.get(`${API_BASE}/fee-estimates`); return response.data.halfHour; } async function sendBitcoin() { // 生成当前地址(P2WPKH格式) const address = bitcoin.payments.p2wpkh({ pubkey: keyPair.publicKey }).address; console.log("当前地址:", address); const utxos = await getUtxos(address); if (utxos.length === 0) { console.log("无可用UTXO,无法转账"); return; } const feeRate = await getFeeRate(); const psbt = new bitcoin.Psbt({ network: bitcoin.networks.bitcoin }); let totalInput = 0; // 添加所有UTXO作为输入 utxos.forEach(utxo => { psbt.addInput({ hash: utxo.txid, index: utxo.vout, witnessUtxo: { script: Buffer.from(utxo.scriptpubkey, 'hex'), value: utxo.value } }); totalInput += utxo.value; }); // 估算交易大小并计算手续费 const txSize = utxos.length * 141 + 31; // 简化估算:每个输入约141vB,输出约31vB const fee = txSize * feeRate; const sendAmount = totalInput - fee; if (sendAmount <= 0) { console.log("余额不足以支付手续费"); return; } // 添加目标地址输出 psbt.addOutput({ address: targetAddress, value: sendAmount }); // 签名所有输入 utxos.forEach((_, index) => { psbt.signInput(index, keyPair); }); // 完成签名并提取交易十六进制 psbt.finalizeAllInputs(); const txHex = psbt.extractTransaction().toHex(); // 广播交易 const response = await axios.post(`${API_BASE}/tx`, txHex); console.log("交易广播成功,TXID:", response.data); } sendBitcoin();
内容的提问来源于stack exchange,提问作者James
相关产品推荐
相关产品推荐

