P2WSH

Pay To Witness Script Hash

BIP 141: Segregated Witness

A diagram showing the structure of a P2WSH.

P2WSH is a locking script that locks an output to the hash of a custom locking script.

It works in the same way as a legacy P2SH, but it's unlocked via the Witness field instead of the ScriptSig.

The benefit of using P2WSH over P2SH is that the Witness field carries less weight, so you'll pay less in transaction fees when you come to unlock a P2WSH (compared to P2SH).

P2WSH was introduced as part of the Segregated Witness upgrade as a replacement for P2SH.

Usage

How does P2WSH work?

ScriptPubKey

To create a P2WSH locking script, you just need to put an OP_0 followed by a 32-byte data push in the ScriptPubKey.

This data push is the Script Hash, and it's the single SHA-256 hash of a custom locking script

OP_0
OP_PUSHBYTES_32
65f91a53cb7120057db3d378bd0f7d944167d43a7dcbff15d6afc4823f1d3ed3
002065f91a53cb7120057db3d378bd0f7d944167d43a7dcbff15d6afc4823f1d3ed3

Transaction: 46ebe264b0115a439732554b2b390b11b332b5b5692958b1754aa0ee57b64265 (Output 1)

Script
SHA-256

The OP_0 is called the version byte, and indicates that this ScriptPubKey is either going to be a P2WPKH or a P2WSH.

A locking script that starts with OP_0 followed by a 32-byte data push is always interpreted as a special P2WSH locking script.

ScriptSig

The ScriptSig must be empty.

Witness Field

To unlock a P2WSH, you need to put the Witness Script (the original locking script that formed the Script Hash) as the last item in the Witness field.

All of the items before this Witness Script are what's required to unlock it.

