區(qū)塊鏈賬號(hào)體系之UTXO模型

我的博客,歡迎大家捧場(chǎng)

生活類比

首先看這個(gè)名詞UTXO (Unspent Transaction Output, “未花費(fèi)事務(wù)輸出”)欲侮,老實(shí)說殉农,第一次看到這個(gè)術(shù)語的時(shí)候茎匠,一時(shí)之間真是有些懵吁朦,如果說是未花費(fèi)的余額還能理解忍啤,我錢包里有1000编检,花了200胎食,還有800未花費(fèi),這是很符合通常的理解邏輯的允懂,可這個(gè)未花費(fèi)的“事務(wù)輸出”是個(gè)什么意思厕怜,實(shí)際上,這與比特幣中的交易事務(wù)結(jié)構(gòu)是很有關(guān)系的。為了讓大家更容易理解粥航,我們暫且先不來解析這個(gè)交易數(shù)據(jù)結(jié)構(gòu)琅捏,讓我們進(jìn)入到一個(gè)倉庫,我們知道倉庫的主要業(yè)務(wù)就是進(jìn)和出递雀,倉庫也會(huì)把日常的進(jìn)出流水賬記錄下來柄延, 為了查詢統(tǒng)計(jì)方便, 除了流水賬通常還會(huì)匯總一 份庫存表出來缀程,舉例如下:

image.png

以上圖為例搜吧,這是從2017-8- 1倒2017-8- 5之間,倉庫記錄的出入流水賬杨凑, 為了統(tǒng)計(jì)方便滤奈,倉庫還匯總保存了一份每天的庫存日?qǐng)?bào)表,如下:

image.png

