Multi-signature Native Segwit 2 of 4
To follow along this tutorial
|
Let’s create a 2 of 4 multi-signature with a native Segwit P2WSH transaction.
Creating and Funding the P2WSH
Import libraries, test wallets and set the network
const bitcoin = require('bitcoinjs-lib')
const { alice, bob, carol, dave } = require('./wallets.json')
const network = bitcoin.networks.regtest
Prepare four keypairs.
const keyPairAlice1 = bitcoin.ECPair.fromWIF(alice[1].wif, network)
const keyPairBob1 = bitcoin.ECPair.fromWIF(bob[1].wif, network)
const keyPairCarol1 = bitcoin.ECPair.fromWIF(carol[1].wif, network)
const keyPairDave1 = bitcoin.ECPair.fromWIF(dave[1].wif, network)
And an other alice_2 that will redeem the multi-signature funds.
const keyPairAlice2 = bitcoin.ECPair.fromWIF(alice[2].wif, network)
const p2wpkhAlice2 = bitcoin.payments.p2wpkh({pubkey: keyPairAlice2.publicKey, network})
Create the locking script with the special
p2ms
payment method.const p2ms = bitcoin.payments.p2ms({
m: 2, pubkeys: [
keyPairAlice1.publicKey,
keyPairBob1.publicKey,
keyPairCarol1.publicKey,
keyPairDave1.publicKey], network})
console.log('Script:')
console.log(p2ms.output.toString('hex'))
Check the locking script.
decodescript SCRIPT
02 03745c9aceb84dcdeddf2c3cdc1edb0b0b5af2f9bf85612d73fa6394758eaee35d 027efbabf425077cdbceb73f6681c7ebe2ade74a65ea57ebcf0c42364d3822c590 023a11cfcedb993ff2e7523f92e359c4454072a66d42e8b74b4b27a8a1258abddd 02e9d617f38f8c3ab9a6bde36ce991bafb295d7adba457699f8620c8160ec9e87a 04 OP_CHECKMULTISIG
Feed the
p2wsh
method with the special BitcoinJS p2ms
object.const p2wsh = bitcoin.payments.p2wsh({redeem: p2ms, network})
console.log('P2WSH address')
console.log(p2wsh.address) (1)
1 | The p2wsh method generates an object that contains the P2WSH address. |
Send 1 BTC to this P2WSH address.
sendtoaddress bcrt1qtvraes6lc2efmwqtupv7f9wg3adhvzwpu0vg3s2zgpnc7qpp0v7sj6dkmu 1
Get the output index so that we have the outpoint (txid / vout).
gettransaction TX_ID
Find the output index (or vout) under | .
Preparing the spending transaction
Now let’s prepare the spending transaction by setting input and output and having two persons (private keys) to sign the transaction. Here alice_1 and bob_1 will redeem the P2WSH multi-signature and send the funds to alice_2 P2WPKH address.
Create a BitcoinJS transaction builder object.
const txb = new bitcoin.TransactionBuilder(network)
Create the input by referencing the outpoint of our P2WSH funding transaction.
txb.addInput('TX_ID', TX_VOUT)
Create the output that will send the funds to alice_2 P2WPKH address, leaving 100 000 satoshis as mining fees.
txb.addOutput(p2wpkhAlice2.address, 999e5)
Alice_1 and bob_1 now sign the transaction.
// txb.sign(index, keyPair, redeemScript, sign.hashType, value, witnessScript)
txb.sign(0, keyPairAlice1, null, null, 1e8, p2wsh.redeem.output)
txb.sign(0, keyPairBob1, null, null, 1e8, p2wsh.redeem.output)
Note that, because we are doing a P2WSH, we need to provide the locking script as witnessScript sixth parameter of the sign
method, as well as the previous output value.
|
Build the transaction and get the raw hex serialization.
const tx = txb.build()
console.log('Transaction hexadecimal:')
console.log(tx.toHex())
Inspect the raw transaction with Bitcoin Core CLI, check that everything is correct.
decoderawtransaction TX_HEX