UTXO 模型與帳戶模型深度比較:跨鏈原子交換、DLC 規格差異與實例分析

從形式化定義出發,深入分析比特幣 UTXO 模型與以太坊帳戶模型的技術原理與資料結構差異。通過跨鏈原子交換(Atomic Cross-Chain Swap)和離散對數合約(DLC)兩個實際應用場景,展示兩種模型在實作上的具體差異與取捨。涵蓋 HTLC 的密碼學原理、Pedersen 承諾、DLC 的 CET 構造、Ark 虛擬 UTXO 等核心主題。

UTXO 模型與帳戶模型深度比較:跨鏈原子交換、DLC 規格差異與實例分析

概述

比特幣採用未花費交易輸出(Unspent Transaction Output, UTXO)模型作為其核心會計架構,與以太坊等智慧合約平台所採用的帳戶模型(Account Model)形成根本性的架構差異。本篇文章從形式化定義出發,深入分析兩種模型的技術原理、資料結構設計、交易驗證邏輯,並通過跨鏈原子交換(Atomic Cross-Chain Swap, ACS)與離散對數合約(Discreet Log Contract, DLC)兩個實際應用場景,展示兩種模型在實作上的具體差異與取捨。

理解 UTXO 模型與帳戶模型的差異,不僅是掌握比特幣底層設計的關鍵,更是評估比特幣與其他區塊鏈系統互操作性(Interoperability)的重要基礎。兩種模型的設計哲學反映了截然不同的安全性假設與效能考量。

UTXO 模型的形式化定義

基本資料結構

UTXO 模型的核心是未花費輸出集合。比特幣網路中的每一筆交易都會消耗(Consume)先前交易的輸出,並產生新的輸出。一個 UTXO 的形式化定義如下:

UTXO = {
    txid: TransactionHash,     // 產生此輸出的交易 ID
    vout: OutputIndex,         // 輸出在交易中的索引(0, 1, 2, ...)
    scriptPubKey: Script,      // 鎖定腳本,定義花費條件
    value: SatoshiAmount,      // 輸出金額,單位為聰(1 BTC = 10^8 聰)
    coinbase: Boolean,         // 是否為 Coinbase 交易(新區塊獎勵)
    height: BlockHeight        // 所在區塊高度
}

比特幣網路的完整狀態是 UTXO 集合的快照(Snapshot),而非餘額的連續記錄。這種設計的關鍵特性在於:每個 UTXO 只能被花費一次,不存在「餘額」的概念,只有「未花費的輸出」集合。

UTXO 的花費條件

UTXO 的花費條件由 scriptPubKey(又稱鎖定腳本)定義。最常見的形式是 P2PKH(Pay to Public Key Hash):

scriptPubKey: OP_DUP OP_HASH160 <PubKeyHash> OP_EQUALVERIFY OP_CHECKSIG

要花費此輸出,必須提供對應的簽名與公鑰:

scriptSig: <Signature> <PublicKey>

比特幣腳本語言(Bitcoin Script)是一種基於堆疊的 Forth-like 語言,支援多種操作碼。P2PKH 的執行邏輯如下:

  1. scriptSig 中的 Signature 和 PublicKey 壓入堆疊
  2. 執行 OP_DUP:複製堆疊頂層的 PublicKey
  3. 執行 OP_HASH160:對 PublicKey 計算 RIPEMD-160(SHA-256(...))
  4. 壓入堆疊
  5. 執行 OP_EQUALVERIFY:比較兩個哈希值,若相等則繼續,否則失敗
  6. 執行 OP_CHECKSIG:驗證簽名是否對交易哈希有效

UTXO 集合的狀態特性

UTXO 集合具有以下形式化特性:

封閉性(Closure):UTXO 集合的變化完全由交易決定。交易輸入總是引用先前交易的輸出,交易的輸出要么被後續交易引用,要么留在 UTXO 集合中成為新的未花費輸出。沒有任何輸出可以「憑空產生」。

原子性(Atomicity):UTXO 的花費是不可分割的。一個 UTXO 要么被完整花費,要么完全不被花費。不存在「部分花費」的概念——如果要花費部分金額,必須將剩餘金額以新的 UTXO 形式發送回自己的位址。

