在閱讀本文以前,建議你們能夠先 Google 瞭解一下非對稱加密算法和 Hash 算法,這裏就不詳細介紹了。下面咱們只描述一下非對稱加密傳輸信息的一個大體流程:git
在比特中使用的 hash 算法是 SHA(Secure Hash Algorithm),其摘要長度爲 256 bits,即 32個 字節,故稱 SHA256,對於一個區塊都會對其區塊頭(header)進行 double sha256。github
在比特幣中使用的非對稱加密算法是 ECDSA, 橢圓曲線數字簽名算法的原理這裏就不介紹了。算法
一個區塊是由區塊頭和區塊體組成。區塊體則是全部 transaction 的集合,區塊頭由五個部分組成,這篇咱們重點來看一下 merkle root。剩下的幾個元素之後在單獨寫一篇 mining 相關的文章描述。數據庫
一個 block header 的組成以下:bash
02000000 ........................... Block version: 2
b6ff0b1b1680a2862a30ca44d346d9e8
910d334beb48ca0c0000000000000000 ... Hash of previous block's header 9d10aa52ee949386ca9385695f04ede2 70dda20810decd12bc9b048aaab31471 ... Merkle root 24d95a54 ........................... Unix time: 1415239972 30c31b18 ........................... Target: 0x1bc330 * 256**(0x18-3) fe9f0864 ........................... Nonce 複製代碼
比特幣的 SPV(Simplified Payment Verification 簡單支付驗證) 機制,保證了每次只須要下載區塊頭(80 bytes),而不須要加載整個區塊。平均每一個 transaction 至少是 250 bytes,並且平均每一個區塊包含 2000 個transaction。所以,包含完整交易的區塊比區塊頭的 4k 倍還要大。網絡
當咱們去下載一個文件的時候,下載連接後面提供了一個MD5(MD5也是一種Hash算法),這樣咱們能夠在下載以後對文件計算MD5,若是MD5與提供的MD5相等,說明文件有沒有被損壞或者沒有被惡意劫持。wordpress
在 p2p,好比咱們下載一個 BT 種子的時候,若是這個文件比較大好比下載一步電影,這個大電影文件會被分紅多個小的 data block (數據塊)。這些小的 data block 會從多個不一樣的機器下載,如何保證從其餘機器下載的 data block 沒有被修改呢?區塊鏈
開始下載以前,咱們會先下載一個 hash list(哈希列表),若是有一個 data block 損壞了,只須要從新下載這個 data block 就好了。以下圖所示,把 hash list 中的各個 hash 值拼接成一個長的字符串,在對這個長字符串作一次 hash,獲得 top hash(根哈希)。把這個 top hash 和 origin top hash 來判斷有沒有數據塊缺失以及是否有數據庫被篡改。加密
事實上 hash list 能夠看作是一課樹高爲 merkle tree,top hash 就是 blockchain 中一個節點的 merkle root。spa
如上圖所示,Lx 能夠是作是 blockchain 中的一筆 transaction。
在比特幣中確認一個 transaction 是否合法有五個步驟:
p.s: 一個 SPV 節點想知道它錢包中某個比特幣地址即將到達的支付。該節點會在節點間的通訊連接上創建起 bloom filter,限制只接受含有目標比特幣地址的交易。當對等體探測到某交易符合 bloom filter,它將以 Merkleblock 消息的形式發送該區塊。Merkleblock 消息包含區塊頭和一條鏈接目標交易與 Merkle 根的 Merkle 路徑。
咱們重點來看一下上面的步驟三。
如上圖所示咱們相驗證交易 K 是否合法便是否包含在區塊中。Merkleblock 中返回的 Merkle 路徑會包含 H(L),H(IJ),H(MNOP),H(ABCDEFGH),根據這五個 hash 值就能夠肯定一個 Merkle Root,和使用 hash list 相比,不須要將全部小 hash 作一次 hash,也就是隻須要獲得 Merkle 路徑下面的四個路徑加上這個 transaction 自己的 hash 就能夠了不須要獲得全部 transaction 的 action。在實際應用場景,當一個區塊中交易數很是多的時候,驗證速度很是快,是呈對數增加的。
第一次看這部分的時候,當時有兩個比較困惑的問題,這裏列一下,若是能回答出了這兩個問題,對於 Bitcoin 的 merkle tree 的 spv 驗證的基本原理就差很少了。
SPV 自己沒有 block 信息,都是從全節點拿到的。其中的 getdata 請求中若是指定了 inventory type 爲 MSG_MERKLEBLOCK,全節點就會在響應中回覆一個 MerkleBlock。
SPV 解析 MerkleBlock 的過程以下:
以太坊使用的是 Merkle Patricia Tree,和比特幣有很大不一樣要複雜一些,這個準備下一篇文章在詳細介紹。總的來講比特幣中交易是無狀態,好比咱們要查一個帳戶的餘額是沒法直接實現的,咱們平時看到的 balance 都是比特幣相關的 wallet client 本身實現生成計算的。在區塊鏈中交易是有狀態的,不只僅是有一棵 Merkle Tree,有三棵 Merkle Tree:
TODO: Git 和 IPFS 中對於 Merkle Tree 的應用。