What is the content of ScriptPubKey for P2WPKH?

Master bitcoin book 2end edition says the following (link):

Example P2WPKH output script

0 ab68025513c3dbd2f7b92a94e0581f5d50f654e7

In programming Bitcoin by Jimmy Song, it says the following:

The ScriptPubKey for p2wpkh is OP_0 <20-byte hash>.

It also provides the following image:

enter image description here

Additionally, when Jimmy Song is checking if the scriptPubKey is of P2WPKH type, he is using the following code:

enter image description here

So my question is: Where is OP_PUSHBYTES_20 here? Okay, maybe in the examples we can omit it and just say OP_0 20-byte hash, but how can we omit it in a program checking if the script is P2WPKH as Jimmy Song did?

I thought that I missed something, so I went into Bitcoin block explorer to find any P2WPKH scriptPubKey and I found it with OP_PUSHBYTES_20. Here is the link for it.

So, should we consider the P2WPKH output is: OP_0 OP_PUSHBYTES_20 <20-byte hash> and not just OP_0 <20-byte hash>. Does it mean Jimmy Song made a mistake in his program?

1 Answer 1


This is just a matter of notation.

<20-byte value> is a human-readable way of writing "the script that pushes said 20-byte value onto the stack". Practically that's encoded using 0x14 followed by those 20 bytes. Some sources will refer to that 0x14 byte as "OP_PUSHBYTES_20", some just print the hex bytes, while others denote it by putting <> around the thing being pushed.

To answer your titular question

What is the content of ScriptPubKey for P2WPKH?

It is a 22-byte script, whose first byte is 0x00 ("OP_0"), whose second byte is 0x14 ("push the 20 bytes that follow", or "OP_PUSHBYTES_20"), and whose last 20 bytes are the Hash160 (SHA256 + RIPEMD160) of the receiver's public key.

Certain frameworks for operating on Bitcoin Script represent scripts naturally in a parsed format, where the 0x14 byte is implicitly interpreted as "the next 20 bytes form a unit" rather than being explicitly represented as an opcode. In such a framework, a P2WPKH scriptPubKey would be represented as the 2-element sequence (OP_0, the 20 byte hash). This is by the way the case inside the Bitcoin Core source code too; it does not treat the 0x14 as a separate opcode.

  • Well yes, but the problem is that Jimmy in his is_p2wpkh_script_pubkey function checks only if the first "element" is 0x00 and if the second is of length 20. He is not checking if the second element is 0x14 and then the third element of length 20. It looks like this function won't work as it should.
    – dassd
    Commented Aug 30, 2023 at 19:54
  • 1
    @joke Presumably it's working in a framework where the script is represented in parsed form rather than in byte-serialized form. In parsed form, it'd be represented as just the sequence (OP_0, the 20-byte-value). In the byte serialized, the 0x14 before the 20-byte value is implicit (added when serializing, and just used as indicator that a 20-byte value follows when parsing). Commented Aug 30, 2023 at 19:56
  • Yes, I guess that's the case here.
    – dassd
    Commented Aug 30, 2023 at 19:59
  • 1
    I expanded my answer a bit to include this. Commented Aug 30, 2023 at 20:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.