每天倉庫在需要出庫的時(shí)候撩满,只要查看一下庫存日?qǐng)?bào)表就知道數(shù)量是否足夠了蜒程,比如2017-8-3需要出庫15支毛筆,此時(shí)查看庫存表發(fā)現(xiàn)毛筆的庫存量有30支伺帘,足夠發(fā)出搞糕,于是就將庫存表中的毛筆數(shù)量減掉15,并且將出庫明細(xì)記錄在流水賬中曼追。然而窍仰,這里有一個(gè)問題,庫存日?qǐng)?bào)表是另外編制保存的礼殊,那就有可能發(fā)生數(shù)據(jù)不一致的情況驹吮,比如2017-8-2時(shí)毛筆的庫存本來是30卻誤寫為20,這樣導(dǎo)致后續(xù)的賬務(wù)就都是錯(cuò)的了晶伦。因此在有些系統(tǒng)中碟狞,為了防止出現(xiàn)這樣的不一致,索性不再另外保存庫存表婚陪,而只是出一張視圖統(tǒng)計(jì)(邏輯統(tǒng)計(jì)族沃,并非實(shí)際去保存這樣一個(gè)統(tǒng)計(jì)比特幣中的交易事務(wù)過程與.上述的庫存進(jìn)出是很相像的,某個(gè)錢包地址中轉(zhuǎn)入了一筆比特幣泌参,然后這個(gè)地址又向其他錢包地址轉(zhuǎn)出了一筆比特幣脆淹,這些不斷發(fā)生的入和出跟倉庫的進(jìn)出是異曲同工的。然而沽一,在比特幣中并沒有去保存份“庫存表 ”每當(dāng)“出庫”的時(shí)候也并不是去“庫存表”中進(jìn)行扣除盖溺,而是直接消耗“入庫記錄”,也就是說在出庫的時(shí)候就去找有沒有之前的入庫記錄拿來扣除铣缠,比如2017-8-3時(shí)需要出庫15支毛筆烘嘱,此時(shí)系統(tǒng)就會(huì)去搜索之前的入庫記錄昆禽,發(fā)現(xiàn)有2017-8-1和2017-8-2分別有一筆數(shù)量為10和20的入庫記錄,為了滿足15的發(fā)出數(shù)量蝇庭,首先可以消耗掉10的這一筆醉鳖,然后從20的這筆再消耗掉5支, 判斷成功后哮内, 系統(tǒng)會(huì)直接產(chǎn)生一條數(shù)量為10的出庫記錄和數(shù)量為5的出庫記錄盗棵,按這樣的方法,將每一筆入和出都對(duì)應(yīng)了起來牍蜂。在比特幣的交易事務(wù)結(jié)構(gòu)中,“入”就是指金額轉(zhuǎn)入泰涂,“出”就是指金額轉(zhuǎn)出鲫竞,為了讓大家對(duì)這種金額轉(zhuǎn)入與轉(zhuǎn)出有一個(gè)更加通俗的理解,我們來看一幅 示意圖:

image.png

上圖展示 了比特幣中的交 易事務(wù)結(jié)構(gòu)逼蒙,在比特幣的交易事務(wù)數(shù)據(jù)中从绘, 存儲(chǔ)的就是這樣的輸入和輸出,相當(dāng)于倉庫中的進(jìn)出流水賬是牢,并且“輸入”和“輸出’彼此對(duì)應(yīng)僵井,或者更準(zhǔn)確地說,“輸入”就是指向之前的“ 輸出”驳棱,我們解釋一下圖中發(fā)生的交易事務(wù)批什。

  • 001號(hào)交易為Coinbase交易,也就是挖礦交易社搅,在這個(gè)交易中驻债,“輸入”部分沒有對(duì)應(yīng)的“輸出”,而是由系統(tǒng)直接獎(jiǎng)勵(lì)發(fā)行比特幣形葬,礦工Alice得到了12.5個(gè)比特幣的獎(jiǎng)勵(lì)合呐,放在001號(hào)交易的“輸出” 部分。此時(shí)笙以,對(duì)于Alice來說淌实, 擁有了這12.5個(gè)比特幣的支配權(quán),這12.5個(gè)比特幣的輸出可以作為下一筆交易的“輸入”猖腕,顧名思義拆祈,這筆“輸出”就稱之為是Alice的未花費(fèi)輸出,也就是Alice的UTXO的意思倘感。

  • 002號(hào)交易中缘屹,Alice轉(zhuǎn) 賬6比特幣到Bob的地址,Alice找到 了自己的UTXO (如果Alice不止一筆UTXO侠仇,可以根據(jù)一定的規(guī)則去選用轻姿,比如將小金額的先花費(fèi)掉)犁珠。由于只需要轉(zhuǎn)賬6比特幣,可是UTXO中卻有12.5個(gè)互亮,因此需要找零6.5個(gè)到自己的地址中犁享,由此產(chǎn)生了002號(hào)中的交易輸出,注意豹休,在002號(hào)交易輸出中的Alice地址是可以和001號(hào)中的Alice地址不一樣的炊昆,只要都是屬于Alice自己的錢包地址就可以。

  • 003號(hào)交易中威根,Bob轉(zhuǎn)賬了2比特幣到Lily的地址凤巨,過程與002號(hào)交易相同,就不再贅述了洛搀。相信大家看到這里敢茁,已經(jīng)基本理解了所謂的UTXO是什么意思,我們?cè)賮砜偨Y(jié)一下留美。

1)比特幣的交易中不是通過賬戶的增減來實(shí)現(xiàn)的彰檬,而是一筆筆關(guān)聯(lián)的輸入/輸出交易事務(wù)。

2)每一筆的交易都要花費(fèi)“輸入”谎砾,然后產(chǎn)生“輸出”逢倍,這個(gè)產(chǎn)生的“輸出”就是所謂的“未花費(fèi)過的交易輸出”,也就是UTXO景图。每一筆交易事務(wù)都有一個(gè)唯一的編號(hào)较雕,稱為交易事務(wù)ID,這是通過哈希算法計(jì)算而來的,當(dāng)需要引用某一筆交易事務(wù)中的“輸出”時(shí)挚币,主要提供交易事務(wù)ID和所處“輸出”列表中的序號(hào)就可以了郎笆。

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

在比特幣中凄吏,是使用輸入腳本和輸出腳本程序?qū)崿F(xiàn)的,有時(shí)候也稱為“鎖定腳本”和“解鎖腳本”闰蛔。簡(jiǎn)單地說痕钢,就是通過“鎖定腳本”,利用私鑰簽名解鎖自己的某一條UTXO (也就是之前的“輸出”)序六,然后使用對(duì)方的公鑰鎖定新的“輸出”任连,成功后,這筆新的“輸出”就成為了對(duì)方的UTXO例诀。同樣随抠,對(duì)方也可以使用“鎖定腳本”和“解鎖腳本”來實(shí)現(xiàn)轉(zhuǎn)賬裁着。這個(gè)腳本程序其實(shí)本質(zhì)上就可以看成是比特幣中的數(shù)字合約,這也是為什么比特幣被稱為可編程數(shù)字貨幣的原因拱她,它的轉(zhuǎn)入/轉(zhuǎn)出或者說輸入/輸出是通過腳本程序的組合來自動(dòng)實(shí)現(xiàn)的二驰,實(shí)現(xiàn)過程中還使用到了私鑰和公鑰,也就是公開密鑰算法秉沼,所以比特幣還稱為可編程加密數(shù)字貨幣桶雀。

