私有區塊鏈 blockchain_go 學習筆記
學習原始碼地址
https://github.com/Jeiwan/blockchain_go.git
原作者講解的部落格
以下是上述內容的學習筆記
專案級開源的區塊鏈推薦
1.以太坊(英文Ethereum)是一個開源的有智慧合約功能的公共區塊鏈平臺,通過其專用加密貨幣以太幣(Ether,簡稱“ETH”)提供去中心化的以太虛擬機器(Ethereum Virtual Machine)來處理點對點合約。
截至2018年2月,以太幣是市值第二高的加密貨幣,僅次於比特幣。
2.金融領域的區塊鏈專案 Chain
Chain Core是設計用於操作和連線符合Chain協議的高度可擴充套件許可區塊鏈網路的軟體。每個網路都維護一個加密安全的交易日誌,稱為區塊鏈,它允許參與者在多資產共享賬本上定義、發行和轉移數字資產。數字資產共享一種通用的、可互操作的格式,可以表示受信任發行人擔保的任何價值單位,如貨幣、債券、證券、借據或忠誠點數。每個鏈核心持有一份分類賬的副本,並獨立驗證每個更新或“塊”,而塊簽名者的聯盟確保分類賬的全域性一致性。
https://github.com/chain/chain.git
3.基於區塊鏈的開源 分散式賬本
https://github.com/hyperledger/fabric.git
比特幣和區塊鏈
比特幣採用區塊鏈做為底層技術,是新一代加密數字貨幣,比特幣由計算(挖礦)產生,交易過程具有安全性,隱私性,可追溯性,不可篡改性。
區塊鏈是一個公開的分散式資料庫,只有在資料庫的其他管理員同意的情況下才能新增新記錄,是加密貨幣和智慧合約的基礎。具備分散式儲存,分散式記錄,去中心化,分散式維護等特性。
區塊鏈1.0:可程式設計貨幣,數字化貨幣及支付系統。
區塊鏈2.0:可程式設計金融,股票,清算,私募,股權等金融領域。
區塊鏈3.0:公證,仲裁,審計,物流,醫療等領域。
核心技術
密碼學和數字簽名用於身份地址標識
共識演算法,用於工作量證明
分散式儲存技術用於儲存交易記錄和區塊,分散式網路技術用於網路通訊和節點發現。
工作量證明
工作的結果作為資料加入區塊鏈成為一個區塊
完成這個工作的人也會獲得獎勵(也就是通過挖礦獲得比特幣)
Bolt
純粹的go語言開發的key和value儲存機制,是基於檔案的儲存。
BoltDB 的一件重要事情是沒有資料型別:鍵和值都是位元組陣列
1.它簡單而簡約。
2.它在 Go 中實現。
3.它不需要執行伺服器。
4.它允許構建我們想要的資料結構。
地址及身份標識
某種途徑可以識別出你是交易輸出的所有者,稱之為身份。
在比特幣中,你的身份就是一對,或者多對公鑰和私鑰。
公鑰演算法和數字簽名
公鑰加密演算法使用的是成對的金鑰:公鑰和私鑰。
公鑰並不是敏感資訊,可以告訴其他人,但是私鑰絕對不能告訴其他人,只有所有者才能知道私鑰,能夠識別鑑定和證明所有者身份的就是私鑰。
錢包
錢包就是公鑰和私鑰的集合
SHA-256雜湊
雜湊的計算方式是區塊鏈非常重要的特性,正是這個特性使區塊鏈變得安全。
區塊
在比特幣規範Timestamp中PrevBlockHash, 和Hash是塊頭,它們形成一個單獨的資料結構,而交易(Data在我們的例子中)是一個單獨的資料結構。所以為了簡單起見,我們在這裡混合它們。
區塊鏈
通過雜湊獲取塊
交易
在獲得新增塊的許可權之前必須執行一些繁重的計算(這種機制稱為工作量證明)。此外,區塊鏈是一個分散式資料庫,沒有單一的決策者。因此,新區塊必須得到網路其他參與者的確認和批准(這種機制稱為共識)。
工作量證明 PoW
一種工作計算很難,驗算很容易,在比特幣中,此類工作的目標是為塊找到滿足某些要求的雜湊。正是這個雜湊值作為證明。
儲存資料型別
我們將為此使用encoding/gob,但也可以使用JSON、XML、Protocol Buffers等。
查詢區塊
將從上到下、從最新到最舊的順序獲取塊。一個區塊鏈可以有多個分支,其中最長的被認為是主要的。
交易 輸出
關於輸出的一件重要的事情是它們是不可分割的,這意味著你不能引用它的一部分值。當一個輸出在一個新的事務中被引用時,它被作為一個整體來使用。如果其值大於要求,則會生成更改並將其傳送回傳送者。這類似於現實世界的情況,例如,您支付 5 美元的鈔票以換取價值 1 美元的東西並獲得 4 美元的找零。
區塊獎勵
subsidy是獎勵的金額。在比特幣中,這個數字不儲存在任何地方,僅根據區塊總數計算:區塊數除以210000. 挖掘創世塊產生 50 BTC,每個210000塊獎勵減半。
Merkle 樹(工作量證明)
比特幣使用了一種更精細的技術:它將塊中包含的所有交易表示為Merkle 樹,並在工作量證明系統中使用樹的根雜湊。這種方法允許快速檢查一個塊是否包含某些交易,僅具有根雜湊並且無需下載所有交易。
查詢餘額
由於交易儲存在區塊中,我們必須檢查區塊鏈中的每個區塊,賬戶餘額是賬戶地址鎖定的所有未使用交易輸出的價值總和。
轉賬
傳送硬幣意味著建立交易並通過挖掘區塊將其新增到區塊鏈中。但比特幣不會立即這樣做(就像我們所做的那樣)。相反,它將所有新交易放入記憶體池(或記憶體池)中,當礦工準備好挖一個區塊時,它會從記憶體池中取出所有交易並建立一個候選區塊。只有當包含交易的區塊被挖掘並新增到區塊鏈時,交易才會得到確認。
比特幣地址
比特幣地址是公開的。如果你想向某人傳送硬幣,你需要知道他們的地址。
數字簽名
數字簽名使用私鑰進行,驗證需要公鑰。比特幣中的每筆交易輸入都由建立交易的人簽名。比特幣中的每筆交易都必須在被放入區塊之前進行驗證。驗證方式(除其他程式外):
1.檢查輸入是否有權使用先前交易的輸出。
2.檢查交易簽名是否正確。
交易事務
當一個人傳送硬幣時,就會建立一筆交易。交易的輸入將參考先前交易的輸出。每個輸入都將儲存一個公鑰(未雜湊)和整個交易的簽名。
接收交易的比特幣網路中的其他節點將對其進行驗證。除其他事項外,他們還將檢查: 輸入中公鑰的雜湊與引用輸出的雜湊匹配(這確保傳送者只花費屬於他們的硬幣);簽名是正確的(這可以確保交易是由硬幣的真正所有者建立的)。
簽署交易,因為這是比特幣中唯一保證一個人不能花費屬於其他人的硬幣的方法。
Base58
比特幣使用 Base58 演算法將公鑰轉換為人類可讀的格式,該演算法與著名的 Base64 非常相似,但它使用較短的字母表:從字母表中刪除了一些字母,以避免一些使用字母相似性的攻擊。因此,沒有這些符號:0(零)、O(大寫 o)、I(大寫 i)、l(小寫 L),因為它們看起來很相似。此外,沒有 + 和 / 符號。
UTXO
由於交易儲存在塊中,因此它會遍歷區塊鏈中的每個塊並檢查其中的每筆交易。截至 2017 年 9 月 18 日,比特幣中有 485,860 個區塊,整個資料庫佔用 140+ Gb 的磁碟空間。這意味著必須執行一個完整的節點來驗證交易。此外,驗證交易將需要迭代許多塊。UTXO 集不儲存所有交易,而只儲存那些具有未使用輸出的交易。
該問題的解決方案是有一個只儲存未使用輸出的索引,這就是 UTXO 集所做的:這是一個由所有區塊鏈事務構建的快取(通過迭代塊,是的,但這隻完成一次),然後用於計算餘額和驗證新交易。截至 2017 年 9 月,UTXO 集約為 2.7 Gb。
UTXO更新
當一個新的區塊被挖出時,UTXO 集應該被更新。更新意味著從新挖掘的交易中刪除已使用的輸出並新增未使用的輸出。如果一個輸出被刪除的交易不再包含輸出,它也會被刪除。非常簡單!
Merkle 樹
如上所述,完整的比特幣資料庫(即區塊鏈)佔用超過 140 Gb 的磁碟空間。由於比特幣的去中心化特性,網路中的每個節點都必須是獨立且自給自足的,即每個節點都必須儲存區塊鏈的完整副本。隨著許多人開始使用比特幣,這條規則變得更加難以遵循:不可能每個人都會執行一個完整的節點。此外,由於節點是網路的成熟參與者,他們有責任:他們必須驗證交易和區塊。此外,與其他節點互動和下載新塊需要一定的網際網路流量。
簡化支付驗證
SPV 是一個輕量級的比特幣節點,它不下載整個區塊鏈,也不驗證區塊和交易。相反,它在塊中查詢交易(以驗證付款)並連結到完整節點以僅檢索必要的資料。這種機制允許多個輕錢包節點只執行一個完整節點。
SPV 中應該有一種方法可以在不下載整個塊的情況下檢查一個塊是否包含某個交易。
Merkle 樹的好處是節點可以在不下載整個塊的情況下驗證某個交易的成員資格。為此,只需要一個交易雜湊、一個 Merkle 樹根雜湊和一個 Merkle 路徑。
P2PKH
用於鎖定交易輸出;交易輸入提供資料來解鎖輸出。
支付公鑰雜湊(P2PKH),這是比特幣中最常用的指令碼。從字面上看,它支付給公鑰雜湊,即用某個公鑰鎖定硬幣。這是比特幣支付的核心:沒有賬戶,它們之間沒有資金轉移;只有一個指令碼可以檢查提供的簽名和公鑰是否正確。
區塊鏈網路
區塊鏈網路是一個 P2P(Peer-to-Peer)網路,這意味著節點之間是直接相互連線的。
節點角色
儘管功能成熟,區塊鏈節點可以在網路中扮演不同的角色。他們來了:
1.礦工。
此類節點執行在功能強大或專用的硬體(如 ASIC)上,它們的唯一目標是儘可能快地挖掘新塊。礦工只有在使用工作量證明的區塊鏈中才有可能,因為挖礦實際上意味著解決 PoW 難題。例如,在 Proof-of-Stake 區塊鏈中,沒有挖礦。
2.全節點。
這些節點驗證礦工開採的區塊並驗證交易。為此,他們必須擁有區塊鏈的完整副本。此外,此類節點執行此類路由操作,例如幫助其他節點發現彼此。
擁有許多完整節點對網路來說非常重要,因為正是這些節點做出決定:它們決定一個區塊或交易是否有效。
3.特殊目的公司。
SPV 代表簡化支付驗證。這些節點不儲存區塊鏈的完整副本,但它們仍然能夠驗證交易(不是全部,而是一個子集,例如,那些傳送到特定地址的交易)。一個 SPV 節點依賴於一個全節點來獲取資料,並且可能有許多 SPV 節點連線到一個全節點。SPV 使錢包應用成為可能:不需要下載完整的區塊鏈,但仍然可以驗證他們的交易。
DNS 伺服器
在比特幣核心中,有硬編碼的DNS 種子。這些不是節點,而是知道某些節點地址的 DNS 伺服器。當您啟動一個乾淨的比特幣核心時,它會連線到其中一個種子並獲取完整節點列表,然後從中下載區塊鏈。
實施
在我們的實施中,雖然會有中心化。我們將有三個節點:
1.中心節點。這是所有其他節點將連線到的節點,也是將在其他節點之間傳送資料的節點。
2.一個礦工節點。該節點將新交易儲存在記憶體池中,當交易足夠多時,它將挖掘一個新塊。
3.一個錢包節點。該節點將用於在錢包之間傳送硬幣。不過,與 SPV 節點不同的是,它將儲存區塊鏈的完整副本。
情景
本文的目標是實現以下場景:
中央節點建立一個區塊鏈。
其他(錢包)節點連線到它並下載區塊鏈。
另外一個(礦工)節點連線到中央節點並下載區塊鏈。
錢包節點建立交易。
礦工節點接收交易並將其儲存在其記憶體池中。
當記憶體池中有足夠的事務時,礦工開始挖掘一個新塊。
當一個新塊被挖掘出來時,它被髮送到中心節點。
錢包節點與中心節點同步。
錢包節點的使用者檢查他們的支付是否成功。
這就是它在比特幣中的樣子。儘管我們不打算建立一個真正的 P2P 網路,但我們將實現一個真正的、主要和最重要的比特幣用例。
version
節點通過訊息進行通訊。當一個新節點執行時,它會從 DNS 種子中獲取多個節點,並向它們傳送version訊息,
version用於尋找更長的區塊鏈。當節點接收到version訊息時,它會檢查節點的區塊鏈是否比 的值長BestHeight。如果不是,節點將請求並下載丟失的塊。
中心節點
檢查當前節點是否為中心節點。在我們的實現中,中心節點不會挖掘區塊。相反,它將新交易轉發到網路中的其他節點。