bitcoinjs-lib
bitcoinjs-lib copied to clipboard
I need help asap 2
Good day everyone I need help I went to broadcast my transaction it’s giving me error when I’m trying to push transaction

On the below when I decode raw transaction it’s giving me this addresses": [ "14XzvjeSSPTNt1in2XZtug8aXxVyVVe8tq", "bc1qdkezmg0ah89l23tfleasngcd4tfnpsgh2lh9jl" ], "block_height": -1, "block_index": -1, "confirmations": 0, "double_spend": false, "fees": 29700000, "hash": "6922dc59f148b4b8268bc914f7fcf016e46c4a8d8a053be45ded09729b933c79", "inputs": [ { "addresses": [ "14XzvjeSSPTNt1in2XZtug8aXxVyVVe8tq" ], "age": 741957, "output_index": 1, "output_value": 149700000, "prev_hash": "f73f407dcb4d4d7f0570a615e2fdde1f6fc5bf75f7183e7dd39b428286d75670", "script": "76a91426c535f6258a5cfcee1ccbb879cd8dc147a0fd7388ac", "script_type": "pay-to-pubkey-hash", "sequence": 4294967293 } ], "opt_in_rbf": true, "outputs": [ { "addresses": [ "bc1qdkezmg0ah89l23tfleasngcd4tfnpsgh2lh9jl" ], "script": "00146db22da1fdb9cbf54569fe7b09a30daad330c117", "script_type": "pay-to-witness-pubkey-hash", "value": 120000000 } ], "preference": "high", "received": "2022-06-23T08:34:47.604665062Z", "relayed_by": "3.236.233.149", "size": 107, "total": 120000000, "ver": 1, "vin_sz": 1, "vout_sz": 1, "vsize": 107
}
I Have found this older issue (it might help): https://github.com/bitcoinjs/bitcoinjs-lib/issues/924
Please also describe how the API of this lib is being used.
Hello everyone, I have the same problem.
import { ECPairAPI, ECPairFactory } from 'ecpair';
import * as bitcoin from 'bitcoinjs-lib';
import * as ecc from 'tiny-secp256k1';
create keys using the function:
const generateKey = () => {
const NETWORK = bitcoin.networks.testnet;
const ECPair: ECPairAPI = ECPairFactory(ecc);
const keyPair = ECPair.makeRandom({ network: NETWORK });
const { address } = bitcoin.payments.p2pkh({
pubkey: keyPair.publicKey,
network: NETWORK,
});
const publicKey = keyPair.publicKey.toString('hex');
const privateKeyWif = keyPair.toWIF();
return {
address,
publicKey,
privateKeyWif,
};
};
output:
{
address: 'mx8HFEoW6gnZ3993N5p2B2hAgQwW85biLd',
publicKey: '03a91708dc31db2376e7ee11d9945478dda2dfe5047651acb90948bffa8ab0038e',
privateKeyWif: 'cRzY6KknsptFznYgGsdQCTghVXB5ZQayde7qthsYXEAVWqiYAcQv'
}
{
address: 'mkYC3kNNgVCN5dHS4Ao7ZDYpXcXQM7BwLv',
publicKey: '028389bfbfb2775ff7b346d772a495983eb50cd49162ae3087aadafb5090a001d1',
privateKeyWif: 'cSrYNJfE1eCpsJcbyu1GnvRusAwZuuiTTqkWdtRCbbQoGsmjKmA1'
}
const getTxUtho = async (address: string) => {
try {
const res = await fetch(`https://api.blockcypher.com/v1/btc/test3/addrs/${address}/full?includeHex=true`, {
method: 'GET',
headers: {
'Content-Type': 'application/json'
},
});
if (!!res.txs.length) {
return {
hash: res.txs[0].hash,
hex: res.txs[0].hex,
};
}
} catch(e) {
console.error(e);
}
}
const pushRawTransaction = async ( txHex: string ) => {
try {
const res = await fetch(`https://api.blockcypher.com/v1/btc/test3/txs/push`, {
method: 'POST',
body: JSON.stringify({ tx: txHex }),
headers: {
'Content-Type': 'application/json'
},
});
return res.hash;
} catch(e) {
console.error(e);
}
};
const validator = (
pubkey: Buffer,
msghash: Buffer,
signature: Buffer,
): boolean => {
const ECPair = ECPairFactory(ecc);
return ECPair.fromPublicKey(pubkey).verify(msghash, signature);
};
const sendTransactions = async (
to: string,
amount: number,
from: string,
privateKey: string,
publicKey: string,
) => {
const publicKeyBuffer = Buffer.from(publicKey, 'hex');
const ECPair = ECPairFactory(ecc);
const NETWORK = bitcoin.networks.testnet;
const alice = ECPair.fromWIF(privateKey, NETWORK);
const p2wpkh = bitcoin.payments.p2wpkh({
pubkey: publicKeyBuffer,
network: NETWORK,
m: 1,
});
const p2sh = bitcoin.payments.p2sh({ redeem: p2wpkh, network: NETWORK });
const redeemScript = p2sh.redeem.output;
const { hash, hex } = await getTxUtho(from);
const psbt = new bitcoin.Psbt({ network: NETWORK });
psbt.addInput({
hash: hash, //txId
index: 0,
nonWitnessUtxo: Buffer.from(hex, 'hex'),
redeemScript,
});
psbt.addOutput({
address: to,
value: amount,
});
psbt.signInput(0, alice);
psbt.validateSignaturesOfInput(0, validator);
psbt.finalizeAllInputs();
const txRaw = psbt.extractTransaction(true); // max fee
const txHash = await pushRawTransaction(txRaw.toHex());
return txHash;
}
sendTransactions(
'mx8HFEoW6gnZ3993N5p2B2hAgQwW85biLd', // to
10000, // amount
'mkYC3kNNgVCN5dHS4Ao7ZDYpXcXQM7BwLv', // from
'cSrYNJfE1eCpsJcbyu1GnvRusAwZuuiTTqkWdtRCbbQoGsmjKmA1', //private
'028389bfbfb2775ff7b346d772a495983eb50cd49162ae3087aadafb5090a001d1', //public
);
Can you please point out what is my mistake?
@mb38 You are mixing up p2pkh and p2wpkh. Pick one.
(Your generate keys is generating p2pkh address, but your send function treats it like p2sh-p2wpkh...)
@junderw Thanks, I fixed it to p2pkh.
const p2pkh = bitcoin.payments.p2pkh({
pubkey: publicKeyBuffer,
network: NETWORK,
m: 1,
});
const p2sh = bitcoin.payments.p2sh({ redeem: p2pkh, network: NETWORK });
But now I'm getting a new error when sending a POST request to: https://api.blockcypher.com/v1/btc/test3/txs/push
{
"error": "Error validating transaction: Error running script for input 0 referencing 867e6297d599e36220c3542095123f3de120d45fd57e014be634db0cb603efe6 at 0: Script was NOT verified successfully.."
}
HEX that I send:
{
"tx":"0200000001e6ef03b60cdb34e64b017ed55fd420e13d3f12952054c32062e399d597627e860000000085483045022100dfbcbc3d66bacbd4c2b31372d5caa4c65709f7a8749d38ee37d5393512b5d97b022017d9543d892f9280b916081fa7c4a4ef1a0a9486f212b4b6a8fd59a315aa6c4f0121028389bfbfb2775ff7b346d772a495983eb50cd49162ae3087aadafb5090a001d11976a9143714868de0b58bd838ac2e7e40033ee1970204fc88acffffffff0101000000000000001976a914b630641e3b490b573cf53e34b1bc20a10a54042b88ac00000000"
}
psbt.validateSignaturesOfInput(0, validator) // true Do I need to do any additional checks before sending a transaction?
you don't need p2sh.
p2sh-p2pkh is not the same as p2pkh.
@junderw Thank you very much this fixed the problem and redeemScript should not be used in this case. Just in case, here is a working code for sending a transaction for those who will face the same problem
const sendTransactions = async (
to: string,
amount: number,
from: string,
privateKey: string,
) => {
const network = bitcoin.networks.testnet;
const ECPair: ECPairAPI = ECPairFactory(ecc);
const alice = ECPair.fromWIF(privateKey, network);
const { hash, hex } = await getTxUtho(from);
const psbt = new bitcoin.Psbt({ network });
psbt.addInput({
hash: hash, //txId
index: 0,
nonWitnessUtxo: Buffer.from(hex, 'hex'),
});
psbt.addOutput({
address: to,
value: amount,
});
psbt.signInput(0, alice);
psbt.validateSignaturesOfInput(0, validator);
psbt.finalizeAllInputs();
const txRaw = psbt.extractTransaction(true); // max fee
const txHash = await pushRawTransaction(txRaw.toHex());
return txHash;
};
I've seen psbt.validateSignaturesOfInput(0, validator); without further checks in many code examples.
I believe it would be a good idea to throw if psbt.validateSignaturesOfInput(0, validator) !== true.