1. 程式人生 > 實用技巧 >區塊鏈筆記-(肖臻)(二刷自用筆記)

區塊鏈筆記-(肖臻)(二刷自用筆記)

區塊鏈筆記-(肖臻)(二刷自用筆記)

密碼學

crypto-currency 加密貨幣

cryptographic hash function 密碼學

hash

collision resistance(不可篡改,經驗證明) hiding puzzle friendly

1.H(m) m為內容,沒有辦法修改內容 變為m’ 使得H(m’)為原來的值 可以用hash值比較看原來的內容有沒有被篡改

沒有哪一個可以被證明----人為檢驗 MD5可以人為碰撞

X------>H(X) 不可逆推 ,輸入空間大,且分佈比較均勻

2.digital commitment/ digital equivalent of sealed envelope 我們可以用hiding的性質,公佈出hash值,檢驗是否正確

x值比較小可以加一個nonce拼接起來

3.hash值的計算,是不可預測的(落在哪個空間)

應用(比特幣)H(block header)<=target pow工作量證明 沒有捷徑-大量工作找出nonce 但是證明很容易

簽名

怎樣開賬戶?

建立一個公私鑰的對(public key,private key) 非對稱加密體系

我用你的公鑰加密,你用你的私鑰解密 A用B的公鑰對內容進行加密,B用自己的私鑰解密(用的同一個人的公私鑰)

A釋出一筆交易,用A的私鑰簽名,其他人可以用A的公鑰驗證,是否是A發起的交易

公私鑰對建立相同-(概率極小) a good source of randomness (好的隨機緣)

資料結構

hash pointer

p指向結構點的指標,存放結構體的位置 H()->不僅存放結構體的位置,還有hash值-能檢測內容有沒有被篡改

區塊鏈 Block chain is a linked list using hash pointers

[ ] <- [ ] <-[ ] <- [ ] <-[ ] <- [ ] <-[ ] <- [ ] <-[ ] <- [ ] <-[ ] <- [ ] <-[ ] <- [ ] <-[ ] <- [ ]

| |

genesis block most recent block

區塊鏈第一個區塊叫作創世紀塊(genesis block) 最後一個區塊 是最近產生的區塊(most recent block) 每一個區塊都包含指向前一個區塊的雜湊指標
一個區塊的雜湊指標怎麼算:是把前面整個區塊的內容,包括裡面的hash pointer ,合在一起取雜湊值。通過這種結構,可以實現tamper-evident log。如果有人改變了一個區塊的內容,後面一個區塊的雜湊指標就對不上,因為後一個區塊雜湊指標是根據前一個區塊的內容算出來的,所以後一個雜湊指標也得改,以此類推,我們保留的是最後一個雜湊值也會變化。

Merkle tree

在這裡插入圖片描述

其中最下面一層是資料塊(data blocks),上面三層內部節點都是雜湊指標(hash pointers),第一層是根節點,根節點的區塊也可以取個雜湊,叫根雜湊(root hash))-------這種結構的好處:只要記住根雜湊值,就能檢測出對樹中任何部位的修改。

比特幣當中各區塊之間用雜湊指標連線在一起,每個區塊所包含的交易組織成一個merkle tree的形式,最下面一行data blocks每個區塊實際上是一個交易,每個區塊分為兩部分,分別是塊頭和塊身(block header ,block body)。塊頭裡面有根雜湊值,每個區塊所包含的所有交易組成的merkle tree的根雜湊值存在於區塊的塊頭裡面,但是,塊頭裡沒有交易的具體內容,只有一個根雜湊值,塊身裡面是有交易的列表的。

全節點:包含block header -block body

輕節點:只有block header

Merkle Proof

這時存在一個問題:如何向一個輕節點證明某個交易是寫入區塊鏈的?
這時需要用到merkle proof :找到交易所在的位置(最底行的其中一個區塊),這時該區塊一直往上到根節點的路徑就叫merkle proof

在這裡插入圖片描述

proof of membership 複雜度 log(n)

proof of non-membership 把整個樹給輕節點,檢視每一層變化,複雜度就是n

對交易內容取Hash 排序,看在哪個之間 log(n)
輕節點中沒包含具體的交易資訊,就給交易證明帶來一些困難。在比特幣系統中採用Merkle proof方法。輕節點想要證明圖中tx(黃色框代表的某一筆)交易,輕節點儲存了區塊頭資訊,需要向全節點請求區中三個紅色H()雜湊資訊,並在本地計算三個綠色H()雜湊資訊,並最終計算Merkle root資訊,如果計算得到的Merkle root資訊和輕節點儲存在區塊頭中的Merkle root資訊一致,那麼證實了區塊中確實記錄了該筆交易。

