區塊鏈賬號體系之UTXO模型

我的博客,歡迎大家捧場

生活類比

首先看這個名詞UTXO (Unspent Transaction Output, “未花費事務輸出”),老實說,第一次看到這個術語的時候,一時之間真是有些懵,如果說是未花費的余額還能理解,我錢包里有1000,花了200,還有800未花費,這是很符合通常的理解邏輯的,可這個未花費的“事務輸出”是個什么意思,實際上,這與比特幣中的交易事務結構是很有關系的。為了讓大家更容易理解,我們暫且先不來解析這個交易數據結構,讓我們進入到一個倉庫,我們知道倉庫的主要業務就是進和出,倉庫也會把日常的進出流水賬記錄下來, 為了查詢統計方便, 除了流水賬通常還會匯總一 份庫存表出來,舉例如下:

image.png

以上圖為例,這是從2017-8- 1倒2017-8- 5之間,倉庫記錄的出入流水賬, 為了統計方便,倉庫還匯總保存了一份每天的庫存日報表,如下:

image.png

每天倉庫在需要出庫的時候,只要查看一下庫存日報表就知道數量是否足夠了,比如2017-8-3需要出庫15支毛筆,此時查看庫存表發現毛筆的庫存量有30支,足夠發出,于是就將庫存表中的毛筆數量減掉15,并且將出庫明細記錄在流水賬中。然而,這里有一個問題,庫存日報表是另外編制保存的,那就有可能發生數據不一致的情況,比如2017-8-2時毛筆的庫存本來是30卻誤寫為20,這樣導致后續的賬務就都是錯的了。因此在有些系統中,為了防止出現這樣的不一致,索性不再另外保存庫存表,而只是出一張視圖統計(邏輯統計,并非實際去保存這樣一個統計比特幣中的交易事務過程與.上述的庫存進出是很相像的,某個錢包地址中轉入了一筆比特幣,然后這個地址又向其他錢包地址轉出了一筆比特幣,這些不斷發生的入和出跟倉庫的進出是異曲同工的。然而,在比特幣中并沒有去保存份“庫存表 ”每當“出庫”的時候也并不是去“庫存表”中進行扣除,而是直接消耗“入庫記錄”,也就是說在出庫的時候就去找有沒有之前的入庫記錄拿來扣除,比如2017-8-3時需要出庫15支毛筆,此時系統就會去搜索之前的入庫記錄,發現有2017-8-1和2017-8-2分別有一筆數量為10和20的入庫記錄,為了滿足15的發出數量,首先可以消耗掉10的這一筆,然后從20的這筆再消耗掉5支, 判斷成功后, 系統會直接產生一條數量為10的出庫記錄和數量為5的出庫記錄,按這樣的方法,將每一筆入和出都對應了起來。在比特幣的交易事務結構中,“入”就是指金額轉入,“出”就是指金額轉出,為了讓大家對這種金額轉入與轉出有一個更加通俗的理解,我們來看一幅 示意圖:

image.png

上圖展示 了比特幣中的交 易事務結構,在比特幣的交易事務數據中, 存儲的就是這樣的輸入和輸出,相當于倉庫中的進出流水賬,并且“輸入”和“輸出’彼此對應,或者更準確地說,“輸入”就是指向之前的“ 輸出”,我們解釋一下圖中發生的交易事務。

  • 001號交易為Coinbase交易,也就是挖礦交易,在這個交易中,“輸入”部分沒有對應的“輸出”,而是由系統直接獎勵發行比特幣,礦工Alice得到了12.5個比特幣的獎勵,放在001號交易的“輸出” 部分。此時,對于Alice來說, 擁有了這12.5個比特幣的支配權,這12.5個比特幣的輸出可以作為下一筆交易的“輸入”,顧名思義,這筆“輸出”就稱之為是Alice的未花費輸出,也就是Alice的UTXO的意思。

  • 002號交易中,Alice轉 賬6比特幣到Bob的地址,Alice找到 了自己的UTXO (如果Alice不止一筆UTXO,可以根據一定的規則去選用,比如將小金額的先花費掉)。由于只需要轉賬6比特幣,可是UTXO中卻有12.5個,因此需要找零6.5個到自己的地址中,由此產生了002號中的交易輸出,注意,在002號交易輸出中的Alice地址是可以和001號中的Alice地址不一樣的,只要都是屬于Alice自己的錢包地址就可以。

  • 003號交易中,Bob轉賬了2比特幣到Lily的地址,過程與002號交易相同,就不再贅述了。相信大家看到這里,已經基本理解了所謂的UTXO是什么意思,我們再來總結一下。

1)比特幣的交易中不是通過賬戶的增減來實現的,而是一筆筆關聯的輸入/輸出交易事務。

2)每一筆的交易都要花費“輸入”,然后產生“輸出”,這個產生的“輸出”就是所謂的“未花費過的交易輸出”,也就是UTXO。每一筆交易事務都有一個唯一的編號,稱為交易事務ID,這是通過哈希算法計算而來的,當需要引用某一筆交易事務中的“輸出”時,主要提供交易事務ID和所處“輸出”列表中的序號就可以了。

3)由于沒有賬戶的概念,因此當“輸入”部分的金額大于所需的“輸出”時,必須給自己找零,這個找零也是作為交易的一部分包含在‘輸出”中。有朋友會問:這個UTXO的意思是明白了,可是就這么一條條的“輸入”和“輸出怎么證明哪一條UTXO是屬于誰的呢?

