跳至主要內容
高級

nSequence

深入了解 Bitcoin 交易輸入的 nSequence 字段,其在 RBF、時間鎖和相對鎖定中的應用。

12 分鐘

什麼是 nSequence?

nSequence 是每個交易輸入的 32 位字段,最初設計用於交易替換, 後來被重新定義用於 RBF(Replace-By-Fee)信號和相對時間鎖(BIP-68)。

nSequence 演進

時期 用途
最初設計 交易替換(已棄用)
BIP-68(2016) 相對時間鎖
BIP-125(2015) RBF 選擇性加入

字段結構

nSequence 32 位結構:

┌─────────────────────────────────────────────────────────────┐
│ Bit 31 │ Bit 22 │ Bits 21-16 │ Bits 15-0                   │
│ Disable│ Type   │ Reserved   │ Value                       │
│ Flag   │ Flag   │            │                             │
└─────────────────────────────────────────────────────────────┘

Bit 31(Disable Flag):
├── 1 = 禁用相對時間鎖(BIP-68 不適用)
└── 0 = 啟用相對時間鎖

Bit 22(Type Flag):
├── 1 = 以 512 秒為單位的時間鎖
└── 0 = 以區塊數為單位

Bits 15-0(Value):
├── 時間鎖值
└── 最大 65535(區塊或 512 秒單位)

特殊值:
├── 0xFFFFFFFF (4294967295) = 禁用 RBF 和相對鎖
├── 0xFFFFFFFE (4294967294) = 禁用相對鎖,啟用 RBF
└── < 0xFFFFFFFE = 啟用 RBF

RBF 信號

RBF(Replace-By-Fee)信號規則:

任何輸入的 nSequence < 0xFFFFFFFE 時:
└── 交易被標記為可替換(BIP-125)

常用值:
├── 0xFFFFFFFD = 啟用 RBF,禁用相對鎖
├── 0xFFFFFFFE = 禁用 RBF,禁用相對鎖
└── 0xFFFFFFFF = 禁用 RBF,禁用相對鎖(最終)

┌─────────────────────────────────────────────────────────────┐
│ nSequence 值         │ RBF   │ 相對時間鎖                   │
├─────────────────────────────────────────────────────────────┤
│ 0xFFFFFFFF           │ 否    │ 否(禁用)                   │
│ 0xFFFFFFFE           │ 否    │ 否(禁用)                   │
│ 0xFFFFFFFD           │ 是    │ 否(禁用)                   │
│ 0x00000000 - 0xEFFF  │ 是    │ 是(區塊)                   │
│ 0x00400000 - 0x40EF  │ 是    │ 是(時間)                   │
└─────────────────────────────────────────────────────────────┘
# 創建可替換交易
bitcoin-cli createrawtransaction '[
  {"txid": "abc...", "vout": 0, "sequence": 4294967293}
]' '[{"bc1q...": 0.5}]'

# 4294967293 = 0xFFFFFFFD(啟用 RBF)

# 使用 send 命令啟用 RBF
bitcoin-cli send '[{"bc1q...": 0.5}]' null "unset" null '{"replaceable": true}'

# 檢查交易是否可替換
bitcoin-cli getmempoolentry "txid" | jq '.bip125-replaceable'

相對時間鎖

BIP-68 相對時間鎖:

當 Bit 31 = 0 時,nSequence 定義相對鎖定:

區塊高度鎖定(Bit 22 = 0):
├── 值 = 區塊數
├── 最大 65535 區塊(約 455 天)
└── 輸入必須等待 N 個區塊確認

時間鎖定(Bit 22 = 1):
├── 值 = 512 秒單位數
├── 最大 65535 × 512 秒(約 388 天)
└── 輸入必須等待 N × 512 秒

示例:
├── 0x00000001 = 等待 1 個區塊
├── 0x00000006 = 等待 6 個區塊
├── 0x00400001 = 等待 512 秒
├── 0x0040000C = 等待 6144 秒(~1.7 小時)
└── 0x80000000 = 禁用(Bit 31 = 1)
# 計算 nSequence 值

# 區塊相對鎖定
def block_sequence(blocks: int) -> int:
    """區塊數相對鎖定"""
    assert 0 < blocks <= 0xFFFF
    return blocks

# 時間相對鎖定
def time_sequence(seconds: int) -> int:
    """時間相對鎖定(512 秒為單位)"""
    units = (seconds + 511) // 512  # 向上取整
    assert 0 < units <= 0xFFFF
    return (1 << 22) | units  # 設置 Bit 22

# 示例
print(hex(block_sequence(6)))        # 0x6 - 等待 6 區塊
print(hex(time_sequence(3600)))      # 0x400007 - 等待約 1 小時

# 禁用相對鎖定
SEQUENCE_FINAL = 0xFFFFFFFF
SEQUENCE_LOCKTIME_DISABLE_FLAG = (1 << 31)

OP_CHECKSEQUENCEVERIFY

OP_CHECKSEQUENCEVERIFY (CSV) - BIP-112

用途:在腳本中強制執行相對時間鎖

工作原理:
1. 從堆棧取值作為要求的 sequence
2. 比較交易輸入的 nSequence
3. 如果 nSequence 不滿足要求,驗證失敗

示例腳本:
┌─────────────────────────────────────────────────────────────┐
│ <6> OP_CHECKSEQUENCEVERIFY OP_DROP  OP_CHECKSIG    │
│                                                             │
│ 含義:必須等待 6 個區塊確認後才能花費                        │
└─────────────────────────────────────────────────────────────┘

