跳至主要內容
協議 進階

SegWit

Segregated Witness

又稱:隔離見證、BIP-141

SegWit(Segregated Witness,隔離見證)是 2017 年 8 月在區塊高度 481,824 啟用的比特幣軟分叉升級。它將交易的簽名資料(「見證」)從交易主體結構中分離出來,解決了多年來困擾比特幣的交易延展性問題,為閃電網路等二層方案奠定基礎。

為什麼需要 SegWit?

交易延展性問題

升級前,簽名是 TXID 計算的一部分:

問題場景:
1. Alice 發送交易 TX1(TXID: abc123)
2. 惡意節點修改簽名格式(不影響有效性)
3. 產生新 TXID(xyz789),但功能相同
4. 如果 xyz789 先被確認,abc123 失效
5. Alice 的錢包以為 abc123 失敗,可能重複支付

影響:
- 無法可靠追蹤未確認交易
- 閃電網路等依賴 TXID 的協議無法運作
- 交易所等服務商處理困難

SegWit 如何解決

升級後:
簽名(見證)不再計入 TXID
TXID = hash(版本 + 輸入 + 輸出 + locktime)
WTXID = hash(完整交易含見證)

結果:
- TXID 不可篡改
- 閃電網路可安全使用 TXID 建構通道

核心改進

1. 解決交易延展性

改進前改進後
簽名格式可變 → TXID 可變簽名獨立 → TXID 固定
閃電網路不可行閃電網路成為可能
依賴 TXID 的協議不安全可安全建構多層協議

2. 增加區塊容量

引入「區塊權重」取代「區塊大小」:

權重計算規則:
- 非見證資料:1 byte = 4 WU(權重單位)
- 見證資料:1 byte = 1 WU

區塊上限:4,000,000 WU(4 MW)

實際效果:
- 舊格式交易:約 1 MB
- 全 SegWit 交易:約 2-2.3 MB
- 混合情況:約 1.5-2 MB

3. 腳本版本化

為未來升級預留空間:

SegWit 輸出結構:
<version> <witness program>

version 0:P2WPKH、P2WSH
version 1:Taproot(BIP-341)
version 2-16:保留未來升級

地址格式

原生 SegWit(Bech32)

類型格式範例
P2WPKHbc1q + 20 bytesbc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4
P2WSHbc1q + 32 bytesbc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qccfmv3

兼容包裝(P2SH-wrapped)

為了向後兼容,可將 SegWit 腳本包裝在 P2SH 內:

P2SH-P2WPKH:
- 地址以 3 開頭(看起來像傳統多簽)
- 內部是 SegWit 腳本
- 比純 SegWit 稍大,但兼容舊錢包

結構:
scriptPubKey: OP_HASH160 <hash(redeemScript)> OP_EQUAL
redeemScript: OP_0 <20-byte pubKeyHash>
witness: <signature> <pubKey>

地址比較

類型前綴大小(vbytes)手續費
P2PKH1…最大最高
P2SH-P2WPKH3…中等中等
P2WPKHbc1q…最小最低
P2TRbc1p…較小較低

交易結構變化

傳統交易

[version][input_count][inputs][output_count][outputs][locktime]

SegWit 交易

[version][marker=0x00][flag=0x01][input_count][inputs][output_count][outputs][witnesses][locktime]

marker + flag:標識這是 SegWit 交易
witnesses:每個輸入的見證資料(簽名等)

見證資料結構

每個輸入的見證:
[witness_count][witness_item_1][witness_item_2]...

P2WPKH 見證(2 項):
[2][<signature>][<pubKey>]

P2WSH 2-of-3 多簽見證:
[4][<>][<sig1>][<sig2>][<redeemScript>]

交易大小比較

單簽 1 輸入 2 輸出

類型大小vsize節省
P2PKH226 bytes226 vB-
P2SH-P2WPKH167 bytes134 vB40%
P2WPKH141 bytes110 vB51%

2-of-3 多簽

類型大小vsize節省
P2SH371 bytes371 vB-
P2SH-P2WSH274 bytes167 vB55%
P2WSH249 bytes139 vB62%

實施細節

軟分叉兼容性

SegWit 作為軟分叉的關鍵:

