Multi-signature Transactions

Multi-signature (multisig) refers to requiring more than one key to authorize a Bitcoin transaction. It is generally used to divide up responsibility for possession of bitcoins.

Standard transactions on the Bitcoin network could be called "single-signature transactions" because transfers require only one signature — from the owner of the private key associated with the Bitcoin address. However, the Bitcoin network supports much more complicated transactions that require the signatures of multiple people before the funds can be
transferred. These are often referred to as M-of-N transactions.

The idea is that bitcoins become "encumbered" by providing addresses of multiple parties, thus requiring cooperation of those parties in order to do anything with them. These parties can be people, institutions or programmed scripts.

Multi-signature Legacy 2 of 4

To follow along this tutorial and enter the commands step-by-step

Type node in a terminal after cd into ./code for a Javascript prompt

Open the Bitcoin Core GUI console or use bitcoin-cli for the Bitcoin Core commands

Feed the p2sh method with the special BitcoinJS p2ms object.
The p2sh method generates an object that contains the P2SH address.

const p2sh = bitcoin.payments.p2sh({redeem: p2ms, network})

Send 1 BTC to this P2SH address.

$ sendtoaddress 2NAjnUkVxAv34bnfpC1edhW5qstF2QHSUk5 1

Get the output index so that we have the outpoint (txid / vout).

Find the output index (or vout) under details > vout.

$ gettransaction "txid"

Preparing the spending transaction

Now let's prepare the spending transaction by setting input and output and having two people (private keys) to sign the
transaction. Here Alice_0 ad Bob_0 will redeem the P2SH multi-signature and send the funds to Alice_1 P2WPKH address.

Create a BitcoinJS transaction builder object.

const txb = new bitcoin.TransactionBuilder(network)

Create the input by referencing the outpoint of our P2SH funding transaction.
Create the output that will send the funds to Alice_1 P2WPKH address, leaving 100 000 satoshis as mining fees.

Preparing the spending transaction

Now let's prepare the spending transaction by setting input and output and having two people (private keys) to sign the
transaction. Here Alice_0 ad Bob_0 will redeem the P2WSH multi-signature and send the funds to Alice_1 P2WPKH address.

Create a BitcoinJS transaction builder object.

const txb = new bitcoin.TransactionBuilder(network)

Create the input by referencing the outpoint of our P2SH funding transaction.
Create the output that will send the funds to Alice_1 P2WPKH address, leaving 100 000 satoshis as mining fees.

Alice_0 and Bob_0 now sign the transaction. 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 input value.

Preparing the spending transaction

Now let's prepare the spending transaction by setting input and output and having two people (private keys) to sign the
transaction. Here Alice_0 ad Bob_0 will redeem the P2SH-P2WSH multi-signature and send the funds to Alice_1 P2WPKH address.

Create a BitcoinJS transaction builder object.

const txb = new bitcoin.TransactionBuilder(network)

Create the input by referencing the outpoint of our P2SH funding transaction.
Create the output that will send the funds to Alice_1 P2WPKH address, leaving 100 000 satoshis as mining fees.

Alice_0 and Bob_0 now sign the transaction.
Note that, because we are doing a P2SH-P2WSH, we need to provide the locking script as the redeemScript third parameter,
the same script as the witnessScript sixth parameter, as well as the input value.

Inspect the raw transaction with Bitcoin Core CLI, check that everything is correct.

$ decoderawtransaction "hexstring"

Broadcasting the transaction

It's time to broadcast the transaction via Bitcoin Core CLI.

$ sendrawtransaction "hexstring"

Inspect the transaction.

$ getrawtransaction "txid" true

Observations

We can see that the scriptSig is a special unlocking script that contains the version byte 00 followed by a 32-bytes
witness program. This script has to match the HASH160 in the P2SH UTXO we are spending.

After checking hash equality, the script interpreter recognize that it is actually a Segwit transaction thanks to the
version byte and triggers execution of the witness data.
The witness, located in the txinwitness field contains

an empty string that will convert to a useless but mandatory 00 value due to a bug in OP_CHECKMULTISIG

Comments

Explore Website

About Bitcoin Developer Network

The Bitcoin Developer Network (BDN) is a community-driven project looking at educating the generation of Bitcoin developers. We invite developers, authors, editors, proofreaders, enthusiasts, subject matter experts and technical writers to get in touch so that we may reduce the barrier to entry in developing solutions at various layers of this technology.

Bitcoin Developer Network Newsletter

Enter your email address to subscribe to this blog and receive notifications of new posts by email.