具體模型

比特幣的區(qū)塊鏈由一個(gè)個(gè)區(qū)塊串聯(lián)構(gòu)成,而每個(gè)區(qū)塊又包含一個(gè)或多個(gè)交易唬复。
任何一個(gè)交易矗积,它總是由若干個(gè)輸入(Input)和若干個(gè)輸出(Output)構(gòu)成,一個(gè)Input指向的是前面區(qū)塊的某個(gè)Output敞咧,只有Coinbase交易(礦工獎(jiǎng)勵(lì)的鑄幣交易)沒有輸入棘捣,只有憑空輸出。所以妄均,任何交易柱锹,總是可以由Input溯源到Coinbase交易哪自。

這些交易的Input和Output總是可以串聯(lián)起來:

┌─────────────┐     ┌─────────────┐     ┌─────────────┐     ┌─────────────┐
│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││
│             │     │└──┴────┴───┘│ │   │└──┴────┴───┘│  │  │└──┴────┴───┘│
└─────────────┘     └─────────────┘ │   └─────────────┘  │  └─────────────┘
                                    └────────────────────┘

還沒有被下一個(gè)交易花費(fèi)的Output被稱為UTXO:Unspent TX Output丰包,即未花費(fèi)交易輸出。給定任何一個(gè)區(qū)塊壤巷,計(jì)算當(dāng)前所有的UXTO金額之和邑彪,等同于自創(chuàng)世區(qū)塊到給定區(qū)塊的挖礦獎(jiǎng)勵(lì)之和。

因此胧华,比特幣的交易模型和我們平時(shí)使用的銀行賬號(hào)有所不同寄症,它并沒有賬戶這個(gè)說法,只有UTXO矩动。想要確定某個(gè)人擁有的比特幣有巧,并無法通過某個(gè)賬戶查到,必須知道此人控制的所有UTXO金額之和悲没。

在錢包程序中篮迎,錢包管理的是一組私鑰,對(duì)應(yīng)的是一組公鑰和地址示姿。錢包程序必須從創(chuàng)世區(qū)塊開始掃描每一筆交易甜橱,如果:

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

錢包的當(dāng)前余額總是錢包地址關(guān)聯(lián)的所有UTXO金額之和子檀。

如果剛裝了一個(gè)新錢包镊掖,導(dǎo)入了一組私鑰乃戈,在錢包掃描完整個(gè)比特幣區(qū)塊之前,是無法得知當(dāng)前管理的地址余額的堰乔。那么偏化,給定一個(gè)地址,要查詢?cè)摰刂返挠囝~镐侯,難道要從頭掃描幾百GB的區(qū)塊鏈數(shù)據(jù)侦讨?

當(dāng)然不是。

要做到瞬時(shí)查詢苟翻,我們知道韵卤,使用關(guān)系數(shù)據(jù)庫的主鍵進(jìn)行查詢,由于用了索引崇猫,速度極快沈条。

因此,對(duì)區(qū)塊鏈進(jìn)行查詢之前诅炉,首先要掃描整個(gè)區(qū)塊鏈蜡歹,重建一個(gè)類似關(guān)系數(shù)據(jù)庫的地址-余額映射表。這個(gè)表的結(jié)構(gòu)如下:

address balance lastUpdatedAtBlock
address-1 50.0 0

一開始涕烧,這是一個(gè)空表月而。每當(dāng)掃描一個(gè)區(qū)塊的所有交易后,某些地址的余額增加议纯,另一些地址的余額減少父款,兩者之差恰好為區(qū)塊獎(jiǎng)勵(lì):

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

