天天看點

utxo模型_第16講 | 深入區塊鍊技術(八): UTXO與普通賬戶模型

我們在第2講“區塊鍊到底是怎麼運作”一文中,提到了村長給張三轉賬的例子,那裡村長的例子就是UTXO模型的一個簡化版本。

評論區裡有不少留言在問:“為什麼不直接記餘額呢?”看來很多人都對這個問題很感興趣,今天我們就來聊一聊這個話題。

區塊鍊網絡中有兩種記賬模式,除了UTXO模型還有 Account Based 結構,也就是普通賬戶模型,也叫賬戶餘額模型,前者在比特币系的數字貨币中被廣泛使用,後者更多是用在智能合約型的區塊鍊上。

普通賬戶模型

我們先從傳統的賬戶模型出發來聊聊是如何記賬的,假設我們現在有一個支付系統,在這個支付系統中有村長和張三兩個賬戶,村長賬戶裡有100萬,現在要轉賬給張三10萬,這其中涉及的操作是這樣的:

檢查村長的賬戶餘額是否大于10萬;

把村長的賬戶扣除10萬變成90萬,然後發送一筆轉賬消息給張三的賬戶;

張三的賬戶接受到轉賬消息,将張三的賬戶餘額加10萬。

我們可以發現,無論是村長還是張三,都具有一個餘額作為狀态,即目前餘額是記錄在某個地方的,隻需要讀出來即可,這種設計我們叫做賬戶餘額模型。

如果以上三個步驟是在一個中心化系統中,甚至在同一個資料庫中,那将非常簡單,會直接退化成一個事務,我們見到的銀行賬戶、信用卡系統、證券交易系統、各種電商類應用,理财類應用基本都是一個中心化系統中的,最多也就是跨表跨資料庫。

想必這類場景下的設計,各位工程師對此應該是了如指掌的。

如果以上的步驟中,村長和張三的賬戶分屬兩個不同的系統,例如從A銀行到B銀行,就需要經過人民銀行支付系統,即可信任的中心化第三方來做中介。

你可能發現了,在跨行轉賬的這種情況下,是沒有辦法做事務的,是以1和3是不同步的,如果3操作失敗,還需要從2倒退到1的狀态,這個情況叫做沖正交易。

普通賬戶模型具有自定義資料類型的優點,但是卻需要自己設計事務機制,就是上述所說的沖正交易。而接下來所講的UTXO模型則恰恰相反。

UTXO模型

UTXO全稱是:“Unspent Transaction Output”,這指的是:未花費的交易輸出。這裡面三個單詞分别表示 “未花費的”“交易”“輸出”,接下來我來詳細講解一下UTXO的含義。

UTXO的核心設計思路是無狀态,它記錄的是交易事件,而不記錄最終狀态,也就是說隻記錄變更事件,使用者需要根據曆史記錄自行計算餘額。

有點像MySQL中的Binlog,主從模式的情況下,按照Binlog來更新資料,Redis的AOF模式備份模式也是如此,UTXO也是類似的思路。

下面我們按照按照普通賬戶中的例子來重新講解一遍。

如果要記錄交易本身,那麼我們可以構造一筆交易,這筆交易中村長轉賬10萬給張三的同時,90萬轉給自己。

如下所示:

村長 100萬 --> 張三 10萬

--> 村長 90萬

這裡其實有三條子記錄,左邊一條,右邊兩條,左邊叫做輸入,右邊叫做輸出。

輸入和輸出組成了交易,輸入和輸入需要滿足一些限制條件:

任意一個交易必須至少一個輸入、一個輸出;

輸入必須全部移動,不能隻使用部分,是以才産生了第二個輸出指向村長自己;

輸入金額 = 輸出金額之和 + 交易手續費,這裡必須是等式。

對于村長來說,首先構造交易的輸入輸出,滿足上述條件,然後廣播到全網,接收方自行判斷交易是否屬于自己。這裡滿足限制條件構成的交易模型,也就是村長記錄的三條轉賬事件就是UTXO模型。

賬戶餘額模型與UTXO的比較

