1. 賬號?不存在的
我們都知道,像銀行卡、支付寶都是基于賬號的設(shè)計(jì),賬號有其對應(yīng)的余額。我們也經(jīng)??吹絼e人這么講解比特幣的轉(zhuǎn)賬過程:A轉(zhuǎn)給B 5個(gè)比特幣,A賬號里就會減少5個(gè)比特幣,同時(shí)B賬號里就會增加5個(gè)比特幣,然后把這筆交易計(jì)入?yún)^(qū)塊鏈。事實(shí)上這只是表面現(xiàn)象,因?yàn)楸忍貛畔到y(tǒng)中并沒有賬號一說。你可能會說:不對,我用錢包時(shí)明明是有賬號密碼的,而且我賬戶里是有余額的。其實(shí)比特幣系統(tǒng)并不知道你的賬號,也不知道余額,那它知道什么呢?
2. 并沒有什么比特幣,只有 UTXO
比特幣沒有設(shè)計(jì)成基于賬戶的系統(tǒng),而是發(fā)明了 UTXO 方案。比特幣區(qū)塊鏈記錄的并不是一個(gè)個(gè)賬號,也不是一個(gè)個(gè)比特幣,而是由交易輸入和交易輸出組成的一筆筆交易。比特幣系統(tǒng)中并沒有比特幣,只有UTXO。你可以理解為UTXO就是比特幣。
UTXO(Unspent Transaction Output)就是未花費(fèi)交易輸出。每筆交易都有若干交易輸入,也就是資金來源,也都有若干筆交易輸出,也就是資金去向。一般來說,每一筆交易都要花費(fèi)至少一筆輸入,產(chǎn)生至少一筆輸出,而其所產(chǎn)生的輸出,就是“未花費(fèi)過的交易輸出”,也就是 UTXO。。每一次的交易輸入都可以追溯到之前的UTXO,直至最初的挖礦所得。由挖礦所得創(chuàng)建的比特幣交易,是每個(gè)區(qū)塊中的首個(gè)交易,又稱之為coinbase交易,它由礦工創(chuàng)建,沒有上一筆交易輸出。
UTXO本質(zhì)上來講就是用比特幣擁有者的公鑰哈希鎖定一個(gè)數(shù)字(比特幣數(shù)量),具體就是一個(gè)數(shù)字加一個(gè)鎖定腳本。所有的UTXO都被存在數(shù)據(jù)庫中,花費(fèi)比特幣其實(shí)是花費(fèi)掉屬于你的UTXO,并生成新的UTXO,用接受者的公鑰哈希進(jìn)行鎖定。鎖定腳本: OP_DUP OP_HASH160<pubKeyHash>OP_EQUALVERIFY OP_CHECKSIG,鎖定腳本中只有公鑰哈希是可變的,其它操作符都是固定的。鎖定腳本里是誰的公鑰哈希,誰就是這個(gè)UTXO的擁有者,誰就能花費(fèi)這筆UTXO。
pubKeyHash公鑰哈希 是用公鑰生成的:pubKeyHash = ripemd160(sha256(pubKey)),即先對公鑰進(jìn)行sha256運(yùn)算,再對其結(jié)果進(jìn)行ripemd160運(yùn)算。
3. 怎么證明此UTXO屬于你呢?
解鎖腳本可以驗(yàn)證UTXO是否屬于你,解鎖腳本包括你的數(shù)字簽名和你的公鑰。上一章講過用私鑰簽名,公鑰可以驗(yàn)證簽名。
-
比特幣的腳本語言是一種基于逆波蘭表示法和棧的執(zhí)行語言。
- 棧是一個(gè)非常簡單的數(shù)據(jù)結(jié)構(gòu),有壓棧和出棧兩種操作,其特點(diǎn)是先進(jìn)后出,后進(jìn)先出。
- 逆波蘭表示法,在逆波蘭表示法中,所有操作符置于操作數(shù)的后面,又被稱為后綴表示法(我們傳統(tǒng)的運(yùn)算為中綴表示法,比如(1+2)*3)。逆波蘭表示法不需要括號來標(biāo)識操作符的優(yōu)先級,只需按照表達(dá)式順序求值即可。
在逆波蘭表示法中,(1+2)*3可以寫作1 2 + 3 *,先讀取1和2兩個(gè)操作數(shù),然后遇到加號后1、2相加得出3,然后3后面又有一個(gè)3,之后遇到乘號,3再乘以3得出9 。
-
驗(yàn)證UTXO歸屬
- 將解鎖腳本和鎖定腳本組合在一起,即:<signature><pubKey>OP_DUP OP_HASH160<pubKeyHash>OP_EQUALVERIFY OP_CHECKSIG,在這個(gè)表達(dá)式里,簽名、公鑰和公鑰哈希都是操作數(shù),在驗(yàn)證不同人的UTXO時(shí)這3個(gè)都是不同的。而OP開頭的都是指操作符。
- 計(jì)算的過程是遇到操作數(shù)就壓棧,遇到操作符就進(jìn)行相應(yīng)的計(jì)算。由于數(shù)字簽名和公鑰都是操作數(shù),所以先將它們進(jìn)行壓棧。
- 接著遇到OP_DUP,它會將棧頂?shù)墓€復(fù)制一份,然后復(fù)制的公鑰放置棧頂,此時(shí),棧里的數(shù)據(jù)從下到上以次為:數(shù)字簽名、公鑰、公鑰。
- 然后是OP_HASH160,對棧頂?shù)墓€執(zhí)行ripemd160(sha256(公鑰))運(yùn)算,其結(jié)果其實(shí)就是pubKeyHash。此時(shí)棧里的數(shù)據(jù)從下到上以次為:數(shù)字簽名、公鑰、公鑰哈希
- 接著遇到公鑰哈希,并將公鑰哈希壓棧,此時(shí)棧里的數(shù)據(jù)從下到上以次為:數(shù)字簽名、公鑰、公鑰哈希、公鑰哈希。然后遇到OP_EQUALVERIFY,此操作符是對比兩個(gè)數(shù)據(jù)是否相等,所以先把棧頂?shù)膬蓚€(gè)數(shù)據(jù)彈棧,如果相等則繼續(xù)往下走,彈出來的兩個(gè)數(shù)據(jù)也不再壓棧。此時(shí)棧里的數(shù)據(jù)從下到上以次為:數(shù)字簽名、公鑰。
- 最后一個(gè)操作符是OP_CHECKSIG,其作用是驗(yàn)證簽名是否正確。此時(shí)將棧內(nèi)僅剩的簽名和公鑰彈棧,上一篇講過用私鑰進(jìn)行簽名,公鑰可以驗(yàn)證簽名,如果結(jié)果是true,則可以證明該UTXO屬于該簽名和公鑰的所有者。
- 舉例:假如這筆UTXO是你的,那么鎖定腳本里面的公鑰哈希必然是用你的公鑰生成的,解鎖腳本里面的數(shù)字簽名和公鑰也是你的,那么在執(zhí)行OP_HASH160時(shí)生成的公鑰哈希必然和鎖定腳本里的公鑰哈希相等,在執(zhí)行OP_CHECKSIG時(shí),你的公鑰也必然能驗(yàn)證你的數(shù)字簽名。如果這筆UTXO是小明的,那么鎖定腳本里面的公鑰哈希就是小明的,你的公鑰生成的公鑰哈希必然與其不同。如果你在解鎖腳本里用小明的公玥代替你的公鑰,則在執(zhí)行OP_EQUALVERIFY時(shí)是能成功的,但是你是不能拿到小明的數(shù)字簽名的,所以最后執(zhí)行OP_CHECKSIG時(shí),小明的公鑰必然不能驗(yàn)證你自己的簽名,所以最后你是不能花費(fèi)別人的UTXO的。
4.交易過程
- 假如A分兩次轉(zhuǎn)給B 2個(gè)和3個(gè)比特幣,此時(shí)B表面上就擁有了5個(gè)比特幣,實(shí)質(zhì)上是有2個(gè)UTXO,其中一個(gè)有2個(gè)比特幣,另一個(gè)有3個(gè)。
- B如果需要向C轉(zhuǎn)4個(gè)比特幣,此時(shí)的交易就會有2個(gè)輸入,就是分別有2個(gè)和3個(gè)的那兩個(gè)UTXO,這兩個(gè)UTXO都是用B的地址鎖定的。由于只需要向C轉(zhuǎn)4個(gè)比特幣,那么還會剩余一個(gè)(先不考慮手續(xù)費(fèi)),那這個(gè)會存放在哪里呢?是不是某個(gè)UTXO里面會留一個(gè)?
- 比特幣的設(shè)計(jì)機(jī)制是只要某個(gè)UTXO被消耗掉,就會從數(shù)據(jù)庫中永久刪除,也就是說B的這兩個(gè)UTXO都會被徹底刪除。這時(shí)需要一個(gè)找零地址,將剩余的比特幣用找零地址對應(yīng)的公鑰哈希生成一個(gè)新的UTXO。
- 具體就是4個(gè)比特幣用C的公鑰哈希鎖定生成一個(gè)新的UTXO,剩余的比特幣用找零地址對應(yīng)的公鑰哈希再生成一個(gè)新的UTXO,這個(gè)找零地址可以是B現(xiàn)在的地址,也可以是一個(gè)新的地址。
ps.
- 最后再說下賬號余額的問題,錢包之所以能顯示某一個(gè)賬號下余額是多少,是因?yàn)殄X包通過遍歷UTXO數(shù)據(jù)庫獲取該地址對應(yīng)的UTXO計(jì)算出來的。
To be continued...