sorted Merkle tree 比特幣不需要證明不在

無環都可以用hash指標,由環的就可以

BTC協議

交易

double spending attack(雙花攻擊 )

誰發行貨幣?

怎麼防範double spending attack-區塊鏈(類似於央行數字貨幣的大型資料庫)

區塊鏈之間進行轉賬交易

1.A給B轉錢 -幣的來源 ,A的公鑰 -輸出 收款人公鑰的hash

2.A需要幹什麼,要什麼?A的簽名,B的地址 比特幣系統裡收款的地址是通過公鑰推算出來的。比如B的地址就是B的公鑰取雜湊然後經過一些轉換得到的。

3.B?B需要知道A的公鑰(身份)–所有都要知道A的公鑰 怎麼才能知道A的公鑰?1.

那就存在了安全漏洞,假如B的同夥偽造了這次交易呢?其實第一個方框裡鑄幣交易的輸出就有A的公鑰的雜湊,所以第二個方框交易裡A的公鑰要跟前面雜湊對的上。

注意:coinbase tx 要和交易中A的公鑰說明要和幣的來源的hash要對的上

在比特幣系統當中,前面這些驗證過程,是通過執行指令碼來實現的。每個交易的輸入提一段指令碼,包括給出公鑰的過程,公鑰也是在輸入的腳本里指定的。每個交易的輸出也是一段指令碼,驗證其的合法性,就需要把當前交易的輸入指令碼跟前面交易(提供幣來源的交易)的輸出指令碼拼在一起,然後看看能不能順利執行,如果能執行說明是合法的。比特幣指令碼(BitCoin Script)。

實際上每個區塊(對應圖中的每個方框)可以有很多交易,這些交易就組成merkle tree。每個區塊分為塊頭和塊身。

塊頭包含的是區塊的巨集觀資訊,比如:用的是比特幣哪個版本(version)的協議,區塊鏈當中指向前一個區塊的指標(hash of previous block header),整顆merkle tree 的根雜湊值(merkle root hash),還有兩個域是跟挖礦相關的,一個是挖礦的難度目標預值(target),另一個是隨機數nonce。

這裡的target,就是前面講到的,整個塊頭的雜湊要小於這個預值,即H(block header)≤target。block header裡存的就是這個目標預值的編碼(nBits)。這裡需要注意,前一個區塊的雜湊只算的是前一個區塊的塊頭,所以前面畫的,一個區塊引出一個剪頭指向另一個區塊中間,是不正確的,所以有的書剪頭是指向一個區塊的上面。取雜湊時是把塊頭的所有部分都取雜湊。

塊身裡面有交易列表(transaction list)。

全節點-輕節點

每個節點都需要驗證所有的交易,實際上系統中的節點分全節點(full node)和輕節點(light node),全節點是儲存區塊鏈所有的資訊的,驗證每一個交易,所以全節點又叫fully validating node。輕節點只儲存block header的資訊,一般來說輕節點沒法獨立驗證交易的合法性。

比如一個交易是不是double spending,輕節點沒有存以前的交易資訊所以它沒法驗證。系統中大多數節點是輕節點,這節課內容主要針對全節點,因為輕節點沒有參與區塊鏈的構造和維護,只是利用了區塊鏈的一些資訊做一些查詢。

寫入區塊鏈

區塊鏈裡的內容是如何寫到區塊鏈裡面的呢:每個節點,每個賬戶都可以釋出交易,交易是廣播給所有節點的。有些交易是合法的,有些是非法的。誰來決定哪些交易應該被寫入下一個區塊中呢?按照什麼順序寫呢?如果每個節點自己決定可以嗎?如果每個人在本地維護一個區塊鏈,那區塊鏈的統一性得不到保證,而賬本的內容是要取得分散式的共識(distributed consensus)。

下面的筆記跟比特幣的應用關係不大,可以作為了解:
分散式的共識一個簡單的例子就是分散式的雜湊表(distributed hash table),比如系統裡有很多臺機器,共同維護一個全域性的雜湊表。

這裡需要取得共識的內容是什麼?雜湊表中包含了哪些鍵值對key valve pair。假如有人在自己電腦上插入一個鍵值對,'xiao’這個pair對應的是12345,即’xiao’→12345。那麼別人在另一臺讀的時候也要能把這個讀出來,這就叫一個全域性的雜湊表。