無副作用(No Side Effects):UTXO 的花費條件僅涉及輸入和輸出,不會觸發任何外部狀態變化。這使得 UTXO 的驗證邏輯是確定性的(Deterministic)和可靜態分析的(Statically Analyzable)。

並行性(Parallelism):UTXO 的驗證天然支持平行處理。多個無關聯的 UTXO 可以被獨立地驗證,因為它們之間沒有共享狀態依賴。這是 UTXO 模型相較於帳戶模型的重要優勢。

UTXO 驗證平行性示意:

交易 A 花費 {UTXO-1, UTXO-2} → 可在核心 1 驗證
交易 B 花費 {UTXO-3, UTXO-4} → 可在核心 2 平行驗證
交易 C 花費 {UTXO-5}         → 可在核心 3 平行驗證

帳戶模型驗證(對比):
帳戶 A 餘額變動              → 需獲取帳戶 A 的鎖
帳戶 B 餘額變動              → 需獲取帳戶 B 的鎖
(若 A 和 B 為同一帳戶,則需串列處理)

帳戶模型的形式化定義

基本資料結構

帳戶模型將區塊鏈狀態定義為帳戶餘額的映射。與 UTXO 不同,帳戶模型維護的是帳戶的「現狀」,而非交易的歷史集合:

AccountModel = Map<Address, AccountState>

AccountState = {
    balance: TokenAmount,           // 帳戶餘額
    nonce: TransactionCount,       // 已執行交易計數(防止重放攻擊)
    codeHash: Bytes,                // 關聯的合約程式碼哈希(僅適用於合約帳戶)
    storageRoot: MerkleRoot,       // 儲存狀態的 Merkle 樹根(僅適用於合約帳戶)
}

以太坊的帳戶模型同時支援外部擁有帳戶(EOA, Externally Owned Account)和合約帳戶(Contract Account)。兩者的根本區別在於:EOA 的 codeHash 為空字串,而合約帳戶的 codeHash 指向一段 EVM 位元組碼。

交易的原子狀態轉換

帳戶模型的交易執行會導致原子性的狀態轉換:

StateTransition(tx, state):
    // 1. 驗證簽名與 nonce
    assert tx.nonce == state[tx.from].nonce
    assert verify(tx.signature, tx.message, tx.from)
    
    // 2. 扣除發送方餘額
    assert state[tx.from].balance >= tx.value + tx.gasLimit * tx.gasPrice
    state[tx.from].balance -= tx.value + tx.gasLimit * tx.gasPrice
    
    // 3. 增加接收方餘額
    if tx.to is EOA or Contract:
        state[tx.to].balance += tx.value
    
    // 4. 執行合約程式碼(如有)
    if tx.to is Contract:
        result = execute(tx.data, state, tx.gasLimit)
        state[tx.gasLimit].balance += result.unusedGas * tx.gasPrice
    
    // 5. 更新 nonce
    state[tx.from].nonce += 1
    
    return state

帳戶模型的關鍵特性是狀態轉換的順序依賴性。兩個帳戶之間的交易順序會影響最終的狀態,這使得帳戶模型的驗證必須考慮狀態的歷史順序,而 UTXO 模型的驗證則只需考慮當前的 UTXO 集合快照。

UTXO 與帳戶模型的核心差異分析

資料儲存複雜度

UTXO 模型和帳戶模型在資料儲存上呈現截然不同的特性。UTXO 集合的大小與交易輸出數量直接相關,而帳戶狀態的大小與獨立帳戶數量相關。

截至 2024 年,比特幣的 UTXO 集合約包含 7,000 萬至 8,000 萬個未花費輸出。若每個 UTXO 以約 60 位元組儲存,完整 UTXO 集合約為 4-5 GB。然而,UTXO 集合支援高效的增量驗證(Merkle proof),客戶端只需下載區塊頭(約 80 位元組/區塊)即可驗證交易包含性。

