• About
  • FAQ
  • Earn Bitcoin while Surfing the net
  • Buy & Sell Crypto on Paxful
Newsletter
Approx Foundation
  • Home
    • Home – Layout 1
  • Bitcoin
  • Ethereum
  • Regulation
  • Market
  • Blockchain
  • Business
  • Guide
  • Contact Us
No Result
View All Result
  • Home
    • Home – Layout 1
  • Bitcoin
  • Ethereum
  • Regulation
  • Market
  • Blockchain
  • Business
  • Guide
  • Contact Us
No Result
View All Result
Approx Foundation
No Result
View All Result
Home Bitcoin

Broadcast Error RPC error: {“code”:-26,”message”:”non-mandatory-script-verify-flag (Invalid Schnorr signature)”}

Moussa by Moussa
November 28, 2024
in Bitcoin
0
peer discovery – how to obtain the IP addresses of nodes for mining pools?
189
SHARES
1.5k
VIEWS
Share on FacebookShare on Twitter


While broadcasting raw transaction has to chain, got the below error
RPC error: {“code”:-26,”message”:”non-mandatory-script-verify-flag (Invalid Schnorr signature)”} but signature verification method says its a valid signature for the given message.

I’m trying to do a simple taproot send transaction (key path spending). Signature is given by external signer

My data points are as below

{
  message: '60ccb78b5936d80f63c32eeafe9b746909d7e716f0f96988f437972e633ec7e0',
  signature: 'ed3061523f39137cdab4c9ca0bf9b62433b9642bb8165d996dcc120662866e8060e6f2314d7b03bab31f0a95b4574ddbed2892a176d2723810bd28fda66d1496',
  publicKey: 'ddb666300b8d7ef23e61e2ff3af3c70b59f882d6de1deb601590bb4d15b5d5d3'
}

Transaction hash

020000000001012bd272fa216d2370e265f591907266a8e76a26bc0be4318c9b1b340eaa6134860000000000ffffffff021027000000000000225120ddb666300b8d7ef23e61e2ff3af3c70b59f882d6de1deb601590bb4d15b5d5d3a8c8fa0200000000225120ddb666300b8d7ef23e61e2ff3af3c70b59f882d6de1deb601590bb4d15b5d5d30141ed3061523f39137cdab4c9ca0bf9b62433b9642bb8165d996dcc120662866e8060e6f2314d7b03bab31f0a95b4574ddbed2892a176d2723810bd28fda66d14960100000000

enter image description here

This is my entire code

import sha256 from "sha256";
import { Psbt, networks, payments, Transaction } from "bitcoinjs-lib";
import dotenv from 'dotenv';
import { verifySchnorrSignature } from "./mpc/address.js";
import { signBTCTransaction } from "./systemCallerUtils.js";
dotenv.config();

const UNCONFIRMED_HEIGHT = 4194303;

async function btcSendTransaction() {
  try {
    const address = process.env.BTC_ADDRESS;
    return await createSendTransaction(address);
  } catch (err) {
    console.error("Error in btcSendTransaction:", err);
    throw err;
  }
}

async function createSendTransaction(address) {
  const txObj = await handleTxObj(address);
  const { preSignTxHashes, psbt } = await generatePreSignTxHash(txObj);
  console.log("preSignTxHashes", preSignTxHashes);
  
  // Generate signatures for each input
  const generatedSigns = [];
  for (let i = 0; i < preSignTxHashes.length; i++) {
    const generatedSign = await signBTCTransaction(preSignTxHashes[i], "HASH");
    if (generatedSign) {
      generatedSigns.push(generatedSign);
    }
  }

  // Remove the '0x' prefix for verification
  const hashToVerify = preSignTxHashes[0].replace('0x', '');
  console.log('Hash for verification:', hashToVerify);
  
  try {
    const isValid = await verifySchnorrSignature(
      hashToVerify,
      generatedSigns[0].sign
    );
    console.log("Signature verification:", isValid);

    if (!isValid) {
      console.error('Verification failed:', {
        hash: hashToVerify,
        signature: generatedSigns[0].sign,
        pubkey: process.env.MPC_PUB_KEY
      });
      throw new Error('Invalid signature generated');
    }
  } catch (error) {
    console.error('Verification error:', error);
    throw error;
  }

  try {
    if (generatedSigns.length) {
      const response = await broadCastTx(generatedSigns, psbt);
      return response;
    }
  } catch (e) {
    console.error('Broadcast error:', e);
    throw e;
  }
}

