BTC-比特幣系統的實現(區塊鏈技術與應用)


基於交易的賬本模式(transaction-based ledger)

區塊鏈是去中心化的賬本,比特幣采用的是基於交易的賬本模式(transaction-based ledger),只記錄了轉賬交易和鑄幣交易,並沒有直接記錄每個賬戶上有多少錢。如果想知道某個比特幣賬戶上有多少錢,要通過交易記錄來推算。

(1)UTXO(Unspent Transaction Output)

比特幣中的全結點要維護一個叫UTXO的數據結構,即還沒有被花出去的交易的輸出。一個交易可能有多個輸出,被花掉的就不在UTXO里了。

如下圖中A轉賬給B和C的交易,B的已經花出去了,也就不在UTXO里了,而C的還沒花出去,就在UTXO里

在這里插入圖片描述

UTXO集合中的每個元素要給出產生這個輸出的交易的哈希值,以及它在這個交易中是第幾個輸出。用這兩個信息就可以定位到一個確定的交易中確定的輸出。

使用UTXO可以用來快速檢測雙花攻擊,想知道新發布的交易是不是合法的,要查一下全結點存在內存中的UTXO。要花掉的幣只有在這個UTXO這個集合里才是合法的,否則要么是不存在的,要么是已經花過了的。

隨着交易的發布,每個交易會消耗掉一些輸出,同時也會產生一些新的輸出。例如上圖例子中B將5個BTC給D,這消耗掉了前面A把5個BTC給B的輸出,但產生了新的B把5個BTC給D的輸出,這個輸出會保存在UTXO里。

(2)交易中:total inputs=total outputs

每個交易可以有若干輸入和若干輸出,所有輸入的金額之和要等於所有輸出的金額之和。

(3)第二個激勵機制:交易費(transaction fee)

有些交易的總輸入可能略微大於總輸出,如可能總輸入是1個BTC,總輸出是0.99個BTC,這之中的差額就作為記賬費給了獲得記賬權的那個結點

目前來講礦工挖礦,主要的目的還是為了第一個激勵機制——得到出塊獎勵。因為出塊獎勵是要逐漸減少的,每隔21萬個區塊就要減半,比特幣系統的平均出塊時間是10分鍾,大約每隔4年出塊獎勵就會減半。到很多年之后,出塊獎勵變得很小,這時候交易費就成為主要動機了。

transaction-based ledger

除了比特幣系統這樣基於交易的賬本模式(transaction-based ledger),還有一些系統是基於賬戶的模式(account-based ledger),比如后面要學的以太坊。在這種模式中系統要顯式的記錄每個賬戶中有多少個幣。

比特幣系統的這種模式,隱私保護性比較好,但會帶來一些代價,如轉賬交易要說明幣的來源(幣是從之前的哪個交易的哪個輸出中來的)以防止雙花攻擊。

一些區塊的例子

在這里插入圖片描述

區塊中的nonce是4字節即32位整數,也就只232
種取值。因為比特幣近些年太火爆了,挖礦的人數很多,所以挖礦的難度被調整的很高,單純靠調整nonce是很可能得不到符合難度要求的解的(搜索空間不夠大)。所以區塊的塊頭中哪些域可以改?

  • 版本號(4):不能改
  • 前一個區塊塊頭哈希值(32):不能改
  • Merkle Tree的根哈希值(32):通過修改Merkle Tree中鑄幣交易的CoinBase域來調整其根哈希值
  • 區塊產生的時間(4):有一定的調整余地,比特幣系統並不要求非常精確的時間,這個域可以在一定范圍內調整
  • 挖礦目標閾值編碼后的版本(4):只能按照協議中的要求定期進行調整,不能隨便改
  • nonce(4):可以改

在這里插入圖片描述

可以看到,因為鑄幣交易是沒有交易來源的,所以可以在其CoinBase域里隨便寫入內容,鑄幣交易的變化會使該交易的哈希發生變化,變化沿着Merkle Tree一路向上傳遞,最終使整棵Merkle Tree的根哈希值發生變化,間接地調整塊頭的哈希值。

所以可以把這個字段當做一個extra nonce,塊頭的nonce字段不夠用,就再拿着這個域的一部分字節一起調整,就增大了搜索空間。

實際挖礦時,一般也是為此設計了兩層循環,外層循環調整鑄幣交易的CoinBase域的extra nonce,算出Merkle Tree的根哈希值;內層循環調整塊頭的nonce,計算整個塊頭的哈希值。