帳戶模型的狀態儲存則面臨「狀態爆炸」問題。以太坊的完整狀態(World State)包含所有帳戶的餘額、程式碼和儲存。以太坊狀態嘗試(State Trie)的規模已超過數十 GB,且隨著智慧合約的普及持續增長。

隱私特性的差異

UTXO 模型和帳戶模型在隱私保護上各有優劣。

UTXO 模型的隱私優勢在於:每個 UTXO 是獨立的,花費一個 UTXO 不會直接透露帳戶的全部持倉。使用者可以將不同來源的 UTXO 分別花費,實現一定程度的資金隔離。此外,CoinJoin、PayJoin 等隱私增強技術天然適合 UTXO 模型,因為多個參與者可以將各自的 UTXO 合併後再拆分,模糊資金流向。

帳戶模型的隱私劣勢在於:每次交易都會直接反映帳戶的餘額變動。任何觀察者都可以追蹤特定帳戶的全部資金流向。然而,帳戶模型支援更複雜的密碼學隱私機制,例如ZK-SNARKs(Zero-Knowledge Succinct Non-Interactive Arguments of Knowledge),這在 UTXO 模型中的整合相對困難。

交易驗證效率

UTXO 模型的交易驗證是「無狀態」的:只需確認輸入引用的 UTXO 存在於當前集合中,且腳本滿足執行條件。驗證過程不需要訪問區塊鏈的完整歷史。

帳戶模型的交易驗證需要訪問帳戶的當前狀態(餘額和 nonce),並在執行過程中更新狀態。這意味著驗證節點必須維護完整的狀態資料庫,且交易處理是「有狀態」的。

從平行處理的角度,UTXO 模型的優勢明顯。獨立的 UTXO 可以被平行驗證,不存在鎖競爭問題。帳戶模型中的狀態更新則可能產生資料競賽(Race Condition),需要精確的鎖機制或順序處理。

跨鏈原子交換:UTXO 與帳戶模型的交互

原子交換的密碼學原理

跨鏈原子交換(Atomic Cross-Chain Swap, ACS)是一種在不依賴信任第三方的情況下,在兩條不同區塊鏈之間進行去中心化交換的協議。原子交換的核心機制是 HTLC(Hash Time-Locked Contract),利用密碼學時間鎖和哈希鎖確保交換的原子性。

最基本的原子交換涉及比特幣(UTXO 模型)和以太坊(帳戶模型)。假設 Alice 持有比特幣,Bob 持有以太幣,雙方希望進行交換。原子交換的流程如下:

  1. Alice 產生秘密 s:Alice 生成一個隨機數 s,計算 h = H(s)(哈希鎖)。
  2. Alice 在比特幣網路部署 HTLC:Alice 創建一筆比特幣交易,鎖定她的比特幣。這個 UTXO 的花費條件是:Bob 提供 s 的簽名,或者 Alice 在超時後取回。
  3. Bob 在以太坊部署對應合約:Bob 部署一個以太坊合約,鎖定他的以太幣。合約的解鎖條件是:提供 s 使得 H(s) = h,或者 Bob 在超時後取回。
  4. Bob 揭露秘密:Bob 觀察到比特幣 HTLC 的存在(區塊鏈可見性),在以太坊合約中提交 s,從而解鎖 Alice 的以太幣。此時 s 公開。
  5. Alice 提現比特幣:Alice 看到 s 後,在比特幣 HTLC 中使用 s 提現比特幣。

整個過程的原子性由以下不變式保證:

Invariant: 
  - 若 Bob 成功提現比特幣(提交 s),則 Alice 可在比特幣網路使用 s 提現
  - 若 Bob 未提現比特幣(超時),則雙方可各自取回原始資產
  - 無論哪種情況,雙方都不會損失資產

UTXO 模型的 HTLC 實作

比特幣的腳本語言支援 HTLC 的直接實作:

# Alice 部署的 HTLC(比特幣)
scriptPubKey_A:
    OP_HASH256 <h> OP_EQUAL
    OP_IF
        # 條件 1: Bob 提供原像 s,且有 Bob 簽名
        <Bob_PubKey>
    OP_ELSE
        # 條件 2: 60 個區塊後,Alice 可重新聲明
        60 OP_CHECKSEQUENCEVERIFY OP_DROP
        <Alice_PubKey>
    OP_ENDIF
    OP_CHECKSIG

