Bitcoinjs-lib: How to sign a native P2WPKH ?

Created on 27 Jan 2018  路  17Comments  路  Source: bitcoinjs/bitcoinjs-lib

Am creating a transaction that spends from a Bech32 address.

I checked the examples provided but there is no one that shows how to sign a native P2WPKH transaction

how to / question / docs

Most helpful comment

var bitcoin = require('bitcoinjs-lib')
var key = bitcoin.ECPair.fromWIF("cPfgEigfyffeCYFoEo1dyCfVGJf7tFu5E26ATR3Pq8dbifRyofT9",
                                  bitcoin.networks.testnet)
var scriptPubkey = bitcoin.script.witnessPubKeyHash.output.encode(
                       bitcoin.crypto.hash160(
                           key.getPublicKeyBuffer()
                       )
                   )
// <Buffer 00 14 d3 3f 86 f2 30 a4 ac bc 3f 3f 40 14 81 ce 3d 1a 0d b6 68 01>
var addr = bitcoin.address.fromOutputScript(scriptPubkey, bitcoin.networks.testnet)
// 'tb1q6vlcdu3s5jktc0elgq2grn3argxmv6qpq0lfm5'


var txb = new bitcoin.TransactionBuilder(bitcoin.networks.testnet)

// txid, vout, sequence, previousOutputScriptPubkey
txb.addInput("a78a506e73e4a6b065d2865515be333d465b2f5080401c3fc406daee8a123787",
             0, null, scriptPubkey)

txb.addOutput("2N8hwP1WmJrFF5QWABn38y63uYLhnJYJYTF", 129800000)

// vin, key, redeemScript, hashType, witnessValue
txb.sign(0, key, null, null, 129900000)

var txhex = txb.build().toHex()

010000000001018737128aeeda06c43f1c4080502f5b463d33be155586d265b0a6e4736e508aa70000000000ffffffff014097bc070000000017a914a9974100aeee974a20cda9a2f545704a0ab54fdc870247304402207369f6c31501b0a298703e3ef5b1f7096a2f478c9154f2f992d40b5a536c3e73022000d068f99bc156a515bb9695c92432cf863567cba2b84ac602eb34c892d557b001210305f569040b1419b4327cdb0a947e042e295044be50422b9bb2e315eca370105400000000

Resulted in transaction: 9f2907308dd130194946ca3b2f4b92174bfedcd96ed6b3c8ddf0ed412dcb5ee1

All 17 comments

Pass along the scriptpubkey and it should work

Do you mean like this ?

var redeemScriptHash = bitcoin.crypto.hash160(redeemScript)
var scriptPubKey = bitcoin.script.scriptHash.output.encode(redeemScriptHash)
txb.sign(i, keyPair, redeemScript, null, unspent.value,scriptPubKey)

I tried also :

txb.sign(i, keyPair, null, null, unspent.value,scriptPubKey)

And :

txb.sign(i, keyPair, scriptPubKey, null, unspent.value)

But that doesn't work

P2WPKH shouldn鈥檛 have a redeemscript.

Your scriptpubkey should be the output of bitcoin.script.witnesspubkeyhash.output.encode(pubkeyhash)

I can now sign the transaction with :

let pubkeyhash = bitcoin.crypto.hash160(keyPair.getPublicKeyBuffer())
let scriptPubKey = bitcoin.script.witnessPubKeyHash.output.encode(pubkeyhash)
txb.sign(i, keyPair, scriptPubKey, null, unspent.value)

But my transaction get rejected with error :

non-mandatory-script-verify-flag (Witness requires empty scriptSig)

Here is the raw TX:

01000000000101cbf8fc65d81048fed8209fd189f83e116f98ec1d9800036b8ae295f0db86d3f7000000001716001468d1144f117d5d369e9195aeb1e54d2c4f59668affffffff0240420f000000000017a9148f201c799fbf54ba5761021de0fdebfb7431e3cc87a44a89000000000016001468d1144f117d5d369e9195aeb1e54d2c4f59668a02483045022100a6c350913bfce4f81e64885215347a962ac4f99106b09558bad9d8577477ee0b022053ed4a4fd5f108aaaded04663f24017bf18390c66b70423cd7a2087a0d8d537e012103f6ed88de44738cd10555c2dfdce5f576d1d9c9145af6e2511dd340eeb645937e00000000