const handleTxObj = async (address) => {
  try {
    let utxos = await getUtxos(address);
    utxos = utxos.filter((v) => v.height !== UNCONFIRMED_HEIGHT);
    
    const outputAmount = 10000;
    const feeRate = 200;
    const outputs = [{
      address: address,
      amount: outputAmount,
    }];

    const { selectedUtxos, totalValue } = selectUtxos(utxos, outputAmount + feeRate);

    console.log("selectedUtxos", selectedUtxos);

    return {
      fromAddress: address,
      utxos: selectedUtxos,
      outputs,
      feeRate,
      toAddress: address,
    };
  } catch (error) {
    console.error("handleTxObj error:", error);
    throw error;
  }
}

export function selectUtxos(utxos, targetAmount) {
  utxos.sort((a, b) => b.value - a.value);
  const selectedUtxos = [];
  let totalValue = 0;

  for (const utxo of utxos) {
    selectedUtxos.push(utxo);
    totalValue += utxo.value;
    if (totalValue >= targetAmount) break;
  }

  if (totalValue < targetAmount) {
    throw new Error('Insufficient UTXOs to cover the target amount');
  }

  return { selectedUtxos, totalValue };
}

export const generatePreSignTxHash = async (txObject) => {
  const network = networks.testnet;
  const psbt = new Psbt({ network });
  
  try {
    const { utxos, fromAddress, outputs, feeRate } = txObject;
    let inputSum = 0;
    const pubKey = process.env.MPC_PUB_KEY;
    const xOnlyPubKey = Buffer.from(pubKey, 'hex');

    // Add inputs using the actual UTXO script
    for (const utxo of utxos) {
      inputSum += utxo.value;
      
      // Get the actual UTXO details
      const txDetails = await fetch(`https://esplora.signet.surge.dev/tx/${utxo.txid}/hex`).then(r => r.text());
      const tx = Transaction.fromHex(txDetails);
      const outputScript = tx.outs[utxo.vout].script;
      
      console.log('UTXO details:', {
        script: outputScript.toString('hex'),
        value: utxo.value
      });

      psbt.addInput({
        hash: utxo.txid,
        index: utxo.vout,
        witnessUtxo: {
          script: outputScript,
          value: utxo.value,
        },
        tapInternalKey: xOnlyPubKey,
      });
    }

    // Add outputs
    for (const output of outputs) {
      psbt.addOutput({
        address: output.address,
        value: output.amount,
      });
    }

    // Add change output
    const totalOutputAmount = outputs.reduce((sum, output) => sum + output.amount, 0);
    const changeAmount = inputSum - totalOutputAmount - feeRate;

    if (changeAmount > 546) {
      psbt.addOutput({
        address: fromAddress,
        value: changeAmount,
      });
    }

    // Generate signing hashes
    const unsignedTx = Transaction.fromBuffer(psbt.data.globalMap.unsignedTx.toBuffer());
    const preSignTxHashes = psbt.data.inputs.map((input, index) => {
      const hash = unsignedTx.hashForWitnessV1(
        index,
        [input.witnessUtxo.script],
        [input.witnessUtxo.value],
        Transaction.SIGHASH_ALL
      );
      
      console.log('Input details:', {
        script: input.witnessUtxo.script.toString('hex'),
        value: input.witnessUtxo.value,
        hash: hash.toString('hex')
      });
      
      return `0x${hash.toString('hex')}`;
    });

    return { preSignTxHashes, psbt };
  } catch (error) {
    console.error('Error in generatePreSignTxHash:', error);
    throw error;
  }
};

export const broadCastTx = async (signatures, psbt) => {
  if (!signatures.length) {
    throw new Error('No signatures provided');
  }

  try {
    signatures.forEach((sig, index) => {
      const sigBuffer = Buffer.from(sig.sign.replace('0x', ''), 'hex');
      console.log(`Raw signature for input ${index}:`, sigBuffer.toString('hex'));
      console.log('Signature length:', sigBuffer.length);

      // For Taproot with SIGHASH_ALL
      const sigWithHashtype = Buffer.concat([
        sigBuffer,
        Buffer.from([Transaction.SIGHASH_ALL])
      ]);

      console.log(`Signature with hashtype for input ${index}:`, sigWithHashtype.toString('hex'));

      psbt.updateInput(index, {
        tapKeySig: sigWithHashtype
      });
    });

    psbt.finalizeAllInputs();
    const tx = psbt.extractTransaction(true);
    const rawTx = tx.toHex();
    
    console.log('Final transaction:', rawTx);
    console.log('Transaction details:', {
      version: tx.version,
      inputs: tx.ins.map(input => ({
        txid: input.hash.reverse().toString('hex'),
        vout: input.index,
        witness: input.witness.map(w => w.toString('hex'))
      })),
      outputs: tx.outs.map(output => ({
        value: output.value,
        script: output.script.toString('hex')
      }))
    });
    
    return await pushTx(rawTx);
  } catch (error) {
    console.error('Failed to broadcast transaction:', error);
    throw error;
  }
};