scriptSig_Bob:
    <Bob_Signature> <s>

關鍵參數說明:

比特幣的 HTLC 執行具有確定性:給定相同的輸入(交易上下文和堆疊元素),比特幣腳本引擎的執行結果總是確定的。這是 UTXO 模型無副作用特性的直接體現。

帳戶模型的 HTLC 實作(Solidity)

以太坊的 HTLC 實作則完全不同,因為合約帳戶支援有狀態的執行:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract HTLC {
    address payable public sender;
    address payable public recipient;
    bytes32 public hashlock;           // h = keccak256(s)
    uint256 public timelock;           // 區塊高度形式的時間鎖
    uint256 public amount;             // 鎖定金額
    string public secret = "";         // 秘密原像(鎖定後公開)
    bool public withdrawn = false;     // 是否已提現
    bool public refunded = false;      // 是否已退款
    bool public isOpen = true;         // 合約是否處於開啟狀態

    event Withdrawn(string _secret);
    event Refunded();

    modifier onlyOpen() {
        require(isOpen, "Contract is closed");
        _;
    }

    constructor(
        address payable _recipient,
        bytes32 _hashlock,
        uint256 _timelock
    ) payable {
        require(_timelock > block.number, "Timelock must be in future");
        sender = payable(msg.sender);
        recipient = _recipient;
        hashlock = _hashlock;
        timelock = _timelock;
        amount = msg.value;
    }

    function withdraw(string memory _secret) external onlyOpen {
        require(!withdrawn, "Already withdrawn");
        require(msg.sender == recipient, "Only recipient can withdraw");
        require(
            keccak256(abi.encodePacked(_secret)) == hashlock,
            "Invalid secret"
        );
        
        secret = _secret;
        withdrawn = true;
        isOpen = false;
        
        emit Withdrawn(_secret);
        recipient.transfer(amount);
    }

    function refund() external onlyOpen {
        require(!withdrawn, "Already withdrawn");
        require(msg.sender == sender, "Only sender can refund");
        require(block.number >= timelock, "Timelock not expired");
        
        refunded = true;
        isOpen = false;
        
        emit Refunded();
        sender.transfer(amount);
    }
}

UTXO 與帳戶模型原子交換的關鍵差異

比特幣和以太坊在原子交換實作上的差異,深刻反映了 UTXO 模型與帳戶模型的根本差異:

特性比特幣 UTXO以太坊帳戶
合約類型無狀態腳本(Script)有狀態合約(Contract)
狀態儲存僅存於交易輸出(UTXO)存於合約存儲(Storage)
執行確定性完全確定性取決於合約邏輯
時間鎖粒度區塊高度(相對/絕對)區塊高度
氣炸(Gas)無(費用固定)有(動態定價)
秘密揭露時機解鎖時自動揭露需明確觸發事件
交易大小固定(約 250-300 位元組)可變(取決於合約複雜度)

以太坊 HTLC 的最大風險在於「氣炸耗盡」(Gas Exhaustion)。如果合約邏輯在執行過程中消耗過多 Gas,整個交易會 revert,已執行的狀態變更也會回滾。這在比特幣 UTXO 模型中不存在——比特幣腳本的執行要么成功要么失敗,不會有部分執行的概念。

比特幣的原子交換則面臨另一個實務挑戰:HTLC 的交易大小固定,但多個 HTLC 的組合可能導致複雜的多重簽名交易,增加區塊空間費用。

DLC 規格差異:UTXO 模型的應用場景

DLC 的基本概念

離散對數合約(Discreet Log Contract, DLC)是一種利用比特幣預言機(Oracle)機制,在比特幣區塊鏈上實現基於外部事件結果的條件化支付的智慧合約形式。DLC 由 MIT 數位貨幣 Initiative 的 Tadge Dryja 於 2017 年提出,其核心創新在於:即使智能合約的邏輯完全在鏈下執行,鏈上仍能實現不可欺騙的結算。