在這里插入圖片描述

在這個轉賬交易中,左邊是交易的兩個輸入(雖然旁邊寫的是Output,這是表示它們花掉的是之前哪個交易的Output);右邊是交易的兩個輸出(從綠色Unspent字樣可以看到還沒有花出去,所以會保存在UTXO里)

在這里插入圖片描述

可以看到比特幣系統中交易的輸入和輸出都是用腳本來指定的,驗證交易輸入輸出的過程就是把輸入腳本和輸出腳本配對執行(不是把同一個交易的輸入輸出腳本配對執行,而是把這個交易的輸入腳本和提供幣的來源的那個交易的輸出腳本配對執行)。只要配對后都能成功執行,交易驗證就是通過的。

挖礦過程的概率分析

挖礦的過程就是不斷嘗試nonce去求解puzzle,每次嘗試可以看做一個伯努利試驗(Bernoulli trial:a random experiment with binary outcome)

當進行了大量的伯努利試驗,這些伯努利試驗就構成了伯努利過程(Bernoulli process)。伯努利過程的一個性質是無記憶性(memoryless),即做大量的試驗,前面的試驗結果對后面沒有影響

當伯努利分布(也即二項分布)的n很大而p很小時(試驗次數很多,每次試驗成功概率很小),可以近似為泊松分布。這里挖礦就是一個n很大p很小的伯努利過程,所以可以近似為泊松過程(Poisson process)

progress free與算力優勢——挖礦公平性的保證:

出塊時間是服從指數分布(exponential distribution) 的,整個系統的出塊時間按照比特幣協議被調整在10分鍾左右,而具體到某個礦工的出塊時間,取決於其算力占整個系統中礦工的算力的百分比

比特幣安全性的分析

  1. 轉走別人的BTC

假設一個有惡意的結點M獲得了記賬權,它想把結點A的錢轉走,但因為沒法偽造A的簽名(沒有A的私鑰),寫個任何不正確的簽名上去,都會導致誠實的結點不會接受這個候選區塊,而是繼續沿着上一個區塊擴展。因為這個區塊是不合法的,所以多長都不是最長合法鏈,這樣的攻擊是無效的。

  1. 分叉攻擊

M把BTC轉給A,然后就緊接着挖礦挖到了一個區塊,在這里填寫了M把BTC轉給自己的交易,以希望沿着這個區塊成為最長合法鏈,這樣就能將轉給A的擠掉,從而將花出去的BTC回滾。這也是雙花攻擊的一種

如果M->A這個交易所在區塊后面又跟上一些區塊,這個攻擊的難度就會大大增加。因為它最好的方式仍然是在M->A的前一個區塊位置插入,但是想讓它成為最長合法鏈卻非常難,因為它已經不是最長合法鏈,誠實的結點只會去擴展最長合法鏈。

在這里插入圖片描述

如果大部分結點掌握在誠實結點手里,這樣攻擊的難度非常大,有惡意的結點要連續獲得好多次記賬權才可能改變最長合法鏈。所以一種最簡單的防范方法就是多等幾個區塊,也叫多等幾個確認(confirmation)

比特幣協議中缺省的是要等6個confirmation(大約一小時),才認為one confirmation區塊中的交易是不可篡改的。從前面的分析可以看出,比特幣交易在區塊鏈賬本上的不可篡改性(irrevocable) 只是一種概率上的保證。

  1. zero confirmation

zero confirmation是指交易剛發布出去,還沒有寫入區塊鏈中的時候,就認為交易已經不可篡改了。

  1. 故意不發布某些合法交易

比特幣協議沒有規定獲得記賬權的結點必須發布哪些交易,而且沒有寫進這個區塊也可以寫進下一個區塊,總有誠實的結點願意發布這些交易。而且比特幣系統在正常工作時候也會出現某些交易被滯后發布的情況,可能就是一段時間內的交易太多了,畢竟一個區塊不能超過1M。

  1. selfish mining

正常情況下結點挖到一個區塊就立即發布,這是為了得到出塊獎勵和收取交易費。selfish mining就是挖到的區塊都留着,這樣的動機是,比如在前面的分叉攻擊中,一直等到6個confirmation過了,再一口氣把算好的很長的分叉發布出去,替換掉最長合法鏈。

實際上這樣做的難度還是很大,因為這個惡意結點的算力要超過那些誠實的算力才可能在一定時間后比它長。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM