🎯 什麼情境該想到我

當你想理解「比特幣帳本到底怎麼記帳、一筆交易如何構成與驗證」時。

⚙️ 怎麼用(理解模型)

  1. 帳本不存餘額,存 UTXO:Unspent Transaction Output——一堆「還沒被花掉的輸出」。你的「餘額」=你能花的所有 UTXO 總和。
  2. 交易 = 消耗舊 UTXO(輸入)+ 產生新 UTXO(輸出):輸入引用之前的輸出並用簽章解鎖。
  3. 找零:輸入通常大於支付額,多的部分轉回自己的新 UTXO(找零)。
  4. 驗證:節點檢查輸入的 UTXO 存在、未被花、簽章有效、輸入 ≥ 輸出(差額為手續費)。

對照:以太坊用「帳戶餘額模型」(見 精通以太坊),與 UTXO 是兩種記帳哲學。

★ 走一遍:一筆有找零的交易

Alice 的錢包裡有兩個 UTXO:0.5 BTC 和 0.3 BTC。她要付 Bob 0.7 BTC:

輸入                              輸出
─────────────────────             ─────────────────────────
UTXO #1  0.5 BTC  (Alice 簽章) ─┐  ┌─ 0.7   BTC → Bob 的地址
                                ├──┤
UTXO #2  0.3 BTC  (Alice 簽章) ─┘  └─ 0.099 BTC → Alice 的新地址(找零)

輸入總額 0.8 − 輸出總額 0.799 = 0.001 BTC → 手續費(給礦工)
  • UTXO 只能整個花掉:0.5 不夠付 0.7,所以兩個都要用,多出來的 0.1 要自己找零。
  • 手續費是隱含的:交易裡沒有「手續費」欄位,它就是「輸入 − 輸出」的差額。忘記寫找零輸出,差額會全部變成手續費——這是真實發生過的昂貴錯誤。
  • 交易完成後,UTXO #1、#2 消失(被花掉),產生兩個新的 UTXO:Bob 的 0.7 和 Alice 的 0.099。

★ 節點怎麼驗證一筆交易

  1. 每個輸入引用的 UTXO 存在於目前的 UTXO 集合中(沒有被花過)→ 防雙花。
  2. 每個輸入的簽章能通過該 UTXO 的鎖定條件(通常是:用對應地址的私鑰簽章)。
  3. 輸入總額 ≥ 輸出總額。
  4. 格式、大小等規則都符合。

節點維護的是UTXO 集合,而不是每個地址的餘額。驗證一筆交易只需要查 UTXO 集合,不需要回頭掃描整條鏈的歷史。

★ UTXO 模型 vs 帳戶模型

UTXO(比特幣)帳戶(以太坊)
狀態一堆未花費的輸出每個地址一個餘額
餘額錢包計算出來(加總自己的 UTXO)直接存在鏈上
防雙花天然:一個 UTXO 只能被花一次靠每個帳戶的 nonce(交易序號)
平行驗證容易:不同 UTXO 的交易互不影響較難:同一帳戶的交易有先後順序
隱私較好:可以每次用新地址較差:一個地址累積所有活動
複雜狀態(智能合約)困難自然

以太坊帳戶模型的細節 → 工具-以太坊帳戶與交易。

★ 對軟體設計的啟發:不可變的帳本

UTXO 模型的核心是只新增、不修改:從不「修改餘額」,只「消耗舊的輸出、產生新的輸出」。這個思路在一般系統中也很有用:

  • 複式簿記的帳務系統:不直接更新餘額欄位,而是新增分錄;餘額是分錄的加總。好處是可稽核,任何時間點的餘額都能重算。
  • 事件溯源:狀態由事件序列推導,事件本身不可變(和領域事件的關係見 領域事件)。
  • 冪等與併發:「這個 UTXO 已被花掉」是一個清楚的狀態轉換,天然防止重複處理——和用條件更新做狀態機的思路相同(見 工具-用條件更新做狀態機冪等)。

🧪 我實際套用的紀錄

  • 2026-07-15:(待填)

⚠️ 注意

  • UTXO 天然防雙花(一個 UTXO 只能被花一次)、利於平行驗證,但表達複雜狀態較麻煩。

  • UTXO 太碎會讓交易變貴:手續費按交易大小計算,而每個輸入都會增加大小。錢包裡有一百個小額 UTXO,一次付款可能要帶上幾十個輸入。手續費低的時候可以先把小額 UTXO 合併。

🔗 相關工具