DLC 的安全性完全依賴於離散對數問題(ECDLP)的計算困難性,這與比特幣簽名機制相同。

DLC 的 UTXO 模型實作

DLC 在比特幣上以一組特殊構造的交易形式實作,而非像以太坊那樣以帳戶模型的合約形式存在。具體來說,DLC 包含以下交易集合:

CET(Contract Execution Transaction)

每個可能的結算結果對應一個 CET。每個 CET 的花費條件如下:

CET_n scriptPubKey:
    # 由於 CECEP(Covenant ECDSA Claim Execution Protocol),
    # CET 只能在特定時間後花費
    <timeout> OP_CHECKLOCKTIMEVERIFY OP_DROP
    
    # 兩種花費方式:
    # 方式 1: Alice 單方面關閉(Oracle 未及時公告)
    # 方式 2: 雙方聯名簽名(Oracle 公告結果後結算)

    OP_IF
        <Alice_PubKey> <Bob_PubKey> 2 OP_CHECKMULTISIG
    OP_ELSE
        <Refund_Script>  # 退款腳本
    OP_ENDIF

每個 CET 都是一個獨立的 UTXO,其 scriptPubKey 定義了花費條件。在 DLC 建立時,雙方將各自需要的 CET 對應的 UTXO 預先簽署(但不上鏈),並將這些已簽署交易交換保存。直到 Oracle 公告結果後,雙方才廣播對應的 CET 完成結算。

這種設計的關鍵特性是:DLC 的所有交易都是預先計算好的,Oracle 只需對結果簽名,無需見證整個交易過程。這大幅降低了對 Oracle 的信任需求和通訊複雜度。

DLC 與以太坊智慧合約的規格差異

DLC 和以太坊智慧合約在設計哲學和技術實作上存在根本性差異:

特性比特幣 DLC(UTXO)以太坊合約(帳戶)
執行模型離線計算,鏈上驗證鏈上執行
狀態管理無內在狀態(純交易組合)合約存儲(State)
邏輯複雜度受腳本語言限制(環路禁用)可程式性高(圖靈完整)
結果宣告Oracle 對結果簽名合約直接讀取外部數據
隱私性結算前結果不可見合約狀態可查詢
可升級性需重建 DLC可設計代理合約
Gas 效率高(結算交易費用固定)低(執行複雜度影響費用)
失敗模式退款交易(預先簽署)revert(狀態回滾)

DLC 的最顯著優勢是隱私性。在 Oracle 正式公告結果之前,所有未執行的 CET 都保持未廣播狀態,因此外部觀察者無法從區塊鏈得知 DLC 的具體內容和當前狀態。這與以太坊合約的狀態完全透明形成對比。

DLC 的另一個優勢是失敗模式的可預測性。雙方在建 DLC 時會預先簽署退款交易(Refund Transaction),確保在超時或 Oracle 失效時可以安全退出。以太坊合約的失敗(revert)則可能導致部分狀態更新,需要精心設計的重入鎖(Reentrancy Guard)來防止攻擊。

DLC 的實際應用實例

DLC 的典型應用場景是比特幣價格預言機結算。例如,Alice 和 Bob 對比特幣的日收盤價進行對賭:

事件定義:
- 事件 ID: E = H("BTC/USD_price_2024-12-31_close")
- 結果範圍: R = {<$50000, $50000-$60000, $60000-$70000, >$70000}

Oracle:
- Schnorr 公鑰: P_Oracle = x × G
- 公告簽名: σ = x × H(E || result_i)
- 可驗證簽名: (r, s) where s = k^(-1)(H(m) + x·r) mod n

DLC 結構(4 個結果分支):
- CET_0: 若 price < $50000 → Alice 贏
- CET_1: 若 $50000 ≤ price < $60000 → Bob 贏
- CET_2: 若 $60000 ≤ price < $70000 → Alice 贏
- CET_3: 若 price ≥ $70000 → Bob 贏