這樣,掃描完所有區(qū)塊后瞻凤,我們就得到了整個(gè)區(qū)塊鏈所有地址的完整余額記錄憨攒,查詢的時(shí)候,并不是從區(qū)塊鏈查詢阀参,而是從本地?cái)?shù)據(jù)庫查詢肝集。大多數(shù)錢包程序使用LevelDB來存儲(chǔ)這些信息,手機(jī)錢包程序則是請(qǐng)求服務(wù)器蛛壳,由服務(wù)器查詢數(shù)據(jù)庫后返回結(jié)果杏瞻。

如果我們把MySQL這樣的數(shù)據(jù)庫看作可修改的,那么區(qū)塊鏈就是不可修改炕吸,只能追加的只讀數(shù)據(jù)庫伐憾。但是,MySQL這樣的數(shù)據(jù)庫雖然其狀態(tài)是可修改的赫模,但它的狀態(tài)改變卻是由修改語句(INSERT/UPDATE/DELETE)引起的树肃。把MySQL的binlog日志完整地記錄下來,再進(jìn)行重放瀑罗,即可在另一臺(tái)機(jī)器上完整地重建整個(gè)數(shù)據(jù)庫胸嘴。把區(qū)塊鏈看作不可修改的binlog日志雏掠,我們只要把每個(gè)區(qū)塊的所有交易重放一遍,即可重建一個(gè)地址-余額的數(shù)據(jù)庫劣像。

可見乡话,比特幣的區(qū)塊鏈記錄的是修改日志,而不是當(dāng)前狀態(tài)耳奕。

小結(jié)

比特幣區(qū)塊鏈?zhǔn)褂肬TXO模型绑青,它沒有賬戶這個(gè)概念;

重建整個(gè)地址-余額數(shù)據(jù)庫需要掃描整個(gè)區(qū)塊鏈屋群,并按每個(gè)交易依次更新記錄闸婴,即可得到當(dāng)前狀態(tài)。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末芍躏,一起剝皮案震驚了整個(gè)濱河市邪乍,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌对竣,老刑警劉巖庇楞,帶你破解...
    沈念sama閱讀 216,692評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異否纬,居然都是意外死亡吕晌,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門烦味,熙熙樓的掌柜王于貴愁眉苦臉地迎上來聂使,“玉大人壁拉,你說我怎么就攤上這事谬俄。” “怎么了弃理?”我有些...
    開封第一講書人閱讀 162,995評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵溃论,是天一觀的道長。 經(jīng)常有香客問我痘昌,道長钥勋,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,223評(píng)論 1 292
  • 正文 為了忘掉前任辆苔,我火速辦了婚禮算灸,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘驻啤。我一直安慰自己菲驴,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,245評(píng)論 6 388
  • 文/花漫 我一把揭開白布骑冗。 她就那樣靜靜地躺著赊瞬,像睡著了一般先煎。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上巧涧,一...
    開封第一講書人閱讀 51,208評(píng)論 1 299
  • 那天薯蝎,我揣著相機(jī)與錄音,去河邊找鬼谤绳。 笑死占锯,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的缩筛。 我是一名探鬼主播烟央,決...
    沈念sama閱讀 40,091評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼歪脏!你這毒婦竟也來了疑俭?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,929評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤婿失,失蹤者是張志新(化名)和其女友劉穎钞艇,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體豪硅,經(jīng)...
    沈念sama閱讀 45,346評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡哩照,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,570評(píng)論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了懒浮。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片飘弧。...
    茶點(diǎn)故事閱讀 39,739評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖砚著,靈堂內(nèi)的尸體忽然破棺而出次伶,到底是詐尸還是另有隱情,我是刑警寧澤稽穆,帶...
    沈念sama閱讀 35,437評(píng)論 5 344
  • 正文 年R本政府宣布冠王,位于F島的核電站,受9級(jí)特大地震影響舌镶,放射性物質(zhì)發(fā)生泄漏柱彻。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,037評(píng)論 3 326
  • 文/蒙蒙 一餐胀、第九天 我趴在偏房一處隱蔽的房頂上張望哟楷。 院中可真熱鬧,春花似錦否灾、人聲如沸卖擅。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,677評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽磨镶。三九已至溃蔫,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間琳猫,已是汗流浹背伟叛。 一陣腳步聲響...
    開封第一講書人閱讀 32,833評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留脐嫂,地道東北人统刮。 一個(gè)月前我還...
    沈念sama閱讀 47,760評(píng)論 2 369
  • 正文 我出身青樓,卻偏偏與公主長得像账千,于是被迫代替她去往敵國和親侥蒙。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,647評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容