乾貨|比特幣如何產生與交易

image

最近研究區塊鏈,從區塊鏈起源比特幣入手,有些許收穫,整理成文分享給你們。**文章着重講解比特幣交易系統,適合對比特幣系統或區塊鏈技術有必定了解的人羣閱讀。經過此文可瞭解比特幣底層技術區塊鏈的運做原理。**由於大多數文章要麼泛泛而談區塊鏈能去中心化、能防篡改、能追溯,能夠改變行業改變世界,而不加以解釋如何實現,要麼只針對某一環節進行深度解析,缺少總體的串聯介紹,因此本文嘗試進行有必定深度的總體介紹,但願能幫助你們理解比特幣系統的實現。算法

中本聰在比特幣白皮書中介紹說,比特幣交易系統是一種徹底經過點對點技術實現的電子現金系統,它使得在線支付可以直接由一方發起並支付給另外一方,中間不須要經過任何的金融機構(基於密碼學原理而不基於信用)也能防止雙重支付問題(double-spending)(去中心化)。該網絡經過隨機散列(hashing)對所有交易加上時間戳(timestamps),將他們合併入一個不斷延伸的基於隨機散列的工做量證實(proof-of-work)的鏈條做爲交易記錄,除非從新完成所有的工做量證實,造成的交易記錄將不可更改(防篡改、可追溯)。其實就是一串使用密碼學方法相關聯產生的數據塊,每個數據塊中包含比特幣交易信息,用於驗證其信息的有效性和生成下一個區塊。這個系統核心流程是比特幣的產生與交易。編程

接下來將會對如何產生比特幣,比特幣如何交易,去中心化系統如何解決共識問題,數據爲什麼不可篡改,如何追溯進行講解(這些問題的答案在文中都會用下劃線標出便於你們定位)。數組

文章主要分爲三大塊:一是比特幣的產生;二是比特幣的交易;三是附錄,包含常見問題和涉及技術介紹,幫助你們理解文章。安全

1

比特幣的誕生-挖礦

整個挖礦流程以下:服務器

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

  • 構造Coinbase,肯定打包交易集,統計手續費等信息;數據結構

  • 構造HashMerkleRoot,對全部交易構造Merkle數;架構

  • 填充其餘字段,得到完整區塊頭;(步驟234若是不懂不要緊,看徹底文再回頭看就好理解了)分佈式

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

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

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

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

image

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

image

表2:區塊頭結構

  • 將結果哈希值與目標哈希值進行比較,若是當前nonce值計算的哈希值小,那麼挖礦成功,不然,挖礦失敗,曠工須要更改nonce值(一般加1)再試,直到成功(暴力搜索);--以上其實就是工做量證實機制(Proof-of-Work),解決了共識問題。

其中,

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

  • 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個硬幣所有正面向上則獲取記帳權,挖礦成功。若是是十六進制,直接比較就行。(二進制也可直接比較)

image

圖1:挖礦原理圖 

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

image

圖2:比特幣產生年份表

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

image

圖3:創世區塊信息

2

比特幣的交易

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

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

  • 私鑰通過SECP256K1橢圓曲線算法處理,生成公鑰,沒法反向推出私鑰;

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

image

圖4:地址產生算法

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

image

表3:Coinbase交易結構

image

表4:普通交易結構

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

image

圖5:交易例圖

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

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

image

圖6:區塊連接圖

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

3

附  錄

附錄一:哈希算法

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

**Text:**xingfushifendouchulaide

**算法:**sha256

結果:

b717189a738923eca3789287390b9b9c8a7839bca783928000cbdabed892bc43

若是用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。

image

附圖1:默克爾樹結構

image

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

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

附錄三:常見問題

  • 什麼是區塊鏈?

通俗來說那就是去中心化的分佈式帳本。在區塊鏈系統中,只要有能力部署本身的服務器都能加入區塊鏈網絡,成爲網絡節點,全部節點擁有徹底同樣的權利與義務,可進行讀寫操做,只要知足機制,其餘全部節點會依次同步,實現整個網絡中全部節點的數據徹底一致。

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

  • 如何防止雙重支付?(工做量證實/共識機制)

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

  • 對稱性加密算法和非對稱性加密算法的區別?

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

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

在中心化方式下,若是某種協議一旦肯定,想要變動是很是困難的,須要通過普遍討論並取得共識。而若是是腳本系統,那麼徹底能夠經過升級或者推出補丁,甚至發行一個新版原本解決。

  • 爲什麼區塊的產生時間是10分鐘?

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

內容來源:SteveMark

做者:李魔王

如下是咱們的社區介紹,歡迎各類合做、交流、學習:)

image

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息