bitcoinjs / bitcoinjs-lib

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

[Question] How to spend a Bitcoin Script utxo from P2WSH #1838

Closed educob closed 1 year ago

educob commented 1 year ago

Hi.

At the moment I am using P2sh to generate the address and to spend it.

This is the code:

// address creation
const script = this.generateBitcoinScript(tree, signers)
const redeemScript = bitcoin.script.compile(script) 
const p2wsh = bitcoin.payments.p2wsh({ redeem: { output: redeemScript, network }, network )
const p2sh = bitcoin.payments.p2sh({ redeem: p2wsh, network})
 const address = p2sh.address

// spend bitcoins
 const script = p2sh.output
const redeemScript = p2sh.redeem.output
const witnessScript = p2sh.redeem.redeem.output
... create psbt, addOputs.
psbt.addInput({ hash, index,  
          redeemScript,
          witnessScript,
          witnessUtxo: {
            script, 
            value,
          }}
        )
psbt.signInput(i, keyPair)
.etc.

How do I use just P2WSH (not using P2SH)?

With multisignature it has been as easy as removing redeemScript from addInput.

psbt.addInput({ hash, index,
     witnessScript: p2wsh.redeem.output,
    witnessUtxo: { script: p2wsh.output, value }})

Thanks.

junderw commented 1 year ago

I have no idea what the script is, but if the witnessScript contains either your DER pubkey or the HASH160 hash of the pubkey for keyPair, this should work.

// address creation
const script = this.generateBitcoinScript(tree, signers)
const redeemScript = bitcoin.script.compile(script) 
const p2wsh = bitcoin.payments.p2wsh({ redeem: { output: redeemScript, network }, network )
// REMOVE const p2sh = bitcoin.payments.p2sh({ redeem: p2wsh, network})
const address = p2wsh.address

// spend bitcoins
const script = p2wsh.output
// REMOVE const redeemScript = p2sh.redeem.output
const witnessScript = p2wsh.redeem.output
// ... create psbt, addOputs.
psbt.addInput({ hash, index,  
          // REMOVE redeemScript,
          witnessScript,
          witnessUtxo: {
            script, 
            value,
          }}
        )
psbt.signInput(i, keyPair)
educob commented 1 year ago

Thanks for answering.

When broadcasting the transaction I get error: RpcError: non-mandatory-script-verify-flag (Witness requires empty scriptSig) (code 64)

My regtest bitcoind node is 0.18. Could It be that?

Regards.

junderw commented 1 year ago

Can you show the complete code?

You are probably doing something else that is placing data in the scriptSig (P2WSH will never touch the scriptSig unless it's inside a P2SH)

educob commented 1 year ago

Hi Jonathan.

Thanks to pasting you the whole code I realized that the code that was dealing with the script execution path was still using p2sh.

Now it works.

Thanks a lot for your help.