比較規則:
├── 類型必須匹配(都是區塊或都是時間)
├── 實際 sequence >= 要求的 sequence
└── 禁用標誌必須一致
# 創建帶 CSV 的腳本

# P2WSH 腳本:10 區塊後可花費
# OP_10 OP_CSV OP_DROP  OP_CHECKSIG
script="5ab27521$(pubkey)ac"

# 使用 miniscript 表示
# and_v(v:older(10),pk(key))

# 在交易中設置 sequence
bitcoin-cli createrawtransaction '[
  {"txid": "...", "vout": 0, "sequence": 10}
]' '[{"bc1q...": 0.5}]'

閃電網路應用

閃電網路中的 nSequence 使用:

1. HTLC 超時
   ├── 使用 CSV 設置 HTLC 超時
   ├── 防止過早取回資金
   └── 給對方足夠時間提供原像

2. 懲罰交易延遲
   ├── to_local 輸出有 CSV 延遲
   ├── 典型值:144 區塊(~1 天)
   └── 給對方時間發現作弊並懲罰

3. 承諾交易結構
   ┌─────────────────────────────────────────────────────────┐
   │ 本地輸出(to_local):                                   │
   │  OP_CHECKSIG                         │
   │ OP_IFDUP OP_NOTIF                                       │
   │    OP_CSV OP_DROP                                │
   │    OP_CHECKSIG                    │
   │ OP_ENDIF                                                │
   └─────────────────────────────────────────────────────────┘

4. 錨點輸出
   ├── 使用 1 區塊 CSV
   └── 防止第三方搶占

實用範例

# 範例 1:創建 RBF 可替換交易

# 使用低 sequence 值
bitcoin-cli createrawtransaction '[
  {"txid": "abc...", "vout": 0, "sequence": 4294967293}
]' '[{"bc1q...": 0.5}]'

# 替換交易(提高手續費)
bitcoin-cli createrawtransaction '[
  {"txid": "abc...", "vout": 0, "sequence": 4294967293}
]' '[{"bc1q...": 0.499}]'  # 更低金額 = 更高手續費

# 範例 2:創建相對時間鎖交易

# 等待 6 個區塊
bitcoin-cli createrawtransaction '[
  {"txid": "abc...", "vout": 0, "sequence": 6}
]' '[{"bc1q...": 0.5}]'

# 等待 1 小時(7 × 512 秒)
bitcoin-cli createrawtransaction '[
  {"txid": "abc...", "vout": 0, "sequence": 4194311}
]' '[{"bc1q...": 0.5}]'
# 4194311 = 0x400007 = (1 << 22) | 7
# 解析 nSequence 值

def parse_sequence(seq: int) -> dict:
    """解析 nSequence 字段"""
    DISABLE_FLAG = 1 << 31
    TYPE_FLAG = 1 << 22
    VALUE_MASK = 0xFFFF

    if seq >= 0xFFFFFFFE:
        return {
            "rbf": seq < 0xFFFFFFFF,
            "relative_lock": False,
            "final": seq == 0xFFFFFFFF
        }

    disabled = bool(seq & DISABLE_FLAG)
    if disabled:
        return {
            "rbf": True,
            "relative_lock": False
        }

    is_time = bool(seq & TYPE_FLAG)
    value = seq & VALUE_MASK

    return {
        "rbf": True,
        "relative_lock": True,
        "type": "time" if is_time else "blocks",
        "value": value,
        "seconds": value * 512 if is_time else None,
        "blocks": value if not is_time else None
    }

# 示例
print(parse_sequence(0xFFFFFFFF))  # final, no RBF
print(parse_sequence(0xFFFFFFFD))  # RBF enabled
print(parse_sequence(6))           # 6 blocks relative lock
print(parse_sequence(0x400007))    # ~1 hour time lock

與 nLockTime 的關係

nSequence vs nLockTime:

nLockTime(交易級別):
├── 絕對時間鎖
├── 區塊高度或 Unix 時間戳
├── 需要所有輸入的 nSequence < 0xFFFFFFFF
└── 使用 OP_CHECKLOCKTIMEVERIFY 腳本驗證

nSequence(輸入級別):
├── 相對時間鎖
├── 相對於 UTXO 確認的時間
├── 每個輸入可以不同
└── 使用 OP_CHECKSEQUENCEVERIFY 腳本驗證

組合使用:
┌─────────────────────────────────────────────────────────────┐
│ 場景:2024年後 + 確認後 1 週才能花費                         │
│                                                             │
│ nLockTime: 1704067200(2024-01-01 的 Unix 時間戳)          │
│ nSequence: 1008(約 1 週的區塊數)                           │
│                                                             │
│ 腳本:                                                      │
│ <1704067200> OP_CLTV OP_DROP                                │
│ <1008> OP_CSV OP_DROP                                       │
│  OP_CHECKSIG                                        │
└─────────────────────────────────────────────────────────────┘

常用值參考

nSequence 十六進制 含義
4294967295 0xFFFFFFFF 最終(無 RBF,無相對鎖)
4294967294 0xFFFFFFFE 無 RBF,無相對鎖,啟用 nLockTime
4294967293 0xFFFFFFFD 啟用 RBF,無相對鎖
1 0x00000001 相對鎖:1 區塊
144 0x00000090 相對鎖:~1 天
4194305 0x00400001 相對鎖:512 秒

總結

  • RBF 信號:nSequence < 0xFFFFFFFE 啟用替換
  • 相對鎖:BIP-68 定義基於區塊或時間的鎖定
  • CSV:OP_CHECKSEQUENCEVERIFY 腳本驗證
  • 注意:與 nLockTime 配合使用更強大
已複製連結
已複製到剪貼簿