新一年的開始也是比特幣論文部份的結束。希望大家能透過這篇論文,了解到最初的區塊鏈設計思想,以及區塊鏈技術最初的應用-比特幣的設計精神,最後今天就來算點數學吧。
論文的最後考慮了有攻擊者真的試圖攻擊比特幣網路的情況,假設真的用了超誇張的算力追上現在比特幣網路中最長的區塊鏈,基本上也不太能幹麻,因為交易一定要是合法的,亂改比特幣交易中的數字只會被其他節點當作不合法交易丟掉。
哪怕真的從很前面的區塊開始追到最長鏈,大不了就是像day8說的開大絕硬分叉把攻擊者的鏈丟掉,或是直接修改共識演算法變成day11說的不依賴算力的POS等等。唯一比較可能的攻擊就是把那些只等待一兩個區塊出來就當作交易成功的交易取消掉,不過大筆金額的交易基本上都會在等待交易成功之後的好幾個區塊才當作交易成功。
論文提到Binomial Random Walk、Gambler's Ruin problem的類比,個人覺得作者在這裡的敘述有沒有看對內容不太有影響,總之論文假設的情境是攻擊者打算追上最長鏈來把之前紀錄自己交易的區塊紀錄拿掉。
p=誠實節點找到下一個區塊的機率
q=攻擊者找到下一個區塊的機率
qz=攻擊者追上誠實節點z個區塊的機率
如下圖所示,q>=p就是51%攻擊沒什麼好說的,但如果p>q的話隨著要追趕的區塊越多,攻擊者追上的機會也會越小。
假設誠實節點計算每個區塊耗費的時間是平均期望時間,那攻擊者發起交易前先偷偷追趕的進展就是有如下期望值的Poisson分佈。
然後將Poisson分佈的概率密度乘上攻擊者在偷偷領先後發起交易能追趕誠實節點的機率,這裡的k的意思是指攻擊者已經偷偷先追過最長鏈k個區塊才發起交易,然後當下才去追z-k個區塊。
把上面的式子改寫一下避免計算0加到無限大,思路就是Poission分佈的部份是機率,本來機率0加到無限大就是1,然後去補式子剩下的數字。
最後論文給出了C code的實際機率計算,來用python改寫一下:
# -*- coding: utf-8 -*-
import math
def AttackerSuccessProbability(q, z):
p = 1.0 - q
lamb = z * (q / p)
sum = 1.0
for k in range(z+1):
poisson = math.exp(-lamb)
for i in range(1, k+1):
poisson *= lamb / i
sum -= poisson * (1 - math.pow(q / p, z - k))
return sum
我們來看看在目前一般交易都是預設交易完後再等待6個區塊才會交易成功的情況下,如果要有30%成功撤銷交易的可能性要掌握多少算力呢?
結果如下:
q = 0
while True:
prob = AttackerSuccessProbability(q, 6)
if prob > 0.3:
break
q += 0.01
print("攻擊者至少需掌握%.2f%%算力才能有30%%可能性攻擊成功" % q)
# 攻擊者至少需掌握0.36%算力才能有30%可能性攻擊成功
在github放有完整的範例程式提供,可以直接執行參考。
看來如果是利益足夠令人瘋狂的交易金額,等待6個區塊作為交易完成還是稍嫌不夠的,雖然只要在多等幾個交易就能把安全提高,不過這也可以看出比特幣設計上的一些缺陷,之後有機會會來介紹一些其他區塊鏈應用中改善交易速度的技術。
以比特幣論文運作機制為主軸的第一部份就到這裡,接下來將介紹區塊鏈技術在其他方面的應用和技術改善。
《Bitcoin: A Peer-to-Peer Electronic Cash System》
https://bitcoin.org/bitcoin.pdf