跳至主要內容
Informational Final

BIP-381: 非 SegWit 描述符

定義 pk()、pkh() 和 sh() 描述符函數,用於傳統比特幣腳本類型。

Pieter Wuille, Andrew Chow 2021年6月27日
BIP 編號

381

類型

Informational

狀態

Final

創建日期

2021-06-27

摘要

BIP-381 定義了三個描述符函數,用於表達非 SegWit 的傳統腳本類型: pk()(Pay-to-PubKey)、 pkh()(Pay-to-PubKey-Hash)和 sh()(Pay-to-Script-Hash)。

pk() — Pay-to-PubKey

格式

語法:pk(KEY)

輸出腳本:
<pubkey> OP_CHECKSIG

範例:
pk(0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798)

生成的腳本:
21 0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 AC
│  └─────────────────── 33 bytes 公鑰 ───────────────────┘    │
└─ OP_PUSHBYTES_33                                            └─ OP_CHECKSIG

歷史背景

P2PK 是比特幣最早的腳本類型,用於 Satoshi 挖的前幾個區塊。 它直接在腳本中包含完整公鑰,沒有對應的地址格式。 現在已經很少使用,因為 P2PKH 更節省空間且有地址格式。

特性

缺點

  • • 沒有標準地址格式
  • • 公鑰直接暴露(量子風險)
  • • 輸出較大(33-65 bytes)

優點

  • • 花費時腳本較小(只需簽章)
  • • 歷史相容性

pkh() — Pay-to-PubKey-Hash

格式

語法:pkh(KEY)

輸出腳本:
OP_DUP OP_HASH160 <20-byte-hash> OP_EQUALVERIFY OP_CHECKSIG

範例:
pkh([d34db33f/44'/0'/0']xpub6ERApfZ.../0/*)

生成的腳本(對於第一個地址):
76 A9 14 <20-byte-hash> 88 AC
│   │  │                 │   └─ OP_CHECKSIG
│   │  │                 └─ OP_EQUALVERIFY
│   │  └─ OP_PUSHBYTES_20
│   └─ OP_HASH160
└─ OP_DUP

對應地址:1BvBMSEYstWetqTFn5Au4m4GFg7xJaNVN2(Base58Check)

地址格式

P2PKH 地址編碼:

1. 計算公鑰哈希
   hash = RIPEMD160(SHA256(pubkey))

2. 添加版本前綴
   主網:0x00
   測試網:0x6f

3. Base58Check 編碼
   address = Base58Check(0x00 || hash)

結果:
主網地址以 "1" 開頭
測試網地址以 "m" 或 "n" 開頭

使用範例

BIP-44 相容錢包

pkh([d34db33f/44'/0'/0']xpub6ERApfZwUNrhL.../0/*)#checksum

派生路徑:m/44'/0'/0'/0/*
• 44' = BIP-44 用途
• 0' = 比特幣
• 0' = 第一帳戶
• 0 = 接收鏈
• * = 地址索引

單一地址

pkh(02c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5)#checksum

固定公鑰,只生成一個地址

sh() — Pay-to-Script-Hash

格式

語法:sh(SCRIPT)

輸出腳本:
OP_HASH160 <20-byte-script-hash> OP_EQUAL

範例:
sh(multi(2, KEY1, KEY2, KEY3))

生成的腳本:
A9 14 <20-byte-hash> 87
│   │                 └─ OP_EQUAL
│   └─ OP_PUSHBYTES_20
└─ OP_HASH160

對應地址:3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy(以 "3" 開頭)

可包裝的腳本

sh() 可以包裝多種內部腳本:

描述符 說明 常見用途
sh(multi(...)) P2SH 多簽 傳統多簽錢包
sh(wpkh(KEY)) P2SH-P2WPKH 相容性 SegWit
sh(wsh(...)) P2SH-P2WSH 相容性 SegWit 多簽
sh(sortedmulti(...)) 排序多簽 確定性多簽

P2SH-P2WPKH 範例

相容性 SegWit 地址(BIP-49):

sh(wpkh([d34db33f/49'/0'/0']xpub6CUGRUo.../0/*))#checksum

結構:
┌─────────────────────────────────────────────┐
│ P2SH 輸出腳本                               │
│   OP_HASH160 <script-hash> OP_EQUAL        │
├─────────────────────────────────────────────┤
│ 贖回腳本(redeemScript)                    │
│   OP_0 <20-byte-pubkey-hash>               │
│   (這是 P2WPKH 見證程序)                  │
├─────────────────────────────────────────────┤
│ 見證資料                                    │
│   [signature, pubkey]                       │
└─────────────────────────────────────────────┘

地址格式:以 "3" 開頭(主網)

腳本大小限制

P2SH 限制

  • 贖回腳本大小:最大 520 bytes(推送到堆疊的限制)
  • 多簽限制:最多約 15 個公鑰(15-of-15)
  • 標準化限制:某些腳本可能被認為是非標準的,不會被節點轉發

Bitcoin Core 範例

# 獲取描述符資訊
$ bitcoin-cli getdescriptorinfo "pkh(02c6047f...)"
{
  "descriptor": "pkh(02c6047f...)#checksum",
  "checksum": "8fhd9pwu",
  "isrange": false,
  "issolvable": true,
  "hasprivatekeys": false
}

# 從描述符派生地址
$ bitcoin-cli deriveaddresses "pkh([d34db33f/44'/0'/0']xpub.../0/*)#checksum" "[0,4]"
[
  "1BvBMSEYst...",
  "1HB5XMLmzF...",
  "1LqBGSKuXa...",
  "14u2pAKbZx...",
  "1M8L5JSN3L..."
]

# 導入描述符錢包
$ bitcoin-cli importdescriptors '[{
  "desc": "pkh([d34db33f/44h/0h/0h]xpub.../0/*)#checksum",
  "timestamp": "now",
  "range": [0, 999],
  "watchonly": true
}]'

總結

BIP-381 定義了傳統比特幣腳本的描述符函數。雖然這些腳本類型相對較舊, 但對於歷史錢包恢復和相容性 SegWit 地址仍然重要。 理解這些基礎類型有助於理解更複雜的 SegWit 和 Taproot 描述符。

已複製連結
已複製到剪貼簿