很久之前看過 北京大學肖臻老師《區塊鏈技術與應用》公開課 的比特幣部分,國內少有的高質量科班技術課程。最近又重看了一遍,準備用自己的話寫一下,加深下理解。
密碼學原理
比特幣通過哈希和非對稱加密的簽名,來保障安全。
生成的錢包和簽名的信息需要足夠隨機的 source. 否則可能洩漏私鑰。
協議
- 如何防止
double spent
轉賬方需要公佈自己的公鑰,讓節點使用公鑰驗證自己的簽名。
FLP
一個異步系統,即使只有一個成員是 faulty 的,也不可能取得共識。
CAP Theorem 的不可能三角
Consistency一致性Availability可用性Partition tolerance分區容錯性:指分佈式系統在遇到網絡分區(即某些節點之間的網絡連接中斷)時,仍能夠繼續正常工作的能力。
Paxos 著名的共識協議
比特幣的共識協議
通過比拼算計,找到正確範圍內的 nonce, 獲得記賬權(會獲得區塊獎勵),達成共識。
只有最長合法鏈會得到認可。
分叉可能會維持一段時間,知道最後有一條鏈成為最長合法鏈。
實現
UTXO
unspent transaction output 維護賬本中未被消費的賬戶餘額,用於快速驗證交易合法性。
每一筆交易都會有交易費,交易費會獎勵給區塊打包者,也就是礦工。
驗證交易合法性
提供幣來源的輸出腳本和本次交易的輸入腳本拼接後能順利執行,不出現錯誤。即代表交易合法。
等待越多的區塊,交易的確認會越有保障,因為越難篡改。
網絡
P2P 網絡,在網絡裏面所有節點都是平等的。通過 TCP 通信,有利於穿透防火牆。
消息傳遞性質是 Flooding (Best effort), 收到消息之後,轉發給其他節點,同時記錄這個消息自己已經收到過了。
為了保證區塊傳播,區塊大小限制是 1M.
挖礦 & 挖礦難度
全節點
- 一直在線;
- 在本地硬盤上維護完整的區塊鏈信息;
- 在內存裏維護
UTXO集合,以便快速檢驗交易的正確性; - 監聽比特幣網絡上的交易信息,驗證每個交易的合法性;
- 決定哪些交易會被打包到區塊裏;
- 監聽別的礦工挖出來的區塊,驗證其合法性;
- 挖礦:
- 決定沿著哪條鏈挖下去?
- 當出現等長的分叉的時候,選擇哪一個分又?
輕節點
- 不是一直在線;
- 不用保存整個區塊鏈,只要保存每個區塊的塊頭;
- 不用保存全部交易,只保存與自己相關的交易;
- 無法檢驗大多數交易的合法性,只能檢驗與自己相關的那些交易的合法性;
- 無法檢測網上發布的區塊的正確性;
- 可以驗證挖礦的難度;
- 只能檢測哪個是最長鏈,不知道哪個是最長合法鏈。
比特幣的挖礦本質上是通過計算找到在合理範圍內的 nonce, 這個過程是 memoryless (progress free)的。
要成為最長合法鏈不止是找到在合理範圍內的 nonce, 還要被最先其他節點採納,也就是要盡快提交到網絡中。
挖礦難度會在每 2016 個區塊之後進行調整,理想的時間是 2016 區塊 × 10 分鐘 = 1209600 秒(14天)(三年來的出塊時間)。超過理想時間會降低難度,低於理想時間提高難度。通過調整,使得實際出塊時間逼近理想時間。也就是一般 14 天左右會調整一次難度。

到時間不調整難度的礦工出的區塊會無法通過驗證,是不會被其他節點接受的。
一個我覺得很有趣的結論,💡比特幣的挖礦難度和價格基本成正比。一個幣難度越來愈低,說明市場熱情在降低,這對於幣的價值是不利的,反之亦然。

現在的挖礦已經從最開始的 CPU 挖礦,到 GPU 挖礦,到現在的 ASIC 芯片挖礦了。
而且競爭非常激烈,普通人基本沒有機會拿到記賬權。可以通過加入礦池(Mining Pool),貢獻算力,計算出 share,最後按勞分配。
計算得到的 share 不一定是最後要找的 nonce,最後只會得到 Almost valid block.
礦池記錄每個礦工提交的 share 份額,並最終按比例發放獎勵。
這裏不存在礦工計算得到正確的 nonce 不提交給礦池私自到比特幣網絡提交 block 的可能。
試圖損人利己,是不可能的:
- 區塊獎勵的地址是礦池的;
- 如果礦工私自修改獎勵地址,礦主驗證會失敗,
nonce和獎勵地址是綁定的,提交的share份額也會作廢。
試圖損人不利己,是可能的:
- 挖到
share不提交,因為礦池之間存在競爭。
危機:礦池集中過多算力,可能會導致 51% 攻擊:
Forking attack, 可回滾交易;Boycott, 拒絕特定的交易;
分叉
硬分叉,軟分叉都是因為協議不同導致出現分叉。
硬分叉是永久性的,舊節點不認新協議挖出的節點; 軟分叉是臨時性的,舊節點也會認可新協議挖出的節點。
比特幣著名的軟分叉 P2SH: Pay to Script Hash.
匿名性
一筆交易的多個輸入地址和輸出地址可以關聯起地址。
任何比特幣和現實世界發生的聯繫都可能被追踪到真實身份。
保持匿名性最好的比特幣用戶,中本聰,擁有大量比特幣卻沒有花;也沒有為出名而現身。不為名不為利,就是保持匿名性最好的方法。
可以用閃電網絡完成交易。
coin mixing 有提供這種服務的供應商;某些在線錢包或者交易所的交易(交易所不泄漏交易信息)也帶有這個屬性。
零知識證明
零知識證明是指一方(證明者)向另一方(驗證者)證明一個陳述是正確的,而無需透露除該陳述是正確的外的任何信息。
錢包(私鑰)擁有者對信息進行簽名,驗證者使用公鑰驗證簽名。即可證明誰是錢包(私鑰)擁有者。
是否屬於零知識證明?有爭議,因為多給出了簽名信息。
思考
比特幣很多有意思的使用例子,區塊戀… 😆
肖臻老師的一段話,我很受用:
很多理論上的不可能,在現實中是可能的。同學們不要被學術思維限制了頭腦。不要被程序員的思維限制了想象力。
量子計算的威脅
量子計算不能擊潰比特幣,公開的是取哈希後的公鑰,這個過程是不可逆的。再去推導私鑰更是不可能。
公鑰只有在轉出比特幣的時候才會暴露,因為最為安全的做法應該是比特幣地址每一筆交易之後就換一個新錢包,儘管需要花費一些交易費。
一些我的感悟
比特幣設計的網絡等等,都很簡單其實,理解起來也很容易。網絡以 Robust 為先,它不高效,要十分鐘才出一個塊,但是系統設計的美感很在線。又回到軟件工程學裏面的那句話:
Keep it simple! Stupid!
最後,下面這句是肖臻老師課程資料裏面的一句話,送給看到這裏的你。
炒幣有風險,投資需謹慎。
BTW,2018 年要是看完課程買的話,現在回報率應該還是不錯的吧。lol