export const pushTx = async (rawtx) => {
  try {
    const endpoint="https://esplora.signet.surge.dev/tx";
    const resp = await fetch(endpoint, {
      method: "POST",
      headers: { "Content-Type": "text/plain" },
      body: rawtx,
    });
    
    if (!resp.ok) {
      const errorText = await resp.text();
      throw new Error(`HTTP error! status: ${resp.status}, message: ${errorText}`);
    }
    
    const txid = await resp.text();
    return { txid };
  } catch (error) {
    console.error('Push transaction error:', error);
    throw error;
  }
};

export const getUtxos = async (address) => {
  try {
    const endpoint = `https://esplora.signet.surge.dev/address/${address}/utxo`;
    const resp = await fetch(endpoint, {
      method: "GET",
      headers: { "Content-Type": "application/json" },
    });
    if (!resp.ok) {
      throw new Error(`HTTP error! status: ${resp.status}`);
    }
    return await resp.json();
  } catch (error) {
    console.error('Get UTXOs error:', error);
    throw error;
  }
};

export { btcSendTransaction };

Can anyone help me with this?



Source link

Related articles

Zcash Price Slides 23% as Grayscale ETF Hits Reverse

Zcash Price Slides 23% as Grayscale ETF Hits Reverse

October 4, 2026
Crypto Market News Today, December 17: Fidelity Says Bitcoin Is the Gold Standard as They Scoop The Bottom Price and Hal Finney–Satoshi Talk Returns

Trump AI News: Jay Clayton Lined Up as New AI Czar, Heading up Super Intelligence Taskforce

October 4, 2026
Share76Tweet47

Related Posts

Zcash Price Slides 23% as Grayscale ETF Hits Reverse

Zcash Price Slides 23% as Grayscale ETF Hits Reverse

by Moussa
October 4, 2026
0

Key TakeawaysZcash price fell roughly 23% from ZEC’s Sept. 27 peak of $1,697 per unit.Grayscale’s ZCSH lost around $93 million...

Crypto Market News Today, December 17: Fidelity Says Bitcoin Is the Gold Standard as They Scoop The Bottom Price and Hal Finney–Satoshi Talk Returns

Trump AI News: Jay Clayton Lined Up as New AI Czar, Heading up Super Intelligence Taskforce

by Moussa
October 4, 2026
0

In Trump AI news, The Wall Street Journal reported on October 3 that Director of National Intelligence Jay Clayton will...

Latam Cartels Tap Crypto to Expand Their Illicit Workflows

Latam Cartels Tap Crypto to Expand Their Illicit Workflows

by Moussa
October 4, 2026
0

Key TakeawaysLatam cartels operate crypto mining farms, making illicit funds appear legitimate to evade law enforcement.Criminal groups built fintech networks...

Saylor Stirs Strategy Bitcoin Buy Speculation

Saylor Stirs Strategy Bitcoin Buy Speculation

by Moussa
October 4, 2026
0

Key TakeawaysSaylor’s latest orange message raises the prospect of further buying.The shared chart values 847,666 BTC at approximately $72.29 billion.Strategy’s...

Up and Onwards – Week In Review

Up and Onwards – Week In Review

by Moussa
October 4, 2026
0

Bitcoin’s recovery is looking better against gold as well as dollars. Tuur Demeester highlighted a break above resistance at 18...

Load More

youssufi.com

sephina.com

[vc_row full_width="stretch_row" parallax="content-moving" vc_row_background="" background_repeat="no-repeat" background_position="center center" footer_scheme="dark" css=".vc_custom_1517813231908{padding-top: 60px !important;padding-bottom: 30px !important;background-color: #191818 !important;background-position: center;background-repeat: no-repeat !important;background-size: cover !important;}" footer_widget_title_color="#fcbf46" footer_button_bg="#fcb11e"][vc_column width="1/4"]

