TeachMeBitcoin

P2PK Script - Full Anatomy and Execution

From TeachMeBitcoin, the free encyclopedia Reading time: 3 min

1. P2PK Script — Full Anatomy and Execution

Overview

Pay-to-Public-Key (P2PK) is the oldest and simplest locking script in Bitcoin. It was used extensively in the earliest blocks, including Satoshi's coinbase transactions in 2009. Unlike later script types, P2PK locks funds directly to a raw public key rather than a hashed address. This design is both elegant and historically significant, though it has been largely superseded by P2PKH due to privacy and security improvements.

Script Structure

A P2PK locking script (scriptPubKey) takes the following form:

<pubkey> OP_CHECKSIG

Where <pubkey> is a 65-byte uncompressed public key (prefix 0x04) or a 33-byte compressed public key (prefix 0x02 or 0x03). The corresponding unlocking script (scriptSig) is simply:

<signature>

That is the entire spending mechanism — a single DER-encoded signature pushed onto the stack.

Byte-Level Anatomy

For an uncompressed key, the full locking script in hex resembles:

41                        <- push 65 bytes
04
<32-byte X coordinate>
<32-byte Y coordinate>
AC                        <- OP_CHECKSIG

For a compressed key:

21                        <- push 33 bytes
02 or 03
<32-byte X coordinate>
AC                        <- OP_CHECKSIG

The unlocking script pushes a DER-encoded signature followed by a 1-byte SIGHASH flag:

47 or 48                  <- push 71 or 72 bytes
<DER-encoded signature>
01                        <- SIGHASH_ALL flag

Execution Walkthrough

Script execution in Bitcoin works as a stack machine. To validate a P2PK spend, the interpreter concatenates the scriptSig and scriptPubKey and executes them sequentially.

Step 1: Execute scriptSig

Stack before: []
Instruction: PUSH <signature>
Stack after:  [<sig>]

Step 2: Execute scriptPubKey — push public key

Stack before: [<sig>]
Instruction: PUSH <pubkey>
Stack after:  [<sig>, <pubkey>]

Step 3: Execute OP_CHECKSIG

Stack before: [<sig>, <pubkey>]
Instruction: OP_CHECKSIG
  - Pops pubkey and sig from stack
  - Serializes the transaction according to the SIGHASH type
  - Computes double-SHA256 of the serialized tx
  - Verifies ECDSA signature over the hash
Stack after:  [1]  (success) or [0] (failure)

Step 4: Validation check

Stack final: [1]

Result: Non-empty, non-zero top element → VALID spend

Signature Hash Types

The SIGHASH byte at the end of the signature controls which parts of the transaction are committed to:

SIGHASH_ALL    = 0x01  <- commits to all inputs and outputs
SIGHASH_NONE   = 0x02  <- commits to inputs only, outputs flexible
SIGHASH_SINGLE = 0x03  <- commits to corresponding output only
SIGHASH_ANYONECANPAY modifier = 0x80  <- only current input is committed

Security Considerations

P2PK exposes the full public key on-chain at the time the UTXO is created (in the locking script). This means:

  1. Quantum vulnerability window: If large-scale quantum computers become viable, an attacker could derive the private key from the exposed public key before it's spent. P2PKH only reveals the public key at spend time, providing a smaller window.

  2. No address abstraction: The raw public key serves as the "address," which is unwieldy for humans to communicate.

  3. No checksum: Unlike Base58Check addresses, raw public keys have no built-in error detection.

Despite these issues, P2PK outputs remain spendable and still exist in the UTXO set from early Bitcoin history. Nodes recognize and validate them correctly to this day.

Example: Satoshi's Genesis Block

The coinbase of block 0 (the genesis block) uses a P2PK output paying to a 65-byte uncompressed public key:

scriptPubKey (hex):
4104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61d
eb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f
ac

Decoded:
PUSH 65 bytes [04 67 8a fd b0 ... 1d 5f]
OP_CHECKSIG

This output has never been spent.

☕ Help support TeachMeBitcoin

TeachMeBitcoin is an ad-free, open-source educational repository curated by a passionate team of Bitcoin researchers and educators for public benefit. If you found our articles helpful, please consider supporting our hosting and ongoing content updates with a clean donation:

Ethereum: 0x578417C51783663D8A6A811B3544E1f779D39A85
Bitcoin: bc1q77k9e95rn669kpzyjr8ke9w95zhk7pa5s63qzz
Solana: 4ycT2ayqeMucixj3wS8Ay8Tq9NRDYRPKYbj3UGESyQ4J
Address copied to clipboard!