每個 CET 的交易輸出:
CET_0: <Alice_PubKey> 2 OP_CHECKMULTISIGVERIFY
CET_1: <Bob_PubKey> 2 OP_CHECKMULTISIGVERIFY
CET_2: <Alice_PubKey> 2 OP_CHECKMULTISIGVERIFY
CET_3: <Bob_PubKey> 2 OP_CHECKMULTISIGVERIFY

這個 DLC 中共有 4 個 CET(離散對數合約的「離散」由此而來——結果空間是離散的而非連續的)。每個 CET 都是一個獨立的 UTXO,在建 DLC 時雙方會預先交換對每個 CET 的部分簽名(2-of-2 多重簽名)。

UTXO 模型的擴展:Ark 虛擬 UTXO

vUTXO 的設計動機

傳統 UTXO 模型的挑戰之一是其無狀態特性難以支援複雜的狀態邏輯。Ark 協議提出的虛擬 UTXO(vUTXO)概念,在保留 UTXO 模型安全特性的同時,引入了有狀態的虛擬層。

Ark vUTXO 的核心思想是:將狀態存儲在鏈下,而僅將狀態承諾(Commitment)記錄在比特幣 UTXO 中。這與閃電網路(Lightning Network)的通道管理模式類似,但提供了更通用的虛擬化框架。

vUTXO 的承諾結構

Ark 的 vUTXO 使用比特幣腳本的 MAST(Merkelized Abstract Syntax Tree)結構來承諾虛擬 UTXO 的狀態:

vUTXO Commitment:
- vUTXO Root Hash: H(vUTXO_1 || vUTXO_2 || ... || vUTXO_n)
- 每個 vUTXO 包含:
  {
    amount: SatoshiAmount,
    recipient: BitcoinAddress,
    expiry: BlockHeight,         // 虛擬 UTXO 過期高度
    prev_vout: Previous_vUTXO,    // 引用前一個虛擬 UTXO
    next_hash: Next_Commitment    // 下一個狀態承諾哈希
  }

比特幣 UTXO(Floor UTXO):
- 由 Ark Service Provider(ASP)控制
- 鎖定脚本:
  OP_HASH256 <vUTXO_Root> OP_EQUAL
  OP_IF
      # 條件 1: ASP 提供原像(清理週期)
      <ASP_Sig>
  OP_ELSE
      # 條件 2: 持有者聲明(轉移到新 ASP 或直接鏈上)
      <Holder_Conditional_Script>
  OP_ENDIF

這種雙層結構使得比特幣區塊鏈只見證「承諾的快照」,而完整的 vUTXO 狀態由 ASP 在鏈下維護。當使用者希望退出 Ark 協議時,只需提供對應 vUTXO 的存在性證明(Membership Proof),即可將 vUTXO 轉換為真實的比特幣 UTXO。

結論

UTXO 模型與帳戶模型代表了區塊鏈狀態管理的兩種根本範式。UTXO 模型的無狀態、確定性和平行驗證優勢,使其成為比特幣這樣注重安全性和簡潔性的系統的理想選擇。帳戶模型的狀態表達力和程式化能力,則為以太坊等智慧合約平台提供了更靈活的設計空間。

在跨鏈原子交換場景中,UTXO 模型與帳戶模型的差異體現在:比特幣的 HTLC 以確定的無狀態腳本形式存在,而以太坊的 HTLC 以有狀態合約形式存在。這一差異導致兩者在 Gas 消耗、失敗模式和隱私特性上的顯著不同。

在 DLC 應用場景中,UTXO 模型的離散化設計天然支援「結果離散化」的 DLC 語義,且 DLC 的無內在狀態特性提供了極強的隱私保證。以太坊的連續狀態合約則更適合需要複雜狀態轉換的應用,但犧牲了 UTXO 模型的確定性安全屬性。

理解這兩種模型的優劣,對於設計跨鏈互操作性解決方案和評估比特幣 Layer 2 擴展方案(如 Ark vUTXO)的設計取捨具有重要價值。

延伸閱讀與來源

這篇文章對您有幫助嗎?

評論

發表評論

注意:由於這是靜態網站,您的評論將儲存在本地瀏覽器中,不會公開顯示。

目前尚無評論,成為第一個發表評論的人吧!