We bring you the latest in Crypto News

[/vc_column][vc_column width="1/4"][vc_wp_categories]
[/vc_column][vc_column width="1/4"][vc_wp_tagcloud taxonomy="post_tag"][/vc_column][vc_column width="1/4"]

Newsletter

[vc_raw_html]JTNDcCUzRSUzQ2RpdiUyMGNsYXNzJTNEJTIydG5wJTIwdG5wLXN1YnNjcmlwdGlvbiUyMiUzRSUwQSUzQ2Zvcm0lMjBtZXRob2QlM0QlMjJwb3N0JTIyJTIwYWN0aW9uJTNEJTIyaHR0cHMlM0ElMkYlMkZhcHByb3gub3JnJTJGJTNGbmElM0RzJTIyJTNFJTBBJTBBJTNDaW5wdXQlMjB0eXBlJTNEJTIyaGlkZGVuJTIyJTIwbmFtZSUzRCUyMm5sYW5nJTIyJTIwdmFsdWUlM0QlMjIlMjIlM0UlM0NkaXYlMjBjbGFzcyUzRCUyMnRucC1maWVsZCUyMHRucC1maWVsZC1maXJzdG5hbWUlMjIlM0UlM0NsYWJlbCUyMGZvciUzRCUyMnRucC0xJTIyJTNFRmlyc3QlMjBuYW1lJTIwb3IlMjBmdWxsJTIwbmFtZSUzQyUyRmxhYmVsJTNFJTBBJTNDaW5wdXQlMjBjbGFzcyUzRCUyMnRucC1uYW1lJTIyJTIwdHlwZSUzRCUyMnRleHQlMjIlMjBuYW1lJTNEJTIybm4lMjIlMjBpZCUzRCUyMnRucC0xJTIyJTIwdmFsdWUlM0QlMjIlMjIlM0UlM0MlMkZkaXYlM0UlMEElM0NkaXYlMjBjbGFzcyUzRCUyMnRucC1maWVsZCUyMHRucC1maWVsZC1lbWFpbCUyMiUzRSUzQ2xhYmVsJTIwZm9yJTNEJTIydG5wLTIlMjIlM0VFbWFpbCUzQyUyRmxhYmVsJTNFJTBBJTNDaW5wdXQlMjBjbGFzcyUzRCUyMnRucC1lbWFpbCUyMiUyMHR5cGUlM0QlMjJlbWFpbCUyMiUyMG5hbWUlM0QlMjJuZSUyMiUyMGlkJTNEJTIydG5wLTIlMjIlMjB2YWx1ZSUzRCUyMiUyMiUyMHJlcXVpcmVkJTNFJTNDJTJGZGl2JTNFJTBBJTNDZGl2JTIwY2xhc3MlM0QlMjJ0bnAtZmllbGQlMjB0bnAtcHJpdmFjeS1maWVsZCUyMiUzRSUzQ2xhYmVsJTNFJTNDaW5wdXQlMjB0eXBlJTNEJTIyY2hlY2tib3glMjIlMjBuYW1lJTNEJTIybnklMjIlMjByZXF1aXJlZCUyMGNsYXNzJTNEJTIydG5wLXByaXZhY3klMjIlM0UlQzIlQTBCeSUyMGNvbnRpbnVpbmclMkMlMjB5b3UlMjBhY2NlcHQlMjB0aGUlMjBwcml2YWN5JTIwcG9saWN5JTNDJTJGbGFiZWwlM0UlM0MlMkZkaXYlM0UlM0NkaXYlMjBjbGFzcyUzRCUyMnRucC1maWVsZCUyMHRucC1maWVsZC1idXR0b24lMjIlM0UlM0NpbnB1dCUyMGNsYXNzJTNEJTIydG5wLXN1Ym1pdCUyMiUyMHR5cGUlM0QlMjJzdWJtaXQlMjIlMjB2YWx1ZSUzRCUyMlN1YnNjcmliZSUyMiUyMCUzRSUwQSUzQyUyRmRpdiUzRSUwQSUzQyUyRmZvcm0lM0UlMEElM0MlMkZkaXYlM0UlM0NiciUyRiUzRSUzQyUyRnAlM0U=[/vc_raw_html][/vc_column][/vc_row]
No Result
View All Result
  • Contact Us
  • Homepages
  • Business
  • Guide

© 2024 APPROX FOUNDATION - The Crypto Currency News