當前位置:
首頁 > 最新 > 比特幣如何產生與交易

比特幣如何產生與交易

最近研究區塊鏈,從區塊鏈起源比特幣入手,有些許收穫,整理成文分享給大家。文章著重講解比特幣交易系統,適合對比特幣系統或區塊鏈技術有一定了解的人群閱讀。通過此文可了解比特幣底層技術區塊鏈的運作原理。因為大多數文章要麼泛泛而談區塊鏈能去中心化、能防篡改、能追溯,可以改變行業改變世界,而不加以解釋如何實現,要麼只針對某一環節進行深度解析,缺乏整體的串聯介紹,所以本文嘗試進行有一定深度的整體介紹,希望能幫助大家理解比特幣系統的實現。

中本聰在比特幣白皮書中介紹說,比特幣交易系統是一種完全通過點對點技術實現的電子現金系統,它使得在線支付能夠直接由一方發起並支付給另一方,中間不需要通過任何的金融機構(基於密碼學原理而不基於信用)也能防止雙重支付問題(double-spending)(去中心化)。該網路通過隨機散列(hashing)對全部交易加上時間戳(timestamps),將他們合併入一個不斷延伸的基於隨機散列的工作量證明(proof-of-work)的鏈條作為交易記錄,除非重新完成全部的工作量證明,形成的交易記錄將不可更改(防篡改、可追溯)。其實就是一串使用密碼學方法相關聯產生的數據塊,每一個數據塊中包含比特幣交易信息,用於驗證其信息的有效性和生成下一個區塊。這個系統核心流程是比特幣的產生與交易。接下來將會對如何產生比特幣,比特幣如何交易,去中心化系統如何解決共識問題,數據為何不可篡改,如何追溯進行講解(這些問題的答案在文中都會用下劃線標出便於大家定位)。文章主要分為三大塊,一是比特幣的產生;二是比特幣的交易;三是附錄,包含常見問題和涉及技術介紹,幫助大家理解文章。

一、比特幣的誕生-挖礦

整個挖礦流程如下:

檢索待確認交易內存池,選擇包含進區塊的交易。中本聰創造的創世區塊並無交易打包,所以挖的是空塊。因為每一個區塊都有容量限制,後人挖礦一般會根據手續費對待確認交易集進行排序,由高到低進行打包,儘可能使得每次挖礦的收益最大;(挖礦除了比特幣獎勵外還有交易確認記錄的手續費)

構造Coinbase,確定打包交易集,統計手續費等信息;

構造HashMerkleRoot,對所有交易構造Merkle數;

填充其他欄位,獲得完整區塊頭;(步驟234如果不懂沒關係,看完全文再回頭看就好理解了)

對區塊頭進行SHA256D運算(兩次SHA256計算)(詳見下文,建議先看看附錄一的哈希運算,有助於理解);

驗證結果,如果符合難度,則廣播全網,全網驗證通過則所有節點一起記錄,不符合改變參數繼續計算並驗證;(共識機制其實就是此演算法及其驗證過程,無中心卻人人認可;比特幣產自哪個節點完全看算力看運氣;每個節點都擁有所有交易記錄信息)

上述過程最重要的就是哈希計算,過程如下:

通過Sha256D(version+hashPrevBlock+hashMerkleRoot+nTime+nBits+nonce)(這幾個欄位見表2區塊頭結構)得到64位的十六進位或者256位的二進位哈希值;

表1:區塊結構(區塊頭信息見表2和交易詳情結構見表3表4)

表2:區塊頭結構

2. 將結果哈希值與目標哈希值進行比較,如果當前nonce值計算的哈希值小,那麼挖礦成功,否則,挖礦失敗,曠工需要更改nonce值(通常加1)再試,直到成功(暴力搜索);--以上其實就是工作量證明機制(Proof-of-Work),解決了共識問題。

其中,

1)目標哈希值target=2*(256-difficulty)

2)difficulty值由節點自動調整,規則為New difficulty=OldDifficulty*(Actual time of last 2016 Blocks/20160minutes)即:最新2016個區塊花費時長與20160分鐘比較所得,其中20160分鐘是這些區塊以10分鐘一個的速率所花費的時長。

