檢查序列號 CSV(OP_CHECKSEQUENCEVERIFY)
檢查序列號,是 Bitcoin Script 中的一個操作碼,用來限制某個 UTXO 必須在被確認後,再經過指定的區塊數量或時間,才能被花費。

OP_CHECKSEQUENCEVERIFY(CSV),檢查序列號,是 Bitcoin Script 中的一個操作碼,用來限制某個 UTXO 必須在被確認後,再經過指定的區塊數量或時間,才能被花費。
CSV 由 BIP 112 定義,與 BIP 68、BIP 113 一同透過軟分叉於 2016 年啟用。BIP 68 讓交易輸入的 nSequence 可以表示相對時間鎖定,但只限制交易何時可以被納入區塊。CSV 將相對時間條件寫進鎖定腳本,使相對時間鎖定成為 UTXO 的花費條件。
因此,CSV 是 Bitcoin 腳本層的重要相對時間鎖定機制,連結了鎖定腳本、nSequence、交易版本與 Lightning Network 等機制。
檢查序列號 基本概念
-
腳本層相對時間鎖定
nSequence 是交易輸入中的欄位,由建立交易的人自行設定。
持有私鑰的人可以建立另一筆不使用相對鎖定的交易,立即花費同一個 UTXO。
CSV 則是寫在 UTXO 的鎖定腳本中,任何人想要花費該 UTXO,都必須滿足腳本中的相對時間條件。
因此,CSV 讓相對時間鎖定從「交易何時有效」,變成「UTXO 何時可以被花費」。
-
相對時間與絕對時間
CLTV 檢查的是絕對時間點,例如區塊高度 900000 或某個指定日期。
CSV 檢查的是相對時間,也就是 UTXO 被確認之後,還需要經過多少區塊或多少時間。
因此,CSV 的等待時間從 UTXO 被確認的那一刻開始計算,不需要事先知道 UTXO 會在哪一個區塊被確認。
-
操作碼
OP_CHECKSEQUENCEVERIFY 的操作碼為 0xb2。
這個操作碼原本是 OP_NOP3,屬於沒有任何作用的保留操作碼。
BIP 112 將其重新定義為 CSV。
未升級的舊節點仍將它視為 NOP,因此這項變更屬於軟分叉,新舊節點可以共同運作。
-
檢查 nSequence
CSV 並不直接計算 UTXO 已經被確認多久,而是檢查花費該 UTXO 的交易輸入的 nSequence。
CSV 要求該交易輸入的 nSequence 所表示的相對鎖定,必須大於或等於腳本中指定的數值。
交易實際何時可以被納入區塊,再由 BIP 68 的 nSequence 規則決定。
因此,CSV 與 BIP 68 結合後,才完成整個相對時間鎖定的驗證。
-
不移除堆疊數值
由於 CSV 是從 NOP 升級而來,為了與舊節點相容,它執行後不會移除堆疊頂端的數值。
因此,腳本中通常會在 CSV 之後加上 OP_DROP,將該數值移除。
常見的寫法為:
[鎖定值] OP_CHECKSEQUENCEVERIFY OP_DROP
-
鎖定值格式
CSV 的鎖定值使用與 BIP 68 nSequence 相同的位元格式。
- Bit 31:Disable Flag
- Bit 22:Type Flag,0 為區塊模式,1 為時間模式
- 低 16 bits:相對鎖定值
區塊模式中,數值代表相對區塊數量。
時間模式中,數值代表以 512 秒為單位的相對時間。
檢查序列號 運作方式
-
建立鎖定腳本
建立 UTXO 時,將 CSV 條件寫入鎖定腳本。如:
[144] OP_CHECKSEQUENCEVERIFY OP_DROP [PubKey] OP_CHECKSIG
代表該 UTXO 被確認後,必須再經過 144 個區塊,並且提供對應公鑰的簽章,才能被花費。
以平均每 10 分鐘一個區塊計算,144 個區塊約為 1 天。
-
建立花費交易
花費該 UTXO 時,交易版本必須為 Version >= 2。
同時,該交易輸入必須設定符合條件的 nSequence,而且 nSequence 的 Disable Flag 不可以被設定。
-
讀取鎖定值
節點執行腳本時,CSV 會讀取堆疊頂端的數值,作為鎖定值。
如果堆疊為空,或鎖定值為負數,驗證失敗。
-
判斷鎖定值的 Disable Flag
如果鎖定值的 Bit 31 被設定,CSV 不進行任何檢查,直接視為通過,效果等同 NOP。
這是為了保留未來升級的空間。
如果 Bit 31 沒有被設定,CSV 繼續進行以下檢查。
-
檢查交易版本
CSV 檢查花費交易的版本。
如果 Version < 2,BIP 68 的相對鎖定不會生效,因此驗證失敗。
-
檢查 nSequence 的 Disable Flag
CSV 檢查該交易輸入 nSequence 的 Bit 31。
如果 Bit 31 被設定,nSequence 不具有相對鎖定的效果,時間條件可以被繞過,因此驗證失敗。
-
判斷鎖定類型
CSV 檢查鎖定值與 nSequence 的 Bit 22 是否相同。
如果一個是區塊模式,另一個是時間模式,驗證失敗。
-
比較相對鎖定值
CSV 比較鎖定值與 nSequence 的低 16 bits。
如果 nSequence 的相對鎖定值小於鎖定值,驗證失敗。
-
繼續執行腳本
CSV 檢查通過後,腳本繼續執行。
OP_DROP 移除鎖定值,接著執行 OP_CHECKSIG 等其他條件。
-
節點驗證
腳本驗證通過後,交易輸入的 nSequence 仍須符合 BIP 68 的規則。
使用區塊模式,會檢查 UTXO 被確認後經過的區塊數量。
使用時間模式,會以 Median Time Past 檢查 UTXO 被確認後經過的時間。
只有在腳本條件與 BIP 68 條件都符合後,交易才可以被納入區塊。
檢查序列號 使用示例
-
相對區塊鎖定
假設 UTXO 的鎖定腳本為:
[144] OP_CHECKSEQUENCEVERIFY OP_DROP [PubKey] OP_CHECKSIG
該 UTXO 在區塊 900000 被確認。
花費交易設定:
Version = 2
Input 0 → nSequence = 144
交易版本為 2,nSequence 的 Disable Flag 沒有被設定,兩者都是區塊模式。
nSequence 等於鎖定值,因此 CSV 檢查通過。
依照 BIP 68 規則,該交易最早可以被納入區塊 900144。
-
相對時間鎖定
假設 UTXO 的鎖定腳本為:
[4194314] OP_CHECKSEQUENCEVERIFY OP_DROP [PubKey] OP_CHECKSIG
4194314 換算為十六進位是 0x0040000a,Bit 22 被設定,代表時間模式,低 16 bits 的值為 10。
花費交易設定:
Version = 2
Input 0 → nSequence = 0x0040000a
兩者都是時間模式,相對鎖定值相同,因此 CSV 檢查通過。
10 × 512 = 5,120 秒,約 85.3 分鐘。
該交易必須等到 UTXO 被確認後,Median Time Past 經過 5,120 秒以上,才可以被納入區塊。
-
nSequence 不足
假設 UTXO 的鎖定值為 144,花費交易設定:
Version = 2
Input 0 → nSequence = 100
由於 100 小於 144,CSV 驗證失敗。
因此,無論 UTXO 已經被確認多久,這筆交易都不是有效交易。
-
交易版本為 1
假設 UTXO 的鎖定值為 144,花費交易設定:
Version = 1
Input 0 → nSequence = 144
雖然 nSequence 等於鎖定值,但交易版本為 1,BIP 68 的相對鎖定不會生效。
為了避免時間條件被繞過,CSV 驗證失敗。
-
鎖定類型不同
假設 UTXO 的鎖定值為 144,屬於區塊模式,花費交易設定:
Version = 2
Input 0 → nSequence = 0x00400090
nSequence 的 Bit 22 被設定,屬於時間模式,與鎖定值的類型不同。
因此 CSV 驗證失敗。
CSV 應用
-
閃電網路 Lightning Network
Lightning Channel 的承諾交易中,屬於自己的輸出會加上 CSV 條件。
單方關閉通道後,這筆資金必須等待指定的區塊數量才能取回。
在這段期間,如果對方發現廣播的是已經作廢的舊狀態,可以使用撤銷金鑰取走全部資金。
因此,CSV 是 Lightning Network 撤銷與安全結算機制的重要底層基礎。
-
延遲取款 Vault
使用者可以將資金鎖定在帶有 CSV 條件的腳本中,取款時必須等待一段時間。
在等待期間,如果發現取款不是本人操作,可以使用另一組備援金鑰將資金轉到安全的地址。
這讓私鑰被盜時,仍有時間阻止資金被轉走。
-
備援恢復路徑
錢包可以在腳本中加入多條花費路徑,例如平常使用主要金鑰花費,或是 UTXO 長時間沒有移動後,允許備援金鑰花費。
CSV 讓備援路徑只有在 UTXO 一段時間未被花費後才能使用,適合遺產規劃或金鑰遺失的恢復機制。
-
與 CLTV 搭配
CSV 與 CLTV 可以在同一個腳本中搭配使用,分別設定相對與絕對時間條件。
例如 Lightning Network 的 HTLC,使用 CLTV 設定付款逾時,使用 CSV 設定單方關閉通道後的延遲。
CSV 相關 BIP
- BIP 112:CHECKSEQUENCEVERIFY
- BIP 68:Relative lock-time using consensus-enforced sequence numbers
- BIP 113:Median time-past as endpoint for lock-time calculations
- BIP 65:OP_CHECKLOCKTIMEVERIFY

更多文章