比特幣哈希值演算法
❶ 公鑰、私鑰、哈希、加密演算法基礎概念
生活中我們對文件要簽名,簽名的字跡每個人不一樣,確保了獨特性,當然這還會有模仿,那麼對於重要文件再加蓋個手印,指紋是獨一無二的,保證了這份文件是我們個人所簽署的。
那麼在區塊鏈世界裡,對應的就是數字簽名,數字簽名涉及到公鑰、私鑰、哈希、加密演算法這些基礎概念。
首先加密演算法分為對稱加密演算法、非對稱加密演算法、哈希函數加密演算法三類。
所謂非對稱加密演算法,是指加密和解密用到的公鑰和私鑰是不同的,非對稱加密演算法依賴於求解一數學問題困難而驗證一數學問題簡單。
非對稱加密系統,加密的稱為公鑰,解密的稱為私鑰,公鑰加密,私鑰解密、私鑰簽名,公鑰驗證。
比特幣加密演算法一共有兩類:非對稱加密演算法(橢圓曲線加密演算法)和哈希演算法(SHA256,RIMPED160演算法)
舉一個例子來說明這個加密的過程:A給B發一個文件,B怎麼知道他接收的文件是A發的原始文件?
A可以這樣做,先對文件進行摘要處理(又稱Hash,常見的哈希演算法有MD5、SHA等)得到一串摘要信息,然後用自己的私鑰將摘要信息加密同文件發給B,B收到加密串和文件後,再用A的公鑰來解密加密串,得到原始文件的摘要信息,與此同時,對接收到的文件進行摘要處理,然後兩個摘要信息進行對比,如果自己算出的摘要信息與收到的摘要信息一致,說明文件是A發過來的原始文件,沒有被篡改。否則,就是被改過的。
數字簽名有兩個作用:
一是能確定消息確實是由發送方簽名並發出來的;
二是數字簽名能確定消息的完整性。
私鑰用來創建一個數字簽名,公鑰用來讓其他人核對私人密鑰,
而數字簽名做為一個媒介,證明你擁有密碼,同時並不要求你將密碼展示出來。
以下為概念的定義:
哈希(Hash):
二進制輸入數據的一種數字指紋。
它是一種函數,通過它可以把任何數字或者字元串輸入轉化成一個固定長度的輸出,它是單向輸出,即非常難通過反向推導出輸入值。
舉一個簡單的哈希函數的例子,比如數字17202的平方根是131.15639519291463,通過一個簡單的哈希函數的輸出,它給出這個計算結果的後面幾位小數,如後幾位的9291463,通過結果9291463我們幾乎不可能推算出它是哪個輸入值的輸出。
現代加密哈希比如像SHA-256,比上面這個例子要復雜的多,相應它的安全性也更高,哈希用於指代這樣一個函數的輸出值。
私鑰(Private key):
用來解鎖對應(錢包)地址的一串字元,例如+。
公鑰(Public keycryptography):
加密系統是一種加密手段,它的每一個私鑰都有一個相對應的公鑰,從公鑰我們不能推算出私鑰,並且被用其中一個密鑰加密了的數據,可以被另外一個相對應的密鑰解密。這套系統使得你可以先公布一個公鑰給所有人,然後所有人就可以發送加密後的信息給你,而不需要預先交換密鑰。
數字簽名(Digital signature):
Digital signature數字簽名是這樣一個東西,它可以被附著在一條消息後面,證明這條消息的發送者就是和某個公鑰相對應的一個私鑰的所有人,同時可以保證私鑰的秘密性。某人在檢查簽名的時候,將會使用公鑰來解密被加密了的哈希值(譯者註:這個哈希值是數據通過哈希運算得到的),並檢查結果是否和這條信息的哈希值相吻合。如果信息被改動過,或者私鑰是錯誤的話,哈希值就不會匹配。在比特幣網路以外的世界,簽名常常用於驗證信息發送者的身份 – 人們公布他們自己的公鑰,然後發送可以被公鑰所驗證的,已經通過私鑰加密過的信息。
加密演算法(encryption algorithm):
是一個函數,它使用一個加密鑰匙,把一條信息轉化成一串不可閱讀的看似隨機的字元串,這個流程是不可逆的,除非是知道私鑰匙的人來操作。加密使得私密數據通過公共的網際網路傳輸的時候不需要冒嚴重的被第三方知道傳輸的內容的風險。
哈希演算法的大致加密流程
1、對原文進行補充和分割處理(一般分給為多個512位的文本,並進一步分割為16個32位的整數)。
2、初始化哈希值(一般分割為多個32位整數,例如SHA256就是256位的哈希值分解成8個32位整數)。
3、對哈希值進行計算(依賴於不同演算法進行不同輪數的計算,每個512位文本都要經過這些輪數的計算)。
區塊鏈中每一個數據塊中包含了一次網路交易的信息,產生相關聯數據塊所使用的就是非對稱加密技術。非對密加密技術的作用是驗證信息的有效性和生成下一個區塊,區塊鏈上網路交易的信息是公開透明的,但是用戶的身份信息是被高度加密的,只有經過用戶授權,區塊鏈才能得到該身份信息,從而保證了數據的安生性和個人信息的隱私性。
公鑰和私鑰在非對稱加密機制里是成對存在的,公鑰和私鑰可以去相互驗證對方,那麼在比特幣的世界裡面,我們可以把地址理解為公鑰,可以把簽名、輸密碼的過程理解為私鑰的簽名。
每個礦工在拿到一筆轉賬交易時候都可以驗證公鑰和私鑰到底是不是匹配的,如果他們是匹配的,這筆交易就是合法的,這樣每一個人只需要保管好TA自己的私鑰,知道自己的比特幣地址和對方的比特幣地址就能夠安全的將比特幣進行轉賬,不需要一個中心化的機構來驗證對方發的比特幣是不是真的。
❷ 什麼是哈希
散列是指從可變大小的輸入生成固定大小的輸出的過程。這是通過使用稱為散列函數(作為散列演算法實現)的數學公式來完成的。
盡管並非所有哈希函數都涉及密碼學的使用 ,但所謂的密碼哈希函數是加密貨幣的核心。多虧了它們,區塊鏈和其他分布式系統能夠實現顯著水平的 數據完整性和安全性。
傳統和加密散列函數都是確定性的。確定性意味著只要輸入不變,散列演算法將始終產生相同的輸出(也稱為摘要或散列)。
通常,加密貨幣的散列演算法被設計為單向函數,這意味著如果沒有大量的計算時間和資源,它們就無法輕易恢復。換句話說,從輸入創建輸出非常容易,但在相反的方向(僅從輸出生成輸入)相對困難。一般來說,越難找到輸入,哈希演算法被認為越安全。
不同的散列函數將產生不同大小的輸出,但每種散列演算法可能的輸出大小始終是恆定的。例如,SHA-256 演算法只能生成 256 位的輸出,而 SHA-1 將始終生成 160 位的摘要。
為了說明這一點,讓我們通過 SHA-256 哈希演算法(比特幣中使用的演算法)運行「Bitcoin」和「bitcoin」這兩個詞。
請注意,微小的更改(第一個字母的大小寫)會導致完全不同的哈希值。但由於我們使用 SHA-256,輸出將始終具有 256 位(或 64 個字元)的固定大小 - 無論輸入大小如何。此外,無論我們通過演算法運行這兩個單詞多少次,兩個輸出都將保持不變。
相反,如果我們通過 SHA-1 哈希演算法運行相同的輸入,我們將得到以下結果:
值得注意的是,首字母縮略詞 SHA 代表安全哈希演算法。它指的是一組加密哈希函數,包括 SHA-0 和 SHA-1 演算法以及 SHA-2 和 SHA-3 組。SHA-256 是 SHA-2 組的一部分,還有 SHA-512 和其他變體。目前,只有 SHA-2 和 SHA-3 組被認為是安全的。
傳統的哈希函數具有廣泛的用例,包括資料庫查找、大文件分析和數據管理。另一方面,加密散列函數廣泛用於信息安全應用,例如消息認證和數字指紋。就比特幣而言,加密哈希函數是挖礦過程的重要組成部分, 也在新地址和密鑰的生成中發揮作用。
散列的真正威力在於處理大量信息時。例如,可以通過哈希函數運行一個大文件或數據集,然後使用其輸出來快速驗證數據的准確性和完整性。由於散列函數的確定性,這是可能的:輸入將始終產生簡化的、壓縮的輸出(散列)。這種技術消除了存儲和「記住」大量數據的需要。
散列在區塊鏈技術的背景下特別有用。比特幣區塊鏈有幾個涉及散列的操作,其中大部分在挖掘過程中。事實上,幾乎所有的加密貨幣協議都依賴散列來將交易組鏈接和壓縮成塊,並在每個塊之間產生加密鏈接,從而有效地創建區塊鏈。
同樣,部署密碼技術的散列函數可以定義為密碼散列函數。一般來說,破解密碼哈希函數需要無數次的蠻力嘗試。對於「還原」加密哈希函數的人來說,他們需要通過反復試驗來猜測輸入是什麼,直到產生相應的輸出。然而,也有可能不同的輸入產生完全相同的輸出,在這種情況下會發生「沖突」。
從技術上講,加密哈希函數需要遵循三個屬性才能被視為有效安全。我們可以將這些描述為抗碰撞性、抗原像性和抗二次原像性。
在討論每個屬性之前,讓我們用三個簡短的句子總結它們的邏輯。
如前所述,當不同的輸入產生完全相同的散列時,就會發生沖突。因此,哈希函數被認為是抗沖突的,直到有人發現沖突為止。請注意,任何散列函數都將始終存在沖突,因為可能的輸入是無限的,而可能的輸出是有限的。
換句話說,當發現碰撞的可能性非常低以至於需要數百萬年的計算時,哈希函數是抗碰撞的。因此,盡管沒有無沖突的哈希函數,但其 中一些函數足夠強大,可以被視為具有抵抗力(例如,SHA-256)。
在各種 SHA 演算法中,SHA-0 和 SHA-1 組不再安全,因為已經發現沖突。目前,SHA-2 和 SHA-3組被認為是抗沖突的。
原像電阻的特性與單向函數的概念有關。當有人找到生成特定輸出的輸入的可能性非常低時,哈希函數被認為是抗原像的。
請注意,此屬性與前一個屬性不同,因為攻擊者會試圖通過查看給定的輸出來猜測輸入是什麼。另一方面,當有人發現產生相同輸出的兩個不同輸入時,就會發生沖突,但使用哪個輸入並不重要。
原像抗性的特性對於保護數據很有價值,因為消息的簡單散列可以證明其真實性,而無需披露信息。在實踐中,許多服務提供商和 Web 應用程序存儲和使用從密碼生成的哈希值,而不是明文密碼。
為簡化起見,我們可以說第二原像電阻介於其他兩個屬性之間。當有人能夠找到一個特定的輸入,該輸入生成與他們已經知道的另一個輸入相同的輸出時,就會發生二次原像攻擊。
換句話說,第二原像攻擊涉及尋找碰撞,但不是搜索生成相同散列的兩個隨機輸入,而是搜索生成由另一個特定輸入生成的相同散列的輸入。
因此,任何抗碰撞的哈希函數也能抗第二原像攻擊,因為後者總是意味著碰撞。然而,人們仍然可以對抗碰撞函數執行原像攻擊,因為它意味著從單個輸出中找到單個輸入。
比特幣挖礦有很多步驟 涉及哈希函數,例如檢查余額、鏈接交易輸入和輸出,以及對區塊內的交易進行哈希處理以形成 默克爾樹。但比特幣區塊鏈安全的主要原因之一 是礦工需要執行無數的散列操作,以便最終為下一個區塊找到有效的解決方案。
具體來說,礦工在為其候選塊創建哈希值時必須嘗試幾種不同的輸入。本質上,如果他們生成以一定數量的零開頭的輸出哈希,他們將只能驗證他們的塊。零的數量決定了挖礦難度,它根據網路的哈希率而變化。
在這種情況下,哈希率表示在比特幣挖礦中投入了多少計算機能力。如果網路的哈希率增加,比特幣協議會自動調整挖礦難度,使挖出一個區塊所需的平均時間保持在接近 10 分鍾。相反,如果幾個礦工決定停止挖礦,導致算力大幅下降,則會調整挖礦難度,使其更容易挖礦(直到平均出塊時間回到10分鍾)。
請注意,礦工不必發現沖突,因為他們可以生成多個散列作為有效輸出(從一定數量的零開始)。所以對於某個區塊有幾種可能的解決方案,礦工只需要找到其中一種——根據挖礦難度確定的閾值。
由於比特幣挖礦是一項成本密集型任務,礦工沒有理由欺騙系統,因為這會導致重大的經濟損失。加入區塊鏈的礦工越多,它就變得越大越強大。(國內禁止參與挖礦)
毫無疑問,哈希函數是計算機科學中必不可少的工具,尤其是在處理大量數據時。當與密碼學結合時,散列演算法可以非常通用,以多種不同的方式提供安全性和身份驗證。因此,加密哈希函數對幾乎所有加密貨幣網路都至關重要,因此了解它們的屬性和工作機制對於任何對區塊鏈技術感興趣的人肯定會有所幫助。
❸ 區塊鏈記賬原理
區塊鏈是由一個個區塊構成的有序列表,每一個區塊都記錄了一系列交易,並且每一個區塊都指向前一個區塊從而形成一個鏈條。
區塊鏈有以下幾個特徵:
區塊鏈具有不可篡改的特性,是由哈希演算法保證的。
什麼是哈希演算法/Hash:
安全哈希演算法的特點:
哈希演算法的作用:
假設我們相信一個安全的哈希演算法:如果H(x) = H(y),則x = y
常用的哈希演算法:
比特幣使用兩種哈希演算法:
假設這個區塊有5筆交易,首先,對每一筆交易進行第一hash,也就是2次SHA-256的運算,得到5個哈希值,也就是a1、a2、a3、a4、a5,這五個哈希值也可以看做是數據,將a1和a2拼起來、a3和a4拼起來,再計算出2個哈希值b1和b2。那a5怎麼辦呢?答案是將a5復制一份在與a5拼起來進行哈希計算得到b3;繼續將b1和b2拼起來進行哈希運算得到c1,同樣的b3會被復制一份再與b3拼起來進行哈希運算得到c2;最後將c1和c2拼起來進行哈希運算得到最終的哈希值,這個哈希值就是Merkle Hash。
從Merkle Hash的計算方法可以得出結論:修改任意一筆交易,哪怕是一個位元組,或者交換兩個交易的順序,都會導致Merkle Hash驗證失敗,也就會導致這個區塊本身是無效的。所以Merkle Hash記錄在頭部,它的作用就是保證交易記錄永遠不能夠被修改。
區塊本身用Block Hash來標識:Block Hash是區塊唯一標識。一個區塊的hash並沒有記錄在區塊頭部,而是通過計算區塊的hash得到的。
區塊的Prev Hash記錄了上一個區塊的Hash,這樣就可以通過Prev Hash追蹤到上一個區塊,由於下一個區塊的Prev Hash又會指向當前區塊,這樣每一個區塊的Prev Hash都指向上一個區塊,這些區塊串起來就形成了區塊鏈。如果一個攻擊者惡意攻擊了某一個區塊的交易記錄,那麼這個區塊的Merkle Hash驗證就不會通過,所以攻擊者只能重新計算Merkle Hash,然後把區塊頭的Merkle Hash也修改了,但是這個區塊本身的Hash已經改變,那麼下一個區塊指向該區塊的鏈接也斷掉了。由於比特幣區塊的hash必須滿足一定的難度值,所以攻擊者只能把後面所以區塊全部重新計算,並且偽造出來,才能修改整個區塊鏈。
修改一個區塊的成本已經非常高了,如果要修改整個區塊鏈,那麼其成本非常非常的高昂。在比特幣網路中,偽造區塊鏈需要擁有超過51%的全網算力。所以比特幣網路運行了6年,從來沒有被攻破過。
❹ 區塊鏈技術中的哈希演算法是什麼
1.1. 簡介
計算機行業從業者對哈希這個詞應該非常熟悉,哈希能夠實現數據從一個維度向另一個維度的映射,通常使用哈希函數實現這種映射。通常業界使用y = hash(x)的方式進行表示,該哈希函數實現對x進行運算計算出一個哈希值y。
區塊鏈中哈希函數特性:
函數參數為string類型;
固定大小輸出;
計算高效;
collision-free 即沖突概率小:x != y => hash(x) != hash(y)
隱藏原始信息:例如區塊鏈中各個節點之間對交易的驗證只需要驗證交易的信息熵,而不需要對原始信息進行比對,節點間不需要傳輸交易的原始數據只傳輸交易的哈希即可,常見演算法有SHA系列和MD5等演算法
1.2. 哈希的用法
哈希在區塊鏈中用處廣泛,其一我們稱之為哈希指針(Hash Pointer)
哈希指針是指該變數的值是通過實際數據計算出來的且指向實際的數據所在位置,即其既可以表示實際數據內容又可以表示實際數據的存儲位置。下圖為Hash Pointer的示意圖