那麼計算得到的64位的十六進位或者256位的二進位哈希值如何與目標哈希值進行比較呢?如果是二進位直接看結果哈希值的前N個比特位是否全部為0(如下圖),是的話挖礦成功。(0越多值越小;值越小,N越大,難度越大)可以類比拋硬幣,按順序拋256個硬幣,編號為1至256,每進行一次Hash運算,就像拋一次硬幣,256個硬幣拋出的結果若前N個硬幣全部正面向上則獲取記賬權,挖礦成功。如果是十六進位,直接比較就行。(二進位也可直接比較)

圖1:挖礦原理圖

所以,挖礦流程就是節點構造區塊,初始化區塊頭各欄位,計算hash值並驗證區塊的過程。不合格則nonce自增,再計算並驗證,如此往複。每次大約需10分鐘產生一個區塊(全網),最初每個區塊產生50個比特幣,每個比特幣為1億聰,之後大約每4年(21萬個區塊)減半(比特幣的產生)。總量大約2100萬,到2140年才挖完,而到2045年就挖掉99.9%了。下圖是比特幣產生年份表

圖2:比特幣產生年份表

看上表可以發現第一個區塊是在2009年產生的,具體時間是格林威治時間2009年1月3日18:15:05,由中本聰創造。有趣的是,中本聰在創世區塊上留下了泰晤士當天的頭版文章標題「The Times 03/Jan/2009 Chancellor on brink of second bailout forBanks」,諷刺了中心化金融體系並巧妙地證明此區塊的生成時間是在09年1月3號之個報紙標題出現之後。下圖是創世區塊的信息截圖,做個了解,記錄了區塊高度、哈希值、前一區塊哈希值、時間難度等交易信息,根據前一區塊hash、下一區塊哈希可以追溯前一個區塊、後一個區塊。

圖3:創世區塊信息

二、比特幣的交易

交易得先從公鑰、私鑰、地址講起,構造流程如下:

使用隨機數發生器生成一個256位的私鑰;

私鑰經過SECP256K1橢圓曲線演算法處理,生成公鑰,無法反向推出私鑰;

將公鑰通過SHA256哈希計算得出32位元組哈希值(下方有流程圖,可參照著理解),再用哈希值進行RIPEMD-160計算得到20位元組的哈希值,把版本號—20位元組的哈希值組成的21位元組數組進行SHA256D運算,取得到的哈希值的頭4個位元組作為校驗和,放在21位元組組的尾部,對組成的25位數組進行Base58編碼,得到地址。

圖4:地址產生演算法

通過上述流程得到公私鑰地址就可以交易了,在交易過程需要通過私鑰對交易進行簽名,簽完名後發起交易,交易會到待確認池子裡面,等待節點來打包確認放進區塊,也就是上文的挖礦過程。簽名通過演算法Sig=FuncSig(FuncHash(m),dA)=(R,S)進行,其中dA是簽名私鑰、m是交易信息、FuncHash是哈希函數、FuncSig是簽名演算法、Sig是簽名結果。驗證過程則是通過一系列函數演算法進行驗證,略複雜感興趣可自行了解。數據簽名演算法的核心在於證明數據的發送方是簽名者發出的,防抵賴。簽名的這些數據存放在解鎖腳本里,如表4交易結構2。比特幣系統里的交易分為兩種,一種是挖礦所得,即一個區塊的第一筆交易,稱為coinbase交易;第二種是普通交易,也就是非挖礦交易。

表3:Coinbase交易結構

表4:普通交易結構

交易結構構造完畢後即可發起交易,交易信息會到待確認交易池中等待打包確認。在比特幣的交易信息里,有兩個很關鍵的欄位:輸入/輸出,輸入並非明確某人有多少數量的比特幣,而是指向比特幣來源,即前一個已確認的交易中的UTXO(可追溯);輸出定義某人有多少比特幣,並且輸出要全部輸出(最多只有兩個),分為兩部分,一部分給外人,一部分給自己,其實就是找零機制。正是這種設計建立起分散式賬簿,所有區塊和交易形成互相連接的鏈條。找零機制有個好處就是保護隱私。因為每一筆比特幣交易都可在全球性的公共總賬上看到,如果某個比特幣地址偶然被知道其使用者,那麼將不利於使用者的隱私保護。而有了找零機制,地址A發起付款給地址B,找零地址不設置為A,而是改為C(自己的另一個賬戶)。那麼地址B和C是不是A?都有可能,這樣整個交易的真相將變得難以推測。

