比特幣腳本編程進階實戰:從理論到部署
深入講解比特幣腳本指令集、腳本類型開發流程、腳本調試方法,透過多個實際案例展示如何構建安全的比特幣腳本應用,包括多簽名、時間鎖、HTLC 等。
比特幣腳本編程進階實戰:從理論到部署
摘要
比特幣腳本語言(Bitcoin Script)是比特幣系統的核心組成部分,它定義了比特幣交易的驗證邏輯。不同於圖靈完整的智能合約語言,比特幣腳本採用簡單的堆疊式執行模型,專為比特幣的安全性和簡潔性而設計。本文從實戰角度出發,深入講解比特幣腳本的指令集、腳本類型開髮流程、腳本調試方法,並透過多個實際案例展示如何構建安全的比特幣腳本應用。
比特幣腳本基礎架構
執行模型:堆疊式虛擬機
比特幣腳本採用獨特的堆疊式執行模型,理解這個模型是掌握比特幣腳本編程的關鍵:
堆疊執行模型示意:
初始狀態:
堆疊:[ ]
執行 OP_ADD(彈出兩個元素相加後壓回):
步驟 1: 執行 [5, 3] OP_ADD
堆疊:[5, 3]
步驟 2: OP_ADD 彈出 3 和 5
堆疊:[ ]
步驟 3: 計算 5 + 3 = 8
堆疊:[8]
完整執行範例:
腳本:OP_2 OP_3 OP_ADD OP_5 OP_EQUAL
執行過程:
┌─────────────────────────────────────────┐
│ 步驟 │ 操作 │ 堆疊狀態 │
├─────────────────────────────────────────┤
│ 初始 │ - │ [ ] │
│ 1 │ OP_2 │ [2] │
│ 2 │ OP_3 │ [2, 3] │
│ 3 │ OP_ADD │ [5] │
│ 4 │ OP_5 │ [5, 5] │
│ 5 │ OP_EQUAL │ [True] │
└─────────────────────────────────────────┘
結果:腳本執行成功,返回 True
指令集分類
比特幣腳本指令集可分為多個類別,每個類別執行特定的功能:
指令集分類表:
1. 常數指令(Constants)
OP_0, OP_1-OP_16 推送 0-16 到堆疊
OP_PUSHDATA1-4 推送變長數據
2. 堆疊指令(Stack Operations)
OP_DUP 複製堆疊頂部
OP_DROP 彈出並丟棄頂部
OP_SWAP 交換頂部兩個元素
OP_OVER 複製第二個元素到頂部
OP_ROT 旋轉前三個元素
OP_2DUP 複製前兩個元素
3. 運算指令(Arithmetic)
OP_ADD, OP_SUB 加法、減法
OP_MUL, OP_DIV 乘法、除法
OP_MOD 取模
OP_1ADD, OP_1SUB 加1、減1
OP_NEGATE 取反
4. 邏輯指令(Logic)
OP_NOT, OP_0NOTEQUAL 非、布爾轉換
OP_EQUAL, OP_EQUALVERIFY 相等、相等並驗證
5. 密碼學指令(Cryptography)
OP_SHA256 SHA-256 哈希
OP_RIPEMD160 RIPEMD-160 哈希
OP_HASH160 SHA-256 + RIPEMD-160
OP_HASH256 SHA-256 兩次
OP_CHECKSIG 驗證簽名
OP_CHECKMULTISIG 驗證多簽名
6. 時間鎖指令(Time Locks)
OP_CHECKLOCKTIMEVERIFY (CLTV)
OP_CHECKSEQUENCEVERIFY (CSV)
7. 流程控制(Flow Control)
OP_IF, OP_ELSE, OP_ENDIF 條件分支
OP_VERIFY 驗證並失敗若 false
OP_RETURN 終止並失敗
8. 比特區域操作(Bitwise)
OP_AND, OP_OR, OP_XOR 位運算
OP_1, OP_LESSTHAN 比較運算
###腳本類型詳解
比特幣支持多種腳本類型,每種適用於不同的使用場景:
腳本類型架構:
1. P2PK(Pay to Public Key)
最早的形式,直接支付到公鑰
腳本範例:
輸出腳本:<pubKey> OP_CHECKSIG
輸入腳本:<signature>
2. P2PKH(Pay to Public Key Hash)
支付到公鑰哈希,最常用的傳統格式
腳本範例:
輸出腳本:OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
輸入腳本:<signature> <pubKey>
3. P2SH(Pay to Script Hash)
支付到腳本哈希,支持複雜腳本
腳本範例:
輸出腳本:OP_HASH160 <scriptHash> OP_EQUAL
輸入腳本:<serializedScript> <args...>
4. P2WSH(Pay to Witness Script Hash)
隔離見證版本的 P2SH
腳本範例:
輸出腳本:OP_0 <witnessScriptHash>
輸入腳本:<witness> [serializedScript]
5. P2WPKH(Pay to Witness Public Key Hash)
隔離見證版本的 P2PKH
腳本範例:
輸出腳本:OP_0 <pubKeyHash>
輸入腳本:<witness> <signature> <pubKey>
6. P2TR(Pay to Taproot)
最新的腳本類型,支持 Taproot
腳本範例:
輸出腳本:OP_1 <taprootPubKey>
輸入腳本:<witness> [signature...]
腳本開發環境設置
本地開發環境
建立本地開發環境是進行比特幣腳本開發的第一步:
開發工具棧:
1. Bitcoin Core(測試網)
安裝與配置:
$ brew install bitcoin # macOS
$ sudo apt install bitcoin-core # Ubuntu
配置 testnet:
bitcoin.conf:
testnet=1
server=1
txindex=1
rpcuser=user
rpcpassword=pass
rpcport=18332
2. 命令行工具
$ bitcoin-cli -testnet getblockchaininfo
$ bitcoin-cli -testnet createrawtransaction
$ bitcoin-cli -testnet signrawtransactionwithwallet
3. 腳本調試工具
$ bitcoin-tx -regtest (創建和測試交易)
$ pycoin (Python 比特幣工具庫)
$ rust-bitcoin (Rust 比特幣庫)
Python 開發環境示例
使用 Python 庫可以更方便地開發和測試比特幣腳本:
環境設置:
$ pip install bitcoinlib python-bitcoinlib ethsnarks
比特幣腳本測試腳本:
from bitcoin.core import x, b2x
from bitcoin.core.script import (
OP_DUP, OP_HASH160, OP_EQUALVERIFY, OP_CHECKSIG,
OP_0, OP_1, OP_CHECKMULTISIG
)
# 創建 P2PKH 輸出腳本
def create_p2pkh_script(pubkey_hash):
"""創建 P2PKH 輸出腳本"""
script = [
OP_DUP,
OP_HASH160,
pubkey_hash,
OP_EQUALVERIFY,
OP_CHECKSIG
]
return script
# 示例:創建一個 P2PKH 腳本
# 假設公鑰哈希為 89abcdef...
pubkey_hash = x('89abcdef' + '0' * 56)
p2pkh_script = create_p2pkh_script(pubkey_hash)
print("P2PKH Script:", b2x(p2pkh_script))
# 輸出: 76a91489abcdef...88ac
使用 secp256k1 進行密鑰操作
橢圓曲線密鑰操作是比特幣腳本開發的核心技能:
密鑰生成與操作:
from ecdsa import SigningKey, SECP256k1
import hashlib
import os
# 生成隨機私鑰
private_key = os.urandom(32)
print(f"私鑰: {private_key.hex()}")
# 生成公鑰(壓縮格式)
sk = SigningKey.from_string(private_key, curve=SECP256k1)
vk = sk.verifying_key
public_key = vk.to_string('compressed')
print(f"公鑰: {public_key.hex()}")
# 生成公鑰哈希(P2PKH 格式)
sha256_pubkey = hashlib.sha256(public_key).digest()
ripemd160_pubkey = hashlib.new('ripemd160')
ripemd160_pubkey.update(sha256_pubkey)
pubkey_hash = ripemd160_pubkey.digest()
print(f"公鑰哈希: {pubkey_hash.hex()}")
# 創建 P2PKH 地址(testnet)
version = b'\x6f' # testnet
payload = version + pubkey_hash
checksum = hashlib.sha256(hashlib.sha256(payload).digest())[:4]
address = base58encode(payload + checksum)
print(f"P2PKH 地址: {address}")
# 完整腳本生成
def create_p2pkh_output(pubkey_hash):
"""創建完整的 P2PKH 輸出腳本"""
return bytes([OP_DUP, OP_HASH160]) + \
bytes([len(pubkey_hash)]) + pubkey_hash + \
bytes([OP_EQUALVERIFY, OP_CHECKSIG])
實際腳本開發案例
案例一:多簽名錢包腳本
多簽名腳本是比特幣腳本最重要的應用之一,它要求多個私鑰中的至少一個子集簽名才能花費資金:
多簽名腳本結構:
腳本格式:
<OP_M> <pubKey1> <pubKey2> ... <pubKeyN> <OP_N> OP_CHECKMULTISIG
說明:
- M of N:N 個公鑰中需要 M 個簽名
- 順序:先公鑰,後 OP_N
- 注意:OP_CHECKMULTISIG 有一個比特小陷阱,需要一個 dummy 元素
示例:2-of-3 多簽名
公鑰:
- PK1: 02aab552aa22ae2e...
- PK2: 02b2764a4c62e8e6...
- PK3: 03d5e6a6c2d3e9f1...
腳本構建:
script = [
OP_2, # 需要 2 個簽名
bytes.fromhex('02aab552aa22ae2e...'), # 公鑰 1
bytes.fromhex('02b2764a4c62e8e6...'), # 公鑰 2
bytes.fromhex('03d5e6a6c2d3e9f1...'), # 公鑰 3
OP_3, # 總共 3 個公鑰
OP_CHECKMULTISIG
]
完整腳本字節:
02 = OP_2
21 = 33 bytes 公鑰
02aab552aa22ae2e... = 公鑰 1
21 = 33 bytes 公鑰
02b2764a4c62e8e6... = 公鑰 2
21 = 33 bytes 公鑰
03d5e6a6c2d3e9f1... = 公鑰 3
03 = OP_3
ae = OP_CHECKMULTISIG
腳本十六進制:
02521...ae
案例二:時間鎖定腳本
時間鎖定腳本允許設置資金的可花費時間,這在遺產規劃、托管協議和分期釋放場景中非常有用:
絕對時間鎖定(CLTV):
使用 OP_CHECKLOCKTIMEVERIFY (OP_CLTV) 實現絕對時間鎖定
腳本範例:1 年後可提取
lock_time = 2027-02-27 00:00:00 UTC
epoch_seconds = 1800000000 # 轉換為 Unix 時間戳
腳本結構:
<lock_time> OP_CHECKLOCKTIMEVERIFY OP_DROP
<pubKey> OP_CHECKSIG
完整腳本:
0520cf1300 # lock_time (1800000000)
b1 # OP_CHECKLOCKTIMEVERIFY
75 # OP_DROP
21 # 33 bytes 公鑰
ac # OP_CHECKSIG
相對時間鎖定(CSV):
使用 OP_CHECKSEQUENCEVERIFY (OP_CSV) 實現相對時間鎖定
腳本範例:通道建立 1 個月後可提取
腳本結構:
<sequence> OP_CHECKSEQUENCEVERIFY OP_DROP
<pubKey> OP_CHECKSIG
sequence 計算:
- 最小單位:512 秒
- 1 個月 ≈ 30 天 × 24 × 60 × 60 = 2,592,000 秒
- 2,592,000 / 512 = 5,062.5 ≈ 5063
sequence 值:
5063 = 0x13D7
完整序列:0x13D7
腳本:
13d7 # sequence (5063)
b2 # OP_CHECKSEQUENCEVERIFY
75 # OP_DROP
21 # 33 bytes 公鑰
ac # OP_CHECKSIG
案例三:HTLC(哈希時間鎖合約)
HTLC 是閃電網路的核心組成部分,實現了條件支付和原子交換:
HTLC 腳本結構:
條件:
1. 過時間時間前,提供原像(preimage)可以提取資金
2. 過時間時間後,原則上可以提取資金(退款)
腳本設計:
輸出腳本(收到方):
OP_IF
# 條件 1:提供原像
OP_HASH160 <hashR> OP_EQUALVERIFY <revokePubKey> OP_CHECKSIG
OP_ELSE
# 條件 2:時間鎖後退款
<timeTimeout> OP_CHECKLOCKTIMEVERIFY OP_DROP
<refundPubKey> OP_CHECKSIG
OP_ENDIF
完整腳本字節:
63 # OP_IF
a9 14 <hashR> 88 # OP_HASH160 <hashR> OP_EQUALVERIFY
21 <revokePubKey> ac # <revokePubKey> OP_CHECKSIG
67 # OP_ELSE
04 <timeTimeout> b1 75 # <timeTimeout> OP_CHECKLOCKTIMEVERIFY OP_DROP
21 <refundPubKey> ac # <refundPubKey> OP_CHECKSIG
68 # OP_ENDIF
實例參數:
- hashR = 4f5d8d3e4a5c... (R 的 SHA-256 哈希)
- revokePubKey = 02aab552aa22ae2e...
- refundPubKey = 02b2764a4c62e8e6...
- lock_time = 1800000000 (Unix 時間戳)
完整腳本:
63 a9144f5d8d3e4a5c88ac2102aab552aa22ae2e... ac
6704 6f5e3d00 b1 75 2102b2764a4c62e8e6... ac
68
案例四:閃電網路通道腳本
閃電網路使用複雜的腳本結構來實現通道的各種狀態:
閃電通道承諾交易腳本:
承諾交易輸出腳本(延遲支付給本地):
腳本邏輯:
如果收到方同意最新狀態:
- 等待區塊確認後支付給本地
如果收到方試圖欺詐:
- 立即支付給遠端(罰沒)
腳本結構(簡化版):
OP_IF
# 欺詐路徑:立即支付給遠端
<remotePubKey> OP_CHECKSIG
OP_ELSE
# 正常路徑:延遲支付給本地
<toSelfDelay> OP_CHECKSEQUENCEVERIFY OP_DROP
<localPubKey> OP_CHECKSIG
OP_ENDIF
完整腳本:
63 # OP_IF
21 <remotePubKey> ac # <remotePubKey> OP_CHECKSIG
67 # OP_ELSE
02 <toSelfDelay> b2 75 # <toSelfDelay> OP_CHECKSEQUENCEVERIFY OP_DROP
21 <localPubKey> ac # <localPubKey> OP_CHECKSIG
68 # OP_ENDIF
參數說明:
- toSelfDelay: 延遲區塊數(通常 144 = 1 天)
- remotePubKey: 遠端節點公鑰
- localPubKey: 本地節點公鑰
案例五:原子交換腳本
原子交換允許在不使用信任第三方的情況下交換兩種不同的加密貨幣:
比特幣-萊特幣原子交換協議:
步驟 1:創建 HTLC
Bob(萊特幣持有者)為 Alice(比特幣持有者)創建 HTLC
萊特幣 HTLC 腳本:
OP_IF
# Alice 提供原像
OP_SHA256 <hash> OP_EQUALVERIFY AlicePubKey OP_CHECKSIG
OP_ELSE
# 退款時間鎖
1440 OP_CHECKSEQUENCEVERIFY OP_DROP BobPubKey OP_CHECKSIG
OP_ENDIF
步驟 2:Alice 創建對應的比特幣 HTLC
比特幣 HTLC 腳本:
OP_IF
# Bob 提供原像
OP_SHA256 <hash> OP_EQUALVERIFY BobPubKey OP_CHECKSIG
OP_ELSE
# 退款時間鎖
2880 OP_CHECKLOCKTIMEVERIFY OP_DROP AlicePubKey OP_CHECKSIG
OP_ENDIF
步驟 3:原子執行
如果 Alice 想兌換:
1. Alice 揭露原像 X(SHA256(X) = hash)
2. Bob 使用 X 兌換萊特幣
3. Alice 使用同樣的 X 兌換比特幣
如果一方不合作:
- 時間到期後,各自可以退款
時間鎖設計:
- 萊特幣 HTLC 較短(1 天)
- 比特幣 HTLC 較長(2 天)
- 確保雙方都有足夠時間完成交換
Miniscript:可組合的比特幣腳本
Miniscript 概述
Miniscript 是一種比特幣腳本的高級描述語言,由 Pieter Wuille 開發,它允許以聲明式方式描述比特幣腳本的邏輯:
Miniscript 語法示例:
傳統腳本:
OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
Miniscript 表達:
pk(pubkey_hash)
多簽名:
thresh(2, [pk(key1), pk(key2), pk(key3)])
時間鎖:
and_v(v:pk(key), older(144))
HTLC 示例:
or_i(and_v(hash256(x), pk(receiver)), and_v(older(1000), pk(sender)))
Miniscript 編譯為腳本:
表達式:thresh(2, [pk(A), pk(B), pk(C)])
編譯過程:
1. 解析:2-of-3 多簽名
2. 構建腳本:
OP_2
<pubKeyA>
<pubKeyB>
<pubKeyC>
OP_3
OP_CHECKMULTISIG
3. 產生的十六進制腳本:
52 <pubKeyA> <pubKeyB> <pubKeyC> 53 ae
Miniscript 開發實戰
使用 Miniscript 可以更安全、更高效地開發比特幣腳本:
Rust 中的 Miniscript 使用:
use miniscript::bitcoin::PublicKey;
use miniscript::miniscript::Segwitv0;
fn main() {
// 解析公鑰
let pk_a = PublicKey::from_str("02aab552aa22ae2e...").unwrap();
let pk_b = PublicKey::from_str("02b2764a4c62e8e6...").unwrap();
// 創建 2-of-2 多簽名 Miniscript
let ms: Segwitv0 = miniscript::Segwitv0::new_pk(pk_a)
.and(miniscript::Segwitv0::new_pk(pk_b))
.unwrap();
println!("Miniscript: {}", ms);
// 產生的腳本
let script = ms.encode();
println!("Script: {}", script);
// 類型檢查
println!("Type: {}", ms.ty);
// Output:
// Type: Wsh
// - spends: witness
// - type: B
// - compiled: true
}
腳本安全性分析
常見腳本漏洞
比特幣腳本開發中常見的安全問題需要特别注意:
安全漏洞分析:
漏洞 1:整數溢出
問題代碼:
OP_2 OP_ADD OP_10 OP_LESSTHAN
# 如果 OP_ADD 結果溢出,可能繞過檢查
防禦:
- 使用足夠大的數字表示
- 比特幣腳本本身防止溢出(某些操作碼有限制)
漏洞 2:時間鎖混淆
問題場景:
- CLTV vs CSV 混用
- absolute vs relative time lock
防禦:
- 明確標註時間單位
- 使用標準模板庫
漏洞 3:多簽名順序依賴
問題:
OP_CHECKMULTISIG 會消費一個額外的 dummy 元素
導致簽名順序影響結果
防禦:
- 標準化簽名順序
- 使用 miniscript 避免手動構建
漏洞 4:哈希原像長度攻擊
問題:
某些腳本允許任意長度的原像
可能導致額外數據注入
防禦:
- 明確限制原像長度
- 使用標準化模板
形式化驗證工具
使用形式化方法可以確保腳本的安全性:
形式化驗證工具:
1. Coq 驗證框架
- 證明腳本行為的數學性質
- 適用於關鍵應用
2. K-Framework
- 比特幣腳本的形式化語義
- 自動驗證腳本正確性
3. Ivy
- 區塊鏈協議驗證
- 檢測協議級漏洞
驗證示例:
# 使用 Coq 證明 2-of-2 多簽名的安全性
Theorem two_of_two_secure:
forall (sk1 sk2: secret_key) (msg: message),
exists (s1: signature) (s2: signature),
verify s1 msg (pk sk1) = true /\
verify s2 msg (pk sk2) = true /\
(forall (s: signature),
verify s msg (pk sk1) = false /\
verify s msg (pk sk2) = false) ->
~ (exists (s: signature),
verify s msg (combine_pk (pk sk1) (pk sk2)) = true).
證明思路:
- 使用離散對數困難假設
- 組合公鑰的安全性
- 驗證每個簽名的獨立性
腳本調試與測試
測試網測試流程
在正式部署腳本之前,必須在測試環境中進行全面測試:
測試流程:
1. 準備測試環境
# 啟動 Bitcoin Core 測試網
$ bitcoind -testnet -daemon
# 獲取測試比特幣
$ bitcoin-cli -testnet getnewaddress
# 訪問測試水龍頭領取測試幣
2. 創建測試腳本
# 創建 P2SH 地址
$ bitcoin-cli -testnet createpsbtwitnessv0
# 腳本
redeemScript = 5251...
# 添加到錢包
$ bitcoin-cli -testnet addmultisigaddress 2 '["pk1", "pk2", "pk3"]'
3. 測試腳本執行
# 創建測試交易
$ txid = bitcoin-cli -testnet createrawtransaction \
'[{"txid": "...", "vout": 0}]' \
'[{"address": "mvine...", "satoshis": 100000}]'
# 簽名
$ signed = bitcoin-cli -testnet signrawtransactionwithwallet "$txid"
# 廣播
$ bitcoin-cli -testnet sendrawtransaction "$signed"
腳本模擬器
使用腳本模擬器可以在隔離環境中測試腳本邏輯:
Python 腳本模擬器示例:
class ScriptSimulator:
def __init__(self):
self.stack = []
self.ops = {
OP_DUP: self.op_dup,
OP_HASH160: self.op_hash160,
OP_EQUALVERIFY: self.op_equalverify,
OP_CHECKSIG: self.op_checksig,
OP_ADD: self.op_add,
# ... 更多操作
}
def execute(self, script):
for op in script:
if isinstance(op, int):
if op in self.ops:
self.ops[op]()
else:
self.stack.append(op)
else:
self.stack.append(op)
def op_dup(self):
if len(self.stack) > 0:
self.stack.append(self.stack[-1])
def op_hash160(self):
if len(self.stack) > 0:
data = self.stack.pop()
h = hashlib.new('ripemd160')
h.update(hashlib.sha256(data).digest())
self.stack.append(h.digest())
# ... 更多操作實現
# 使用示例
script = [
OP_1, # 1
OP_1, # 1
OP_ADD, # 1+1=2
OP_2, # 2
OP_EQUALVERIFY, # 驗證 2==2
OP_TRUE
]
sim = ScriptSimulator()
sim.execute(script)
print(f"結果: {sim.stack}") # [True]
腳本部署最佳實踐
部署檢查清單
在將腳本部署到主網之前,必須完成以下檢查:
部署前檢查清單:
□ 功能測試
□ 正常路徑測試
□ 所有分支條件測試
□ 邊界條件測試
□ 錯誤處理測試
□ 安全審計
□ 代碼審計
□ 靜態分析
□ 形式化驗證(如適用)
□ 第三方審計
□ 參數驗證
□ 時間鎖參數正確
□ 公鑰格式正確
□ 腳本長度符合限制
□ 費用估算合理
□ 備份與恢復
□ 私鑰安全存儲
□ 腳本模板備份
□ 恢復流程測試
□ 監控設置
□ 交易監控
□ 餘額監控
□ 異常行為警報
□ 法律合規
□ 當地法規遵循
□ KYC/AML 要求
□ 稅務申報準備
腳本升級策略
比特幣腳本一旦部署,通常無法直接修改,需要採用適當的升級策略:
升級策略:
策略 1:腳本版本控制
初始版本:
v1 = OP_2 A B C OP_3 OP_CHECKMULTISIG
升級版本:
v2 = OP_3 A B C D OP_4 OP_CHECKMULTISIG
優點:簡單
缺點:需要新地址
策略 2:MAST 結構
使用 Taproot 的 MAST:
Merkle 樹:
Root
/ \
Script1 Script2
/ \
Script2 Script3
花費時只需揭示使用的分支
優點:隱私、靈活
缺點:複雜
策略 3:延遲升級
使用 CSV 實現延遲升級:
腳本:
OP_IF
OP_2 NewPubKey1 NewPubKey2 OP_2 OP_CHECKMULTISIG
OP_ELSE
OP_1 OldPubKey OP_CHECKSIG
1000 OP_CHECKSEQUENCEVERIFY
OP_ENDIF
優點:可以在任何時候回滾
缺點:需要時間鎖到期
策略 4:多簽名托管
使用多簽名實現升級:
腳本:
OP_2
UpgradeAuthority1
UpgradeAuthority2
UpgradeAuthority3
OP_3 OP_CHECKMULTISIG
優點:完全控制
缺點:需要信任托管方
高級應用場景
去中心化托管
使用比特幣腳本實現去中心化的托管服務:
三方托管腳本:
參與方:
- 買方:Alice
- 賣方:Bob
- 托管方:Escrow
腳本邏輯:
1. 資金鎖定在腳本中
2. 達成條件時釋放資金
3. 爭議時托管方裁決
腳本結構:
OP_3
<AlicePubKey>
<BobPubKey>
<EscrowPubKey>
OP_3 OP_CHECKMULTISIG
花費條件:
條件 1:Alice 和 Bob 同意
<AliceSig> <BobSig>
條件 2:Bob 和 Escrow 同意
<BobSig> <EscrowSig>
條件 3:Alice 和 Escrow 同意
<AliceSig> <EscrowSig>
OP_CHECKTEMPLATEVERIFY(CTV)與比特幣儲存槽
OPCHECKTEMPLATEVERIFY(又稱 OPCTV)是比特幣腳本的重要升級提案,允許交易輸出綁定到特定的模板,從而實現更複雜的金融應用。
CTV 技術原理:
OP_CHECKTEMPLATEVERIFY (BIP-119)
═══════════════════════════════════════════════════════════════════════════════
核心功能:
┌─────────────────────────────────────────────────────────────┐
│ • 允許輸出指定花費時必須滿足的條件模板 │
│ • 實現「比特幣合約」的鎖定機制 │
│ • 支援一次性金鑰、棺材鋪、禮物卡等應用 │
│ • 增強比特幣的智能合約能力 │
└─────────────────────────────────────────────────────────────┘
腳本範例:遺產規劃
# 遺產鎖定腳本
OP_CTV <template_hash>
template_hash 包含:
- 繼承人公鑰
- 時間鎖條件
- 監護人條件
實際腳本:
52 # OP_2
20 <template_hash> # 模板哈希 (32 bytes)
b3 # OP_CHECKTEMPLATEVERIFY
21 <heir_pubkey> ac # 繼承人公鑰
CTV 儲存槽(Storage Slots)詳解
═══════════════════════════════════════════════════════════════════════════════
儲存槽是 CTV 的一種應用,允許在比特幣上創建「虛擬」的儲存空間:
┌─────────────────────────────────────────────────────────────┐
│ 儲存槽概念: │
│ • 每個 UTXO 可以綁定多個「儲存槽」 │
│ • 每個槽可以存放特定類型的數據 │
│ • 類似傳統資料庫的記錄系統 │
└─────────────────────────────────────────────────────────────┘
應用場景:
1. 一次性金鑰(One-time Locks)
- 資金只能在特定條件下一次花費
- 適合遺產規劃、保險理賠
2. 棺材鋪機制(Dead Man's Switch)
- 設定時間鎖,若 creator 不行動則釋放資金
- 支援自動捐贈、慈善基金
3. 禮物卡/Gift Cards
- 預先載入資金到特定腳本
- 接收者滿足條件後兌換
4. 國庫系統
- 多重審批的資金支出
- 確保組織資金安全
BIP-347 與 Ark 協議深度解析
Ark 協議是比特幣隱私和擴容的重要提案,允許創建非監護式的閃電通道,實現高效的隱私支付。
Ark 協議核心概念
═══════════════════════════════════════════════════════════════════════════════
Ark 協議設計目標:
┌─────────────────────────────────────────────────────────────┐
│ • 隱私保護:交易對手無法得知資金流向 │
│ • 非監護:用戶保留對資金的控制權 │
│ • 簡便性:無需運行完整節點 │
│ • 規模化:支援大量小額支付 │
└─────────────────────────────────────────────────────────────┘
Ark 架構組成:
┌─────────────────────────────────────────────────────────────┐
│ 1. 服務商(Server/Provider) │
│ • 運行比特幣全節點 │
│ • 管理虛擬 UTXO(VUTXO) │
│ • 處理交易確認 │
│ │
│ 2. 用戶(User) │
│ • 持有 Liquid 網路的比特幣 │
│ • 與服務商進行離鏈交易 │
│ • 最終在比特幣主網結算 │
└─────────────────────────────────────────────────────────────┘
Ark 協議運作流程
═══════════════════════════════════════════════════════════════════════════════
步驟 1:存入資金
用戶將比特幣存入 Ark 服務商
→ 服務商在 Liquid 網路發給用戶 VUTXO
步驟 2:離鏈轉帳
用戶 A → 轉帳給用戶 B(通過服務商)
→ 只記錄在服務商的內部帳本
→ 不上比特幣主網
步驟 3:提領
用戶 B 想要提領比特幣
→ 服務商創建比特幣時間鎖輸出
→ 用戶可以選擇:
a) 等待時間鎖到期直接提領
b) 通過閃電網路即時提領
步驟 4:結算
時間鎖到期後,服務商廣播比特幣交易
→ 完成最終結算
Ark 協議的隱私特性
═══════════════════════════════════════════════════════════════════════════════
Ark 如何實現隱私:
1. 批次交易
┌─────────────────────────────────────────────────────────────┐
│ 所有用戶的交易被打包成單一交易 │
│ 外部觀察者無法識別具體的輸入輸出對應關係 │
└─────────────────────────────────────────────────────────────┘
2. 虛擬 UTXO (VUTXO)
┌─────────────────────────────────────────────────────────────┐
│ VUTXO 存在於 Liquid 側鏈 │
│ 與比特幣主網 UTXO 分離 │
│ 提供額外的隱私層 │
└─────────────────────────────────────────────────────────────┘
3. 一次性花費
┌─────────────────────────────────────────────────────────────┐
│ 每個 VUTXO 只能花費一次 │
│ 防止交易追蹤 │
└─────────────────────────────────────────────────────────────┘
與其他隱私方案比較:
特性 Ark 閃電網路 Chaumian CoinJoin
────────────────────────────────────────────────────────────────────────
隱私程度 高 中 高
複雜度 中 高 中
非監護 是 是 是
門檻 低 高 中
即時確認 是 是 否
BitVM:比特幣上的驗證遊戲
BitVM 是比特幣智能合約的新範式,允許在比特幣上驗證任意計算。
BitVM 核心概念
═══════════════════════════════════════════════════════════════════════════════
BitVM 設計理念:
┌─────────────────────────────────────────────────────────────┐
│ • 不需要比特幣共識升級 │
│ • 利用比特幣腳本實現圖靈完整的驗證 │
│ • 主要應用:零知識證明驗證、跨鏈橋、去中心化預言機 │
└─────────────────────────────────────────────────────────────┘
運作原理:
1. 挑戰-回應遊戲
Prover 聲稱某陳述為真
Verifier 可以挑戰 Prover
透過多輪互動驗證真假
2. 二進制博弈
使用比特幣腳本實現簡單的博弈
透過大量簡單步驟實現複雜計算
3. 樂觀 Rollup
假設大多數情況是誠實的
只有爭議時才需要在比特幣主網解決
比特幣腳本升級提案時程表
比特幣腳本升級時間════════════════════════════════線
═══════════════════════════════════════════════
已實現升級:
─────────────────────────────────────────────────────────────────────────────
2017年:SegWit (BIP-141)
- 隔離見證
- 交易延展性解決
- 腳本版本控制
2021年:Taproot (BIP-340/341/342)
- Schnorr 簽名
- MAST 結構
- 腳本彈性提升
待實現升級:
─────────────────────────────────────────────────────────────────────────────
BIP-119:OP_CHECKTEMPLATEVERIFY
- 比特幣合約
- 儲存槽機制
- 預計:2025-2026
BIP-347:Ark 協議
- 隱私支付 Layer 2
- 非監護式閃電通道
- 預計:2026-2027
BIP-325:Drivechains
- 側鏈雙向錨定
- 礦工算力投票
- 預計:2027+
研究階段:
─────────────────────────────────────────────────────────────────────────────
OP_CAT:字串串聯操作
- 實現更複雜的腳本
- 需要共識升級
OP_VAULT:保險庫
- 延遲提領機制
- 盜竊防護
客戶端驗證:RGB、Stacks
- 比特幣上的智能合約
- 不需要共識升級
保險基金
建立比特幣保險基金來保護用戶資金:
保險基金腳本:
腳本目的:
- 保護用戶免受智能合約漏洞損失
- 提供快速理賠
腳本設計:
基金鎖定腳本:
OP_IF
# 理赔條件:保險公司簽名 + 受益人簽名
<InsurerSig> <BeneficiarySig>
OP_ELSE
# 時間鎖後:保險公司可以提取
26280 OP_CHECKSEQUENCEVERIFY OP_DROP # 6 個月
<InsurerSig>
OP_ENDIF
OP_CHECKSIG
理赔流程:
1. 用戶提交理赔申請
2. 保險公司驗證並簽名
3. 受益人簽名後廣播交易
理赔上限:
- 每個用戶理赔上限:10 BTC
- 基金總額:100 BTC
區塊鏈投票
實現基於比特幣腳本的去中心化投票系統:
投票腳本設計:
每個投票者獲得一個投票代幣
投票腳本(壓縮格式):
OP_IF
# 投票給選項 A
<OptionAScript>
OP_ELSE
# 投票給選項 B
<OptionBScript>
OP_ENDIF
實現方式:
選項 A 腳本:
OP_DUP OP_HASH160 <HashA> OP_EQUALVERIFY OP_CHECKSIG
選項 B 腳本:
OP_DUP OP_HASH160 <HashB> OP_EQUALVERIFY OP_CHECKSIG
投票過程:
1. 投票者創建帶有自己簽名的投票交易
2. 投票交易只能選擇一個選項
3. 計數節點統計每個選項的總票數
結論
比特幣腳本雖然設計簡潔,但透過組合各種指令,可以構建出功能強大且安全的應用程式。本文從基礎架構出發,深入講解了腳本開發的各個環節,包括:
- 執行模型理解:堆疊式虛擬機是理解比特幣腳本的關鍵
- 腳本類型掌握:P2PKH、P2SH、P2WSH、P2TR 等各有適用場景
- 實際案例學習:透過多簽名、時間鎖、HTLC 等案例掌握開發技巧
- 安全性優先:形式化驗證和嚴格測試是確保腳本安全的必要手段
- 最佳實踐遵循:部署檢查清單和升級策略確保長期運營
比特幣腳本的可組合性和安全性使其成為構建各種金融應用的可靠基礎。隨著 Taproot 升級的普及,更複雜的比特幣應用將變得更加私密和高效。
參考資源
- Bitcoin Developer Documentation: https://developer.bitcoin.org/
- BIP-16: P2SH: https://github.com/bitcoin/bips/blob/master/bip-0016.mediawiki
- BIP-141: SegWit: https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki
- BIP-341: Taproot: https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki
- Bitcoin Optech Workshop Materials: https://bitcoinops.org/
- "Programming Bitcoin" by Jimmy Song
- Miniscript Website: https://bitcoin.sipa.jp/miniscript/
更新日期:2026-02-27
版本:1.0
相關文章
- 比特幣腳本語言深度教學 — 深入理解比特幣腳本語言的運作原理、常見腳本類型與進階應用場景。
- MuSig2 多人簽名 — 理解 Schnorr 密鑰聚合與多簽名方案。
- Taproot 全面解析 — 比特幣最新的腳本升級:MAST、BIP-340/341/342。
- Taproot 隱私保護完整教學 — 深入解析 Taproot 如何增強比特幣隱私,包括 MAST、Schnorr 簽名聚合、P2TR 地址類型與實戰應用。
- 比特幣腳本語言深度教學:P2TR、P2WSH 與進階腳本 — 深入探討比特幣腳本語言的進階主題,涵蓋 Pay-to-Taproot(P2TR)、Pay-to-Witness-Script-Hash(P2WSH)的運作原理與實際應用,以及現代比特幣腳本的最新發展。
延伸閱讀與來源
這篇文章對您有幫助嗎?
請告訴我們如何改進:
評論
發表評論
注意:由於這是靜態網站,您的評論將儲存在本地瀏覽器中,不會公開顯示。
目前尚無評論,成為第一個發表評論的人吧!