Spend a Native Segwit P2WPKH UTXO
To follow along this tutorial
|
Let’s spend a native Segregated Witness P2WPKH output and create a new legacy P2PKH output.
Creating a UTXO to spend
sendtoaddress bcrt1qlwyzpu67l7s9gwv4gzuv4psypkxa4fx4ggs05g 1
gettransaction TX_ID
Find the output index (or vout) under |
Creating the transaction
Now let’s spend the UTXO with BitcoinJS.
const bitcoin = require('bitcoinjs-lib')
const { alice, bob } = require('./wallets.json')
const network = bitcoin.networks.regtest
const keyPairAlice1 = bitcoin.ECPair.fromWIF(alice[1].wif, network)
In order to create our input we will have to provide the previous output script. We can get it by inspecting the funding transaction at
.const p2wpkhAlice1 = bitcoin.payments.p2wpkh({pubkey: keyPairAlice1.publicKey, network})
console.log('Previous output script:')
console.log(p2wpkhAlice1.output.toString('hex'))
The script is composed as follow: 00
version + PUSHBYTES_14 + public key hash (witness program)
The HASH160 of the public key should match the 20-bytes witness program in the previous output script (the segwit UTXO we are spending).
$ bx bitcoin160 03745c9aceb84dcdeddf2c3cdc1edb0b0b5af2f9bf85612d73fa6394758eaee35d
fb8820f35effa054399540b8ca86040d8ddaa4d5
or
bitcoin.crypto.hash160(Buffer.from('03745c9aceb84dcdeddf2c3cdc1edb0b0b5af2f9bf85612d73fa6394758eaee35d', 'hex')).toString('hex')
const psbt = new bitcoin.Psbt({network})
.addInput({
hash: 'TX_ID',
index: TX_VOUT,
witnessUtxo: {
script: Buffer.from('0014' + alice[1].pubKeyHash, 'hex'),
value: 1e8, (1)
},
})
.addOutput({
address: bob[1].p2pkh,
value: 999e5,
}) (2)
1 | In a Segwit transaction we need to pass the value of the previous transaction which will be part of the message to be signed |
2 | Lock 0.999 BTC to bob_1 public key hash |
Let’s calculate our mining fee, subtracting the outputs from the inputs.
100 000 000 - 99 900 000 = 100 000 100 000 satoshis, which is equal to 0,001 BTC.
psbt.signInput(0, keyPairAlice1)
psbt.validateSignaturesOfInput(0)
We don’t have to specify any redeem or witness scripts here, since we are spending a native segwit UTXO. |
psbt.finalizeAllInputs()
console.log('Transaction hexadecimal:')
console.log(psbt.extractTransaction().toHex())
decoderawtransaction TX_HEX
Broadcasting the transaction
sendrawtransaction TX_HEX
sendrawtransaction
returns the transaction ID, with which you can inspect your transaction again.
getrawtransaction TX_ID true (1)
1 | Don’t forget the second argument. If false, it returns the hex string, otherwise it returns a detailed json object. |