關於分散式系統有很多不可能結論(impossibility result),其中最著名的是FLP。這三個字母是三個專家的名字縮寫,他們的結論是:在一個非同步的(asynchronous)系統裡,(網路傳輸遲延沒有上限就叫非同步系統),即使只有一個成員是有問題的(faulty),也不可能取得共識。

還有一個著名結論:CAP Theorem。(CAP是指分散式系統的三個我們想要的性質,Consistency【系統狀態的一致性】 Availability【別人都可以用】 Partition tolerance)。該理論內容是:任何一個分散式系統,比如分散式雜湊表,這三個性質中,最多隻能滿足兩個,假如想要前兩個性質,那麼就不會得到第三個性質。

分散式共識一個著名的協議是Paxos,該協議能夠保證一致性,即第一個性質。如果該協議打成了共識,那麼這個共識一定是一致的,即每個成員所認為的共識都是相同的。但是,某些情況下,該協議可能永遠無法達成共識,這種可能性比較小但是客觀存在的。

比特幣中的共識協議(consensus in BitCoin):

比特幣中共識要解決的一個問題是,有些節點可能是有惡意的。我們假設系統中大多數節點是好的,那麼該如何取得共識協議?

第一種方案是投票,首先應該確定哪些區塊有投票權,有些membership是有嚴格要求的,這種情況下基於投票的方案是可行的。但比特幣系統建立賬戶是很容易的,甚至一個人產生了公私鑰對別人都無法得知,只有轉賬時別人才知道。所以有些人可以不停的建立賬戶,當超過賬戶總數的一半時就有了控制權,這種稱為女巫攻擊(sybil attack)。因此投票方法不可取。

比特幣賬戶巧妙的解決了這個問題,不是按照賬戶數目投票,而是按照計算力來投票。每個節點都可以在本地組裝出一個候選區塊,把它認為合法的交易放在裡面,然後開始嘗試各種nonce值(佔4 byte),看哪一個能滿足不等式H(block header)≤target的要求。如果某個節點找到了符合要求的nonce,它就獲得了記賬權。

所謂的記賬權,就是往比特幣賬本里寫入下一個區塊的權利。只有找到這個nonce,獲得記賬權的節點才有權利釋出下一個區塊。其他節點收到這個區塊之後,要驗證這個區塊的合法性。

假如生成了一個新區塊,怎麼知道新區塊插在了哪裡呢?根據生成區塊的指標。有可能就存在一個問題,這兩個交易指A轉賬給B,以及A轉賬給自己。這種情況不是double spending,判斷一個交易是不是double spending ,是看這個區塊所在的分支上幣又沒有被花掉。如圖,一直到第三個區塊,幣都沒有花過,所以這個交易是合法的。雖然該交易是合法的,但是它不在最長合法鏈(longest valid chain)上。這種稱為分叉攻擊(forking attack)。所以接收的區塊應該是擴充套件最長合法鏈。

區塊鏈在正常情況下也可能出現分岔:兩個節點同時獲得記賬權。每個節點在本地自己組裝一個它認為合適的區塊,然後去試各種nonce,如果兩個節點在差不多同一個時間找到了符合要求的nonce,就都可以把區塊釋出,這時會出現兩個等長的分岔。這兩條都是最長合法鏈,那該接受那條呢?比特幣協議當中,在預設(預設的意思)情況下,每個節點是接受它最早收到的那個。所以不同節點根據在網路上的位置不同,有的節點先聽到新生成的其中一個區塊,那就接受這個區塊;有些節點先聽到另一個區塊,那就接受另一個區塊。

block reward 發行貨幣

那麼能造多少幣呢?開始時比特幣剛上線的時候,每一個釋出的區塊可以產生50BTC(BTC就是比特幣的符號)。協議中規定,21萬個區塊以後,初塊獎勵就要減半,就變成了25BTC。再過21萬個區塊,又要減半。

因此當一個區塊勝出後,另一個作廢的區塊得到的比特幣是沒有作用的,其他誠實的區塊是不會承認的。

比特幣系統中要取得什麼共識?去中心化的賬本要取得共識。誰又能決定賬本的內容呢?只有獲得記賬權的節點才能寫東西。怎麼獲得記賬權呢?就是解pow(挖礦)。按照算力記票,算力可以用每秒能試多少nonce數值表示。那怎樣防範女巫攻擊呢?按算力記票,即使建立再多的賬戶,也無法使算力增強。

比特幣爭奪記賬權的過程叫作挖礦(mining),比特幣被稱為數字黃金(digital gold),爭奪記賬權的節點被稱為礦工(miner)