Thanks for your help @dabura667 馃憤

Don鈥檛 pass it to sign, pass it to addInput only

txb.addInput doesn't have a scriptPubKey param

Can you please provide a simple example ?

Thanks

Maybe the name is prevOutScript or something. prevout refers to the previous output and script is referring to the output script which is called scriptPubkey.

txb.addInput(txid, vout, null, scriptPubkey)
var bitcoin = require('bitcoinjs-lib')
var key = bitcoin.ECPair.fromWIF("cPfgEigfyffeCYFoEo1dyCfVGJf7tFu5E26ATR3Pq8dbifRyofT9",
                                  bitcoin.networks.testnet)
var scriptPubkey = bitcoin.script.witnessPubKeyHash.output.encode(
                       bitcoin.crypto.hash160(
                           key.getPublicKeyBuffer()
                       )
                   )
// <Buffer 00 14 d3 3f 86 f2 30 a4 ac bc 3f 3f 40 14 81 ce 3d 1a 0d b6 68 01>
var addr = bitcoin.address.fromOutputScript(scriptPubkey, bitcoin.networks.testnet)
// 'tb1q6vlcdu3s5jktc0elgq2grn3argxmv6qpq0lfm5'


var txb = new bitcoin.TransactionBuilder(bitcoin.networks.testnet)

// txid, vout, sequence, previousOutputScriptPubkey
txb.addInput("a78a506e73e4a6b065d2865515be333d465b2f5080401c3fc406daee8a123787",
             0, null, scriptPubkey)

txb.addOutput("2N8hwP1WmJrFF5QWABn38y63uYLhnJYJYTF", 129800000)

// vin, key, redeemScript, hashType, witnessValue
txb.sign(0, key, null, null, 129900000)

var txhex = txb.build().toHex()

010000000001018737128aeeda06c43f1c4080502f5b463d33be155586d265b0a6e4736e508aa70000000000ffffffff014097bc070000000017a914a9974100aeee974a20cda9a2f545704a0ab54fdc870247304402207369f6c31501b0a298703e3ef5b1f7096a2f478c9154f2f992d40b5a536c3e73022000d068f99bc156a515bb9695c92432cf863567cba2b84ac602eb34c892d557b001210305f569040b1419b4327cdb0a947e042e295044be50422b9bb2e315eca370105400000000

Resulted in transaction: 9f2907308dd130194946ca3b2f4b92174bfedcd96ed6b3c8ddf0ed412dcb5ee1

@dabura667 @junderw that works perfectly
It would be great to have this example as test case for future reference
Thanks a lot for your help

Note to @dcousens:

This would be less complicated if ECPair and HDNode had a scriptType attribute

@dabura667 move that discussion to #508.

Can anyone please point me to an example of how to do this with the new bitcoin.payments API since bitcoin.script.witnessPubKeyHash.output.encode is no more? I'm trying:

 const pubkeyhash = bitcoin.crypto.hash160(keypair.publicKey);
 const scriptPubKey = bitcoin.payments.p2wpkh({ pubkey: keypair.publicKey}).output;
 txBuilder.addInput(vin_txids[0], 0, null, scriptPubKey);

But I'm still getting the 'witnesspubkeyhash not supported' error.

@dwasyluk how are you signing the transaction ?
Please provide the complete code to reproduce your error

What is witnessValue?

What is witnessValue?

I see it is 'unspent.value' upon investigation. The scriptPubKey, parameter 6 of the sign method, is optional eh?

TransactionBuilder is marked for deprecation.

It is recommended you look at the integration tests to see how the PSBT class works and use that instead.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ghost picture ghost  路  3Comments

askucher picture askucher  路  3Comments

tuyennvtb picture tuyennvtb  路  3Comments

hoshsadiq picture hoshsadiq  路  3Comments

panpan2 picture panpan2  路  3Comments