bitcoinjs / bitcoinjs-lib

A javascript Bitcoin library for node.js and browsers.
MIT License
5.69k stars 2.11k forks source link

How do I add scriptsig in psbt input #1880

Closed Thankgod20 closed 2 months ago

Thankgod20 commented 1 year ago

When trying to broadcast a transaction i usually get this error.

{"error": "Error validating transaction: Error running script for input 0 referencing 1db38f15871e424c60ff2424e7c9990b90cc899306f4603fadb0d7d53ad5b14c at 0: nonempty scriptsig in witness transaction."} My code

`sendBitcoin = async(prop,from,to,value,setmodalVisible)=> { //console.log(',,,,,,+++===',prop.propz.route.params.dPath) //let key = (prop.propz.route.params.priv) let seed = prop.propz.route.params.hdN

let hdNode = bip32.fromSeed(seed)
const masterFingerprint = hdNode.fingerprint
const path = prop.propz.route.params.dPath//"m/84'/0'/0'/0/0";
let childNode = hdNode.derivePath(path)
const pubkey = childNode.publicKey;
const prvKey = childNode.privateKey

let redeemScript = (bitcoin.payments.p2wpkh({pubkey: pubkey,network:bitcoin.networks.testnet}))

console.log("++++++",redeemScript.address,"From",from,'public',pubkey.toString('hex'))

const psbt = new bitcoin.Psbt({ network: bitcoin.networks.testnet }) 

const updateData = {
  bip32Derivation: [
    {
      masterFingerprint,
      path,
      pubkey,
    },
  ],
};

console.log(updateData.bip32Derivation[0].pubkey.toString('hex'))
  fetch('https://api.blockcypher.com/v1/btc/test3/addrs/'+redeemScript.address+'/full?unspentOnly=true&includeHex=true')
            .then((response)=>response.json()) 
            .then(async(response)=> {

                console.log(response)
                let vout = 0;
                response.txs.forEach(tx=>{

                  const isSegwit = tx.hex.substring(8, 12) === '0001'
                  console.log("_____FFFF___",isSegwit)
                  let utxo = tx
                  console.log(utxo.hex)
                  psbt.setVersion(2)
                  if (isSegwit) { 
                    //let vout = 0;
                    let txId = ""
                    let totalAmt = 0
                    let scriptx = ""
                    let isSpent = ""
                    utxo.outputs.forEach(x=>{
                      console.log(x.value)
                      if ((x.addresses[0]) == redeemScript.address ) {
                        totalAmt+= parseInt(x.value)
                        isSpent = x.spent_by == undefined?"":x.spent_by
                        if (x.hash != txId) {
                          txId = x.hash
                          scriptx = x.script   
                        }
                      }

                    })
                   console.log("Spent by",isSpent,"PubKey",scriptx) 
                   if (isSpent =="")  {
                    psbt.addInput({
                      hash: utxo.hash,
                      index: vout,
                      witnessUtxo: { 

                        script: Buffer.from(scriptx,'hex'),
                        value: Number(totalAmt)
                      },
                      sequence: utxo.inputs[0].sequence,
                      redeemScript: Buffer.from(redeemScript.output,'hex'),
                    })
                    psbt.updateInput(vout,updateData)
                    vout+=1
                   }

                  } else {
                    //let vout = 0;
                    let txId = ""
                    let totalAmt = 0
                    let script = ""
                    let isSpent = ""
                    utxo.outputs.forEach(x=>{
                      if ((x.addresses[0]) == redeemScript.address ) {
                        totalAmt+= parseInt(x.value)
                        isSpent = x.spent_by == undefined?"":x.spent_by
                        if (x.hash != txId) {
                          txId = x.hash
                          script = x.script
                      }
                      }
                    })
                    psbt.addInput({
                      hash: utxo.hash,
                      index: vout,//utxo.vout_sz,

                      nonWitnessUtxo: Buffer.from(utxo.hex,'hex') , 
                      redeemScript: Buffer.from(redeemScript.output,'hex'),
                      sequence: utxo.inputs[0].sequence
                    })  
                    psbt.updateInput(vout,updateData)
                    vout+=1

                  }
                })
                  //psbt.updateInput(0,updateData)

                  let vl = (parseFloat(value)*100000000)

                  let vvn = vl - (vl*0.05)

                  console.log(vvn)
                  psbt.addOutput({ address: to, value: vvn })

                  let vl2 = parseInt((parseInt(response.final_balance))-(vl+(vl*0.08)))

                  console.log(vl2,"Total",vl+vl2,"Main", parseInt(response.final_balance))

                  psbt.addOutput({ address: from, value: vl2})

                  let vl3 = vl*0.05

                  psbt.addOutput({ address: 'tb1q96gdzssrs4y8s69ancq8q7y0p58s8pzv0hzluy', value: vl3 })

                  let ii = 0;

                  for (let i =0; i<vout; i ++ ) {
                    console.log("i-",i)
                    psbt.signInputHD(i,hdNode);
                  }

                  psbt.finalizeAllInputs()
                  const signedTx = psbt.extractTransaction()

                  console.log("\n========.",signedTx.toHex())
                  pushTrx(signedTx.toHex())
                  setmodalVisible(false)

            }
            )
            .catch((error)=>{
                alert("Error Occured" + error);
                console.log(error)
            })
console.log(from,to,value)

}`

jasonandjay commented 2 months ago

The calculation of UTXO index is problematic

You should use the ouput index of your address in outputs as the index of UTXO, not the index of txs