❺ 哈希函數的本質及生成方式
哈希表與哈希函數
說到哈希表,其實本質上是一個數組。通過前面的學習我們知道了,如果要訪問一個數組中某個特定的元素,那麼需要知道這個元素的索引。例如,我們可以用數組來記錄自己好友的電話號碼,索引 0 指向的元素記錄著 A 的電話號碼,索引 1 指向的元素記錄著 B 的電話號碼,以此類推。
而當這個數組非常大的時候,全憑記憶去記住哪個索引記錄著哪個好友的號碼是非常困難的。這時候如果有一個函數,可以將我們好友的姓名作為一個輸入,然後輸出這個好友的號碼在數組中對應的索引,是不是就方便了很多呢?這樣的一種函數,其實就是哈希函數。哈希函數的定義是將任意長度的一個對象映射到一個固定長度的值上,而這個值我們可以稱作是哈希值(Hash Value)。
哈希函數一般會有以下三個特性:
任何對象作為哈希函數的輸入都可以得到一個相應的哈希值;
兩個相同的對象作為哈希函數的輸入,它們總會得到一樣的哈希值;
兩個不同的對象作為哈希函數的輸入,它們不一定會得到不同的哈希值。
對於哈希函數的前兩個特性,比較好理解,但是對於第三種特性,我們應該如何解讀呢?那下面就通過一個例子來說明。
我們按照 Java String 類里的哈希函數公式(即下面的公式)來計算出不同字元串的哈希值。String 類里的哈希函數是通過 hashCode 函數來實現的,這里假設哈希函數的字元串輸入為 s,所有的字元串都會通過以下公式來生成一個哈希值:
這里為什麼是「31」?下面會講到哦~
注意:下面所有字元的數值都是按照 ASCII 表獲得的,具體的數值可以在這里查閱。
如果我們輸入「ABC」這個字元串,那根據上面的哈希函數公式,它的哈希值則為:
在什麼樣的情況下會體現出哈希函數的第三種特性呢?我們再來看看下面這個例子。現在我們想要計算字元串 "Aa" 和 "BB" 的哈希值,還是繼續套用上面的的公式。
"Aa" 的哈希值為:
"Aa" = 'A' * 31 + 'a' = 65 * 31 + 97 = 2112
"BB" 的哈希值為:
"BB" = 'B' * 31 + 'B' = 66 * 31 + 66 = 2112
可以看到,不同的兩個字元串其實是會輸出相同的哈希值出來的,這時候就會造成哈希碰撞,具體的解決方法將會在第 07 講中詳細討論。
需要注意的是,雖然 hashCode 的演算法里都是加法,但是算出來的哈希值有可能會是一個負數。
我們都知道,在計算機里,一個 32 位 int 類型的整數里最高位如果是 0 則表示這個數是非負數,如果是 1 則表示是負數。
如果當字元串通過計算算出的哈希值大於 232-1 時,也就是大於 32 位整數所能表達的最大正整數了,則會造成溢出,此時哈希值就變為負數了。感興趣的小夥伴可以按照上面的公式,自行計算一下「19999999999999999」這個字元串的哈希值會是多少。
hashCode 函數中的「魔數」(Magic Number)
細心的你一定發現了,上面所講到的 Java String 類里的 hashCode 函數,一直在使用一個 31 這樣的正整數來進行計算,這是為什麼呢?下面一起來研究一下 Java Openjdk-jdk11 中 String.java 的源碼(源碼鏈接),看看這么做有什麼好處。
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
hash = h = isLatin1() ? StringLatin1.hashCode(value)
: StringUTF16.hashCode(value);
}
return
可以看到,String 類的 hashCode 函數依賴於 StringLatin1 和 StringUTF16 類的具體實現。而 StringLatin1 類中的 hashCode 函數(源碼鏈接)和 StringUTF16 類中的 hashCode 函數(源碼鏈接)所表達的演算法其實是一致的。
StringLatin1 類中的 hashCode 函數如下面所示:
public static int hashCode(byte[] value) {
int h = 0;
for (byte v : value) {
h = 31 * h + (v & 0xff);
}
return h
StringUTF16 類中的 hashCode 函數如下面所示:
public static int hashCode(byte[] value) {
int h = 0;
int length = value.length >> 1;
for (int i = 0; i < length; i++) {
h = 31 * h + getChar(value, i);
}
return h
一個好的哈希函數演算法都希望盡可能地減少生成出來的哈希值會造成哈希碰撞的情況。
Goodrich 和 Tamassia 這兩位計算機科學家曾經做過一個實驗,他們對超過 50000 個英文單詞進行了哈希值運算,並使用常數 31、33、37、39 和 41 作為乘數因子,每個常數所算出的哈希值碰撞的次數都小於 7 個。但是最終選擇 31 還是有著另外幾個原因。
從數學的角度來說,選擇一個質數(Prime Number)作為乘數因子可以讓哈希碰撞減少。其次,我們可以看到在上面的兩個 hashCode 源碼中,都有著一條 31 * h 的語句,這條語句在 JVM 中其實都可以被自動優化成「(h << 5) - h」這樣一條位運算加上一個減法指令,而不必執行乘法指令了,這樣可以大大提高運算哈希函數的效率。
所以最終 31 這個乘數因子就被一直保留下來了。
區塊鏈挖礦的本質
通過上面的學習,相信你已經對哈希函數有了一個比較好的了解了。可能也發現了,哈希函數從輸入到輸出,我們可以按照函數的公式演算法,很快地計算出哈希值。但是如果告訴你一個哈希值,即便給出了哈希函數的公式也很難算得出原來的輸入到底是什麼。例如,還是按照上面 String 類的 hashCode 函數的計算公式:
如果告訴了你哈希值是 123456789 這個值,那輸入的字元串是什麼呢?我們想要知道答案的話,只能採用暴力破解法,也就是一個一個的字元串去嘗試,直到嘗試出這個哈希值為止。
對於區塊鏈挖礦來說,這個「礦」其實就是一個字元串。「礦工」,也就是進行運算的計算機,必須在規定的時間內找到一個字元串,使得在進行了哈希函數運算之後得到一個滿足要求的值。
我們以比特幣為例,它採用了 SHA256 的哈希函數來進行運算,無論輸入的是什麼,SHA256 哈希函數的哈希值永遠都會是一個 256 位的值。而比特幣的獎勵機制簡單來說是通過每 10 分鍾放出一個哈希值,讓「礦工們」利用 SHA256(SHA256(x)) 這樣兩次的哈希運算,來找出滿足一定規則的字元串出來。
比方說,比特幣會要求找出通過上面 SHA256(SHA256(x)) 計算之後的哈希值,這個 256 位的哈希值中的前 50 位都必須為 0 ,誰先找到滿足這個要求的輸入值 x,就等於「挖礦」成功,給予獎勵一個比特幣。我們知道,即便知道了哈希值,也很難算出這個 x 是什麼,所以只能一個一個地去嘗試。而市面上所說的挖礦機,其原理是希望能提高運算的速度,讓「礦工」盡快地找到這個 x 出來。
❻ 區塊鏈中的哈希演算法是什麼
哈希演算法是什麼?如何保證挖礦的公平性?
哈希演算法是一種只能加密,不能解密的密碼學演算法,可以將任意長度的信息轉換成一段固定長度的字元串。
這段字元串有兩個特點:
1、 就算輸入值只改變一點,輸出的哈希值也會天差地別。
2、只有完全一樣的輸入值才能得到完全一樣的輸出值。
3、輸入值與輸出值之間沒有規律,所以不能通過輸出值算出輸入值。要想找到指定的輸出值,只能採用枚舉法:不斷更換輸入值,尋找滿足條件的輸出值。
哈希演算法保證了比特幣挖礦不能逆向推導出結果。所以,礦工持續不斷地進行運算,本質上是在暴力破解正確的輸入值,誰最先找到誰就能獲得比特幣獎勵。
❼ 比特幣演算法原理
比特幣演算法主要有兩種,分別是橢圓曲線數字簽名演算法和SHA256哈希演算法。
橢圓曲線數字簽名演算法主要運用在比特幣公鑰和私鑰的生成過程中,該演算法是構成比特幣系統的基石。SHA-256哈希演算法主要是運用在比特幣的工作量證明機制中。
比特幣產生的原理是經過復雜的運演算法產生的特解,挖礦就是尋找特解的過程。不過比特幣的總數量只有2100萬個,而且隨著比特幣不斷被挖掘,越往後產生比特幣的難度會增加,可能獲得比特幣的成本要比比特幣本身的價格高。
比特幣的區塊由區塊頭及該區塊所包含的交易列表組成,區塊頭的大小為80位元組,由4位元組的版本號、32位元組的上一個區塊的散列值、32位元組的 Merkle Root Hash、4位元組的時間戳(當前時間)、4位元組的當前難度值、4位元組的隨機數組成。擁有80位元組固定長度的區塊頭,就是用於比特幣工作量證明的輸入字元串。不停的變更區塊頭中的隨機數即 nonce 的數值,並對每次變更後的的區塊頭做雙重 SHA256運算,將結果值與當前網路的目標值做對比,如果小於目標值,則解題成功,工作量證明完成。
比特幣的本質其實是一堆復雜演算法所生成的一組方程組的特解(該解具有唯一性)。比特幣是世界上第一種分布式的虛擬貨幣,其沒有特定的發行中心,比特幣的網路由所有用戶構成,因為沒有中心的存在能夠保證了數據的安全性。
❽ 比特幣塊哈希是怎麼算出來的
比特幣所採用的哈希演算法,在比特幣系統中,需要大量地進行哈希函數運算。比特幣系統是這樣規定的:每隔十分鍾,大家都需要計算哈希函數,計算的值必須符合我的規定。誰計算的快,誰才會獲得作為獎勵的比特幣。
❾ 小白如何秒懂區塊鏈中的哈希計算
小白如何秒懂區塊鏈中的哈希計算
當我在區塊鏈的學習過程中,發現有一個詞像幽靈一樣反復出現,「哈希」,英文寫作「HASH」。
那位說「拉稀」同學你給我出去!!
這個「哈希」據說是來源於密碼學的一個函數,嘗試搜一搜,論文出來一堆一堆的,不是橫式就是豎式,不是表格就是圖片,還有一堆看不懂得xyzabc。大哥,我就是想了解一下區塊鏈的基礎知識,給我弄那麼難幹啥呀?!我最長的密碼就是123456,復雜一點的就是654321,最復雜的時候在最後加個a,你給我寫的那麼復雜明顯感覺腦力被榨乾,僅有的腦細胞成批成批的死亡!為了讓和我一樣的小白同學了解這點,我就勉為其難,努力用傻瓜式的語言講解一下哈希計算,不求最准確但求最簡單最易懂。下面我們開始:
# 一、什麼是哈希演算法
## 1、定義:哈希演算法是將任意長度的字元串變換為固定長度的字元串。
從這里可以看出,可以理解為給**「哈希運算」輸入一串數字,它會輸出一串數字**。
如果我們自己定義 「增一演算法」,那麼輸入1,就輸出2;輸入100就輸出101。
如果我我們自己定義「變大寫演算法」,那麼輸入「abc」輸出「ABC」。
呵呵,先別打我啊!這確實就只是一個函數的概念。
## 2、特點:
這個哈希演算法和我的「增一演算法」和「變大寫演算法」相比有什麼特點呢?
1)**確定性,算得快**:咋算結果都一樣,算起來效率高。
2)**不可逆**:就是知道輸出推不出輸入的值。
3)**結果不可測**:就是輸入變一點,結果天翻地覆毫無規律。
總之,這個哈希運算就是個黑箱,是加密的好幫手!你說「11111」,它給你加密成「」,你說「11112」它給你弄成「」。反正輸入和輸出一個天上一個地下,即使輸入相關但兩個輸出毫不相關。
# 二、哈希運算在區塊鏈中的使用
## 1、數據加密
**交易數據是通過哈希運算進行加密,並把相應的哈希值寫入區塊頭**。如下圖所示,一個區塊頭包含了上一個區塊的hash值,還包含下一個區塊的hash值。
1)、**識別區塊數據是否被篡改**:區塊鏈的哈希值能夠唯一而精準地標識一個區塊,區塊鏈中任意節點通過簡單的哈希計算都可以獲得這個區塊的哈希值,計算出的哈希值沒有變化也就意味著區塊鏈中的信息沒有被篡改。
2)、**把各個區塊串聯成區塊鏈**:每個區塊都包含上一個區塊的哈希值和下一個區塊的值,就相當於通過上一個區塊的哈希值掛鉤到上一個區塊尾,通過下一個區塊的哈希值掛鉤到下一個區塊鏈的頭,就自然而然形成一個鏈式結構的區塊鏈。
## 2、加密交易地址及哈希
在上圖的區塊頭中,有一個Merkle root(默克爾根)的哈希值,它是用來做什麼的呢?
首先了解啥叫Merkle root? 它就是個二叉樹結構的根。啥叫二叉樹?啥叫根?看看下面的圖就知道了。一分二,二分四,四分八可以一直分下去就叫二叉樹。根就是最上面的節點就叫 根。
這個根的數據是怎麼來的呢?是把一個區塊中的每筆交易的哈希值得出後,再兩兩哈希值再哈希,再哈希,再哈希,直到最頂層的數值。
這么哈希了半天,搞什麼事情?有啥作用呢?
1)、**快速定位每筆交易**:由於交易在存儲上是線性存儲,定位到某筆交易會需要遍歷,效率低時間慢,通過這樣的二叉樹可以快速定位到想要找的交易。
舉個不恰當的例子:怎麼找到0-100之間的一個任意整數?(假設答案是88)那比較好的一個方法就是問:1、比50大還是小?2、比75大還是小?3、比88大還是小? 僅僅通過幾個問題就可以快速定位到答案。
2)、**核實交易數據是否被篡改**:從交易到每個二叉樹的哈希值,有任何一個數字有變化都會導致Merkle root值的變化。同時,如果有錯誤發生的情況,也可以快速定位錯誤的地方。
## 3、挖礦
在我們的區塊頭中有個參數叫**隨機數Nonce,尋找這個隨機數的過程就叫做「挖礦」**!網路上任何一台機器只要找到一個合適的數字填到自己的這個區塊的Nonce位置,使得區塊頭這6個欄位(80個位元組)的數據的哈希值的哈希值以18個以上的0開頭,誰就找到了「挖到了那個金子」!既然我們沒有辦法事先寫好一個滿足18個0的數字然後反推Nounce,唯一的做法就是從0開始一個一個的嘗試,看結果是不是滿足要求,不滿足就再試下一個,直到找到。
找這個數字是弄啥呢?做這個有什麼作用呢?
1)、**公平的找到計算能力最強的計算機**:這個有點像我這里有個沙子,再告訴你它也那一個沙灘的中的一粒相同,你把相同的那粒找出來一樣。那可行的辦法就是把每一粒都拿起來都比較一下!那麼比較速度最快的那個人是最有可能先早到那個沙子。這就是所謂的「工作量證明pow」,你先找到這個沙子,我就認為你比較的次數最多,乾的工作最多。
2)、**動態調整難度**:比特幣為了保證10分鍾出一個區塊,就會每2016個塊(2周)的時間計算一下找到這個nonce數字的難度,如果這2016個塊平均時間低於10分鍾則調高難度,如高於十分鍾則調低難度。這樣,不管全網的挖礦算力是怎麼變化,都可以保證10分鍾的算出這個隨機數nonce。
# 三、哈希運算有哪些?
說了這么多哈希運算,好像哈希運算就是一種似的,其實不是!作為密碼學中的哈希運算在不斷的發展中衍生出很多流派。我看了」滿頭包」還是覺得內在機理也太復雜了,暫時羅列如下,小白們有印象知道是怎麼回事就好。
從下表中也可以看得出,哈希運算也在不斷的發展中,有著各種各樣的演算法,各種不同的應用也在靈活應用著單個或者多個演算法。比特幣系統中,哈希運算基本都是使用的SHA256演算法,而萊特幣是使用SCRYPT演算法,誇克幣(Quark)達世幣(DASH)是把很多演算法一層層串聯上使用,Heavycoin(HAV)卻又是把一下演算法並聯起來,各取部分混起來使用。以太坊的POW階段使用ETHASH演算法,ZCASH使用EQUIHASH。
需要說明的是,哈希運算的各種演算法都是在不斷升級完善中,而各種幣種使用的演算法也並非一成不變,也在不斷地優化中。
**總結**:哈希運算在區塊鏈的各個項目中都有著廣泛的應用,我們以比特幣為例就能看到在**數據加密、交易數據定位、挖礦等等各個方面都有著極其重要的作用**。而哈希運算作為加密學的一門方向不斷的發展和延伸,身為普通小白的我們,想理解區塊鏈的一些基礎概念,了解到這個層面也已經足夠。