圖5:交易例圖

交易信息在進入待確認交易池後,每一個節點都將收到的交易信息納入區塊中,當一個節點找到一個足夠難度的工作量證明後會向全網進行廣播,其他節點會驗證該節點區塊中所有的交易都是有效且之前未存在過才會認可該區塊的有效性(通過默克爾樹進行比對校驗—防篡改,默克爾樹可查看附錄二),驗證通過則全網的節點都會跟隨在該區塊的末尾製造新區塊以延長該鏈條,被接受的區塊的隨機散列哈希值視為先於新區塊的隨機散列哈希值。如果有兩個節點同時找到答案,其他節點會在自己率先收到的區塊基礎上進行工作,直到下一個區塊產生,其中一條鏈條被證實為是較長的一條,那麼較短分支鏈條上的節點將轉換陣營,開始在較長鏈條上工作。

在這個共識機制中,新的交易不需要抵達全部節點,只要交易信息能抵達足夠多的節點(超過一半),那麼這些交易將被整合進一個區塊中,其他沒有接收到的節點後續會發現自己缺失了某個區塊,重新下載更新即可,此為拜占庭容錯。--拜占庭問題可見上一篇文章。最終整個交易信息會被打包在不同的區塊之中,區塊與區塊直接通過哈希演算法、時間戳關聯起來,實現可追溯。

圖6:區塊鏈接圖

總結一下:比特幣電子現金系統通過對每一筆交易進行哈希處理進行關聯、通過默克爾樹將交易與區塊進行關聯,通過區塊頭哈希與下一區塊進行關聯,實現了整個交易-交易、交易-區塊、區塊-區塊之間的關聯,實現過程可追溯;通過哈希處理的默克爾樹進行信息比對校驗、工作量證明機制(POW)、時間戳伺服器,實現了防篡改、防雙重支付;通過工作量證明機制下的共識演算法以及激勵,實現了系統去中心化;當然其中還涉及到各種密碼學原理,比如非對稱性加密技術保證的數據傳輸安全、Merkle tree保證的數據真實並優化存儲等。所以,其實其底層技術區塊鏈優勢無非就兩點,一是共識機制打造的去中心化系統,相比較傳統技術可以更好解決某些問題;二是密碼學技術打造的防篡改可追溯,可以很好解決各行業領域存在的信任問題;至於具體有什麼場景可以應用,如何解決這些場景的痛點,我們下次再聊!

三:附錄

附錄一:哈希演算法

哈希演算法也稱為散列函數演算法,在區塊鏈中應用廣泛。看一個轉換例子比較直觀,一個字元串xingfushifendouchulaide的hash運算結果(64位十六進位)。

Text:xingfushifendouchulaide

演算法:sha256

如果用MD5加密,運算結果是32位十六進位,用Sha512加密,結果是128位十六進位。哈希演算法其實就是一個映射的關係組,可以實現快速將明文轉換為hash值,而極難在短時間內反推出明文。另外,當明文稍作修改,hash值會有很大出入,不同的明文,難以出現相同hash值。萬一(概率極低)真的出現明文x不等於y,而f(x)=f(y)的情況,那麼即產生了衝突,一般會通過鏈接法、開放定址法、桶定址法(可自行了解)來解決。

哈希函數一般有以下幾種:

.直接取余法:取余

.乘法取整法:取整

.平方取中法:平方後取中間

.加法hash:把輸入元素加起來得到結果

.乘法hash:乘以某個固定或不斷變化的數

.位運算hash:利用各種位運算來混合輸入元素

.混合hash:通過各種hash混合構造

區塊鏈中哈希運算簡言之就是通過某種映射(函數關係)將一段字元串轉換為哈希值並與目標對象進行比較,在簽名驗證、默克爾樹比對中需要相等,在挖礦競爭中需要小於目標哈希值。

