現在,因為比特幣談論區塊鏈的人越來越多了,甚至將區塊鏈作為龐氏騙局的說法都開始出現了。區塊鏈算法本身是一種分布式存儲模型,專門用于解決記賬問題的算法。與其看這么多區塊鏈的文章,不如讀一下比特幣的代碼更可靠。
就像是我們寫代碼的來做一個炒菜的設備,你的關注重心應該在哪里?我覺得不應該是你用了什么語言,采用了什么框架,系統穩定性參數是多少,成本有多低,而應該是炒的菜好不好吃。正像是沒人關注技術細節一樣,人們關注的都是它能做什么。無論你的代碼寫得多好,系統架構是怎樣的,硬件或者模型設計多優化,用了多么高科技的技術,但只要菜做的不好吃就是一個廢品。
現在大體上只要提到區塊鏈就是“噶韭菜”、“加密貨幣”、“圈錢”,但是區塊鏈實際上只是一個為了解決中心記賬問題的模型。
現在讓我們回歸區塊鏈的記賬系統的本質,接下來按照區塊鏈是一個記賬模型來講。
傳統會計記賬的模型都是中心模型,以阿里舉例,阿里中心有一個財務總部門,省級有財務部門,市級也有財務部門。阿里每天都有大量的交易產生,財務部門也會有無數的賬單。市級財務部門的會計統計賬單,發給省級;省級統計完市級發上來的賬單,發給阿里的財務總部。
我們現在的財務記賬模型看起來都是這樣的,但是像阿里這樣的大公司,每分每秒產生的交易額都是夸張的,在這種情況下數據量小的時候,各級財務部門自己就統計了,但是越匯總,做的帳就越是大的恐怖。如果這里面有人作假帳或者有人修改歷史賬單或者有人漏寫了某筆帳,在無數的海量賬單里,基本上就是一筆爛賬了。不管管理體系做得多好,想要查出來被修改的錯誤賬單,基本都是不可能的。
區塊鏈就是為了解決這個財務壞賬問題而使用的算法模型。
階 段 一
這里先例舉一個盡可能簡單的區塊鏈最基本的存儲模型的代碼。
// 塊
type Block struct {
// 時間戳
Timestamp int64
// 賬單數據
Data []byte
// 前一個塊的hash值
PrevBlockHash []byte
// 哈希值
Hash []byte
}
Golang的代碼不用看的太明白,看注釋就行。比特幣代碼里這個Block可以理解為在財務賬單上記了一筆帳,而賬單上需要寫明記賬的時間、賬單上的交易數據。
PrevBlockHash暫且理解為一個數字,后面再作解釋。
這個Hash可以理解為當前記賬時間和交易數據,還有PrevBlockHash這個數字,用一個奇怪的數學公式算出來一個校驗值,這個校驗值是用來保護該賬單不被修改的。
如果有人想來查賬有沒有被修改,需要看一下記賬的時間和交易的原始數據,然后查一下PrevBlockHash這個數字是多少。把這三個數據都算一遍,看算出來的數字是不是Hash里面的數字,就知道賬單有沒有被修改了。
這樣的數據塊可以理解成一張一張的賬單,一條一條的交易數據。后面使用賬單塊來稱呼,每一個賬單塊都寫上一個編號。
編號1的賬單的PrevBlockHash就是一個數字,直接寫成數字0,這個編號1的賬單塊俗稱創世塊。
編號2的賬單的PrevBlockHash寫的是編號為1的賬單的Hash校驗值,以此類推。
假設這個賬單現在有100個賬單塊。如果有人想搞事情,作假帳,修改了編號為1的賬單的數據。
編號1的賬單的Hash數字是記賬時間、賬單交易內容和PrevBlockHash計算出來的數字,賬單1的PrevBlockHash內容是0。修改賬單記賬時間或者修改賬單的交易內容,都會導致Hash數字算出來會有變化。這個人要作假帳,他一定需要把Hash這個數字給改成重新算出來的數字。
但是我們的賬單要求編號2的賬單的PrevBlockHash這個數字要寫賬單1的Hash校驗值。
同理因為賬單2里的PrevBlockHash這個數字變化了,Hash這個數字也就變化了。
以此類推,我們現在的賬單塊是100個,為了修改賬單1里的任何一點數據,都會導致需要將從1到100的所有賬單都跟著修改,否則因為校驗值錯誤,該賬本會被作為錯誤賬本被廢棄掉。
這樣一來,之前記的帳就基本不可能被修改了。這也就是區塊鏈作為分布式存儲和記賬系統的優勢所在,賬單一旦錄入基本不可能被修改。記賬系統也是存儲模型,存儲賬單的模型。
階 段 二
上面只是講了最基本的區塊鏈存儲模型。真實使用的時候,Data這里并不是真的賬單,而是一個默克爾樹的根節點的校驗值。后面加上默克爾樹,再重新理解一下區塊鏈。
// 塊
type Block struct {
// 塊頭
Head BlockHead
// 賬單數據
Data Merkle
}
// 塊頭
type BlockHead struct {
// 時間戳
Timestamp int64
// 賬單數據
MerkleRoot []byte
// 前一個塊的hash值
PrevBlockHash []byte
// 哈希值
Hash []byte
}
// 賬單
type Merkle struct {
// 每一筆交易記錄
Data []byte
}
上面這個Merkle參數,默克爾樹可以理解為就是一個賬單。還是剛才的階段一,每一個Data不是一條交易記錄,可以理解為一個塊記錄就是一個賬單。
當交易記錄太多的時候,記賬的交易數據量太大了,將整個賬單參與Hash值的計算,運算量太大,太麻煩了,所以用Merkle樹的方式記賬。
關于默克爾樹就不講太多了,有興趣的可以去查一下,跟區塊鏈其實很像,其中每一個樹節點都是這個樹節點的子節點的Hash校驗值計算出來的。
簡單一點理解,可以認為通過Merkle樹的方式做了一個賬單,這個賬單有一個根節點,這里記做MerkleRoot,是樹結構的一個節點,不明白的還可以理解為一個校驗數字。整個賬單里只要有任何一個字節對不上,都會導致MerkleRoot這個數字產生變化,所以一旦這個賬單做好了之后,將Merkle賬單的MerkleRoot這個數字寫入到區塊頭里面,那么整個賬單的任何一個字都不能修改,一旦有任何修改,都會導致整個樹結構上面的每一筆交易記錄的Hash值需要重算。
最終導致MerkleRoot這個數字會發生變化,一旦有變化,就會導致塊頭的Hash值發生變化。導致這個賬單錄入之后的所有賬單的PrevBlockHash值發生改變,這個塊之后的所有的帳要全部作廢重做。區塊鏈就是通過這樣一個管理模式來管理賬單。
區塊鏈總結
其實到此為止區塊鏈已經講完了。區塊鏈其實就是一個簡單的記賬模型,目的是為了避免有人為意圖的對賬單做修改。區塊鏈的每一個塊都是在隨著交易記錄的增加不停地添加進來的。因為任何一個塊的數據都被一個完善的數學系統鎖定了,任何一個字都是不可修改的,只要有修改,都需要重算從這個賬單塊開始的后面所有的賬單塊,否則賬單就是一個錯誤賬單,不會被系統采納了。
現在的區塊鏈其實有三種使用模型:去中心化型、聯盟中心型、多中心型。按照投票確定誰的賬單是最長的,按照誰的賬單作為總賬。
通過這種方式,避免了中心化記賬,財務總中心的人惡意修改數據,還沒人管得了的問題。如果是多個中心互相牽制,每人手里都有一筆完整的帳,其一驗證賬單每個節點是否計算正確,來確保賬單不被修改,其次驗證每個塊的內容,誰的賬單記賬數量最多(俗稱區塊鏈最長),按照誰的賬單作為總賬,其它所有節點接到通知之后,更新自己的賬單。
去中心型是任何人都可以加入到財務中心里來,每個人都能拿到總賬,都能驗證總賬,也都能幫忙記賬。只要你算的是對的,而且算的最快,都可以被采納。
聯盟中心型是多公司互相牽制的模型,多個公司用這種模型管理總賬,任何一家公司都不能輕易修改這本動態的一直在記錄的賬單。
多中心型類似中國銀行這種,還是中央管理,但是并非一個節點記賬,而是多個點同時記賬,避免任何一本帳被財務總中心的人修改。
這里區塊鏈已經需要面對兩個嚴重的問題。區塊鏈的每個賬單塊能記的賬單數量是有上限的,現在一個賬單塊大小是2 MB,不能超過這個大小,一旦要修改這個塊大小,就需要區塊鏈系統的所有節點算法跟著變化,代價會變得很高。
這里隨便說一個數字,一個塊假設能保存2千筆交易記錄,像是阿里今年雙十一,3分01秒,成交額100億元。除一下就是五百萬,也就是說3分鐘內要寫入500萬賬單塊。因為挖礦等某些原因(后面講解),比特幣平均每十分鐘寫入一個賬單塊。
每小時6個塊,一天是24小時,也就是說阿里巴巴去年雙十一這一天,三分鐘產生的賬單,需要大約34 722天,大概95年來記賬。這個記賬速度根本就是來開玩笑的。
這個記賬速度是可以通過算法調整的,但是這么大的交易量,增加記賬速度會使塊容易沖突,因為需要少數服從多數投票選用哪個最長的賬單,全網通知并投票選舉這件事情也是需要時間的,雖然計算機很快,但是也是需要時間的。增加塊大小還是加快記賬速度都有很高的通信代價,也是一件賬單數量過大情況下很不現實的事情。
階 段 三
看到這里大家應該明白什么是區塊鏈了,比特幣是用區塊鏈技術來管理它的賬單的,比特幣使用區塊鏈技術如何交易也非常清楚了。但是比特幣挖礦又是怎么一回事兒呢?
在這里,加密貨幣的加密交易過程部分就不詳細講了,有興趣的可以自己去查一下。我這里假設明文交易的模型,每一筆交易的交易記錄都不加密,直接寫在賬單上。
這個記賬系統的管理工作都用算法實現了,需要的只有實際記下每一筆帳的“會計”,而在區塊鏈系統里的“會計”,也就是我們俗稱的“礦工”。
所謂礦工挖礦是什么意思,是指這個多中心模型里,沒有財務管理,每一個人都是“會計”,每一個“會計”手里都拿著整個系統完整的賬本,然后開始做賬,在整個區塊鏈里記下下一個賬單塊這樣的工作,成功將賬單寫進去,而且計算正確的那個人,將自己的賬單發給所有人,然后將我們每個人做的帳放到一起,計算正確的賬本而且又是最長的,一定是第一個將該賬單成功寫進去的那個“會計”。
然后按照算法當場計算,他成功記了一筆賬,應該給他多少錢,然后當場發放獎勵,這就是挖礦。但是這個挖礦是有問題的,誰的算力強,算得快就總是誰拿錢,別人就沒有工作的熱情了,而且大家記賬的速度都差不多的,很容易撞車,同時提交賬單。
所以我們重新調整一下這個塊的結構。
// 塊
type Block struct {
// 塊頭
Head BlockHead
// 賬單數據
Data Merkle
}
// 塊頭
type BlockHead struct {
// 時間戳
Timestamp int64
// 難度值
Bits []byte
// 目標數
Nonce []byte
// 賬單數據
MerkleRoot []byte
// 前一個塊的hash值
PrevBlockHash []byte
// 哈希值
Hash []byte
}
// 賬單
type Merkle struct {
// 每一筆交易記錄
Data []byte
}
這里在塊頭結構里添加了兩個參數:Bits難度值和Nonce目標數。
先說一下加這兩個參數的原因。剛才遇到的問題是,一屋子“會計”,每個人都在做賬,誰最快做出來帳,統計投票之后所有人更新賬單,按照最快做賬那個人的賬本更新。
但是算這個賬單,雖然加了一些很麻煩的算法,還是很簡單的,大家算得都很快,一起提交,而且都算得是對的,這事兒很容易產生紛爭。如果有一個人算得非常快,賬本總是他在記,他是不是會搞點小手段呢?所以,還是應該每人記一點帳,這個帳更可靠。
這個就是中本聰提出的“工作證明機制”,我們所有人都先別開始記賬。我們都開始算一個非常難的數學題,而且是個超級麻煩,完全沒有用,基本靠撞大運的數學題。誰算出來了,誰再按照流程算你的帳,計算機按照流程記賬基本就是瞬間寫入,但是算這個很麻煩的數學題,就需要時間了,而且是個基于撞大運的數學題,沒人確保自己能算出來。通過這種方式來拖延記賬時間。
如果真的拿區塊鏈作為記賬系統來用,根本不需要一個刻意去拖慢記賬速度的東西,但是比特幣就是這么寫的。也是我認為這個“工作證明機制”是一個資源空轉,純屬浪費的東西。然后我詳細講一下這個數學體是什么。
剛才講區塊頭的Hash校驗值計算是用記賬時間、賬單數據和前一個塊的Hash值算出來的,我們把Bits難度值和Nonce這兩個數也參與到Hash運算里來。
先說Bits難度值,這個數是依賴于之前記過的帳算出來的,可以認為在當前要記的這個帳里,它是一個確定的寫死的一個數字,具體怎么來的,可以自己查一下資料。
Bits = difficulty_1_target / current_target
所以我要開始計算這個塊的Hash值的時候,這個Bits可以認為不影響計算結果。
然后是Nonce目標數,記賬人隨便寫這個數字。但是因為Nonce參與運算,所以寫不同的Nonce數值,算出來的結果都是不同的。
然后接下來的工作全靠蒙,不停地嘗試各種各樣的Nonce這個數字,讓計算出來的Hash數值小于Bits這個寫死的數字。
如果你成功蒙到了這個數字,就趕緊把算好的賬單,以及帶著賬單里的這個Nonce數字廣播發給屋里所有的人,大家都驗證了一下賬單沒問題。全靠猜寫的Nonce這個數字算出來的Hash數字確實小于Bits這個數字。屋里所有的“會計”全部更新自己的賬單,把你成功記賬這件事情寫到賬單里,然后系統計算應該給你多少工資,當場結算。
因為算出來的Hash小于Bits這個數字,如果Bits這個數字太大還是會導致很多人很快能算出來。因為記賬的時候賬單上寫著記賬的當前時間,而且這個數字還是不允許修改的,所以能算出來平均你們一堆人多長時間可以算出來一個賬單塊,并提交寫入總賬本的。如果速度太快,不到10分鐘就算出來了,稍微把Bits這個數字按照算法稍微調小一點,基于前面的賬本記錄時間計算。
因為每個人手里都有賬本,這個數字要寫多少,自己就直接算出來了,不需要誰來控制這個記賬難度系數,繼續維持區塊鏈記賬系統,無中心無管理的狀態。
同時通過這種難度波動的方式控制大家的記賬速度,也就是上面提到的比特幣平均每10分鐘記賬一次,寫入一個賬單塊,避免多人同時記賬導致數據沖突。
繼續吐槽一下,這個“工作證明機制”單純的是用來拖慢記賬速度的,此模式確實有點蠢,但是的確很有效,確實解決了在互相不信任的無中心模型下,怎么讓互相完全不信任的人之間管理賬本的問題。
補 充
其實還有很多細節沒講,比如比特幣的發放這個模型。通過記賬成功的方式直接按照算法發放獎勵,這只是一種中本聰隨手寫的獎勵方式。為了讓大家把這個記賬游戲繼續玩下去。
比特幣系統里能憑空獲得比特幣的只有“會計”挖礦,記賬成功時按照算法自動獲得,還有系統獎勵衰減來回避通貨膨脹問題等。
但是現在更多的模型是“會計”無獎勵的,由系統從最一開始直接發行貨幣,由中心系統發放貨幣,其實也是有監管的,監管中心可能導致貨幣控制等問題。
這個記賬系統沒什么可記的賬本,就變成了中本聰寫的一個記賬游戲系統“比特幣”系統。在記賬的過程中去產生只對“會計”發放的貨幣,再由參與者之間互相交易的模型。但說白了,比特幣就是個游戲系統,沒人用的時候就是一堆廢棄的數據。尤其當“會計”從系統里消失的時候,這個記賬系統就崩壞了,沒有記賬的“會計”,就無法成交了,所有的成交單都會成為廢品。
再加上比特幣的每次記賬成功發放數量,平均每四年會除以二,你四年前成功記賬獲得一萬,現在成功記賬獲得五千。數字是我隨便寫的,因為獎勵發放是浮點數記錄的,不是數學上那種可以無限細分的數字,所以其實從某一刻開始比特幣記賬就拿不到收益了。
要么有辦法用其它手段讓“會計”掙到錢或者采用交易提成等手段,否則“會計”一定會從這個不賺錢的游戲里退出來,也就是比特幣系統一定有崩壞的那一天。
雖然比特幣的游戲模型是一個注定會崩壞的模型,但它只是一個記賬游戲而已。區塊鏈技術也絕對不是什么龐氏騙局,只是一個記賬系統罷了。
-
區塊鏈
+關注
關注
111文章
15562瀏覽量
106258 -
比特幣
+關注
關注
57文章
7005瀏覽量
140778
原文標題:研究完比特幣代碼,發現了一個驚人秘密!
文章出處:【微信號:mcuworld,微信公眾號:嵌入式資訊精選】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論