我們可以歸納出UTXO與普通賬戶模型的一些差別。

存儲空間,UTXO占用空間比賬戶模型高,因為賬戶模型隻記錄最終狀态。

易用性,UTXO比較難處理,賬戶模型簡單容易了解。例如UTXO在使用上,還需要配合高效的UTXO組裝算法,這個算法要求盡可能降低輸入輸出的個數,還要讓“零錢“歸整,算法的複雜度相比賬戶餘額無疑要高。

安全性,UTXO比賬戶模型要高,UTXO本身具備ACID的記賬機制,而賬戶模型需要自行處理,例如重播攻擊。

普通賬戶模型具有較高的自由度,可以讓智能合約有更好的發揮空間,并且它避免了UTXO的複雜組裝邏輯,精度控制上也更為得心應手。

UTXO似乎天然是為數字貨币設計的,具有較高頻次跨賬戶轉移場景都使用UTXO會比較好,考慮到智能合約的普适性,UTXO與智能合約并不能很好地相容,但是這也對開發者的自身水準提出了更高的要求。

區塊鍊中的UTXO模型

我們借用比特币開發者文檔中UTXO模型的圖示,來看看UTXO實際的構造形式。

utxo模型_第16講 | 深入區塊鍊技術(八): UTXO與普通賬戶模型

上圖中,所有的交易都可以找到前向交易,例如TX5的前向交易是TX2,TX2中的Output1作為TX5中的Input0。

意思就是TX2中的付款人使用了Output1中指向的比特币轉移給 TX5 中的收款人,接着TX5中的人又把收到的比特币轉移給了TX6中的收款人,成為了TX6中 Output0。

我們也可以發現,TX6中的收款人還沒有産生TX7交易,也就是說Output0還沒有被花費,

這時候我們終于得到了UTXO的真正語義:Unspent Transaction Output,未花費的交易輸出。

我們這時候可以發現UTXO也同樣能表示餘額,不過是重演計算的方式,它用不同的方式表達了餘額,我們把一個位址上所有的UTXO全部找出來,就是這個位址總的餘額了。

我們還可以發現,無論是TX5還是TX2,都已經成為曆史交易,它們都忠實客觀地記錄了兩筆交易,這兩筆交易代表的是事件,而不是餘額狀态轉移,這是我們看到的最直覺的差別。

我們再來看看一個真實的交易例子。

utxo模型_第16講 | 深入區塊鍊技術(八): UTXO與普通賬戶模型

這是區塊鍊上一筆真實交易的例子,它記錄了一筆450ETP的轉賬記錄。

左邊是輸入,右邊是兩筆輸出,其中第二個輸出是給自己的賬戶,這和我們村長轉賬給張三的例子是一樣的。

下圖是交易解碼為JSON格式的樣子,可以看到Previous_output是放到Inputs數組裡的,意思就是前向輸出作為本次的輸入。

{"hash" : "89e80e14db07c4904a57e2c1efb689bccbbf43942103c1a92166d5c0f27ea3d2","height" : 1093399,"inputs":

[

{"address" : "MLWtmjwCtmK44FMwJMSfAkHaEvnnb2N6HX","previous_output":

{"hash" : "770a72f35d3e3a78bd468949bad649f03b241cf7e2a84cc2d6fdabacdcc47f06","index" : 0},"script" : "[ 304402202b21d7a79276985dc99777b70fd5095796dad58f35e29a019d2cb6cca5df481802205ffab088a6047f5b6382ba02a0eed4e78ab7950fe264d3774e8b0b357a7593d101 ] [ 03ea3462dc01e7b5569e89737211887035f8f1e99e1fe4332181d83daccaa6d917 ]","sequence" : 4294967295}

],"lock_time" : "0","outputs":

[

{"address" : "MGz9yjLLn4AqyraRjSpiP2GmTWKnT3yfiL","attachment":

{"type" : "etp"},"index" : 0,"locked_height_range" : 0,"script" : "dup hash160 [ 63ab0013d183f2592e4b46a358df01e88a09c0b8 ] equalverify checksig","value" : 45000000000},

{"address" : "MLWtmjwCtmK44FMwJMSfAkHaEvnnb2N6HX","attachment":

{"type" : "etp"},"index" : 1,"locked_height_range" : 0,"script" : "dup hash160 [ 8a63941b392771c40f1c15e4374808f6bb464cba ] equalverify checksig","value" : 118082150283}

],"version" : "2"}