舊節點視角:
- SegWit 輸出看起來是「任何人可花費」
- 但礦工共識規則阻止無效花費
- 舊節點仍可驗證區塊(不驗證見證)

新節點視角:
- 完整驗證見證資料
- 強制執行新的共識規則

WTXID 和 Merkle Tree

區塊結構變化:

傳統 Merkle Tree:
- 只包含 TXID

SegWit 區塊:
- 傳統 Merkle Tree(TXID)保持不變
- 新增 Witness Merkle Tree(WTXID)
- 根存在 coinbase 的 OP_RETURN 輸出中

簽名雜湊改進(BIP-143)

SegWit 改進了簽名時的雜湊計算方式:

舊方式問題:
- 簽名雜湊需要完整序列化交易
- 多輸入時重複計算,O(n²) 複雜度
- 大交易驗證很慢

BIP-143 改進:
- 預計算可重用的雜湊
- 每個輸入簽名 O(1) 複雜度
- 大幅提升多輸入交易驗證速度

簽名雜湊組成

BIP-143 sighash:
1. nVersion(4 bytes)
2. hashPrevouts(32 bytes)- 所有輸入的前序輸出 hash
3. hashSequence(32 bytes)- 所有輸入的 sequence hash
4. outpoint(36 bytes)- 當前輸入的前序輸出
5. scriptCode(變長)- 執行的腳本
6. amount(8 bytes)- 花費金額(新增!)
7. nSequence(4 bytes)- 當前輸入的 sequence
8. hashOutputs(32 bytes)- 所有輸出的 hash
9. nLocktime(4 bytes)
10. sighash type(4 bytes)

採用歷史

啟用過程

時間線:
2015:最初提案
2016:優化後的 BIP-141/143/144
2017.07:BIP-91 鎖定
2017.08.24:區塊 481,824 啟用

採用率成長

時期SegWit 交易佔比
2017.09~10%
2018.06~35%
2020.01~55%
2022.01~70%
2024.01~80%+

交易所支援

大多數主要交易所現已支援 SegWit 提款:

交易所原生 SegWitTaproot
Coinbase
Kraken
Binance部分

開發指南

判斷 SegWit 交易

// 檢查原始交易是否為 SegWit
function isSegWit(rawTx) {
  // 第 5 個字節是 marker
  // SegWit 交易:version(4) + marker(1)=0x00 + flag(1)=0x01
  return rawTx[4] === 0x00 && rawTx[5] === 0x01;
}

創建 SegWit 地址

const bitcoin = require('bitcoinjs-lib');

// P2WPKH 地址
const { address } = bitcoin.payments.p2wpkh({
  pubkey: publicKeyBuffer,
});
// bc1q...

// P2WSH 多簽
const { address } = bitcoin.payments.p2wsh({
  redeem: bitcoin.payments.p2ms({
    m: 2,
    pubkeys: [pubkey1, pubkey2, pubkey3],
  }),
});
// bc1q...(較長)

計算 vsize

function calculateVsize(txHex) {
  const tx = bitcoin.Transaction.fromHex(txHex);

  // 基礎大小(不含見證)
  const baseSize = tx.byteLength(false);

  // 完整大小(含見證)
  const totalSize = tx.byteLength(true);

  // 權重
  const weight = baseSize * 3 + totalSize;

  // vsize(向上取整)
  const vsize = Math.ceil(weight / 4);

  return vsize;
}

常見問題

為什麼還有人用 P2PKH?

原因:
1. 舊錢包未升級
2. 交易所出金限制
3. 不了解 SegWit 好處
4. 某些特殊用途

建議:
- 盡量使用原生 SegWit(bc1q)或 Taproot(bc1p)
- 手續費更低,區塊空間更省

SegWit 和 Taproot 的關係?

Taproot(BIP-341)是 SegWit version 1:
- SegWit v0:P2WPKH、P2WSH
- SegWit v1:P2TR(Taproot)

Taproot 建立在 SegWit 基礎上:
- 使用相同的見證結構
- 使用 Bech32m 編碼(改進版)
- 引入 Schnorr 簽名

相關 BIP

  • BIP-141:SegWit 共識規則
  • BIP-143:交易簽名驗證
  • BIP-144:P2P 協議更新
  • BIP-145:getblocktemplate 更新
  • BIP-173:Bech32 地址編碼
已複製到剪貼簿