跳至主要內容
進階

ScriptPubKey Types

了解比特幣中不同的 scriptPubKey 類型,從 P2PKH 到 P2TR 的演進。

12 分鐘

ScriptPubKey 定義了花費比特幣輸出所需的條件。隨著比特幣的發展, 出現了多種標準的 scriptPubKey 類型,每種都有其特點和用途。

標準類型概覽

類型 地址前綴 引入 狀態
P2PK 創世 已棄用
P2PKH 1... 創世 遺留
P2SH 3... BIP-16 遺留
P2WPKH bc1q... BIP-141 推薦
P2WSH bc1q... BIP-141 推薦
P2TR bc1p... BIP-341 最新

P2PK (Pay to Public Key)

最早的輸出類型,直接使用公鑰:

scriptPubKey:
<pubkey> OP_CHECKSIG

scriptSig:
<signature>

特點:
- 創世區塊使用此類型
- 公鑰直接暴露在輸出中
- 沒有地址格式
- 已不推薦使用

大小: 35 或 67 bytes (壓縮/非壓縮公鑰)

P2PKH (Pay to Public Key Hash)

使用公鑰雜湊,提高隱私和安全性:

scriptPubKey:
OP_DUP OP_HASH160 <pubkey_hash> OP_EQUALVERIFY OP_CHECKSIG

scriptSig:
<signature> <pubkey>

地址格式: Base58Check
前綴: 1 (mainnet), m/n (testnet)
示例: 1BvBMSEYstWetqTFn5Au4m4GFg7xJaNVN2

特點:
- 公鑰只在花費時暴露
- 25 bytes scriptPubKey
- 遺留格式,仍被廣泛支持

P2SH (Pay to Script Hash)

支持任意腳本,由 BIP-16 引入:

scriptPubKey:
OP_HASH160 <script_hash> OP_EQUAL

scriptSig:
<...script_args> <redeem_script>

地址格式: Base58Check
前綴: 3 (mainnet), 2 (testnet)
示例: 3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy

用途:
- 多重簽名 (P2SH-Multisig)
- 嵌套 SegWit (P2SH-P2WPKH, P2SH-P2WSH)
- 任意複雜條件

特點:
- 23 bytes scriptPubKey
- 複雜腳本的成本由花費者承擔

P2SH 多簽示例

// 2-of-3 多重簽名

redeemScript:
OP_2 <pubkey1> <pubkey2> <pubkey3> OP_3 OP_CHECKMULTISIG

scriptPubKey:
OP_HASH160 <HASH160(redeemScript)> OP_EQUAL

scriptSig:
OP_0 <sig1> <sig2> <redeemScript>

P2WPKH (Pay to Witness Public Key Hash)

原生 SegWit 單簽地址:

scriptPubKey:
OP_0 <20-byte pubkey_hash>

witness:
<signature> <pubkey>

地址格式: Bech32
前綴: bc1q (mainnet), tb1q (testnet)
示例: bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4

特點:
- 22 bytes scriptPubKey
- 簽名在 witness 中(有折扣)
- 比 P2PKH 便宜約 40%
- 原生 SegWit,最高效率

P2WSH (Pay to Witness Script Hash)

原生 SegWit 腳本雜湊:

scriptPubKey:
OP_0 <32-byte script_hash>

witness:
<...script_args> <witness_script>

地址格式: Bech32
前綴: bc1q (mainnet,但更長)
示例: bc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qccfmv3

特點:
- 34 bytes scriptPubKey
- 使用 SHA256 (不是 HASH160)
- 支持更複雜的腳本
- 比 P2SH 更便宜(見證折扣)

P2TR (Pay to Taproot)

Taproot 輸出,支持 key path 和 script path:

scriptPubKey:
OP_1 <32-byte tweaked_pubkey>

// Key path spend (最常見)
witness:
<schnorr_signature>

// Script path spend
witness:
<...script_args> <script> <control_block>

地址格式: Bech32m
前綴: bc1p (mainnet), tb1p (testnet)
示例: bc1p5cyxnuxmeuwuvkwfem96lqzszd02n6xdcjrs20cac6yqjjwudpxqkedrcr

特點:
- 34 bytes scriptPubKey
- 單簽和多簽看起來相同
- 最佳隱私和效率
- 使用 Schnorr 簽名

嵌套 SegWit

為了向後兼容,SegWit 可以嵌套在 P2SH 中:

// P2SH-P2WPKH

scriptPubKey:
OP_HASH160 <script_hash> OP_EQUAL

redeemScript (in scriptSig):
OP_0 <pubkey_hash>

witness:
<signature> <pubkey>

地址: 3... (看起來像普通 P2SH)

// P2SH-P2WSH

scriptPubKey:
OP_HASH160 <script_hash> OP_EQUAL

redeemScript:
OP_0 <witness_script_hash>

witness:
<...args> <witness_script>

注意: 嵌套 SegWit 折扣較低,不推薦新應用使用

識別 scriptPubKey 類型

def identify_scriptpubkey(script_hex):
    """識別 scriptPubKey 類型"""
    script = bytes.fromhex(script_hex)

    # P2PKH: OP_DUP OP_HASH160 <20 bytes> OP_EQUALVERIFY OP_CHECKSIG
    if len(script) == 25 and script[0:3] == b'\x76\xa9\x14' and script[23:25] == b'\x88\xac':
        return "P2PKH"

    # P2SH: OP_HASH160 <20 bytes> OP_EQUAL
    if len(script) == 23 and script[0:2] == b'\xa9\x14' and script[22] == 0x87:
        return "P2SH"

    # P2WPKH: OP_0 <20 bytes>
    if len(script) == 22 and script[0:2] == b'\x00\x14':
        return "P2WPKH"

    # P2WSH: OP_0 <32 bytes>
    if len(script) == 34 and script[0:2] == b'\x00\x20':
        return "P2WSH"

    # P2TR: OP_1 <32 bytes>
    if len(script) == 34 and script[0:2] == b'\x51\x20':
        return "P2TR"

    # P2PK:  OP_CHECKSIG
    if script[-1] == 0xac and len(script) in [35, 67]:
        return "P2PK"

    return "Unknown"

RPC 查詢

# 解碼交易查看 scriptPubKey 類型
bitcoin-cli decoderawtransaction <hex> | jq '.vout[].scriptPubKey'
{
  "asm": "0 751e76e8199196d454941c45d1b3a323f1433bd6",
  "desc": "addr(bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4)#8d3c7xwn",
  "hex": "0014751e76e8199196d454941c45d1b3a323f1433bd6",
  "address": "bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4",
  "type": "witness_v0_keyhash"
}

# 類型標識
# - "pubkey": P2PK
# - "pubkeyhash": P2PKH
# - "scripthash": P2SH
# - "witness_v0_keyhash": P2WPKH
# - "witness_v0_scripthash": P2WSH
# - "witness_v1_taproot": P2TR

選擇建議

  • 新應用:使用 P2TR (Taproot) 獲得最佳隱私和效率
  • 廣泛兼容:使用 P2WPKH 原生 SegWit
  • 多簽錢包:使用 P2WSH 或 P2TR
  • 避免:P2PKH、P2SH(除非需要兼容舊系統)
  • 絕不使用:P2PK
已複製連結
已複製到剪貼簿