Spend a Nested Segwit P2SH-P2WPKH UTXO
To follow along this tutorial
|
Learn more about P2SH here
Let’s spend a P2SH-P2WPKH output (embedded Segwit) and create a new P2WPKH output.
Creating a UTXO to spend
sendtoaddress 2MzFvFvnhFskGnVQpUr1ZPr4wYWLwf211s6 1
gettransaction TX_ID
Find the output index (or vout) under | .
You can note that the UTXO is of type scripthash
, which means that it is a P2SH UTXO.
Creating the transaction
Now let’s spend the P2SH-P2WPKH 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) (1)
const p2wpkhAlice1 = bitcoin.payments.p2wpkh({pubkey: keyPairAlice1.publicKey, network}) (2)
const p2shAlice1 = bitcoin.payments.p2sh({redeem: p2wpkhAlice1, network}) (3)
const redeemScript = p2shAlice1.redeem.output.toString('hex')
console.log('Redeem script:')
console.log(redeemScript)
1 | Create a bitcoinJS keypair object for the spender alice_1 |
2 | Create a P2WPKH payment object |
3 | Pass it to the P2SH payment method |
The redeem script is composed of a 00
version byte and a 20 bytes witness program, which is the HASH160 of alice_1 public key.
const psbt = new bitcoin.Psbt({network})
.addInput({
hash: 'TX_ID',
index: TX_VOUT,
witnessUtxo: {
script: Buffer.from('a914' +
bitcoin.crypto.hash160(Buffer.from('0014' + alice[1].pubKeyHash, 'hex')).toString('hex') +
'87', 'hex'), (1)
value: 1e8,
},
redeemScript: Buffer.from(redeemScript, 'hex')
})
.addOutput({
address: bob[1].p2wpkh,
value: 999e5,
}) (2)
1 | The scriptPubKey is the Hash160 of the redeem script, inside a standard P2SH template |
2 | Lock 0.999btc to bob_1 P2WPKH |
psbt.signInput(0, keyPairAlice1)
psbt.validateSignaturesOfInput(0)
psbt.finalizeAllInputs()
console.log('Transaction hexadecimal:')
console.log(psbt.extractTransaction().toHex())
decoderawtransaction TX_HEX
Broadcasting the transaction
sendrawtransaction TX_HEX
getrawtransaction TX_ID true
Observations
In the vin section the scriptSig is the redeem script. When passed through HASH160 it should match the hash contained in the script of the P2SH UTXO we are spending.
$ bx bitcoin 160 0014fb8820f35effa054399540b8ca86040d8ddaa4d5
4cea7ef76a4423240d5f06d96868726f57bd7d30
The signature in txinwitness
is then verified against alice_1 public key.
In the vout section we have one witness_v0_keyhash
UTXO, bob_1 P2WPKH.