P2WPKH

Pay To Witness Public Key Hash

BIP 141: Segregated Witness

A diagram showing the structure of a P2WPKH.

P2WPKH is a script pattern that locks an output to a public key hash.

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

The benefit of using P2WPKH over P2PKH is that Witness field data has less weight than the ScriptSig field data, so when you come to unlock a P2WPKH you will pay slightly less in transaction fees.

P2WPKH was introduced as part of the Segregated Witness upgrade as a replacement for P2PKH.

Usage

How does P2WPKH work?

P2WPKH does not use the traditional Script language.

Instead, the ScriptPubKey and Witness are fixed data structures.

ScriptPubKey

To create a P2WPKH lock, you just need to place an OP_0 followed by a data push of a public key hash in the ScriptPubKey.

OP_0
OP_PUSHBYTES_20
841b80d2cc75f5345c482af96294d04fdd66b2b7
0014841b80d2cc75f5345c482af96294d04fdd66b2b7

Transaction: c178d8dacdfb989f9d4fa45828ed188cd54a0414d625c3e61e75c5e3ac15a83a (Output 0)

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

A ScriptPubKey that starts with an OP_0 followed by a 20-byte data push is always interpreted as a special P2WPKH locking script.

ScriptSig

The ScriptSig must be empty.

Witness Field

To unlock a P2WPKH, you need to provide a valid signature followed by the original public key in the witness field for the transaction input.

3045022100c7fb3bd38bdceb315a28a0793d85f31e4e1d9983122b4a5de741d6ddca5caf8202207b2821abd7a1a2157a9d5e69d2fdba3502b0a96be809c34981f8445555bdafdb01
03f465315805ed271eb972e43d84d2a9e19494d10151d9f6adb32b8534bfd764ab
{
  "stackitems": "02",
  "0": {
    "size": "48",
    "item": "3045022100c7fb3bd38bdceb315a28a0793d85f31e4e1d9983122b4a5de741d6ddca5caf8202207b2821abd7a1a2157a9d5e69d2fdba3502b0a96be809c34981f8445555bdafdb01"
  },
  "1": {
    "size": "21",
    "item": "03f465315805ed271eb972e43d84d2a9e19494d10151d9f6adb32b8534bfd764ab"
  }
}
02483045022100c7fb3bd38bdceb315a28a0793d85f31e4e1d9983122b4a5de741d6ddca5caf8202207b2821abd7a1a2157a9d5e69d2fdba3502b0a96be809c34981f8445555bdafdb012103f465315805ed271eb972e43d84d2a9e19494d10151d9f6adb32b8534bfd764ab

Transaction: 1674761a2b5cb6c7ea39ef58483433e8735e732f5d5815c9ef90523a91ed34a6 (Input 0)

The Witness field is not Script. It uses Compact Size fields for indicating the number of items, and the size of the signature and public key. This is instead of using data push opcodes (e.g. OP_PUSHBYTES_33) as you would do when unlocking a P2PKH.

Only compressed public keys are accepted in P2WPKH. So when you create the public key hash for the ScriptPubKey, make sure it's the hash of a compressed public key and not an uncompressed public key, otherwise it will be considered non-standard and will not be relayed by nodes (although it's still technically valid and could get mined in to the blockchain if you can send it directly to a miner). This is different to P2PKH, where uncompressed public keys are allowed.

Execution

A P2WPKH does not execute like a normal Script. When the Bitcoin program encounters a ScriptPubKey with the P2WPKH structure, special witness validation logic is used:

  1. The signature and public key are first extracted from the Witness field and placed on to the stack.
  2. The public key hash is then extracted from the ScriptPubKey and converted to a P2PKH locking script.
A diagram showing the execution of the P2WPKH locking and unlocking code.

And from here the whole thing is executed like a typical P2PKH script.

An animation showing the execution of a full P2PKH script.

This is just how Bitcoin Core does it. But ultimately, as long as the public key hashes to the same public key hash, and the signature validates against the public key, then the entire P2WPKH script is valid.

Address

How do you create an address for a P2WPKH script?

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

The ScriptPubKey for a P2WPKH has the following structure: 0014<20-byte hash160(public key)>

Public Key
HASH-160
tool-662caeb196656
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:

0014841b80d2cc75f5345c482af96294d04fdd66b2b7

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

bc1qssdcp5kvwh6nghzg9tuk99xsflwkdv4hgvq58q

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

The address is always 42 characters due to the ScriptPubKey being 22 bytes in length (0014 + 20-byte public key hash)

Examples

What do P2WPKH scripts look like?

P2WPKH locking and unlocking scripts always follow the same structure, so there are no unusual or interesting examples to look at.

Once you've got the hang of how the locking and unlocking code works for one P2WPKH, you've got the hang of them all.

Example 1

This was the first ever P2PWKH transaction. It was mined in to block 481,824, which was the first block Segregated Witness was activated.

Example 2

This P2WPKH locking script contains the hash of an uncompressed public key:

042cbc4850b7fdcd938f681240f7a6a4c27860572f7a189068b403acb83b90ff5fb6744659ad92aa2ca4b0cf3295de48339e298c38d1eff3a8b12575740bfa33ad

HASH160

I created it myself to see if P2WPKH would work with uncompressed public keys, but it turns out they are considered non-standard, so I haven't been able to spend it.

So yeah, don't use uncompressed public keys for P2WPKH (not that you would have any reason to anyway).

It wasn't flagged as non-standard when I created the ScriptPubKey, as there's no way to tell if the public key hash was from a compressed public key or not; it's 20-bytes either way. It's only when I came to try and spend it that the uncompressed public key was revealed (and therefore rejected).

History

Why do we have P2WPKH?

The P2WPKH locking script mechanism was introduced in the Segregated Witness upgrade in 2016.

In short, the upgrade added a new section to transactions called the Witness, which is used for unlocking the inputs to a transaction (in place of the old ScriptSig field). The reason was so that the TXIDs would no longer be influenced by the signatures inside the transaction data, as these signatures could be adjusted before the transaction gets mined, which in turn would change the TXID (which is annoying).

P2WPKH was therefore introduced to make use of this new Witness section for unlocking inputs, whilst maintaining the same functionality of the original P2PKH locking script.

So as I say, P2PKH and P2WPKH use the exact same locking mechanism. The main difference being that a P2PKH is unlocked via the ScriptSig (and costs more in transaction fees), whereas a P2WPKH is unlocked via the Witness field (and costs less in transaction fees).

Both P2PKH and P2WPKH are valid options for locking an output to a public key hash, but P2WSH should be your preferred choice out of the two.

Resources