我們再看看比特币上的例子:

utxo模型_第16講 | 深入區塊鍊技術(八): UTXO與普通賬戶模型

這一筆比特币交易包含6個輸入,幾十個輸出,交易一共3.5kb,交易的輸入輸出會影響交易大小,比特币的交易費是根據位元組收費的,交易尺寸越大越貴,而交易尺寸主要和輸入輸出的個數有關,也就是說,算法上并不規定輸入輸出的個數,而隻有區塊尺寸限制。

在比特币中将小于100kb的交易稱為标準交易,超過100kb的稱為非标準交易。它的前向input以及生成一個out約占用161~250 bytes 。是以在比特币中,大約的inputs/ouputs的最大數目限制為 100KB/161B ~= 600個。

UTXO的特性及缺點

從計算的角度來說,UTXO具有非常好的并行支付能力,也就是我們上文中所說的如果沒有尺寸限制,一筆交易可以包含任意筆輸入輸出,同時也沒有次序要求,在一筆交易中哪一個UTXO在前,哪個在後面不影響最終結果。

從存儲的角度來說,UTXO具有較好的可裁剪特性,可裁剪性指的是UTXO類型的交易,如果從最老的那一筆UTXO開始截斷資料庫,那麼之前的資料可以删除掉了。

如果想進一步壓縮資料尺寸,可以在任意位置截斷,記錄UTXO對應的交易哈希即可,然後從其他節點擷取并校驗UTXO,這也是SPV輕錢包工作的基礎之一。

以太坊中并沒有使用比特币的這種UTXO設計,這與以太坊的宗旨有關,以太坊的目标是建構通用計算,而比特币是數字貨币,需求不同導緻設計的不同。

V神指出了UTXO的缺陷,一共有三類。

1.可表達的狀态少 。

UTXO隻能是已花費或者未花費狀态,這就沒有給需要任何其它内部狀态的多階段合約或者腳本留出生存空間,這也意味着UTXO隻能用于建立簡單的、一次性的合約,UTXO更像是一種二進制控制位。

2.區塊鍊盲點(Blockchain-blindness)。

UTXO的腳本隻能看到自己這條曆史軌迹,無法看到區塊鍊的資料的全貌,這導緻了功能性擴充受到了限制,我們在花費比特币的過程中需要小心翼翼的組合UTXO,這也導緻了系統狀态邏輯複雜,不适合設計成智能合約的基礎結構。

3.價值盲點(Value-blindness)。

UTXO腳本不能提供非常精細的金額控制,基于賬戶模型的餘額在花費過程中,可以任意的按值存取,它僅取決于程式能表示的最小精度。

而UTXO要求必須全部移動,如果要滿足一個目标值金額,對組合UTXO算法的要求會比較高,采用許多有不同面值的UTXO,一方面要求盡可能地精确,另一方面又要求輸入輸出的數量盡可能的小。

UTXO是比特币上的原生設計,在區塊鍊以前是沒有這種邏輯資料結構,UTXO的出現給了人們看待資料轉移的不同視角,但UTXO不是所有區塊鍊所必需的,公鍊開發過程中的是否選用UTXO模型可以根據業務場景進行判斷。

總結

好了,今天我們分别介紹了普通賬戶模型和UTXO模型,并從不同角度比較了二者的優劣。

從技術選擇上來看,比特币選擇UTXO是為了滿足支付的安全性,以太坊選擇普通賬戶模型是為了智能合約的自由度。

最後留給你一個問題,曆史上UTXO或賬戶模型是否引發過比較嚴重的使用缺陷呢?你可以給我留言,我們一起讨論,感謝你的收聽,我們下期再見。