應用舉例:比如數據完整性校驗,最簡單的方法是對整個數據做Hash運算得到固定長度的Hash值,然後把得到的Hash值公布,用戶下載數據後對數據再次進行Hash運算,比較運算結果和公布的Hash值,如果兩個Hash值相等,說明數據沒有損壞。可以這樣做是因為輸入數據的稍微改變會引起Hash運算結果的面目全非,而且根據Hash值反推原始輸入數據的特徵是困難的。--防篡改

附錄二:默克爾樹(Merkletree)

Merkle tree的葉子節點的value是區塊數據Hash,非葉子節點的value是根據它下面所有的葉子節點值hash串聯後計算得到的哈希值,如果是單身哈希,就直接對它自己進行哈希運算,得到另一個哈希值,層層往上推,會形成一顆倒三角數,到最頂部就只剩下一個根哈希,叫做Merkle Root。

附圖1:默克爾樹結構

附圖2:默克爾樹在區塊中的位置

比對驗證從根哈希值比對起,如果一樣,那麼整個區塊的信息都沒問題,因為只要有任一環節出現不一樣,根哈希都會不一樣。如果根哈希不一樣,就可以往下層層追溯,找到不一樣的環節。如下圖:

附錄三:常見問題

1、什麼是區塊鏈?

通俗來講那就是去中心化的分散式賬本。在區塊鏈系統中,只要有能力部署自己的伺服器都能加入區塊鏈網路,成為網路節點,所有節點擁有完全一樣的權利與義務,可進行讀寫操作,只要滿足機制,其他所有節點會依次同步,實現整個網路中所有節點的數據完全一致。

晦澀一點講就是利用塊鏈式數據結構來驗證與存儲數據,利用分散式節點共識演算法來生成和更新數據、利用密碼學的方式來保證數據傳輸和訪問安全、利用由自動化腳本代碼組成的智能合約來編程和操作數據的一種全新的分散式基礎架構與計算範式。

2、如何防止雙重支付?(工作量證明/共識機制)

為了達到目的,我們只需要關注交易之前發生的交易,而不需要關注交易之後是否會有雙重支付,因為比特幣系統交易是公開存儲於所有節點並且有一系列的交易時間順序。只要保證交易之前沒有其他交易,那麼此筆交易就是安全的,除非發生51%攻擊。51%攻擊是指攻擊者在一筆交易被確認後在同一區塊發起另一筆交易B,而後聯合全網51%的算力進行挖礦(略大於二分之一的概率挖到),打包交易B確認交易記錄,繼續挖礦,構造一條比之前區塊鏈更長的鏈條,再公布全網,全網會認可最長鏈條的記錄,因為最長鏈包含了最大工作量。所以,只要不發生51%攻擊,通過工作量機制證明機制、哈希演算法構造的唯一公認的歷史交易序列可以避免雙重支付問題產生。

3、對稱性加密演算法和非對稱性加密演算法的區別?

對稱性加密演算法只有一把密鑰保證加密數據的安全,加解密都用這把密鑰。如何保存和傳遞密鑰是一件比較頭疼的事情,一旦傳遞過程中泄露密鑰數據則毫無安全。而非對稱性加密演算法可以實現不直接傳遞密鑰,也能完成解密。加密和解密使用不同的規則,兩種規則存在某種對應關係即可。如下,非對稱性加密演算法使用私鑰進行加密,對方使用公鑰即可解密。

4、交易中的鎖定腳本解鎖腳本的重要性?

在中心化方式下,如果某種協議一旦確定,想要變更是非常困難的,需要經過廣泛討論並取得共識。而如果是腳本系統,那麼完全可以通過升級或者推出補丁,甚至發行一個新版本來解決。

5、為何區塊的產生時間是10分鐘?

總要有一個值,為何不是更短,比如1分鐘。時間過短會導致孤塊增多,因為出塊時間短也就代表著難度低,舉個例子,假如1秒扔10個硬幣全正面視為出塊,若降為1秒扔2個硬幣全正面視為出塊,那麼同一時間出塊的節點將大量增加,卻只有一個能被共同認可加入鏈條,也即無用孤塊過多。那為何不是1小時呢?效率問題。


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 SteveMark 的精彩文章:

TAG:SteveMark |