🎯 什麼情境該想到我
當你想理解「比特幣帳本到底怎麼記帳、一筆交易如何構成與驗證」時。
⚙️ 怎麼用(理解模型)
- 帳本不存餘額,存 UTXO:Unspent Transaction Output——一堆「還沒被花掉的輸出」。你的「餘額」=你能花的所有 UTXO 總和。
- 交易 = 消耗舊 UTXO(輸入)+ 產生新 UTXO(輸出):輸入引用之前的輸出並用簽章解鎖。
- 找零:輸入通常大於支付額,多的部分轉回自己的新 UTXO(找零)。
- 驗證:節點檢查輸入的 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。
★ 節點怎麼驗證一筆交易
- 每個輸入引用的 UTXO 存在於目前的 UTXO 集合中(沒有被花過)→ 防雙花。
- 每個輸入的簽章能通過該 UTXO 的鎖定條件(通常是:用對應地址的私鑰簽章)。
- 輸入總額 ≥ 輸出總額。
- 格式、大小等規則都符合。
節點維護的是UTXO 集合,而不是每個地址的餘額。驗證一筆交易只需要查 UTXO 集合,不需要回頭掃描整條鏈的歷史。
★ UTXO 模型 vs 帳戶模型
| UTXO(比特幣) | 帳戶(以太坊) | |
|---|---|---|
| 狀態 | 一堆未花費的輸出 | 每個地址一個餘額 |
| 餘額 | 錢包計算出來(加總自己的 UTXO) | 直接存在鏈上 |
| 防雙花 | 天然:一個 UTXO 只能被花一次 | 靠每個帳戶的 nonce(交易序號) |
| 平行驗證 | 容易:不同 UTXO 的交易互不影響 | 較難:同一帳戶的交易有先後順序 |
| 隱私 | 較好:可以每次用新地址 | 較差:一個地址累積所有活動 |
| 複雜狀態(智能合約) | 困難 | 自然 |
以太坊帳戶模型的細節 → 工具-以太坊帳戶與交易。
★ 對軟體設計的啟發:不可變的帳本
UTXO 模型的核心是只新增、不修改:從不「修改餘額」,只「消耗舊的輸出、產生新的輸出」。這個思路在一般系統中也很有用:
- 複式簿記的帳務系統:不直接更新餘額欄位,而是新增分錄;餘額是分錄的加總。好處是可稽核,任何時間點的餘額都能重算。
- 事件溯源:狀態由事件序列推導,事件本身不可變(和領域事件的關係見 領域事件)。
- 冪等與併發:「這個 UTXO 已被花掉」是一個清楚的狀態轉換,天然防止重複處理——和用條件更新做狀態機的思路相同(見 工具-用條件更新做狀態機冪等)。
🧪 我實際套用的紀錄
- 2026-07-15:(待填)
⚠️ 注意
-
UTXO 天然防雙花(一個 UTXO 只能被花一次)、利於平行驗證,但表達複雜狀態較麻煩。
-
UTXO 太碎會讓交易變貴:手續費按交易大小計算,而每個輸入都會增加大小。錢包裡有一百個小額 UTXO,一次付款可能要帶上幾十個輸入。手續費低的時候可以先把小額 UTXO 合併。
🔗 相關工具
- 工具-金鑰地址與錢包 —— 前一層:UTXO 的「解鎖」靠的就是這張講的私鑰簽章,所有權怎麼表達先看它
- 工具-去中心化共識與PoW —— 後一層:交易構造好之後,靠 PoW 共識決定它進不進得了帳本、能不能防雙花