00
30440220415899bbee08e42376d06e8f86c92b4987613c2816352fe09cd1479fd639f18c02200db57f508f69e266d76c23891708158bda18690c165a41b0aa88303b97609f7801
304402203973de2303e8787767090dd25c8a4dc97ce1aa7eb4c0962f13952ed4e856ff8e02203f1bb425def789eea8be46407d10b3c8730407176aef4dc2c29865eb5e5542bf01
522103848e308569b644372a5eb26665f1a8c34ca393c130b376db2fae75c43500013c2103cec1ee615c17e06d4f4b0a08617dffb8e568936bdff18fb057832a58ad4d1b752103eed7ae80c34d70f5ba93f93965f69f3c691da0f4607f242f4fd6c7a48789233e53ae
{
  "stackitems": "04",
  "0": {
    "size": "00",
    "item": ""
  },
  "1": {
    "size": "47",
    "item": "30440220415899bbee08e42376d06e8f86c92b4987613c2816352fe09cd1479fd639f18c02200db57f508f69e266d76c23891708158bda18690c165a41b0aa88303b97609f7801"
  },
  "2": {
    "size": "47",
    "item": "304402203973de2303e8787767090dd25c8a4dc97ce1aa7eb4c0962f13952ed4e856ff8e02203f1bb425def789eea8be46407d10b3c8730407176aef4dc2c29865eb5e5542bf01"
  },
  "3": {
    "size": "69",
    "item": "522103848e308569b644372a5eb26665f1a8c34ca393c130b376db2fae75c43500013c2103cec1ee615c17e06d4f4b0a08617dffb8e568936bdff18fb057832a58ad4d1b752103eed7ae80c34d70f5ba93f93965f69f3c691da0f4607f242f4fd6c7a48789233e53ae"
}
04004730440220415899bbee08e42376d06e8f86c92b4987613c2816352fe09cd1479fd639f18c02200db57f508f69e266d76c23891708158bda18690c165a41b0aa88303b97609f780147304402203973de2303e8787767090dd25c8a4dc97ce1aa7eb4c0962f13952ed4e856ff8e02203f1bb425def789eea8be46407d10b3c8730407176aef4dc2c29865eb5e5542bf0169522103848e308569b644372a5eb26665f1a8c34ca393c130b376db2fae75c43500013c2103cec1ee615c17e06d4f4b0a08617dffb8e568936bdff18fb057832a58ad4d1b752103eed7ae80c34d70f5ba93f93965f69f3c691da0f4607f242f4fd6c7a48789233e53ae

Transaction: b38a88b073743bcc84170071cff4b68dec6fb5dc0bc8ffcb3d4ca632c2c78255 (Input 0)

In the example above, the Witness Script is a 2-of-3 P2MS locking script. The two items before it are the signatures required to unlock it.

You can confirm that this Witness Script is a P2MS by decoding the final item in the Witness field:

Script

Execution

A diagram showing the execution of the P2WSH locking and unlocking code.

P2WSH is a special type of locking script and is not executed like normal Script. It is executed using special "witness validation logic" instead:

  1. The Witness Script is hashed via SHA-256 to check that it matches the Script Hash.
  2. The items before the Witness Script are pushed on to the stack.
  3. The Witness Script is deserialized and run like a normal script (using the current stack).

If all of these steps are successful, the input is unlocked

Address

How do you create an address for a P2WSH script?

The address for a P2WSH locking script is the Bech32 encoding of the ScriptPubKey.

The ScriptPubKey for a P2WSH has the following structure: 0020<32-byte sha256(hex script)>

Script
SHA-256
tool-662cae8866389
Tool Icon

Address (Bech32)

Encode the locking script for a P2WPKH or a P2WSH to a segwit address.

Also known as the witness program

0 bytes
Type
0 bytes
Type

Bech32 encoding of the ScriptPubKey

0 characters
0 secs

For example, the hex-encoding of the ScriptPubKey above is:

002065f91a53cb7120057db3d378bd0f7d944167d43a7dcbff15d6afc4823f1d3ed3

And if you Bech32 encode that you get the following address:

bc1qvhu3557twysq2ldn6dut6rmaj3qk04p60h9l79wk4lzgy0ca8mfsnffz65

The address always starts with a bc1q due to the OP_0 version byte at the start.

The address is always 62 characters due to the ScriptPubKey being 34 bytes in length (0020 + 32-byte Script Hash)

Witness Script

The custom script

The Witness Script is a complete custom locking script. It is the last item of the Witness field in a P2WSH.

The example P2WSH above has the following Witness:

00
30440220415899bbee08e42376d06e8f86c92b4987613c2816352fe09cd1479fd639f18c02200db57f508f69e266d76c23891708158bda18690c165a41b0aa88303b97609f7801
304402203973de2303e8787767090dd25c8a4dc97ce1aa7eb4c0962f13952ed4e856ff8e02203f1bb425def789eea8be46407d10b3c8730407176aef4dc2c29865eb5e5542bf01
522103848e308569b644372a5eb26665f1a8c34ca393c130b376db2fae75c43500013c2103cec1ee615c17e06d4f4b0a08617dffb8e568936bdff18fb057832a58ad4d1b752103eed7ae80c34d70f5ba93f93965f69f3c691da0f4607f242f4fd6c7a48789233e53ae
{
  "stackitems": "04",
  "0": {
    "size": "00",
    "item": ""
  },
  "1": {
    "size": "47",
    "item": "30440220415899bbee08e42376d06e8f86c92b4987613c2816352fe09cd1479fd639f18c02200db57f508f69e266d76c23891708158bda18690c165a41b0aa88303b97609f7801"
  },
  "2": {
    "size": "47",
    "item": "304402203973de2303e8787767090dd25c8a4dc97ce1aa7eb4c0962f13952ed4e856ff8e02203f1bb425def789eea8be46407d10b3c8730407176aef4dc2c29865eb5e5542bf01"
  },
  "3": {
    "size": "69",
    "item": "522103848e308569b644372a5eb26665f1a8c34ca393c130b376db2fae75c43500013c2103cec1ee615c17e06d4f4b0a08617dffb8e568936bdff18fb057832a58ad4d1b752103eed7ae80c34d70f5ba93f93965f69f3c691da0f4607f242f4fd6c7a48789233e53ae"
}
04004730440220415899bbee08e42376d06e8f86c92b4987613c2816352fe09cd1479fd639f18c02200db57f508f69e266d76c23891708158bda18690c165a41b0aa88303b97609f780147304402203973de2303e8787767090dd25c8a4dc97ce1aa7eb4c0962f13952ed4e856ff8e02203f1bb425def789eea8be46407d10b3c8730407176aef4dc2c29865eb5e5542bf0169522103848e308569b644372a5eb26665f1a8c34ca393c130b376db2fae75c43500013c2103cec1ee615c17e06d4f4b0a08617dffb8e568936bdff18fb057832a58ad4d1b752103eed7ae80c34d70f5ba93f93965f69f3c691da0f4607f242f4fd6c7a48789233e53ae

Transaction: b38a88b073743bcc84170071cff4b68dec6fb5dc0bc8ffcb3d4ca632c2c78255 (Input 0)

If you decode the Witness Script, you'll see that it corresponds to the following P2MS locking script:

OP_2 OP_PUSHBYTES_33 03848e308569b644372a5eb26665f1a8c34ca393c130b376db2fae75c43500013c OP_PUSHBYTES_33 03cec1ee615c17e06d4f4b0a08617dffb8e568936bdff18fb057832a58ad4d1b75 OP_PUSHBYTES_33 03eed7ae80c34d70f5ba93f93965f69f3c691da0f4607f242f4fd6c7a48789233e OP_3 OP_CHECKMULTISIG
522103848e308569b644372a5eb26665f1a8c34ca393c130b376db2fae75c43500013c2103cec1ee615c17e06d4f4b0a08617dffb8e568936bdff18fb057832a58ad4d1b752103eed7ae80c34d70f5ba93f93965f69f3c691da0f4607f242f4fd6c7a48789233e53ae
Script

The Witness Script in a P2WSH is equivalent to the Redeem Script in a P2SH.

The Witness Script can be any kind of custom locking script of your choice, although it's most commonly a P2MS.

Script Hash

The hash of the custom script

The Script Hash is the 32-byte data push found inside the ScriptPubKey of a P2WSH. It is the single SHA-256 hash of the Witness Script.

For example, the Witness Script is the last item in the Witness field for an input:

00
30440220415899bbee08e42376d06e8f86c92b4987613c2816352fe09cd1479fd639f18c02200db57f508f69e266d76c23891708158bda18690c165a41b0aa88303b97609f7801
304402203973de2303e8787767090dd25c8a4dc97ce1aa7eb4c0962f13952ed4e856ff8e02203f1bb425def789eea8be46407d10b3c8730407176aef4dc2c29865eb5e5542bf01
522103848e308569b644372a5eb26665f1a8c34ca393c130b376db2fae75c43500013c2103cec1ee615c17e06d4f4b0a08617dffb8e568936bdff18fb057832a58ad4d1b752103eed7ae80c34d70f5ba93f93965f69f3c691da0f4607f242f4fd6c7a48789233e53ae
{
  "stackitems": "04",
  "0": {
    "size": "00",
    "item": ""
  },
  "1": {
    "size": "47",
    "item": "30440220415899bbee08e42376d06e8f86c92b4987613c2816352fe09cd1479fd639f18c02200db57f508f69e266d76c23891708158bda18690c165a41b0aa88303b97609f7801"
  },
  "2": {
    "size": "47",
    "item": "304402203973de2303e8787767090dd25c8a4dc97ce1aa7eb4c0962f13952ed4e856ff8e02203f1bb425def789eea8be46407d10b3c8730407176aef4dc2c29865eb5e5542bf01"
  },
  "3": {
    "size": "69",
    "item": "522103848e308569b644372a5eb26665f1a8c34ca393c130b376db2fae75c43500013c2103cec1ee615c17e06d4f4b0a08617dffb8e568936bdff18fb057832a58ad4d1b752103eed7ae80c34d70f5ba93f93965f69f3c691da0f4607f242f4fd6c7a48789233e53ae"
}
04004730440220415899bbee08e42376d06e8f86c92b4987613c2816352fe09cd1479fd639f18c02200db57f508f69e266d76c23891708158bda18690c165a41b0aa88303b97609f780147304402203973de2303e8787767090dd25c8a4dc97ce1aa7eb4c0962f13952ed4e856ff8e02203f1bb425def789eea8be46407d10b3c8730407176aef4dc2c29865eb5e5542bf0169522103848e308569b644372a5eb26665f1a8c34ca393c130b376db2fae75c43500013c2103cec1ee615c17e06d4f4b0a08617dffb8e568936bdff18fb057832a58ad4d1b752103eed7ae80c34d70f5ba93f93965f69f3c691da0f4607f242f4fd6c7a48789233e53ae

Transaction: b38a88b073743bcc84170071cff4b68dec6fb5dc0bc8ffcb3d4ca632c2c78255 (Input 0)

If you SHA-256 this Witness Script, it matches the Script Hash found in the ScriptPubKey on the output:

OP_0
OP_PUSHBYTES_32
65f91a53cb7120057db3d378bd0f7d944167d43a7dcbff15d6afc4823f1d3ed3
002065f91a53cb7120057db3d378bd0f7d944167d43a7dcbff15d6afc4823f1d3ed3

Transaction: 46ebe264b0115a439732554b2b390b11b332b5b5692958b1754aa0ee57b64265 (Output 1)

SHA-256

The script hash within a P2WSH is a single SHA-256. It is not a double SHA-256 hash (i.e. HASH256) as is commonly used everywhere else in Bitcoin, nor is it the HASH160 of a script like in P2SH.

Examples

What do P2WSH scripts look like?

Example 1

This is just a typical example of P2WSH. The Witness Script in the spending transaction contains a 2-of-3 P2MS locking script:

00
304402201d080f90841ee83820c8ab3e07a978066a925554b4b961ac240ca572e65ed25802200956318f0afb6f8355cdae42b71b05349e8f2fcd604fbf1c93caed18f001005901
30440220213ab899cffc6781d569cc54d558c56ea1808ccb0cbd9b4b134c148f639e0df202207affd66499c6c1813a15f8bd5fb6238054f679d111927b77878746a80144fe8301
52210375e00eb72e29da82b89367947f29ef34afb75e8654f6ea368e0acdfd92976b7c2103a1b26313f430c4b15bb1fdce663207659d8cac749a0e53d70eff01874496feff2103c96d495bfdd5ba4145e3e046fee45e84a8a48ad05bd8dbb395c011a32cf9f88053ae
{
  "stackitems": "04",
  "0": {
    "size": "00",
    "item": ""
  },
  "1": {
    "size": "47",
    "item": "304402201d080f90841ee83820c8ab3e07a978066a925554b4b961ac240ca572e65ed25802200956318f0afb6f8355cdae42b71b05349e8f2fcd604fbf1c93caed18f001005901"
  },
  "2": {
    "size": "47",
    "item": "30440220213ab899cffc6781d569cc54d558c56ea1808ccb0cbd9b4b134c148f639e0df202207affd66499c6c1813a15f8bd5fb6238054f679d111927b77878746a80144fe8301"
  },
  "3": {
    "size": "69",
    "item": "52210375e00eb72e29da82b89367947f29ef34afb75e8654f6ea368e0acdfd92976b7c2103a1b26313f430c4b15bb1fdce663207659d8cac749a0e53d70eff01874496feff2103c96d495bfdd5ba4145e3e046fee45e84a8a48ad05bd8dbb395c011a32cf9f88053ae"
  }
}
040047304402201d080f90841ee83820c8ab3e07a978066a925554b4b961ac240ca572e65ed25802200956318f0afb6f8355cdae42b71b05349e8f2fcd604fbf1c93caed18f0010059014730440220213ab899cffc6781d569cc54d558c56ea1808ccb0cbd9b4b134c148f639e0df202207affd66499c6c1813a15f8bd5fb6238054f679d111927b77878746a80144fe83016952210375e00eb72e29da82b89367947f29ef34afb75e8654f6ea368e0acdfd92976b7c2103a1b26313f430c4b15bb1fdce663207659d8cac749a0e53d70eff01874496feff2103c96d495bfdd5ba4145e3e046fee45e84a8a48ad05bd8dbb395c011a32cf9f88053ae

Transaction: 1b2a44f4f8b59d6d7075a3dbd72493a6a158218589e722d7525d1d99b7f287a5 (Input 0)

Script

Example 2

The following example uses a custom hash puzzle.

The ScriptPubKey contains a standard P2WSH locking script pattern:

OP_0
OP_PUSHBYTES_32
ee4fd29ce2f9ca8411778f8e94687d5e75ec3e86cc530ca9ad1787e5208cc996
0020ee4fd29ce2f9ca8411778f8e94687d5e75ec3e86cc530ca9ad1787e5208cc996

Transaction: c6cfbac310715dc35ae5a1edbeae78def5955a67cd891aa3457d8cd4cdb5398a (Output 0)

The Witness in the spending transaction then contains the following unlocking code:

1234
aa20a23421f2ba909c885a3077bb6f8eb4312487797693bbcfe7e311f797e3c5b8fa87
{
  "stackitems": "02",
  "0": {
    "size": "02",
    "item": "1234"
  },
  "1": {
    "size": "23",
    "item": "aa20a23421f2ba909c885a3077bb6f8eb4312487797693bbcfe7e311f797e3c5b8fa87"
  }
}
0202123423aa20a23421f2ba909c885a3077bb6f8eb4312487797693bbcfe7e311f797e3c5b8fa87

Transaction: 64f427122f7951687aea608b5474509a30616d4e5773a83bc1ed8b8271ad1991 (Input 0)

If you decode the Witness Script (the last item), you'll see that it corresponds to the following locking script:

Script
OP_HASH256 OP_PUSHBYTES_32 a23421f2ba909c885a3077bb6f8eb4312487797693bbcfe7e311f797e3c5b8fa OP_EQUAL
aa20a23421f2ba909c885a3077bb6f8eb4312487797693bbcfe7e311f797e3c5b8fa87

To unlock this Witness Script, you have to provide some data where the HASH256 result is a23421f2ba909c885a3077bb6f8eb4312487797693bbcfe7e311f797e3c5b8fa.

And if you look at the first item in the Witness you'll see that it's simply 1234, which does indeed hash to that result.

HASH256

It's quite rare to see these kind of custom locking scripts inside P2WSH, as they're usually used to wrap multisig locking scripts (P2MS). But this just goes to show that you can use them for custom scripts if you want to.

This kind of hash puzzle is an insecure method for locking up bitcoins. A miner who receives this spending transaction could just extract the unlocking script and create a new transaction sending the coins somewhere else. This is because the unlocking code does not contain a signature, so there's nothing to prevent it from being used in a completely different transaction.

Limits

What is the maximum size of a P2WSH?

A diagram showing the limits for a standard P2WSH locking script.

There are a few limits placed on standard P2WSH locks:

If you exceed these limits it will be considered non-standard and the transaction will not be relayed by nodes.

History

Why do we have P2WSH?

P2WSH was introduced in the Segregated Witness upgrade of 2016 as a replacement for P2SH.

They are functionally the same, but P2WSH has two main benefits over P2SH:

  1. P2WSH uses the Witness field for unlocking, whereas P2SH uses the ScriptSig. The data in the Witness field carries less weight than data inside the ScriptSig, so you'll pay less in transaction fees when unlocking a P2WSH compared to a legacy P2SH.
  2. The Witness Script in a P2WSH has an increased maximum size of 10,000 bytes, whereas the Redeem Script in a P2SH is limited to a maximum of 520 bytes. This means you can use much larger custom locking scripts inside a P2WSH compared to a P2SH.

But ultimately, P2WSH was introduced to take advantage of the new Witness area of transactions for unlocking inputs.

You can still use P2SH if you want, but P2WSH is now the preferred choice for locking up bitcoins to custom locking scripts in Bitcoin.

Summary

P2WSH is one of the more complex locking scripts to get your head around at first. This is because it is not executed in the same way as traditional scripts, and it also has the additional step of deserializing the Witness Script before execution takes place.

So don't feel bad if it doesn't make sense at first. It took me a while to figure it out too.

However, it's functionally the same as P2SH. So if you can get the hang of how P2SH works, then P2WSH is pretty much the same, except the unlocking code is placed inside the Witness field for the input instead of the ScriptSig.

An animation showing the execution of a full P2SH script.

Resources