記錢的兩種方式
想像有兩位朋友,各自用不同的方式管理錢。現金卡拉口袋裡裝著實體鈔票;付款時,她遞出整張鈔票,再等找零。手機銀行小本只盯著手機上一個會上下變動的數字。兩人隨時都清楚自己有多少錢——只是表示方式不同。
每條區塊鏈都面臨同樣的選擇。一筆交易必須更新「誰擁有什麼」,而底層記帳有兩種著名設計。比特幣像現金卡拉那樣思考,即 UTXO 模型;以太坊像手機銀行小本那樣思考,即帳戶模型。兩者並無誰「更正確」——各自在簡潔與靈活之間做了取捨。
UTXO 模型:花鈔票、找零錢
UTXO 是 Unspent Transaction Output(未花費交易輸出) 的縮寫——其實就是「一張你還沒花掉的鈔票」的術語化說法。在 UTXO 模型裡,你的錢包根本不保存餘額,而是保存一堆這樣的鈔票,每張都是一筆被鎖定在你密鑰下的離散幣額。你的「餘額」只是所有未花費鈔票的總和,就像卡拉的財富是口袋裡所有鈔票之和。
付款時,你不能把一張鈔票撕成兩半。你必須把整張 UTXO 當作輸入消耗掉,再建立新的 UTXO 作為輸出——一份給收款人,一份把找零退還給自己,就像卡拉用一張 20 美元鈔票買 14 美元的咖啡,再把 6 美元找零收進口袋。被消耗的鈔票從此永遠「已花費」;新生成的鈔票則成為往後唯一有效的鈔票。如果你沒有一張足夠大的鈔票,只需在同一筆交易裡把幾張較小的鈔票湊在一起當作輸入即可。
Alice wants to pay Bob 0.7 BTC.
Her wallet holds two bills:
INPUTS OUTPUTS
[ 0.5 BTC ] ---+----> [ 0.7 BTC ] -> Bob
[ 0.4 BTC ] ---+ [ 0.2 BTC ] -> Alice (change)
(0.5 + 0.4) - 0.7 = 0.2 left over
The two old bills are now spent.
Bob and Alice each hold one fresh bill.帳戶模型:一個滾動餘額
帳戶模型拋棄了那一堆鈔票,轉而維護一份簡單的帳本:一張巨大的表,把每個地址映射到單一的數字。付款只是這邊減、那邊加——和銀行在兩個帳戶之間挪動數字一模一樣。無需計算找零,也無需湊鈔票,因為從來沒有任何東西被拆成碎片。全世界的餘額都存在同一張共享的表裡,每個全節點都保有一份副本。
Ledger before: Alice: 0.9 Bob: 0.0 Alice pays Bob 0.7: Alice -> 0.9 - 0.7 = 0.2 Bob -> 0.0 + 0.7 = 0.7 Ledger after: Alice: 0.2 Bob: 0.7 Just two numbers changed. No bills, no change.
為防止有人把同一筆付款重放兩次,每個帳戶還帶有一個 nonce——一個隨著每筆發出的交易遞增 1 的計數器。數位簽章把整條指令鎖定在你的密鑰之下,而 nonce 則保證網路按順序處理你的付款,且每筆恰好執行一次。
為什麼選這個而不是那個?
兩種風格各有所長。UTXO 模型在並行與隱私上極為出色:由於每張鈔票相互獨立,許多交易可以同時被校驗,你也能把幣分散到多個全新地址上,讓旁觀者難以將它們關聯起來。它還讓單筆交易的有效性易於獨立驗證——只需確認輸入的鈔票存在且尚未被花費即可。
帳戶模型則在簡潔與表達力上極為出色。一個地址、一個餘額,對人來說很好理解。更重要的是,單一且持續存在的數字,正是智慧合約的理想容身之處:持有資金並記住狀態的程式,需要一個穩定的地方來儲存這些狀態——這正是以太坊選擇帳戶模型的原因。正是這一選擇,讓功能豐富的鏈上應用得以自然地建構。
小結
兩種模型回答的是同一個問題——*誰擁有多少?*——而且一經記錄便不可竄改。它們的差別只在於如何表示價值:要麼是一錢包離散、一次性的鈔票,要麼是一個不斷更新的數字。知道一條鏈用哪種模型,就能看出它的思路:卡拉的現金偏向隱私與並行校驗,小本的銀行 App 偏向簡潔與智慧合約。
接下來,我們將看到網路一開始究竟是如何對這些交易達成一致的——成千上萬的陌生人在沒有裁判的情況下,如何就同一段共享歷史取得共識。這正是共識機制的職責。