在比特幣中,是使用輸入腳本和輸出腳本程序實現的,有時候也稱為“鎖定腳本”和“解鎖腳本”。簡單地說,就是通過“鎖定腳本”,利用私鑰簽名解鎖自己的某一條UTXO (也就是之前的“輸出”),然后使用對方的公鑰鎖定新的“輸出”,成功后,這筆新的“輸出”就成為了對方的UTXO。同樣,對方也可以使用“鎖定腳本”和“解鎖腳本”來實現轉賬。這個腳本程序其實本質上就可以看成是比特幣中的數字合約,這也是為什么比特幣被稱為可編程數字貨幣的原因,它的轉入/轉出或者說輸入/輸出是通過腳本程序的組合來自動實現的,實現過程中還使用到了私鑰和公鑰,也就是公開密鑰算法,所以比特幣還稱為可編程加密數字貨幣。

具體模型

比特幣的區塊鏈由一個個區塊串聯構成,而每個區塊又包含一個或多個交易。
任何一個交易,它總是由若干個輸入(Input)和若干個輸出(Output)構成,一個Input指向的是前面區塊的某個Output,只有Coinbase交易(礦工獎勵的鑄幣交易)沒有輸入,只有憑空輸出。所以,任何交易,總是可以由Input溯源到Coinbase交易。

這些交易的Input和Output總是可以串聯起來:

┌─────────────┐     ┌─────────────┐     ┌─────────────┐     ┌─────────────┐
│Block #1     │     │Block #2     │     │Block #3     │     │Block #4     │
│┌──┬────┬───┐│     │┌──┬────┬───┐│     │┌──┬────┬───┐│     │┌──┬────┬───┐│
││CB│50.0│OUT├┼──┐  ││CB│50.0│OUT├┼──┐  ││CB│50.0│OUT├┼──┐  ││CB│50.0│OUT││
│└──┴────┴───┘│  │  │└──┴────┴───┘│  │  │└──┴────┴───┘│  │  │└──┴────┴───┘│
│             │  │  │┌──┬────┬───┐│  │  │┌──┬────┬───┐│  │  │┌──┬────┬───┐│
│             │  │  ││  │8.70│OUT├┼──┼──>│IN│    │   ││  └──>│IN│25.0│OUT││
│             │  └──>│IN├────┼───┤│  │  │├──┤58.7│OUT││     │├──┼────┼───┤│
│             │     ││  │41.3│OUT├┼─┐└──>│IN│    │   ││  ┌──>│IN│66.3│OUT││
│             │     │└──┴────┴───┘│ │   │└──┴────┴───┘│  │  │└──┴────┴───┘│
└─────────────┘     └─────────────┘ │   └─────────────┘  │  └─────────────┘
                                    └────────────────────┘

還沒有被下一個交易花費的Output被稱為UTXO:Unspent TX Output,即未花費交易輸出。給定任何一個區塊,計算當前所有的UXTO金額之和,等同于自創世區塊到給定區塊的挖礦獎勵之和。

因此,比特幣的交易模型和我們平時使用的銀行賬號有所不同,它并沒有賬戶這個說法,只有UTXO。想要確定某個人擁有的比特幣,并無法通過某個賬戶查到,必須知道此人控制的所有UTXO金額之和。

在錢包程序中,錢包管理的是一組私鑰,對應的是一組公鑰和地址。錢包程序必須從創世區塊開始掃描每一筆交易,如果:

  1. 遇到某筆交易的某個Output是錢包管理的地址之一,則錢包余額增加;
  2. 遇到某筆交易的某個Input是錢包管理的地址之一,則錢包余額減少。

錢包的當前余額總是錢包地址關聯的所有UTXO金額之和。

如果剛裝了一個新錢包,導入了一組私鑰,在錢包掃描完整個比特幣區塊之前,是無法得知當前管理的地址余額的。那么,給定一個地址,要查詢該地址的余額,難道要從頭掃描幾百GB的區塊鏈數據?

當然不是。

要做到瞬時查詢,我們知道,使用關系數據庫的主鍵進行查詢,由于用了索引,速度極快。

因此,對區塊鏈進行查詢之前,首先要掃描整個區塊鏈,重建一個類似關系數據庫的地址-余額映射表。這個表的結構如下:

address balance lastUpdatedAtBlock
address-1 50.0 0

一開始,這是一個空表。每當掃描一個區塊的所有交易后,某些地址的余額增加,另一些地址的余額減少,兩者之差恰好為區塊獎勵:

address balance lastUpdatedAtBlock
address-1 50.0 0
address-2 40.0 3
address-3 50.0 3
address-4 10.0 3

這樣,掃描完所有區塊后,我們就得到了整個區塊鏈所有地址的完整余額記錄,查詢的時候,并不是從區塊鏈查詢,而是從本地數據庫查詢。大多數錢包程序使用LevelDB來存儲這些信息,手機錢包程序則是請求服務器,由服務器查詢數據庫后返回結果。

如果我們把MySQL這樣的數據庫看作可修改的,那么區塊鏈就是不可修改,只能追加的只讀數據庫。但是,MySQL這樣的數據庫雖然其狀態是可修改的,但它的狀態改變卻是由修改語句(INSERT/UPDATE/DELETE)引起的。把MySQL的binlog日志完整地記錄下來,再進行重放,即可在另一臺機器上完整地重建整個數據庫。把區塊鏈看作不可修改的binlog日志,我們只要把每個區塊的所有交易重放一遍,即可重建一個地址-余額的數據庫。

可見,比特幣的區塊鏈記錄的是修改日志,而不是當前狀態。

小結

比特幣區塊鏈使用UTXO模型,它沒有賬戶這個概念;

重建整個地址-余額數據庫需要掃描整個區塊鏈,并按每個交易依次更新記錄,即可得到當前狀態。

?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,428評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,024評論 3 413
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,285評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,548評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,328評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,878評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,971評論 3 439
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,098評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,616評論 1 331
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,554評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,725評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,243評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,971評論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,361評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,613評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,339評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,695評論 2 370

推薦閱讀更多精彩內容