初識比特幣

語言: CN / TW / HK

一、什麼是比特幣?

A purely peer-to-peer version of electronic cash would allow online payments to be sent directly from one party to another without going through a financial institution.

一個純正的點對點去中心化的加密數字貨幣,應能夠通過線上支付將幣從一方直接傳送到另一方,而無需通過任何中心金融機構。

比特幣是一種加密貨幣(crypto-currency),實現自一個自稱中本聰(Satoshi Nakamoto)的不明身份的人所發表的一篇論文(比特幣白皮書

與其說比特幣是一種加密貨幣,不如說比特幣是一種基於 P2P 網路的支付結算系統,這樣更易於大家理解其本質。

二、為什麼要發明比特幣?

2.1、中心化,基於信任模型

酒花 App 平臺買了兩瓶精釀啤酒
一個自稱三方供應商的人加我微信,告知我其中一瓶酒沒貨了,可以加錢換其他的酒
雖然這個人微信朋友圈都是精釀啤酒相關的內容,且明確知道我買的哪個酒沒貨了
但是,我內心還是不信任這個人,更信任平臺,於是我還是在平臺換了一瓶酒

平臺就真的值得信任麼? 假如我下單的時候正好趕上平臺伺服器宕機,扣款成功了,但沒收到貨。由於平臺系統做的不好,再也找不到那筆訂單,不能證明我付過錢,也不能給我發貨。 這筆交易就沒有人能說的清楚了,信任也就不存在了。

比特幣要去解決信任問題

What is needed is an electronic payment system based on cryptographic proof instead of trust, allowing any two willing parties to transact directly with each other without the need for a trusted third party.

我們真正需要的是一種基於加密演算法密碼學原理而非基於信任的數字貨幣支付系統,不需要可信任第三方參與的情況下,允許雙方直接進行支付交易

decentralized.png

2.2、雙花攻擊(Double Spending Attack)

「雙花」即同一筆錢花了兩次或多次。

double_spending.png

假設央行發行了一款數字貨幣,貨幣在軟體中其實就是檔案,完全可以複製。 假如 A 在轉給 B 100 元后,又複製了同一筆錢轉給了 C,就是所謂的「雙花」,雙花攻擊只通過驗證數字貨幣的簽名是不夠的,還需要使用額外的手段。

比特幣要去解決雙花問題

We propose a solution to the double-spending problem using a peer-to-peer network

我們將在本文提出一種新方案,使用點對點去中心化網路去解決這個雙花問題

比特幣交易小節中,會詳細解釋比特幣是如何解決雙花問題的。

三、比特幣中的密碼學

3.1、雜湊演算法(Hash Algorithm)

雜湊演算法是用來做什麼的呢?我們先來看一個小故事。

雍正到底是不是篡位登基的?

tamper.png

一直有一個傳說稱雍正不是康熙真正傳位的皇帝,而是有人偷偷修改了遺詔,篡位登基的。

假如康熙知道雜湊函式

anti_tamper.png

如果沒有雜湊函式,在康熙皇帝駕崩後,遺詔是死無對證,只能遺詔寫什麼,大臣就做什麼。

但有了雜湊函式後就變得不一樣了,康熙可以在活著的時候就可以提前寫好遺詔,並用雜湊函式計算出一個雜湊串,交予大臣們。 大臣們看到雜湊串也不能猜出遺詔的內容到底是什麼,只能等到遺詔公佈的那天,再去計算一次雜湊值,看與當初皇帝給的雜湊串是否一致,來判斷遺詔是否被人篡改了。 如果修改了,就不會遵詔行事。

通過這個小故事,可以簡單總結出雜湊的兩個性質:

  1. 防篡改,輸入稍有改動,輸出千差萬別
  2. 輸出結果不可逆,只知道結果不能反推出輸入是什麼

3.2、比特幣使用的雜湊演算法

SHA256(Security Hash Algorithm),是一種密碼雜湊函式(Cryptographic Hash Function)。

$任意輸入 ==> SHA256 ==> 256位雜湊$

在比特幣中,利用了SHA256的三個性質 - 不可逆(Hiding) - 抗雜湊碰撞(Collision resistance) - 雜湊值不可預測(Puzzle friendly)

3.2.1、不可逆(Hiding)

SHA256的特性: 1. 輸入長度任意 2. 輸出長度固定,256bit

比如

$全世界的圖書 ==> SHA256 ==> 256 位雜湊$

如果這個過程可逆的話,我們就發現了一種無敵的壓縮演算法,可以把全世界的圖書壓成 256 位,再進行儲存。

3.2.2、抗雜湊碰撞(Collision resistance)

根據抽屜原理,輸入空間無限,輸出空間有限,理論上一定會存在碰撞。

但是,從長期經驗看,沒有什麼人為的、高效的方式製造碰撞。

只能通過暴力遍歷輸入空間的方式來尋找碰撞

3.2.3、雜湊值不可預測(Puzzle friendly)

Puzzle Friendly,直譯為謎題友好性,是指事先給定一個雜湊串,比如 00000000feacb46d... ,前 8 位都是 0,讓你解謎題找到輸入是什麼。

由於 SHA256 沒有直接辦法或通過找到一定規律來猜出輸入是什麼,只能通過暴力遍歷輸入空間的方式來找到答案。(其實一點都不友好)

比如你找到一個輸入 a,輸出的前 7 位都是 0,感覺再簡單調整一下輸入就能找到答案了,其實不是的,修改輸入後可能得到的答案一個 0 都沒有。也就是說你的每一次計算是無記憶性的(Memoryless),只能通過大量地嘗試,不斷的尋找答案。

除此之外,找到答案後,其他人驗證答案卻很簡單,只需要把你的答案再用雜湊函式計算一次即可。(difficult to solve, but easy to verify)

比特幣挖礦過程充分利用了 Puzzle friendly,後面我們會詳細說明。

3.3、數字簽名(Digital Signature)

瞭解數字簽名之前,需要先對非對稱加密有一定認識。

3.3.1、什麼是非對稱加密?

asymmetric_encryption.png

Alice 想通過非對稱加密的方式傳送一條訊息給 Bob,他要怎麼做呢?

  1. Bob 需要先生成公鑰私鑰對(public key, private key)
  2. Bob 的公鑰是對所有人公開的,所以 Alice 可以拿到 Bob's public key
  3. Alice 使用 Bob's public key 對 Message 加密,並將密文通過網路傳輸給 Bob
  4. Bob 接收到密文後,使用自己的私鑰 Bob's private key 解密,得到了 Message
  5. 完成通訊

由於 Bob's private key 是儲存在 Bob 手裡的,只要私鑰不洩露,就是安全的。

3.3.2、什麼是數字簽名?

還是 Alice 想要給 Bob 傳送一條訊息,並採用非對稱加密的方式,Alice 憑什麼相信 Bob 的公鑰就是 Bob 的呢?有沒有可能被其他人調包了呢?這就需要 Alice 用到數字簽名的技術,來驗證 Bob 的身份是否真實

digital_signature.png

  1. Bob 用私鑰生成數字簽名
  2. Alice 用 Bob 的公鑰驗證簽名
  3. 如果驗證通過,則證明公鑰一定是 Bob 的,因為簽名只能由 Bob 的私鑰生成

四、比特幣是如何交易的?

4.1、區塊鏈

在比特幣系統中,交易是存在區塊裡的,那麼區塊鏈到底是什麼呢?

what_is_block_chain.png

  • 一個區塊是由 block header 和 block body 組成
  • block header 中會儲存前一個區塊頭的雜湊值
  • block body 中會儲存具體的交易資訊(Transaction 簡寫為 Tx)

區塊鏈其實不是區塊組成的連結串列結構,而是通過 (key,value) 資料庫實現的。在資料庫中,key 是區塊頭的雜湊值,value 是區塊內容。

4.2、賬戶

在比特幣中,賬戶就是由本機生成的公私鑰對 - 公鑰的雜湊值用作轉賬地址,相當於銀行卡號 - 私鑰相當於銀行密碼,需要自己妥善保管,一旦丟失是無法找回的

4.3、防止雙花

現實中,A -> B 100元人民幣的過程實際是 A 的錢包減少 100元,B 的錢包增加 100元,天然能防止「雙花」(除非你把花出去的錢偷回來再花一次)。

但是,比特幣中沒有賬戶系統,不會幫你記錄使用者的賬戶中餘額還有多少。 那麼,比特幣是如何驗證「雙花」的呢?

4.3.1、回溯幣源

比特幣的每筆交易由未花費的輸出(UTXO Unspenting Transaction Output),本次交易的輸入拼接而成。每筆交易會去驗證 UTXO 是否能支付足量的幣,具體可以看下面的例子。

btc_transaction.png

  1. coinbase 稱作「鑄幣」交易,是礦工挖出新區塊獲得的出塊獎勵,假設是 A 獲得了出塊獎勵的 10 BTC
  2. A 轉給了 B 5 BTC,同時轉給了 C 5 BTC,這時系統會去驗證 A 有沒有能力支付 10 BTC,會向前回溯找到 A BTC 的來源,於是找到了鑄幣交易,發現有 10 BTC,交易合法
  3. 同理 C 在轉給 E 7BTC 時,需要找到之前交易中得到的 5 + 2 BTC

轉賬者除了要證明幣源,還需要將交易用自己的私鑰簽名,用於身份驗證。

五、比特幣挖礦

5.1、為什麼要挖礦?

  1. 產生比特幣,只有挖出新的區塊,才會產生新的比特幣。中本聰規定,最初出塊獎勵為 50 BTC,每隔 4 年出塊獎勵減半,所以比特幣總量大概為 2100 萬個
  2. 打包交易,通過挖出新區塊,打包記錄新產生的交易
  3. 達成共識,通過工作量證明(Proof of Work)+ 獎勵機制,讓系統中的節點達成共識,向好的方向發展

5.2、挖礦的過程

比特幣挖礦的過程和實際挖金礦的過程很像: - 金子的總量是有限的,越挖會越少,比特幣也是如此 - 挖金子需要付出科技成本和體力勞動後才能得到回報,比特幣也是需要付出算力、電力成本,才能收穫比特幣

下面我們來簡單瞭解一下,比特幣挖礦的過程是怎樣的。

5.2.1、找到最長合法鏈

在比特幣中的礦工指的是系統中的全節點,除了挖礦,還要負責維護全量的區塊資料

誠實的礦工會按照最長合法鏈規則挖礦 - 最長,顧名思義,礦工只沿著系統中最長的鏈向後挖 - 合法,驗證區塊資訊是否被篡改,區塊中記錄的所有的交易是否合法。一旦礦工識別當前鏈不合規,便會馬上找到另外的最長合法鏈,繼續挖礦

5.2.2、挖礦解謎

簡單說,挖礦解謎就是礦工通過暴力雜湊運算,找到符合要求的隨機數 nonce,滿足下面的公式

$H(header || nonce) <= target$

  • target 是一串 256 位的雜湊(前 k 位都是 0)
  • k 越大,target 越小,挖礦難度越高。就像打靶子一樣,k 越大,表示靶子越小,越難命中
  • 增加算力,會增加挖到礦的概率,但不代表當前區塊一定會被算力高的礦工挖到

中本聰設計出塊時間在10分鐘左右,每兩週調整一次挖礦難度。比如上兩週平均出塊時間為 7 分鐘,則會增大難度,否則會降低難度。

5.2.3、廣播

解謎成功後,需要迅速把組裝好的區塊向相鄰節點廣播,讓自己挖的區塊在最長合法鏈中得到確認,拿到出塊獎勵和交易手續費。

5.2.4、6次交易確認機制

6_confirms.png

網路是不可靠的,在廣播階段很有可能出現延時。 所以交易上鍊後,並不是馬上就生效的,中本聰設計了一個區塊上鍊後需要再等 6 個區塊上鍊後才能被真正確認。

為什麼要這樣做? 1. 防止雙花,假如甲、乙礦工同時挖到了新區塊,並且廣播了出去。其中甲記錄 A 轉給 B 10BTC,乙記錄了 A 轉給 C 10BTC,事實上 A 只有 10BTC,如果兩個區塊都被認可,那就出現了雙花。 2. 為什麼是 6 次?中本聰認為,6 個區塊大概要花費一個小時才能挖出來,想要再做一次分叉攻擊篡改,是需要較大成本的。

5.3、51%算力攻擊

51%_attack.png

假設有某個組織擁有了全世界 51% 的算力,並且一直在沿著自己的鏈挖礦,理論上某個時間點,這個組織所挖的鏈就會變成最長的,廣播後,這條鏈就會成為最長合法鏈,那麼以前的交易就會被這個組織替換。

  • 51% 攻擊只能將合法的交易替換上鍊,但是無法偷其他使用者的比特幣,因為誠實的節點會驗證交易的簽名。
  • 51% 攻擊是可以發動雙花攻擊的,由於算力強大,會導致 6 次確認機制失效。比如 A => B (10BTC) 已經得到確認,其中 A 是攻擊者,交易是 A 的簽名,發動 51% 攻擊後,完全可以修改為 A => C (10BTC),C 可以是攻擊者的另一個賬戶。
  • 51% 只是一個象徵性的數字,並不一定算力一定要達到 51 才能攻擊,有研究小組表明只要擁有 30% 的全網算力,就足以發動 51% 攻擊。(為什麼只需要30%?個人猜測是,其他算力之間還存在競爭關係,而這30%是團結一致的)

曾有礦池(GHash.IO)算力超過了 51%,一度引起比特幣價值暴跌,之後很多礦工自覺退出了礦池,來保證系統的安全。

mining_healthy.png

比特幣系統在「安全性」「高價值」「健康挖礦」三個方面已經形成閉環。 算力越高,想發動 51% 攻擊就越困難,系統就越安全,隨之比特幣價格就會越高。 使得想要發動攻擊的人即使發動了攻擊也不一定能賺到什麼,還不如用所有算力穩穩挖礦收益高。

六、比特幣的缺點

  1. 工作量證明機制造成算力、電力的浪費
  2. 出塊時間限定平均10分鐘左右,一筆交易需要大概需要1小時才能得被系統確認
  3. 比特幣私鑰丟失之後,是沒辦法找回的,賬戶中的比特幣永遠都取不出來了
  4. 轉賬寫錯地址,無法回滾

參考