進階
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
已複製連結