合肥網(wǎng)站關(guān)鍵詞推廣業(yè)務(wù)推廣公司
1. 簡介
1.? 區(qū)塊鏈?zhǔn)且粋€很慢的數(shù)據(jù)庫
2. 區(qū)塊鏈不等于比特幣,基于區(qū)塊鏈技術(shù)的一種加密貨幣
3.目前學(xué)習(xí)是否晚,目前還是一個較為萌芽的階段,不要以為自己錯過了比特幣大漲的時刻。學(xué)習(xí)區(qū)塊鏈已經(jīng)超越很多人
2.比特幣
1.比特幣密碼學(xué)原理
1. ?比特幣中主要用到了密碼學(xué)中兩個功能:?1.哈希 2.簽名。密碼學(xué)中的哈希函數(shù)(cryptographtic hash function),
一、哈希函數(shù)
? 哈希函數(shù)主要有三個特性:1、碰撞特性(collision resistance);2、隱秘性(Hiding);3、謎題友好(puzzle friendly)。比特幣使用的加密函數(shù)為SHA-256
?1、collision resistance
? collision resistance 即為輸入兩個輸入值X,Y,經(jīng)過哈希函數(shù)之后得到H(X)=H(Y),即為哈希碰撞。利用哈希碰撞,可以檢測對信息的篡改。假設(shè)輸入x1,哈希值為H(x1),此時很難找到一個x2,使得H(x1)=H(x2)。
?2、Hiding
? hiding 意思是哈希函數(shù)的計(jì)算過程是單向的,不可逆的。但前提要滿足輸入控件足夠大,且分布均勻。通常我們在實(shí)際操作中會使用添加隨機(jī)數(shù)的方法。假設(shè)給定一個輸入值X,可以算出哈希值H(x),但是不能從H(x)推出X。
?3、puzzle friendly
- ???特指哈希值的計(jì)算過程無法被預(yù)測或優(yōu)化,必須通過大量計(jì)算才能找到符合條件的輸入
- ? ?通常我們限定輸出的哈希值在一定范圍內(nèi),即H(block header + nonce) < target (block header是區(qū)塊鏈的鏈頭),這個確定鏈頭范圍的過程即為挖礦。.
- 關(guān)于目前的target難度可以通過http://blockexplorer.com/q/getdifficulty來得到,下一個難度可以通過http://blockexplorer.com/q/estimate來獲得。難度的變化情況可以查看Bitcoin network graphs。
二、簽名
? 簽名就相當(dāng)于每個人的開戶行賬號。公鑰簽名,即開戶賬號,驗(yàn)證簽名用私鑰,即為賬號密碼。以此來確保比特幣的安全傳輸。
???簽名算法是?橢圓曲線數(shù)字簽名算法?(ECDSA)?
2.比特幣的數(shù)據(jù)結(jié)構(gòu)
1. 比特幣系統(tǒng)中使用的數(shù)據(jù)結(jié)構(gòu)主要是以下兩種:
- 哈希指針(hash pointers)
- merkle樹(merkle tree)(默克爾樹)
哈希指針用于區(qū)塊之間的連接作用,而merkle tree用于每個區(qū)塊內(nèi)部交易之間的連接作用。哈希指針與merkle tree的關(guān)系如下圖所示:
2. 哈希指針(Hash Pointers)
普通指針與Hash指針
? ?普通指針存儲的是某個結(jié)構(gòu)體在內(nèi)存中的地址。假如P是指向一結(jié)構(gòu)體的指針,那么P里面存放的就是該結(jié)構(gòu)體在內(nèi)存中的起始位置。
? ? 哈希指針除了要存地址之外,還要保存該結(jié)構(gòu)體的哈希值H(x) 。這樣的好處是:從這個哈希指針,不僅可以找到該結(jié)構(gòu)體的位置,同時還能夠檢測出該結(jié)構(gòu)體的內(nèi)容有沒有被篡改,因?yàn)槲覀儽4媪怂墓V怠?/p>
3. 區(qū)塊鏈和普通的鏈表
- 比特幣中最基本的結(jié)構(gòu)就是區(qū)塊鏈,區(qū)塊鏈就是一個一個區(qū)塊組成的鏈表。區(qū)塊鏈和普通的鏈表相比有什么區(qū)別:
- 用哈希指針代替了普通指針(B block chain is a linked list using hash pointers)
- 區(qū)塊鏈第一個區(qū)塊叫作創(chuàng)世紀(jì)塊(genesis block) ,最后一個區(qū)塊叫做最近產(chǎn)生的區(qū)塊(most recent block), 每一個區(qū)塊都包含指向前一個區(qū)塊的哈希指針。
- 普通鏈表可以改變?nèi)我庖粋€元素,對鏈表中其他元素是沒有影響的。而區(qū)塊鏈?zhǔn)菭恳话l(fā)而動全身,如果區(qū)塊鏈中任一塊被修改,則后面所有的區(qū)塊都要發(fā)生變動(因?yàn)楹笠粋€區(qū)塊頭部存儲是前面所有區(qū)塊求H()后的值),所以只需要保存最后一個哈希值,就可以判斷區(qū)塊鏈有沒有改變。針對這一特性,比特幣沒有要保存所有區(qū)塊的內(nèi)容,可以只保留最近的幾千個區(qū)塊。如果要用到以前的區(qū)塊,可以向系統(tǒng)中其他節(jié)點(diǎn)要這個區(qū)塊。假設(shè)整個區(qū)塊鏈當(dāng)中有些節(jié)點(diǎn)是有惡意的,它給出塊算出它的哈希值,與保留的區(qū)塊的哈希值對比即可判斷是否為異常節(jié)點(diǎn)。
- 由上圖可看到,區(qū)塊鏈系統(tǒng)中的的每個節(jié)點(diǎn)可以獲得最近一個區(qū)塊的哈希值H(recent block),
- 從而就可以追溯到創(chuàng)世紀(jì)塊。通過哈希指針的鏈?zhǔn)浇Y(jié)構(gòu),也可以知道區(qū)塊內(nèi)容是否被篡改,因?yàn)橹灰硞€區(qū)塊A被篡改,它的哈希值就會改變,它之后區(qū)塊B的哈希指針就不會指向A了,這樣系統(tǒng)會很快知道A被篡改?;蛘叽鄹恼邚膮^(qū)塊A一直改到最新區(qū)塊,到最后最新區(qū)塊的哈希值也會改變,跟系統(tǒng)中保存的最近區(qū)塊哈希值H(recent block)對比,也就很快發(fā)現(xiàn)是否被篡改。
2.Merkle Tree(樹形結(jié)構(gòu))(默克爾樹)
- Merkle tree跟二叉樹很類似,只不過把普通指針同樣換成了哈希指針。
- Merkle tree在每個區(qū)塊內(nèi)部將各個交易連接起來了,如下圖所示:
這個樹的最下面是的葉子節(jié)點(diǎn)是區(qū)塊體(block body)里的所有交易,每個交易取哈希值,相鄰交易的哈希值結(jié)合起來一起取哈希,層層往上取哈希,直到得到最后一個哈希值,這個哈希值也就是根哈希值(root hash),并存在區(qū)塊頭(block header)。
從上面分析得到,只要記住了根哈希值(root hash),就可以檢測出對樹的任何節(jié)點(diǎn)的修改。要想改變其他節(jié)點(diǎn)的哈希值同時保證根哈希值的不變,就必須人為制造哈希碰撞,但通過哈希的性質(zhì)知道,這是不可能的。
Merkle tree 的作用:提供Merkle proof
Merkle proof是Merkle tree內(nèi)的從最底層的某個交易出發(fā)到最頂部根哈希的一條路徑。如上圖中最下面的黃色交易開始到最底部的路徑就是一個merkle proof。
在比特幣區(qū)塊鏈網(wǎng)絡(luò)中有很多節(jié)點(diǎn),包括計(jì)算機(jī)、手機(jī)、礦機(jī)、服務(wù)器等等。在所有節(jié)點(diǎn)中分為:全節(jié)點(diǎn)和輕節(jié)點(diǎn)。
全節(jié)點(diǎn)(full node):保存了區(qū)塊的所有內(nèi)容,區(qū)塊頭和區(qū)塊體。輕節(jié)點(diǎn)(light node):只保存了區(qū)塊頭,比如手機(jī)中的比特幣錢包。
問題:如何向一個輕節(jié)點(diǎn)證明某個交易是寫入?yún)^(qū)塊鏈的?
- 假設(shè)某個輕節(jié)點(diǎn)想知道圖中黃色的交易,是否包含在了merkle tree里面。該輕節(jié)點(diǎn)沒有包含交易列表,沒有這顆merkle tree的具體內(nèi)容,只有一個根哈希值。這時輕節(jié)點(diǎn)向一個全節(jié)點(diǎn)發(fā)出請求,請求證明黃色的交易被包含在這顆merkle tree里面的merkle proof(由交易者提供)。全節(jié)點(diǎn)收到這個請求之后,只需要將圖中標(biāo)為紅色的這三個哈希值發(fā)給輕節(jié)點(diǎn)即可。
- 有了這些哈希值之后,輕節(jié)點(diǎn)可以在本地計(jì)算出圖中標(biāo)為綠色三個哈希值。首先算出黃色交易的哈希值,即它正上方的那個綠的哈希值,然后跟旁邊紅色的哈希值拼接起來,可以算出上層節(jié)點(diǎn)綠色的哈希值。
- 然后再拼接,再算出上層綠色哈希值,再拼接,就可以算出整棵樹的根哈希值。
- 輕節(jié)點(diǎn)把這個根哈希值和block header里的根哈希值比較一下,就能知道黃色的交易是否在這顆merkle tree里。
- 全節(jié)點(diǎn)在merkle proof里提供的這幾個哈希值,就是從黃色的交易所在的節(jié)點(diǎn)的位置到樹根的路徑上用到的這些哈希值。輕節(jié)點(diǎn)收到這樣一個merkle proof之后,只要從下往上驗(yàn)證,沿途的哈希值都是正確的即可。(驗(yàn)證時只能驗(yàn)證該路徑的哈希值,其他路徑是驗(yàn)證不了的,即該圖中紅色的哈希值是驗(yàn)證不了的)
- 這樣是否不安全呢? 假如黃色交易被篡改,它的哈希值發(fā)生了變化,那能不能調(diào)整旁邊紅色的哈希值,使得它們拼接起來的哈希值是不變的呢? 不行,根據(jù)collision resistance,這是不可行的。
問題:如何證明merkle tree里面沒有包含某個交易?
1.全節(jié)點(diǎn)將整個區(qū)塊所有交易信息發(fā)給輕節(jié)點(diǎn),這樣可以證明某個交易不在區(qū)塊中,但這是非常不高效的方法且比較笨的方法。
2.思路還是根據(jù)merkle proof計(jì)算根哈希值,輕節(jié)點(diǎn)向全節(jié)點(diǎn)對這個交易發(fā)出請求,全節(jié)點(diǎn)為了證明此交易不在區(qū)塊鏈中。
全節(jié)點(diǎn)只需以下這樣做即可:
- 對區(qū)塊中所有交易的哈希值進(jìn)行排序,然后計(jì)算要證明的交易的哈希值,根據(jù)二分查找法來確定這個交易哈希值的位置,再將此位置相鄰的2個交易merkle proof發(fā)送給輕節(jié)點(diǎn)。
輕節(jié)點(diǎn)只需以下這樣做即可:
- 輕節(jié)點(diǎn)收到merkle proof后,根據(jù)merkle proof計(jì)算得到最后的根哈希值(root hash),若計(jì)算得到的根哈希值跟本地的區(qū)塊頭中的根哈希值比較一樣,則證明此交易一定不在區(qū)塊鏈中,因?yàn)槿绻诘脑?#xff0c;最后計(jì)算出來的根哈希值比較必然是不一樣的。
- 可以把整棵樹傳給輕節(jié)點(diǎn),輕節(jié)點(diǎn)收到后驗(yàn)證樹的構(gòu)造都是對的,每一層用到的哈希值都是正確的,說明樹里只有這些葉節(jié)點(diǎn),要找的交易不在里面,就證明了proof of non-membership。問題在于,它的復(fù)雜度是線性的θ(n),是比較笨的方法。如果對葉節(jié)點(diǎn)的排列順序做一些要求,比如按照交易的哈希值排序。每一個葉節(jié)點(diǎn)都是一次交易,對交易的內(nèi)容取一次哈希,按照哈希值從小到大排列。要查的交易先算出一個哈希值,看看如果它在里面該是哪個位置。比如說在第三個第四個之間,這時提供的proof是第三個第四個葉節(jié)點(diǎn)都要往上到根節(jié)點(diǎn)。如果其中哈希值都是正確的,最后根節(jié)點(diǎn)算出的哈希值也是沒有被改過的,說明第三、四個節(jié)點(diǎn)在原來的merkle tree里面,確實(shí)是相鄰的點(diǎn)。要找的交易如果存在的話,應(yīng)該在這兩個節(jié)點(diǎn)中間。但是它沒有出現(xiàn),所以就不存在。其復(fù)雜度也是log形式,代價是要排序。排好序的叫作sorted merkle tree。比特幣中沒有用到這種排好序的merkle tree,因?yàn)楸忍貛胖胁恍枰霾淮嬖谧C明。
3.比特幣協(xié)議
????????? 比特幣協(xié)議是一套技術(shù)規(guī)則,定義了比特幣網(wǎng)絡(luò)如何運(yùn)作,包括交易的創(chuàng)建、驗(yàn)證和共識機(jī)制。它基于密碼學(xué)和分布式系統(tǒng),確保去中心化、安全性和不可篡改性。
1.雙花攻擊(double spending attack)
定義:
- 雙花是指同一筆比特幣被多次花費(fèi)的行為,這是傳統(tǒng)數(shù)字貨幣面臨的核心問題之一。
比特幣如何解決雙花
- ?? ?比特幣采用UTXO(詳見2 BTC實(shí)現(xiàn))模型,每筆交易都會消耗之前的UTXO,并生成新的UTXO。因此,一旦某個UTXO被用于交易,它就不能再次被使用。比特幣網(wǎng)絡(luò)中的節(jié)點(diǎn)會驗(yàn)證交易是否引用了有效且未花費(fèi)的UTXO,若UTXO已被花費(fèi),則交易無效,雙花攻擊無法成功。? ? ? ? 例如,A擁有一個包含5 BTC的UTXO,并將其全部發(fā)送給B,該UTXO被標(biāo)記為已花費(fèi),新的UTXO由B持有。此時,如果A試圖再用這5 BTC進(jìn)行另一筆交易,例如轉(zhuǎn)給C,節(jié)點(diǎn)會檢查A是否仍有可用的UTXO。如果沒有足夠的UTXO,交易將被拒絕。
2.交易機(jī)制
2.1.交易結(jié)構(gòu)
- ? ? ? ? 輸入(Inputs):引用之前的未花費(fèi)交易輸出(UTXO),證明你有權(quán)花費(fèi)這些比特幣。
- ? ? ? ? 輸出(Outputs):指定比特幣的接收地址和金額。
- ? ? ? ? 簽名:使用私鑰對交易簽名,確保只有比特幣的擁有者可以發(fā)起交易。
2.2.交易流程
? ? ? ? 用戶創(chuàng)建交易并用私鑰簽名 -> 交易被廣播到比特幣網(wǎng)絡(luò) -> 節(jié)點(diǎn)驗(yàn)證交易的合法性(簽名有效、輸入未被雙花等)-> 礦工將交易打包進(jìn)一個新區(qū)塊,通過PoW添加到區(qū)塊鏈 -> 交易確認(rèn)后,接收方可以看到比特幣到達(dá)。
3.輕節(jié)點(diǎn)(light node)和全節(jié)點(diǎn)(full node)
1.3.1.全節(jié)點(diǎn)(Full Node):
- 存儲整個區(qū)塊鏈的完整副本(截至2025年3月,已超過500GB)。
- 獨(dú)立驗(yàn)證所有交易和區(qū)塊的合法性,遵循協(xié)議規(guī)則。
- 增強(qiáng)網(wǎng)絡(luò)的安全性和去中心化,但需要較高的存儲和帶寬。
1.3.2.輕節(jié)點(diǎn)(Light Node):
- 也稱為SPV節(jié)點(diǎn)(簡單支付驗(yàn)證,Simplified Payment Verification)。
- 只下載區(qū)塊頭(約80字節(jié)/區(qū)塊),不存儲完整交易數(shù)據(jù)。
- 依賴全節(jié)點(diǎn)提供相關(guān)交易信息來驗(yàn)證支付。
- 優(yōu)點(diǎn)是占用資源少,適合移動設(shè)備;缺點(diǎn)是安全性較低,依賴其他節(jié)點(diǎn)。
1.3.3.輕節(jié)點(diǎn)與全節(jié)點(diǎn)對比:
- 全節(jié)點(diǎn)對網(wǎng)絡(luò)健康至關(guān)重要,輕節(jié)點(diǎn)則更注重便捷性。
- 輕節(jié)點(diǎn)通過檢查區(qū)塊頭中的Merkle根驗(yàn)證交易,確認(rèn)其是否在鏈上。
4.區(qū)塊鏈構(gòu)成
1. 鏈?zhǔn)浇Y(jié)構(gòu):由按時間順序連接的區(qū)塊組成,每個區(qū)塊包含一批交易。
2. 區(qū)塊鏈有塊頭Block header(80字節(jié)):包含宏觀信息:
-
版本號:標(biāo)識區(qū)塊的協(xié)議版本。
-
前一個區(qū)塊的哈希(Parent Block Hash):鏈接到前一個區(qū)塊,形成鏈條。
-
默克爾根(Merkle Root):本區(qū)塊所有交易的哈希摘要,用于快速驗(yàn)證交易是否存在。
-
時間戳Timestamp:區(qū)塊的大致生成時間。
-
難度目標(biāo)(Difficulty Target)(nBits):當(dāng)前挖礦的難度值。
-
隨機(jī)數(shù)Nonce:礦工調(diào)整的隨機(jī)數(shù),用于滿足工作量證明(PoW)。
3.區(qū)塊鏈內(nèi)容Block body:
- 交易列表:包含該區(qū)塊的所有交易列表(包括Coinbase交易)。
- Merkle 樹(Merkle Tree) 用于高效存儲和驗(yàn)證交易數(shù)據(jù)
5.比特幣共識(Cousensus in BitCoin)
1.定義
比特幣共識是網(wǎng)絡(luò)中所有節(jié)點(diǎn)就區(qū)塊鏈的狀態(tài)(哪些交易有效)達(dá)成一致的機(jī)制。
2.核心機(jī)制
- 工作量證明(PoW):礦工通過算力競爭,解決數(shù)學(xué)難題以生成新區(qū)塊。
- 最長合法鏈規(guī)則:節(jié)點(diǎn)始終接受工作量最大的合法鏈(見1.5)。
- 共識規(guī)則:交易必須符合協(xié)議(如簽名有效、無雙花);區(qū)塊必須滿足難度目標(biāo),且包含有效的前區(qū)塊哈希;每2016個區(qū)塊調(diào)整一次難度,確保出塊時間穩(wěn)定在10分鐘。
- 去中心化特性:沒有中央權(quán)威,共識由全球節(jié)點(diǎn)共同維護(hù)。
- 分叉處理:如果網(wǎng)絡(luò)出現(xiàn)臨時分叉(如兩個礦工同時挖到區(qū)塊),節(jié)點(diǎn)會選擇最長鏈,分叉的短鏈將被丟棄。
5.最長合法鏈(longest valid chain)
1.定義
? ? ? ? 最長合法鏈?zhǔn)侵咐鄯e工作量(Proof of Work)最多的區(qū)塊鏈,且符合所有協(xié)議規(guī)則。
2.作用
解決分叉問題:當(dāng)網(wǎng)絡(luò)出現(xiàn)競爭鏈時,節(jié)點(diǎn)選擇最長鏈作為主鏈。
防止篡改:攻擊者若想修改歷史交易,需重新計(jì)算從目標(biāo)區(qū)塊到當(dāng)前高度的所有工作量,并超過現(xiàn)有鏈的增長速度。
3.工作原理
? ? ? ? 每個區(qū)塊的頭部包含前一區(qū)塊的哈希,形成鏈?zhǔn)浇Y(jié)構(gòu)。
4.實(shí)際案例
? ? ? ? 如果一個礦工挖到一個區(qū)塊,但另一個礦工隨后挖出一條更長的鏈,網(wǎng)絡(luò)會切換到更長鏈,短鏈的區(qū)塊成為“孤塊”(Orphan Block),這也是為什么建議等待6個確認(rèn),以確保交易所在鏈足夠穩(wěn)定。
6.比特幣如何獲取記賬權(quán)
比特幣的區(qū)塊記賬權(quán)是通過?工作量證明(PoW, Proof of Work)?競爭獲得的,礦工必須完成計(jì)算任務(wù)以證明自己消耗了足夠的算力。整個過程涉及?交易打包、哈希計(jì)算、難度調(diào)整、區(qū)塊廣播和鏈上確認(rèn),以下是詳細(xì)步驟:
1. 交易收集與驗(yàn)證
礦工節(jié)點(diǎn)?從比特幣網(wǎng)絡(luò)的?內(nèi)存池(Mempool)?收集未確認(rèn)的交易,并驗(yàn)證:
-
交易簽名是否有效(防止雙花)。
-
交易輸入(UTXO)是否未被使用。
-
交易手續(xù)費(fèi)是否足夠(礦工優(yōu)先打包高手續(xù)費(fèi)交易)。
示例:
一個區(qū)塊通常包含?2000~3000筆交易(約1MB~4MB,取決于SegWit使用情況)。
2. 構(gòu)建候選區(qū)塊
礦工將交易打包成?候選區(qū)塊,結(jié)構(gòu)如下:
字段 | 說明 |
---|---|
版本號 | 區(qū)塊協(xié)議版本(如0x20000000) |
前一個區(qū)塊哈希 | 父區(qū)塊的SHA-256哈希(確保鏈?zhǔn)竭B接) |
默克爾根(Merkle Root) | 本區(qū)塊所有交易的哈希樹根 |
時間戳 | 區(qū)塊生成時間(Unix時間) |
難度目標(biāo)(nBits) | 當(dāng)前網(wǎng)絡(luò)難度(壓縮格式) |
Nonce | 初始隨機(jī)數(shù)(從0開始遞增) |
關(guān)鍵點(diǎn):
-
Coinbase交易:區(qū)塊的第一筆交易,礦工將?區(qū)塊獎勵(6.25 BTC)?和?交易手續(xù)費(fèi)?轉(zhuǎn)入自己的地址。
-
交易排序:礦工可能按手續(xù)費(fèi)率(sat/vB)排序以最大化收益。
3. 工作量證明(PoW)計(jì)算
礦工的任務(wù)是找到一個?Nonce,使得區(qū)塊頭的雙SHA-256哈希值 ≤?當(dāng)前目標(biāo)(Target):
SHA-256(SHA-256(Block?Header))≤TargetSHA-256(SHA-256(Block?Header))≤Target
計(jì)算過程
-
修改Nonce:從0開始遞增,計(jì)算哈希。
-
窮舉嘗試:若Nonce遍歷完畢仍未找到解,則調(diào)整:
-
Coinbase ExtraNonce(擴(kuò)展Nonce空間)。
-
交易列表(替換高手續(xù)費(fèi)交易)。
-
時間戳(微調(diào)以改變哈希)。
-
-
哈希示例:
假設(shè)某次計(jì)算得到哈希:text
復(fù)制
下載
0000000000000000000abc123...(前導(dǎo)19個0)
若符合當(dāng)前難度(如要求前導(dǎo)18個0),則挖礦成功。
4. 難度調(diào)整(Dynamic Difficulty)
比特幣每?2016個區(qū)塊(約兩周)調(diào)整一次難度,確保平均出塊時間維持在?10分鐘:
New?Target=Old?Target×Actual?TimeExpected?TimeNew?Target=Old?Target×Expected?TimeActual?Time?
-
Actual Time:過去2016個區(qū)塊的實(shí)際耗時。
-
Expected Time:2016 × 10分鐘 = 20160分鐘。
調(diào)整限制:單次難度變化不超過?±4倍(防止攻擊)。
5. 區(qū)塊廣播與確認(rèn)
-
廣播區(qū)塊:礦工將新區(qū)塊發(fā)送給相鄰節(jié)點(diǎn)。
-
節(jié)點(diǎn)驗(yàn)證:其他節(jié)點(diǎn)驗(yàn)證:
-
PoW是否有效(哈希 ≤ Target)。
-
交易是否合法(無雙花、簽名有效)。
-
-
鏈上確認(rèn):
-
區(qū)塊被納入最長鏈后,獲得?1次確認(rèn)。
-
每新增一個區(qū)塊,確認(rèn)數(shù)+1(6次確認(rèn)后視為最終確認(rèn))。
-
6. 礦工收益
-
區(qū)塊獎勵:當(dāng)前?6.25 BTC(2020年減半后),下次減半在2024年(3.125 BTC)。
-
交易手續(xù)費(fèi):用戶支付的費(fèi)用(如0.0001 BTC/筆),礦工優(yōu)先打包高手續(xù)費(fèi)交易。
示例:
若某區(qū)塊包含?3000筆交易,平均手續(xù)費(fèi)?0.00005 BTC,則礦工額外收益:
3000×0.00005=0.15?BTC3000×0.00005=0.15?BTC
7. 關(guān)鍵代碼示例(PoW核心邏輯)
python
復(fù)制
下載
import hashlibdef mine_block(header, target):nonce = 0while True:# 更新Nonce(小端序)header_with_nonce = header[:76] + nonce.to_bytes(4, 'little')# 計(jì)算雙SHA-256hash_result = hashlib.sha256(hashlib.sha256(header_with_nonce).digest()).digest()hash_int = int.from_bytes(hash_result, 'big')# 檢查是否≤Targetif hash_int <= target:return nonce, hash_result.hex()nonce += 1# Nonce溢出后調(diào)整其他字段if nonce >= 2**32:nonce = 0# 修改Coinbase ExtraNonce或交易順序
8. 為什么需要PoW?
-
安全性:攻擊者需掌握51%算力才能篡改交易,成本極高。
-
去中心化:任何人均可參與挖礦,無需許可。
-
公平性:算力決定記賬權(quán),而非身份或資本。
總結(jié)
比特幣的記賬權(quán)獲取流程:
-
收集交易?→ 2.?構(gòu)建區(qū)塊?→ 3.?PoW計(jì)算?→ 4.?廣播驗(yàn)證?→ 5.?鏈上確認(rèn)。
礦工通過消耗電力(算力)競爭記賬權(quán),獲得BTC獎勵,同時維護(hù)網(wǎng)絡(luò)安全。這一過程是比特幣?去中心化、抗審查、安全?的核心基石。
4.比特幣的實(shí)現(xiàn)
? ?區(qū)塊鏈?zhǔn)侨ブ行幕馁~本,比特幣采用的是基于交易的賬本模式(transaction-based ledger),只記錄了轉(zhuǎn)賬交易和鑄幣交易,并沒有直接記錄每個賬戶上有多少錢。如果想知道某個比特幣賬戶上有多少錢,要通過交易記錄來推算。
1.UTXO
????????比特幣中的全結(jié)點(diǎn)要維護(hù)一個叫UTXO(Unspent Transaction Output)的數(shù)據(jù)結(jié)構(gòu),即還沒有被花出去的交易的輸出。一個交易可能有多個輸出,被花掉的就不在UTXO里了。如下圖中A轉(zhuǎn)賬給B和C的交易,B的已經(jīng)花出去了,也就不在UTXO里了,而C的還沒花出去,就在UTXO里。
UTXO集合中的每個元素要給出產(chǎn)生這個輸出的交易的哈希值,以及它在這個交易中是第幾個輸出。用這兩個信息就可以定位到一個確定的交易中確定的輸出。
使用UTXO可以用來快速檢測雙花攻擊,想知道新發(fā)布的交易是不是合法的,要查一下全結(jié)點(diǎn)存在內(nèi)存中的UTXO。要花掉的幣只有在這個UTXO這個集合里才是合法的,否則要么是不存在的,要么是已經(jīng)花過了的。隨著交易的發(fā)布,每個交易會消耗掉一些輸出,同時也會產(chǎn)生一些新的輸出。例如上圖例子中B將5個BTC給D,這消耗掉了前面A把5個BTC給B的輸出,但產(chǎn)生了新的B把5個BTC給D的輸出,這個輸出會保存在UTXO里。
如果一個賬戶從交易中獲得比特幣之后,不花出去,那么這些輸出就要一直保存在UTXO里。有的人是一直不花,比如中本聰,有的是把密鑰丟了沒法花,但不論怎樣這些沒消耗掉的交易輸出都要一直存在UTXO里,目前的大小是能保存在一個普通服務(wù)器內(nèi)存中的。
交易中 total?inputs=total?outputs
每個交易可以有若干輸入和若干輸出,所有輸入的金額之和要等于所有輸出的金額之和。
這里可能有些違反直覺,不僅可以有多個輸出,也可以有多個輸入,甚至這些輸入也不必來自同一個地址。每個輸入地址都要提供對應(yīng)的簽名,所以一個交易可能有多個簽名。
2.第二個激勵機(jī)制:交易費(fèi)(transaction fee)
有些交易的總輸入可能略微大于總輸出,如可能總輸出是1個BTC,總輸出是0.99個BTC,這之中的差額就作為記賬費(fèi)給了獲得記賬權(quán)的那個結(jié)點(diǎn)。
這樣設(shè)計(jì)是因?yàn)閮H僅為獲得記賬權(quán)的結(jié)點(diǎn)給予出塊獎勵是不夠的,獲得記賬權(quán)的結(jié)點(diǎn)為什么要把某些交易記下來?這樣做對他有什么好處呢?一個結(jié)點(diǎn)完全可以只打包自己的交易,記錄別人的交易不僅要去驗(yàn)證其合法性,而且一個區(qū)塊裝的交易多了,在網(wǎng)絡(luò)上傳輸?shù)膸捯矔容^多,在網(wǎng)絡(luò)上傳輸?shù)乃俣纫矔?。這里的差額作為記賬費(fèi)就解決了這個給別人記賬的動機(jī)的問題。
這里0.01個BTC已經(jīng)是很大的交易費(fèi)了,也有一些很簡單的交易是沒有交易費(fèi)的,也就是完全符合t o t a l ? i n p u t s = t o t a l ? o u t p u t s 。
目前來講礦工挖礦,主要的目的還是為了第一個激勵機(jī)制——得到出塊獎勵。因?yàn)槌鰤K獎勵是要逐漸減少的,每隔21萬個區(qū)塊就要減半,比特幣系統(tǒng)的平均出塊時間是10分鐘,大約每隔4年出塊獎勵就會減半。到很多年之后,出塊獎勵變得很小,這時候交易費(fèi)就成為主要動機(jī)了。
除了比特幣系統(tǒng)這樣基于交易的賬本模式(transaction-based ledger),還有一些系統(tǒng)是基于賬戶的模式(account-based ledger),比如后面要學(xué)的以太坊。在這種模式中系統(tǒng)要顯式的記錄每個賬戶中有多少個幣。
比特幣系統(tǒng)的這種模式,隱私保護(hù)性比較好,但會帶來一些代價,如轉(zhuǎn)賬交易要說明幣的來源(幣是從之前的哪個交易的哪個輸出中來的)以防止雙花攻擊。
一個區(qū)塊的例子
在blockchain.info上截圖下來的一個區(qū)塊:
注意,區(qū)塊中的nonce是4字節(jié)即32位整數(shù),也就只2的32次方 種取值。因?yàn)楸忍貛沤┠晏鸨?#xff0c;挖礦的人數(shù)很多,所以挖礦的難度被調(diào)整的很高,單純靠調(diào)整nonce是很可能得不到符合難度要求的解的(搜索空間不夠大)。所以區(qū)塊的塊頭中哪些域可以改?再來回顧一下塊頭中的域(括號中是占的字節(jié)數(shù)):
- 版本號(4):不能改
- 前一個區(qū)塊塊頭哈希值(32):不能改
- Merkle Tree的根哈希值(32):通過修改Merkle Tree中鑄幣交易的CoinBase域來調(diào)整其根哈希值
- 區(qū)塊產(chǎn)生的時間(4):有一定的調(diào)整余地,比特幣系統(tǒng)并不要求非常精確的時間,這個域可以在一定范圍內(nèi)調(diào)整
- 挖礦目標(biāo)閾值編碼后的版本(4)
- nonce(4):可以改
可以看到,因?yàn)殍T幣交易是沒有交易來源的,所以可以在其CoinBase域
里隨便寫入內(nèi)容,鑄幣交易的變化會使該交易的哈希發(fā)生變化,變化沿著Merkle Tree一路向上傳遞,最終使整棵Merkle Tree的根哈希值發(fā)生變化,間接地調(diào)整塊頭的哈希值。
所以可以把這個字段當(dāng)做一個extra nonce,塊頭的nonce字段不夠用,就再拿著這個域的一部分字節(jié)一起調(diào)整,就增大了搜索空間。例如,拿出這個域的前8個字節(jié)當(dāng)做extra nonce,則搜索空間一下子就增大到了2的32次方 + 8 ? 8 = 2 96 。 2^{32+8*8}=2^{96}。2的32次方
32+8?8?=2的96次方
實(shí)際挖礦時,一般也是為此設(shè)計(jì)了兩層循環(huán),外層循環(huán)調(diào)整鑄幣交易的CoinBase
域的extra nonce
,然后算出Merkle Tree的根哈希值;內(nèi)層循環(huán)調(diào)整塊頭的nonce,計(jì)算整個塊頭的哈希值。
一個轉(zhuǎn)賬交易的例子
以這個交易為例。
在這個轉(zhuǎn)賬交易中,左邊是交易的兩個輸入(雖然旁邊寫的是Output,這是表示它們花掉的是之前哪個交易的Output);右邊是交易的兩個輸出(從綠色Unspent字樣可以看到還沒有花出去,所以會保存在UTXO里)??梢钥吹奖忍貛畔到y(tǒng)中交易的輸入和輸出都是用腳本來指定的,驗(yàn)證交易輸入輸出的過程就是把輸入腳本和輸出腳本配對執(zhí)行(不是把同一個交易的輸入輸出腳本配對執(zhí)行,而是把這個交易的輸入腳本和提供幣的來源的那個交易的輸出腳本配對執(zhí)行)。只要配對后都能成功執(zhí)行,交易驗(yàn)證就是通過的。
挖礦過程的概率分析
- 挖礦的過程就是不斷嘗試nonce去求解puzzle,每次嘗試可以看做一個伯努利試驗(yàn)(Bernoulli trial:a random experiment with binary outcome)。擲硬幣就是一個最簡單的伯努利試驗(yàn),要么正面朝上要么反面朝上,這兩個概率不必一樣大,對于挖礦而言,成功和失敗的概率相差非常懸殊,成功的概率很小。
- 當(dāng)進(jìn)行了大量的伯努利試驗(yàn),這些伯努利試驗(yàn)就構(gòu)成了伯努利過程(Bernoulli process:a sequence of independent Bernoulli trails)。伯努利過程的一個性質(zhì)是無記憶性(memoryless),即做大量的試驗(yàn),前面的試驗(yàn)結(jié)果對后面沒有影響,例如擲硬幣很多次都是反面朝上,下一次擲硬幣正面朝上的概率也不會增加。
- 當(dāng)伯努利分布(也即二項(xiàng)分布)的n很大而p很小時(試驗(yàn)次數(shù)很多,每次試驗(yàn)成功概率很小),可以近似為泊松分布。這里挖礦就是一個n很大p很小的伯努利過程,所以可以近似為泊松過程(Poisson process)。
- progress free與算力優(yōu)勢——挖礦公平性的保證:出塊時間是服從指數(shù)分布(exponential distribution) 的,整個系統(tǒng)的出塊時間按照比特幣協(xié)議被調(diào)整在10分鐘左右,而具體到某個礦工的出塊時間,取決于其算力占整個系統(tǒng)中礦工的算力的百分比,這比較好理解,例如某個礦工的算力能占到整個系統(tǒng)總算力的1%,那么平均100個區(qū)塊有1個是他挖到的,也即平均要等1000分鐘能挖到1個區(qū)塊。
- 這個出塊時間服從的指數(shù)分布也是無記憶性的, 也就是說從任何一個位置將其截?cái)?#xff0c;剩下的部分仍然是服從指數(shù)分布的。“將來還要挖多少時間”和“過去已經(jīng)挖了多少時間”是沒有關(guān)系的。體現(xiàn)在比特幣系統(tǒng)的挖礦中也就是,不管大家已經(jīng)挖了多長時間,接下來系統(tǒng)中要出塊的平均時間仍然還是10分鐘左右。
- 這也就是progress free——過去做了多少工作不會讓后續(xù)成功的概率變化。這個性質(zhì)看似無情但是是必要的。假設(shè)一個加密貨幣系統(tǒng)不滿足progress free,即過去做的工作越多,后面成功的概率就越大,那么就會造成算力強(qiáng)的礦工會有不成比例的優(yōu)勢,而不能按照算力的比例計(jì)算優(yōu)勢。比特幣總量的分析
- 出塊獎勵是系統(tǒng)中產(chǎn)生新的比特幣的唯一途徑,而出塊獎勵每隔21萬個區(qū)塊(大約每隔4年)要減半,所以新產(chǎn)生的比特幣的總量就形成了一個幾何序列(geometric series)。
所以比特幣總量為:
21 萬 × 50 × 2 = 2100 萬 21萬 \times 50 \times 2 = 2100萬
21萬×50×2=2100萬
這就是系統(tǒng)中所有比特幣的總量。
- 認(rèn)為比特幣挖礦是在解決某種數(shù)學(xué)難題是錯誤的觀念,求解比特幣挖礦的puzzle除了比拼算力之外,沒有任何實(shí)際意義。比特幣越來越難挖只是因?yàn)槌鰤K獎勵人為地被減少了,并且加入的人越來越多而為保持系統(tǒng)中的平均出塊時間而提高了挖礦的難度。
- 但要注意,挖礦的過程雖然沒有實(shí)際意義,但對維護(hù)比特幣系統(tǒng)的安全性是至關(guān)重要的。Bitcoin is security by mining。挖礦提供了一種憑借算力投票的有效手段。
比特幣安全性的分析
- 大部分算力掌握在誠實(shí)的結(jié)點(diǎn)手里,只能說有比較大的概率下一個區(qū)塊是由誠實(shí)的礦工發(fā)布的,但是不能保證記賬權(quán)不會落在有惡意的結(jié)點(diǎn)手里。
轉(zhuǎn)走別人的BTC
- 假設(shè)一個有惡意的結(jié)點(diǎn)M獲得了記賬權(quán),它想把結(jié)點(diǎn)A的錢轉(zhuǎn)走,但因?yàn)闆]法偽造A的簽名(沒有A的私鑰),寫個任何不正確的簽名上去,都會導(dǎo)致誠實(shí)的結(jié)點(diǎn)不會接受這個候選區(qū)塊,而是繼續(xù)沿著上一個區(qū)塊擴(kuò)展。因?yàn)檫@個區(qū)塊是不合法的,所以多長都不是最長合法鏈,這樣的攻擊是無效的。
分叉攻擊
M把BTC轉(zhuǎn)給A,然后就緊接著挖礦挖到了一個區(qū)塊,在這里填寫了M把BTC轉(zhuǎn)給自己的交易,以希望沿著這個區(qū)塊成為最長合法鏈,這樣就能將轉(zhuǎn)給A的擠掉,從而將花出去的BTC回滾。這也是雙花攻擊的一種。
試想A是一個購物網(wǎng)站,允許BTC支付,在M->A這個交易剛寫入?yún)^(qū)塊鏈以后A就認(rèn)為M支付成功,那確實(shí)會出現(xiàn)上述問題。
如果M->A這個交易所在區(qū)塊后面又跟上一些區(qū)塊之后呢?這個攻擊的難度就會大大增加。因?yàn)樗詈玫姆绞饺匀皇窃贛->A的前一個區(qū)塊位置插入,但是想讓它成為最長合法鏈卻非常難,因?yàn)樗呀?jīng)不是最長合法鏈,誠實(shí)的結(jié)點(diǎn)只會去擴(kuò)展最長合法鏈。
如果大部分結(jié)點(diǎn)掌握在誠實(shí)結(jié)點(diǎn)手里,這樣攻擊的難度非常大,有惡意的結(jié)點(diǎn)要連續(xù)獲得好多次記賬權(quán)才可能改變最長合法鏈。所以一種最簡單的防范方法就是多等幾個區(qū)塊,也叫多等幾個確認(rèn)(confirmation)。
zero confirmation
zero confirmation是指交易剛發(fā)布出去,還沒有寫入?yún)^(qū)塊鏈中的時候,就認(rèn)為交易已經(jīng)不可篡改了。
zero confirmation實(shí)際使用的比較廣泛,有兩個原因:
- 兩個交易有沖突,結(jié)點(diǎn)接收最先聽到的交易。上面分叉攻擊的例子中M->A后的M->M大多誠實(shí)結(jié)點(diǎn)會將其拒絕。
- 購物網(wǎng)站委托全結(jié)點(diǎn)監(jiān)聽區(qū)塊鏈,從支付成功到發(fā)貨其實(shí)還有比較長的處理時間,如果發(fā)現(xiàn)這個交易最后沒有寫到最長合法鏈,購物網(wǎng)站可以選擇取消發(fā)貨。
故意不發(fā)布某些合法交易
這個是沒關(guān)系的,因?yàn)楸忍貛艆f(xié)議也沒有規(guī)定獲得記賬權(quán)的結(jié)點(diǎn)必須發(fā)布哪些交易,而且沒有寫進(jìn)這個區(qū)塊也可以寫進(jìn)下一個區(qū)塊,總有誠實(shí)的結(jié)點(diǎn)愿意發(fā)布這些交易。而且比特幣系統(tǒng)在正常工作時候也會出現(xiàn)某些交易被滯后發(fā)布的情況,可能就是一段時間內(nèi)的交易太多了,畢竟一個區(qū)塊不能超過1M。
selfish mining
- 正常情況下結(jié)點(diǎn)挖到一個區(qū)塊就立即發(fā)布,這是為了得到出塊獎勵和收取交易費(fèi)。selfish mining就是挖到的區(qū)塊都留著,這樣的動機(jī)是,比如在前面的分叉攻擊中,一直等到6個confirmation過了,再一口氣把算好的很長的分叉發(fā)布出去,替換掉最長合法鏈。
- 實(shí)際上這樣做的難度還是很大,因?yàn)檫@個惡意結(jié)點(diǎn)的算力要超過那些誠實(shí)的算力才可能在一定時間后比它長。另外就是大多誠實(shí)的結(jié)點(diǎn)已經(jīng)擴(kuò)展那個M->A的交易所在的區(qū)塊了,這個惡意結(jié)點(diǎn)的同伙結(jié)點(diǎn)也要很多才行。
- 即便不是為了做什么攻擊,就是為了賺取出塊獎勵和收取交易費(fèi),selfish mining也有好處——能夠減少自己的競爭對手。比如下圖中大家都在從A挖下一個區(qū)塊,然后某個結(jié)點(diǎn)挖出了B先藏著,這時候別人還在從A挖下一個區(qū)塊,然后這個結(jié)點(diǎn)緊接著挖出了C,將B和C一起發(fā)布出去,這樣就少了一個結(jié)點(diǎn)C的競爭。
- 或者是繼續(xù)往下挖,當(dāng)聽到有人發(fā)布D時,將B和C一起發(fā)布出去,這樣最長合法鏈?zhǔn)茄刂鳤BC的,別人挖出的D就作廢了。
但這樣會帶來不小的風(fēng)險,假設(shè)在挖出C之前就有人挖出D并且發(fā)布了,這時候就只能趕緊把B發(fā)布出去,很可能連這個記賬權(quán)都競爭不到了。
在這個動機(jī)下,selfish mining的回報并非很高,只是讓別人做了無用功,自己少了些競爭,但風(fēng)險卻是挺大的。
參考地址:【區(qū)塊鏈學(xué)習(xí)筆記】4:比特幣系統(tǒng)的實(shí)現(xiàn)_比特幣的激勵機(jī)制-CSDN博客
5.比特幣網(wǎng)絡(luò)
新的交易要發(fā)布到比特幣網(wǎng)絡(luò)上,礦工將交易打包成的區(qū)塊也要發(fā)布到比特幣網(wǎng)絡(luò)上。
- 應(yīng)用層:Bitcoin Blockchain
- 網(wǎng)絡(luò)層:P2P Overlay Network
比特幣網(wǎng)絡(luò)中的P2P網(wǎng)絡(luò)是很簡單的,所有結(jié)點(diǎn)之間都是對等的,沒有超級結(jié)點(diǎn)。要加入這個網(wǎng)絡(luò),至少要有一個種子結(jié)點(diǎn)(seed node),和種子結(jié)點(diǎn)聯(lián)系,它會告知它所知道的網(wǎng)絡(luò)中的其它結(jié)點(diǎn)(有點(diǎn)像構(gòu)造路由表的過程)。結(jié)點(diǎn)之間通過TCP來通信,有利于穿透防火墻。要離開網(wǎng)絡(luò)也不必通知其它結(jié)點(diǎn),只需要直接退出應(yīng)用程序,其它結(jié)點(diǎn)一直沒有聽到你的消息,過一段時間就會將你刪除掉。
比特幣網(wǎng)絡(luò)的設(shè)計(jì)原則是簡單、魯棒(健壯性),而不是高效。每個結(jié)點(diǎn)維護(hù)一個鄰居結(jié)點(diǎn)的集合,消息在網(wǎng)絡(luò)中采用flooding方式傳播,結(jié)點(diǎn)第一次聽到某個消息,會將它傳播給所有鄰居結(jié)點(diǎn),同時記錄一下自己已經(jīng)收到過這個消息了。
?
鄰居結(jié)點(diǎn)的選取是隨機(jī)的,沒有考慮底層的拓?fù)浣Y(jié)構(gòu)。比如美國的一個結(jié)點(diǎn)可能和中國的一個結(jié)點(diǎn)是鄰居結(jié)點(diǎn)。這樣設(shè)計(jì)的好處是增強(qiáng)魯棒性,犧牲了效率。
新發(fā)布的交易的傳播
比特幣網(wǎng)絡(luò)中,每個結(jié)點(diǎn)要維護(hù)一個等待上鏈的交易的集合,這個集合中的交易都是要寫入?yún)^(qū)塊鏈的合法的交易,結(jié)點(diǎn)第一次收到這個交易的時候就會把它寫入這個集合,并轉(zhuǎn)發(fā)給所有鄰居。
如果有兩個有沖突的交易,幾乎同時發(fā)布到網(wǎng)絡(luò)上,每個結(jié)點(diǎn)根據(jù)其位置的不同,可能先收到的交易是不同的,那么另一個交易對于這個結(jié)點(diǎn)而言就是非法的了,不會被收納到集合中。
以左邊的集合為例,它先聽到A->B的交易,將其寫入到了自己的交易集合中。接下來它收到了一個新發(fā)布的區(qū)塊,其中包含A->B這個交易,說明這個交易已經(jīng)被寫入?yún)^(qū)塊鏈了,所以就要在自己的交易集合中將其刪除掉。
risk condition
如果這個結(jié)點(diǎn)收到的新發(fā)布的區(qū)塊中的交易是被自己丟棄掉的A->C的這個交易呢?這時也要將集合中的A->B刪除掉,因?yàn)闄z查可以發(fā)現(xiàn)此時集合中的A->B這個交易是非法交易,因?yàn)樗托掳l(fā)布的區(qū)塊中的A->C這個交易沖突了。
也就是說要看接收A->B交易的結(jié)點(diǎn)先獲得記賬權(quán),還是接收A->C交易的結(jié)點(diǎn)先獲得記賬權(quán)。
best effort
一個交易發(fā)布到比特幣網(wǎng)絡(luò)上,未必所有結(jié)點(diǎn)都能收到(有的結(jié)點(diǎn)不一定按照比特幣協(xié)議的要求來轉(zhuǎn)發(fā),可能合法的不轉(zhuǎn)發(fā),不合法的又轉(zhuǎn)發(fā)了),而且不同結(jié)點(diǎn)收到交易的順序也很可能是不一樣的(網(wǎng)絡(luò)傳輸中的延遲可能很大)。這是一個去中心化的系統(tǒng)中要面臨的實(shí)際問題,只能盡力而為。
新發(fā)布的區(qū)塊的傳播
和新發(fā)布的交易的傳播方式是類似的,不過每個結(jié)點(diǎn)除了要檢查區(qū)塊的內(nèi)容是不是合法的,還要檢查區(qū)塊是不是在最長合法鏈上。
越大的區(qū)塊在網(wǎng)絡(luò)上傳播越慢,比特幣協(xié)議要求區(qū)塊大小不能超過1M,因?yàn)楸忍貛啪W(wǎng)絡(luò)的效率比較低,一個1M大小的區(qū)塊可能要幾十秒才能傳播給比特幣網(wǎng)絡(luò)上的大多數(shù)結(jié)點(diǎn)。
6.比特幣挖礦難度
挖礦難度
挖礦就是不斷嘗試區(qū)塊塊頭中的nonce和extra nonce的值,使得:
顯然目標(biāo)閾值target越小,則挖礦的難度就越大。所以調(diào)整挖礦難度就是在調(diào)整target,以調(diào)整目標(biāo)空間在整個輸出空間中所占的比例。
比特幣中使用的哈希函數(shù)是SHA-256,產(chǎn)生的哈希值是256位的,所以整個輸出空間是2的256次方
?,調(diào)整目標(biāo)空間所占的比例,在這個問題里直觀的來看就是最后得到的哈希值前面有多少位0(這只是通俗直觀來看的,也許第一個非0位是要小于4也說不定),這個0越多顯然值就越小,也就是挖礦難度越大了。
挖礦難度和目標(biāo)閾值的大小成反比:
上式中常量difficulty_1_target
是指挖礦難度difficulty定義為1時所對應(yīng)的目標(biāo)閾值target的值。挖礦難度最小就是1,所以這個常量也就是target允許的最大值。
為什么要調(diào)整挖礦難度?
系統(tǒng)中的總算力越來越強(qiáng),如果挖礦難度保持不變,那么平均出塊時間會越來越短,這會造成一些問題。假設(shè)平均出塊時間減小到了1秒鐘,也就是每隔1秒左右就有一個新的區(qū)塊攜帶一些列交易被發(fā)布到比特幣網(wǎng)絡(luò)上,而在比特幣網(wǎng)絡(luò)上這個區(qū)塊傳播給大多數(shù)結(jié)點(diǎn)可能就要幾十秒。
如果有兩個結(jié)點(diǎn)幾乎同時發(fā)布了區(qū)塊,那么就會出現(xiàn)分叉:
這是一個二分叉的情況,如果出塊時間很短,就會導(dǎo)致這種分叉成為常態(tài)。而且不僅僅是二分叉,可能會出現(xiàn)很多分叉。
分叉過多對比特幣系統(tǒng)達(dá)成共識沒有好處,并且會危害比特幣系統(tǒng)的安全性。例如前面說的分叉攻擊,正常情況下,因?yàn)榇蟛糠纸Y(jié)點(diǎn)是誠實(shí)的,有惡意的結(jié)點(diǎn)想要在6個確認(rèn)后拿這段時間集中算力算出的新鏈去覆蓋掉最長合法鏈?zhǔn)呛茈y的,因?yàn)檎\實(shí)結(jié)點(diǎn)也都在集中算力擴(kuò)展最長合法鏈。如果出塊時間很短,就會導(dǎo)致分叉過多(因?yàn)橄啾扔诔鰤K時間,可以認(rèn)為網(wǎng)絡(luò)上傳輸?shù)臅r間變長了),這樣誠實(shí)結(jié)點(diǎn)的算力就被分散了,這時惡意結(jié)點(diǎn)要進(jìn)行51% attack很可能就不需要50%以上的算力了,可能百分之十幾就足夠了,這樣大大降低了比特幣系統(tǒng)的安全性。
比特幣10分鐘的平均出塊時間也未必是最優(yōu)的,后面要學(xué)的以太坊的出塊時間就降低到了15秒。大幅降低了出塊時間,所以以太坊就要設(shè)計(jì)一個新的共識協(xié)議——
GHOST
。在這個協(xié)議中,分叉產(chǎn)生的orphan block
不能簡單丟棄掉,而是也要給予一些獎勵——uncle reward
。
總之,在不同的區(qū)塊鏈賬本系統(tǒng)中,不論出塊時間設(shè)計(jì)成多長,都要設(shè)法讓其保持穩(wěn)定,而不能允許它隨著系統(tǒng)中總算力的提高而無限減小下去。
怎么調(diào)整挖礦難度?
比特幣協(xié)議中規(guī)定,每隔2016個區(qū)塊(大約每2個星期)要重新調(diào)整一下目標(biāo)閾值target,具體的迭代更新公式是:
如果惡意的結(jié)點(diǎn)不調(diào)整target怎么辦
target是寫在比特幣系統(tǒng)的代碼里的,代碼也都是開源的,如果有結(jié)點(diǎn)到了該調(diào)整的時候不調(diào)整target怎么辦。這也是一個大部分結(jié)點(diǎn)誠實(shí)的問題,如果不調(diào)整target,那么發(fā)布的區(qū)塊塊頭里的4字節(jié)nBits域(32字節(jié)的target壓縮編碼后的版本)就不是正確的,誠實(shí)的結(jié)點(diǎn)不會接收這樣的區(qū)塊。
7.比特幣挖礦
1. 比特幣系統(tǒng)中有兩種節(jié)點(diǎn),一種是全節(jié)點(diǎn),一種是輕節(jié)點(diǎn)。
2. 全節(jié)點(diǎn)的特征
- 一直在線
- 在本地硬盤上維護(hù)完整的區(qū)塊鏈信息
- 在內(nèi)存中維護(hù)UTXO集合,以便快速檢驗(yàn)交易的正確性
- 監(jiān)聽比特幣網(wǎng)絡(luò)上的交易信息,驗(yàn)證每個交易的合法性
- 監(jiān)聽別的礦工挖出的區(qū)塊,驗(yàn)證其合法性:
- 區(qū)塊中的每個交易都要合法(包括鑄幣交易及其出塊獎勵)
- 發(fā)布的區(qū)塊是不是符合難度要求、難度目標(biāo)閾值的設(shè)置是否正確、每兩周調(diào)整的挖礦難度
- 區(qū)塊是在延伸最長合法鏈
- 挖礦:
- 決定沿著哪條鏈挖下去
- 決定哪些交易被打包進(jìn)區(qū)塊
- 決定當(dāng)出現(xiàn)等長分叉時選擇哪個分叉(缺省情況是選擇最先接收到的區(qū)塊的分叉)
3.輕節(jié)點(diǎn)的特征
- 不是一直在線
- 不用保存完整區(qū)塊鏈,只要保存每個區(qū)塊塊頭(這樣和全節(jié)點(diǎn)的大小相差大約1000倍)
- 不用保存全部交易,只需要保存和自己相關(guān)的交易
- 沒法驗(yàn)證大多數(shù)交易的合法性,只能檢驗(yàn)與自己相關(guān)的交易的合法性
- 無法檢測比特幣網(wǎng)絡(luò)上發(fā)布的區(qū)塊的正確性
- 可以驗(yàn)證挖礦的難度(因?yàn)橥诘V時候計(jì)算哈希值只用到了塊頭信息,而塊頭信息輕節(jié)點(diǎn)是保存了的)
- 只能檢測哪個是最長鏈,不知道哪個是最長合法鏈(因?yàn)闊o法檢測這條鏈上所包含的交易都是合法的)
輕節(jié)點(diǎn)假設(shè)礦工(全節(jié)點(diǎn))大多是有理智的,即假設(shè)礦工們不會沿著不合法的鏈一直挖下去。
比特幣網(wǎng)絡(luò)中大部分節(jié)點(diǎn)都是輕節(jié)點(diǎn),如果只是想轉(zhuǎn)賬,而不是去挖礦的話,只用輕節(jié)點(diǎn)就可以了。
挖礦
????????當(dāng)在挖礦過程中發(fā)現(xiàn)新發(fā)布了一個區(qū)塊,那么應(yīng)該停止挖礦,重新從UTXO中取出一系列合法交易組成候選區(qū)塊,在剛發(fā)布的這個區(qū)塊后面開始挖礦。因?yàn)橐环矫孢@個區(qū)塊中的交易可能和剛剛在挖的那個區(qū)塊有重復(fù),另一個本質(zhì)的原因就是候選區(qū)塊的塊頭有指向前一個區(qū)塊的哈希指針。因?yàn)樽钚碌膮^(qū)塊已經(jīng)變了,這個哈希指針也要跟著改變。
那么這樣是不是會因?yàn)橹暗墓ぷ鞫及踪M(fèi)了而很可惜?實(shí)際上不可惜,因?yàn)榍懊鎸W(xué)過挖礦過程的無記憶性(memoryless,progress free),無論是在剛剛的區(qū)塊上繼續(xù)挖,還是新組裝一個區(qū)塊繼續(xù)挖,成功的概率是一樣的。
比特幣系統(tǒng)安全性的保證:因?yàn)閯e人沒法偽造你的私鑰,也就沒法把你賬戶上的BTC轉(zhuǎn)走。但這個密碼學(xué)上的保證是要以“系統(tǒng)中大部分節(jié)點(diǎn)是誠實(shí)的”為前提,即大家不會接受那些不合法的交易進(jìn)入?yún)^(qū)塊鏈。
挖礦的設(shè)備
第一代挖礦設(shè)備:CPU
????????最早時候大家都是用普通計(jì)算機(jī)來挖礦,但如果專門搞一臺計(jì)算機(jī)來挖礦是很不劃算的。因?yàn)橛?jì)算機(jī)大部分內(nèi)存是閑置的(挖礦只要用到很少一部分內(nèi)存),CPU大部分部件是閑置的(計(jì)算哈希值的操作只用到通用CPU中的很少一部分指令),硬盤和其它很多資源也都是閑置的。隨著挖礦難度提高,用通用計(jì)算機(jī)上的CPU挖礦很快就無利可圖了。
第二代挖礦設(shè)備:GPU
????????GPU主要用來做通用的大規(guī)模并行計(jì)算,用來挖礦還是會有不少浪費(fèi),而且GPU的噪音很大,其中很多部件還是浪費(fèi)了(如用于浮點(diǎn)數(shù)計(jì)算的部件)。近些年GPU價格漲得很快,這不僅是DL火熱的原因,實(shí)際上很多GPU是買來挖礦的。不過現(xiàn)在挖礦的難度已經(jīng)提高到用GPU也有些劃不來了,不會再有那么多人買GPU來挖比特幣。
第三代挖礦設(shè)備:ASIC芯片
?????????ASIC即Application Specific Integrated Circuit,這之中有專門為了挖礦而設(shè)計(jì)的芯片,沒有多余的電路,干不了別的事,它的性價比是最高的,而且為某一種加密貨幣設(shè)計(jì)的ASIC芯片只能挖這一種加密貨幣的礦,除非兩個貨幣用同一個mining puzzle。
????????有些加密貨幣在剛啟動的時候,為了吸引更多的人來挖礦,特意用一個和已有的其它加密貨幣一樣的mining puzzle,這種情況叫
merge mining
。
????????研制挖特定加密貨幣的ASIC芯片需要一定周期,但和研制通用芯片的速度相比已經(jīng)是非??斓牧?#xff0c;如研制比特幣挖礦的ASIC芯片大約用一年的時間。不過加密貨幣的價格變化是比較劇烈的,曾經(jīng)就發(fā)生過比特幣價格在幾個月內(nèi)下跌80%,因?yàn)榧用茇泿哦嘧兊膬r格,這些挖礦設(shè)備的研制風(fēng)險也是很大的。
????????挖礦的競爭越來越激烈,定制的ASIC芯片可能用了幾個月就過時了,到時候又要買新的ASIC芯片參與競爭。ASIC礦機(jī)上市后的大部分利潤也就在前幾個月,這個設(shè)備的迭代也是很塊的。
????????要買ASIC礦機(jī)往往要先交錢預(yù)定,過一段時間廠商才會發(fā)過來。實(shí)際上有些黑心廠商在生產(chǎn)出來以后也不交付給用戶,聲稱還沒成產(chǎn)好,然后自己在這段黃金時間用礦機(jī)挖礦賺取比特幣。不過這其實(shí)看得出來,比特幣系統(tǒng)中算力突然有了大的提高,那一般是某個大的廠商生產(chǎn)出了新的礦機(jī)。所以真正賺錢的未必是挖礦的,而是賣礦機(jī)的。
ASIC resistance
????????為了讓通用計(jì)算機(jī)也能參與挖礦過程,抗ASIC芯片化,有些加密貨幣采用
Alternative mining puzzle
,以去對抗那些只為了解決特定mining puzzle而設(shè)計(jì)出來的ASIC礦機(jī)
比特幣挖礦的趨勢:大型礦池
????????單個礦工挖礦的收益是很不穩(wěn)定的,平均出塊時間10分鐘是對于比特幣系統(tǒng)中的所有礦工而言的。一個礦工用一個礦機(jī)挖出礦的時間可能要很久,并且除了挖礦之外還要承擔(dān)全結(jié)點(diǎn)的其它責(zé)任。
????????礦池將很多礦工組織起來,一般的架構(gòu)就是一個礦主(pool manager)全結(jié)點(diǎn)去驅(qū)動很多礦機(jī),下屬礦工只負(fù)責(zé)計(jì)算哈希值,全結(jié)點(diǎn)的其它職能只由礦主來承擔(dān)。有了收益以后再大家一起分配。
礦池收益怎么分配?
如果礦池中的礦機(jī)都是屬于同一個機(jī)構(gòu)的,那怎么分配就只是公司內(nèi)部怎么發(fā)工資的問題了。
????????如果礦機(jī)來自不同機(jī)構(gòu),這時候礦工很可能分布在世界各地,只是都加入了這個礦池。礦工和礦主聯(lián)系,礦主將要計(jì)算的哈希值的任務(wù)分配給他,礦工計(jì)算好后將結(jié)果發(fā)給礦主,最終得到出塊獎勵后一起參與分紅。
????????能否平均分配?即挖到區(qū)塊后獎勵平分給所有礦工。這樣就完全是吃大鍋飯的模式了,有的礦工完全可以不干活或者少干活,所以需要按礦工的貢獻(xiàn)大小進(jìn)行分配,所以這里也需要工作量證明,來證明每個礦工所做的工作。
????????每個礦工單打獨(dú)斗之所以收入不穩(wěn)定,是因?yàn)橥诘V難度太大了(相比比特幣系統(tǒng)的平均出塊時間),所以可以考慮礦池將挖礦的難度降下來。比如本來要求前面有70個0,現(xiàn)在礦池只要求前面有60個0,這樣挖到的是一個share(almost validblock),即這個區(qū)塊差不多在一定程度上是符合難度要求的。礦工挖到這樣的區(qū)塊之后,將其提交給礦主,礦主拿到這些區(qū)塊并沒有什么用,僅僅是因?yàn)槟繕?biāo)空間是這個問題的解空間的子集,并且求解兩個問題的過程是一樣的(都是計(jì)算哈希),因此這些區(qū)塊可以作為證明礦工所做的工作量的證明。等到某個礦工真正挖到礦,獲取出塊獎勵之后,再按照大家提交的share的多少來進(jìn)行分配。
礦工能否在參與礦池時獨(dú)吞出塊獎勵?
????????是否會有這樣的礦工:挖到share提交給礦主,挖到真正的礦自己發(fā)布出去以獲取出塊獎勵?這是沒法獨(dú)吞出塊獎勵的,因?yàn)槊總€礦工的任務(wù)是由礦主來分配的,礦主負(fù)責(zé)組裝好區(qū)塊,然后交給礦工去不斷嘗試nonce和CoinBase transaction中的extra nonce,有可能就是講它們劃分一下,然后分配給不同的礦工去做,要注意鑄幣交易CoinBase transaction中的收款人地址是礦主的地址,不是任何一個礦工的地址。
????????如果自己把鑄幣交易的地址改成自己的,然后去挖礦,這樣提交上去的share礦主是不認(rèn)可的,所以還是沒有用。
礦池之間的競爭
????????礦池之間是有競爭對手的,一種競爭方式就是到對方的礦池里去搗亂,即派遣一些礦工去加入到對方的礦池里去挖礦,只提交share,但挖到真正的礦就將其丟棄掉,故意不提交。然而如果這個對手礦池仍然獲得了出塊獎勵,這些礦工也能參與分紅。
大型礦池帶來的危害
????????如果沒有礦池,如果要發(fā)動51%攻擊,攻擊者要花費(fèi)大量的硬件成本。有了礦池以后,礦池實(shí)際上將算力集中了起來,攻擊者未必?fù)碛泻芏嗨懔?#xff0c;只要吸引大量的不明真相的群眾將算力集中到自己的礦池就可以。
????????在2014年的時候GHash礦池的總算力就超過了比特幣系統(tǒng)中總算力的一半,引起了恐慌,然后GHash主動減少了算力,以防止大家對比特幣失去信心。如今的礦池的算力還算比較分散,有好幾家礦池在競爭,但一個集體的算力完全可以潛伏分散在不同礦池中,等到攻擊時再集中起來,礦工要轉(zhuǎn)換礦池是很容易的。
這有點(diǎn)類似云計(jì)算中ODC(
on demand computing
)的概念,平時不需要維護(hù)這些節(jié)點(diǎn),需要計(jì)算時再召集起來。
????????礦池要收取管理費(fèi),有的收取出塊獎勵中的一部分,有的收取賺取的交易費(fèi)。有惡意的礦池可以在發(fā)動攻擊之前故意將管理費(fèi)降得很低,吸引大量礦工進(jìn)入礦池。
假設(shè)出現(xiàn)超大型礦池,具體能發(fā)動哪些攻擊?
假設(shè)有礦池占據(jù)了半數(shù)以上的算力,能夠發(fā)動下面這些攻擊:
[1]分叉攻擊
因?yàn)?strong>算力占了半數(shù)以上,并且礦工挖礦任務(wù)被分配開并行進(jìn)行,分叉出來的鏈的增長速度很快,最終勢必成為最長合法鏈。
[2]Boycott
假設(shè)攻擊者不喜歡某個賬戶A,不允許和A有關(guān)的所有交易上鏈。這時如果有人發(fā)布了含有和A有關(guān)的交易的區(qū)塊,它可以很快發(fā)布一個不包含這些交易的區(qū)塊,然后不必等候6個確認(rèn)區(qū)塊,立即發(fā)布到比特幣網(wǎng)絡(luò)上競爭最長合法鏈。
這里不必等候的原因是,之前普通分叉攻擊等候幾個確認(rèn)區(qū)塊只是為了讓收款人認(rèn)為已經(jīng)沒問題了,已經(jīng)成功收款了,這里沒有這種顧慮。
在之前學(xué)習(xí)共識協(xié)議時學(xué)過,大部分節(jié)點(diǎn)是誠實(shí)節(jié)點(diǎn)時,記賬權(quán)也可能落在有惡意的節(jié)點(diǎn)手里,它完全可以不發(fā)布某些交易,但在那種情形下總有誠實(shí)的節(jié)點(diǎn)愿意發(fā)布這些交易,所以是沒關(guān)系的。
但當(dāng)在這種情況下,即有惡意的節(jié)點(diǎn)算力很大時,卻可以始終讓某些交易不上鏈。即完全可以公開抵制某些交易,這樣一來別的礦工也不敢隨便打包這些交易了,因?yàn)楹芸赡茏约盒量嗤诘牡V最后淪為丟棄的區(qū)塊。
[3]無法進(jìn)行盜幣
不論算力再強(qiáng),因?yàn)闆]法偽造別人賬戶的簽名(除非獲得其私鑰),所以沒法偽造交易將別人賬戶上的BTC轉(zhuǎn)走。即便是仗著自己算力強(qiáng),強(qiáng)行將不合法的區(qū)塊發(fā)布到區(qū)塊鏈上并沿著這條鏈繼續(xù)延伸,誠實(shí)的節(jié)點(diǎn)依然不會沿著這條不合法的長鏈延伸,所以還是沒用的。
8. 比特幣腳本
比特幣系統(tǒng)中使用的腳本語言很簡單,唯一能訪問的內(nèi)存空間就是一個棧,這點(diǎn)和通用腳本語言的區(qū)別很大。
在blockchain.info上觀察一個交易
以下面這個交易為例:
這個交易有一個輸入和兩個輸出,其中一個輸出已經(jīng)被花出去了,另一個沒有被花出去。
輸入腳本
輸入腳本包含兩個操作,分別將兩個很長的數(shù)壓入棧中。
輸出腳本
輸出腳本有兩行,分別對應(yīng)上面的兩個輸出,即每個輸出有自己單獨(dú)的一段腳本。
交易的結(jié)構(gòu)
這些部分直接截圖肖老師的PPT,在PPT上記一下筆記,在blockchain.info上不太好找那個交易的這些詳細(xì)信息。
交易的整體結(jié)構(gòu)
這里可以看到很多meta data。
交易的輸入
交易的輸入是一個列表,這個例子中輸入只有一個,所以這個列表也就只有一個列表項(xiàng)。
如果一個交易有多個輸入,那么每個輸入都要指明來源,并給出簽名。
交易的輸出
交易的輸出也可以有多個,形成列表。
一個直觀的例子
下圖中兩個交易分屬兩個區(qū)塊,中間隔了兩個區(qū)塊,B轉(zhuǎn)給C的這個交易的BTC的來源是前面A轉(zhuǎn)給B的這個交易。所以右邊這個交易中的相應(yīng)輸入的txid是左邊這個交易的id,右邊這個交易中的vout指向的是左邊這個交易的對應(yīng)輸出。
在早期的比特幣系統(tǒng)中,要驗(yàn)證這個交易的合法性,就要把B->C這個交易的輸入腳本,和A->B這個交易的輸出腳本拼在一起執(zhí)行,看看能不能執(zhí)行通過。
后來,出于安全因素的考慮,這兩個腳本改為分別執(zhí)行,首先執(zhí)行輸入腳本,如果沒有出錯,那么再執(zhí)行輸出腳本,如果能順利執(zhí)行,并且最后得到非零值(true),那么這個交易就是合法的。
如果一個交易有多個輸入,每個輸入腳本都要去找到前面特定區(qū)塊中所對應(yīng)的輸出腳本,匹配之后來進(jìn)行驗(yàn)證。全部驗(yàn)證通過后,這個交易才是合法的。
輸入/輸出腳本的幾種形式
[1]P2PK(Pay to Public Key)
簡述
輸入腳本中直接給出付款人的簽名(付款人用自己的私鑰對輸入腳本所在的整個交易的簽名),輸出腳本中直接給出收款人(注意在這里肯定要是同一個人)的公鑰,最后的CHECKSIG是檢查簽名時用的指令。
這種形式的腳本是最簡單的,因?yàn)镻ublic Key是直接在輸出腳本中給出的。
執(zhí)行情況
一共三條語句,從上往下執(zhí)行。
第一條語句,將輸入腳本中的簽名壓入棧:
第二條語句,將輸出腳本中的公鑰壓入棧:
第三條語句,彈出棧頂?shù)膬蓚€元素,用公鑰PubKey檢查一下簽名Sig是否正確。如果正確,返回True,說明驗(yàn)證通過:
[2]P2PKH(Pay to Public Key Hash)
簡述
P2PKH的輸出腳本中沒有給出收款人的公鑰,給出的是公鑰的哈希值。在輸入腳本中給出了這個人的公鑰(也就是既要給出公鑰又要給出簽名)。其它的都是一些操作指令,后面詳細(xì)學(xué)習(xí)它們是怎么運(yùn)行的。P2PKH是最常用的一種形式。
執(zhí)行情況
一共七條語句,從上往下執(zhí)行。
第一條語句,將輸入腳本中的簽名壓入棧:
第二條語句,將輸入腳本中的公鑰壓入棧:
第三條語句,將棧頂元素復(fù)制一遍(所以又壓入了一次公鑰):
第四條語句,將棧頂元素取出來取哈希,再將得到的哈希值壓入棧(也就是將棧頂?shù)墓€變成了其哈希值):
第五條語句,將輸出腳本中提供的公鑰的哈希值壓入棧:
第六條語句,彈出棧頂?shù)膬蓚€元素,比較它們是否相等(防止有人用自己的公鑰冒充幣的來源的交易的收款人的公鑰):
第七條語句,彈出棧頂?shù)膬蓚€元素,用公鑰PubKey檢查一下簽名Sig是否正確。如果正確,返回True,說明驗(yàn)證通過:
[3]P2SH(Pay to Script Hash)
簡述
這是最復(fù)雜的一種形式,這種形式下輸出腳本給出的不是收款人的公鑰的哈希,而是收款人提供的贖回腳本(Redeem Script)的哈希。將來要花這個輸出腳本的BTC的時候,相應(yīng)交易的輸入腳本要給出贖回腳本的具體內(nèi)容,同時還要給出讓贖回腳本能正確運(yùn)行所需要的簽名。
兩步驗(yàn)證
在驗(yàn)證時,一方面,驗(yàn)證輸入腳本給出的贖回腳本內(nèi)容,是否和對應(yīng)輸出腳本給出的贖回腳本哈希值相匹配;另一方面,反序列化并執(zhí)行贖回腳本,以驗(yàn)證輸入腳本給出的簽名是否正確。
贖回腳本的形式
P2PK形式
P2PKH形式
多重簽名形式
用P2SH實(shí)現(xiàn)P2PK的功能
贖回腳本中給出公鑰,輸入腳本中給出交易簽名和贖回腳本具體內(nèi)容,輸出腳本中給出了贖回腳本的哈希值。
第一階段的驗(yàn)證,先驗(yàn)證輸入腳本和輸出腳本在一起執(zhí)行的結(jié)果。
第一步,將輸入腳本中的交易簽名壓入棧:
第二步,將輸入腳本中給出的贖回腳本壓入棧:
第三步,彈出棧頂元素取哈希再壓棧,也就得到了贖回腳本的哈希(Redeem Script Hash):
第四步,將輸出腳本中給出的贖回腳本的哈希值壓入棧:
第五步,比較棧頂兩個元素是否相等,相當(dāng)于用之前的輸出腳本給出的贖回腳本哈希,驗(yàn)證了輸入腳本提供的贖回腳本是否是正確的:
第二階段的驗(yàn)證,是對輸入腳本提供的贖回腳本的驗(yàn)證,首先要將其反序列化,得到可以執(zhí)行的贖回腳本。然后執(zhí)行這個贖回腳本。
第一步,將腳本中寫死的公鑰壓入棧:
第二步,驗(yàn)證輸入腳本中給出的交易簽名的正確性。驗(yàn)證通過就會返回True:
P2SH在最初版本的比特幣系統(tǒng)中是沒有的,后來通過軟分叉的形式加進(jìn)去了,它常用的一個場景就是多重簽名。
9.比特幣分叉
分叉是指區(qū)塊鏈從一條鏈變成兩條或者多條鏈。
分叉分為:狀態(tài)分叉和協(xié)議分叉。
狀態(tài)分叉:由于對比特幣當(dāng)前的狀態(tài)產(chǎn)生分歧而導(dǎo)致的分叉
協(xié)議分叉:由于對比特幣協(xié)議產(chǎn)生分歧而導(dǎo)致的分叉
根據(jù)對協(xié)議修改的內(nèi)容不同,協(xié)議可以分為硬分叉和軟分叉
2、硬分叉
????????如果區(qū)塊鏈軟件的共識規(guī)則被改變,并且這種規(guī)則改變無法向前兼容,舊節(jié)點(diǎn)無法認(rèn)可新節(jié)點(diǎn)產(chǎn)生的區(qū)塊,區(qū)塊鏈發(fā)生永久性分歧,即為硬分叉
????????如區(qū)塊大小的改變。假設(shè)新規(guī)則從1M變成4M,新規(guī)則下的節(jié)點(diǎn)都會認(rèn)可大節(jié)點(diǎn)和小節(jié)點(diǎn),會接著大節(jié)點(diǎn)來進(jìn)行擴(kuò)展,但是舊規(guī)則下的節(jié)點(diǎn)只會接受小節(jié)點(diǎn),所以只會接著小節(jié)點(diǎn)來擴(kuò)展,這樣就會形成兩條鏈。并且區(qū)塊獎勵是否有效也會進(jìn)行分叉,比如下面這條鏈中的區(qū)塊獎勵在下面這條鏈上是被認(rèn)可的。
必須要系統(tǒng)中所有節(jié)點(diǎn)都更新軟件系統(tǒng)才不會出現(xiàn)永久性的分叉
(一般是放寬限制)
如:比特幣現(xiàn)金、比特幣黃金、比特幣鉆石、以太坊經(jīng)典
比特幣的分叉幣是從比特幣區(qū)塊鏈上分叉出來的新加密貨幣,旨在改進(jìn)或擴(kuò)展比特幣的功能。以下是幾種主要的比特幣分叉幣及其特點(diǎn):
1. 比特幣現(xiàn)金(Bitcoin Cash, BCH)
-
分叉時間:2017年8月1日
-
主要改進(jìn):將區(qū)塊大小從1MB增加到8MB(后升級至32MB),以提高交易速度和降低手續(xù)費(fèi)。每個比特幣投資者的賬戶上將出現(xiàn)與比特幣數(shù)量等量的比特幣現(xiàn)金
-
目標(biāo):成為更適合日常支付的數(shù)字貨幣。
2. 比特幣黃金(Bitcoin Gold, BTG)
-
分叉時間:2017年10月24日
-
主要改進(jìn):采用Equihash算法,使普通用戶可用GPU挖礦,減少ASIC礦機(jī)的壟斷。
-
目標(biāo):實(shí)現(xiàn)更去中心化的挖礦機(jī)制。
3. 比特幣SV(Bitcoin SV, BSV)
-
分叉時間:2018年(從BCH分叉)
-
主要改進(jìn):將區(qū)塊大小增至128MB,強(qiáng)調(diào)回歸中本聰?shù)脑荚O(shè)計(jì)。
-
目標(biāo):支持大規(guī)模商業(yè)應(yīng)用。
4. 比特幣鉆石(Bitcoin Diamond, BCD)
-
分叉時間:2017年11月24日
-
主要改進(jìn):增強(qiáng)隱私保護(hù)功能,并提高交易速度。
-
目標(biāo):提供更安全的匿名交易。
5. 比特幣私人(Bitcoin Private, BTCP)
-
分叉時間:2018年2月28日
-
主要改進(jìn):結(jié)合比特幣和ZClassic的隱私技術(shù)(zk-SNARKs),提供匿名交易。
-
目標(biāo):增強(qiáng)交易隱私性。
6. 閃電比特幣(Lightning Bitcoin, LBTC)
-
分叉時間:2017年12月
-
主要改進(jìn):采用DPoS共識機(jī)制(類似EOS),提高交易速度。
-
目標(biāo):解決比特幣的可擴(kuò)展性問題。
7. 超級比特幣(Super Bitcoin, SBTC)
-
分叉時間:2017年12月12日
-
主要改進(jìn):計(jì)劃引入智能合約、閃電網(wǎng)絡(luò)和零知識證明。
-
爭議:預(yù)挖21萬枚SBTC,引發(fā)社區(qū)質(zhì)疑。
其他分叉幣
-
比特幣黎明(Bitcoin Dawn)
-
比特幣星云(Bitcoin Nebula)
-
比特幣風(fēng)暴(Bitcoin Storm)
(部分分叉幣已逐漸淡出市場)。
總結(jié)
比特幣的分叉幣主要在擴(kuò)容、隱私、挖礦去中心化等方面進(jìn)行改進(jìn),其中BCH、BSV、BTG等仍有一定市場影響力,而許多其他分叉幣已逐漸消失79。投資者需謹(jǐn)慎評估其技術(shù)和社區(qū)支持情況。
如需更詳細(xì)的分叉幣列表,可參考相關(guān)區(qū)塊鏈數(shù)據(jù)平臺或交易所信息。
3、軟分叉
如果區(qū)塊鏈的共識規(guī)則被改變后,這種改變是向前兼容的,舊節(jié)點(diǎn)可以兼容新節(jié)點(diǎn)產(chǎn)生的區(qū)塊,就會產(chǎn)生臨時性區(qū)塊,即為軟分叉。
通過軟件更新增加一些限制,使得原來合法的區(qū)塊在新協(xié)議中不合法。
例如區(qū)塊大小從1M到0.5M。
此時,新舊節(jié)點(diǎn)都會認(rèn)可上面那條鏈,但是只有舊節(jié)點(diǎn)會認(rèn)可下面這一條。所以新節(jié)點(diǎn)只會沿著上面的鏈擴(kuò)展,舊節(jié)點(diǎn)不一定,但是新節(jié)點(diǎn)擁有大部分的算力,所以隨著上面那條鏈的長度增加,下面的鏈就會作廢,最終大家都會認(rèn)可上面那條鏈。
只要系統(tǒng)中擁有半數(shù)算力以上的節(jié)點(diǎn)更新了軟件,系統(tǒng)就不會出現(xiàn)永久性的分叉,肯能會有臨時性的分叉
(一般是增加限制)
4、比特幣系統(tǒng)
4.1比特幣網(wǎng)絡(luò)
運(yùn)行過程:
隱私交易與交易者的連接,類似股票交易
10.比特幣匿名性
比特幣中的匿名: ? ? ??
? ? ? ? 用戶可以使用公鑰產(chǎn)生任意多地址,然后使用不同的地址進(jìn)行交易。
什么情況可能破壞匿名性:
- ? ? 不同地址被關(guān)聯(lián)在一起? ? ? ?網(wǎng)上購物:Input中的addr1、addr2....以及可能存在output中的找零地址(找零的錢肯定是比input中最小的UTXO更小)會被推斷為一個人(因?yàn)橥瑫r擁有這些地址的私鑰)
- 和現(xiàn)實(shí)產(chǎn)生聯(lián)系時,存在資金泄露問題:? 用來支付的時候 ?賬戶就會和實(shí)現(xiàn)身份建立聯(lián)系。如果在交易過程中周圍人記住這筆交易,在鏈上查詢,就能通過這個交易查詢關(guān)聯(lián)到賬戶
如何提高匿名性?
? ? ? ? 網(wǎng)絡(luò)層匿名性:洋蔥路由TOR(只知道上一個節(jié)點(diǎn)是誰,而不知道最早發(fā)出的節(jié)點(diǎn)是誰)
? ? ? ? 應(yīng)用層匿名性:Coin mixing 把幣混在一起,讓人分不出來(把幣發(fā)給提供Coin mixing服務(wù)的網(wǎng)站,再取回來隨機(jī)抽取的幣)
零知識證明:
? ? ? ? 證明者向驗(yàn)證者證明一個陳述是正確的,但不需要透露除了這個陳述是正確的之外的信息。
例1:證明某個比特幣賬戶的所有權(quán)(證明者知道賬戶私鑰) ? ? ? ?解決方法:數(shù)字簽名
同態(tài)隱藏:
? ? ? ? 1. 如果x,y不同,那么它們的加密函數(shù)值E(x)和E(y)也不相同。(不同于hash可能會存在碰撞,同時如果E(x)=E(y),說明x=y)
? ? ? ? 2. 給定E(x)的值,很難反推出x的值。
? ? ? ? 3. 給定E(x)和E(y)的值,可以很容易地計(jì)算出某些關(guān)于x,y的加密函數(shù)值。
? ? ? ? ? ? ? ? -同態(tài)加法:通過E(x)和E(y)計(jì)算出E(x+y)的值? ? ? ? ? ? ? ? -同態(tài)乘法:通過E(x)和E(y)計(jì)算出E(xy)的值
? ? ? ? ? ? ? ? -擴(kuò)展到多項(xiàng)式
例:證明x+y7,但是不透露x、y的具體值
公開E(x)、E(y),通過同態(tài)隱藏的性質(zhì)3算出E(x+y)的值,再對比E(7)的值,如果相同則驗(yàn)證通過,否則驗(yàn)證失敗。
盲簽方法:
- ? ? ? ? 用戶A提供SerialNum,銀行在不知道SerialNum的情況下返回簽名Token,減少A的存款
- ? ? ? ? 用戶A把SerialNum和Token交給B完成交易用戶
- ? ? ? ? B拿SerialNum和Token給銀行驗(yàn)證,銀行驗(yàn)證通過,增加B的存款
- ? ? ? ? 銀行無法把A和B聯(lián)系起來。
- ? ? ? ? 中心化 ? ? ? ?
零幣和零鈔
? ? ? ? 零幣和零鈔在協(xié)議層就融合了匿名化處理,其匿名屬性來自密碼學(xué)保證。
? ? ? ? 零幣(zerocoin)系統(tǒng)中存在基礎(chǔ)幣和零幣,通過基礎(chǔ)幣和零幣的來回轉(zhuǎn)換,消除舊地址和新地址的關(guān)聯(lián)性,其原理類似于混幣服務(wù)。? ? ? ?
???????? 零鈔(zerocash)系統(tǒng)使用zk-SNARKs協(xié)議,不依賴一種基礎(chǔ)幣,區(qū)塊鏈中只記錄交易的存在性和礦工用來驗(yàn)證系統(tǒng)正常運(yùn)行所需要關(guān)鍵屬性的證明。區(qū)塊鏈上既不顯示交易地址也不顯示交易金額,所有交易通過零知識驗(yàn)證的方式進(jìn)行。