比特幣的區塊結構解析

阿里云云棲號發表於2018-04-17

摘要:
比特幣的區塊資料裡包含了比特幣鏈上的核心資訊,包括比特幣如何交易,區塊擴容等問題。 比特幣從誕生到現在,每10分鐘誕生一個區塊,訪問 https://blockchain.info/ 檢視最近的區塊資訊,可以看到當前的區塊大小已經是中本聰設定的1MB容量。

比特幣的區塊資料裡包含了比特幣鏈上的核心資訊,包括比特幣如何交易,區塊擴容等問題。

比特幣從誕生到現在,每10分鐘誕生一個區塊,訪問 blockchain.info/ 檢視最近的區塊資訊,可以看到當前的區塊大小已經是中本聰設定的1MB容量。

當前區塊高度

一、區塊鏈資料結構

一個完整的區塊結構主要由以下幾部分構成:

資料項位元組欄位說明
Magic NO4魔數常數0xD9B4BEF9
Blocksize4區塊大小用位元組表示的該欄位之後的區塊大小
Blockheader80區塊頭組成區塊頭的幾個欄位
Transaction counter1-9交易計數器該區塊包含的交易數量,包含coinbase交易
Transactions不定交易記錄在區塊裡的交易資訊,使用原生的交易資訊格式,並且交易在資料流中的位置必須與Merkle樹的葉子節點順序一致

二、區塊資訊解析

我們從 webbtc.com 選擇一個區塊雜湊值為000000000003ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506的早期區塊進行分析。
區塊資訊

可以看到該區塊中包含了三筆交易資訊,下面對區塊資訊欄位進行解析。

1.區塊頭分析

前80個位元組是區塊頭。

{
    "hash": "000000000003ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506",
    "ver": 1,
    "prev_block": "000000000002d01c1fccc21636b607dfd930d31d01c3a62104612a1719011250",
    "mrkl_root": "f3e94742aca4b5ef85488dc37c06c3282295ffec960994b2c0d5ac2a25a95766",
    "time": 1293623863,
    "bits": 453281356,
    "nonce": 274148111
}複製程式碼
位元組欄位說明
4版本區塊版本號,表示本區塊遵守的驗證規則
32父區塊頭雜湊值前一區塊的雜湊值,使用SHA256(SHA256(父區塊頭))計算
32Merkle根該區塊中交易的Merkle樹根的雜湊值,同樣採用SHA256(SHA256())計算
4時間戳該區塊產生的近似時間,精確到秒的UNIX時間戳,必須嚴格大於前11個區塊時間的中值,同時全節點也會拒絕那些超出自己2個小時時間戳的區塊
4難度目標該區塊工作量證明演算法的難度目標,已經使用特定演算法編碼
4Nonce為了找到滿足難度目標所設定的隨機數,為了解決32位隨機數在算力飛昇的情況下不夠用的問題,規定時間戳和coinbase交易資訊均可更改,以此擴充套件nonce的位數

說明:

  • 版本、父區塊頭雜湊值和Merkle根採用的是小端格式編碼,即低有效位放在前面。
  • 時間戳表示的是自1970年1月1日0時0分0秒以來的秒數

2.Coinbase交易資訊分析

一個區塊第一個交易規定為coinbase交易,即由挖礦產生的比特幣獎勵,可以看到目前挖出每個區塊的獎勵是12.5個比特幣,下一次減半會發生在2020年。除了挖礦獎勵,“礦工”的激勵還有新增賬本記賬的手續費,在未來比特幣總量不增加之後,後者會成為礦工的主要收入。

{
    "hash": "8c14f0db3df150123e6f3dbbf30f8b955a8249b62ac1d1ff16284aefa3d06d87",
    "ver": 1,
    "vin_sz": 1,
    "vout_sz": 1,
    "lock_time": 0,
    "size": 135,
    "in": [{
        "prev_out": {
            "hash": "0000000000000000000000000000000000000000000000000000000000000000",
            "n": 4294967295
        },
        "coinbase": "044c86041b020602"
    }],
    "out": [{
        "value": "50.00000000",
        "scriptPubKey": "041b0e8c2567c12536aa13357b79a073dc4444acb83c4ec7a0e2f99dd7457516c5817242da796924ca4e99947d087fedf9ce467cb9f7c6287078f801df276fdf84 OP_CHECKSIG",
        "next_in": {
            "hash": "f3e6066078e815bb24db0dfbff814f738943bddaaa76f8beba360cfe2882480a",
            "n": 12
        }
    }],
    "nid": "70ab531a68f973f7d20b8260cb5e7fecba3699c48715b8b44539ff9776d0b88e"
}
複製程式碼
位元組欄位描述
4版本這筆交易參照的規則
1-9輸入計數器包含的交易輸入數量
32交易雜湊不引用任何一個交易,值全部為0
4交易輸出索引固定為0xFFFFFFFF
1-9Coinbase資料長度coinbase資料長度
不定Coinbase資料在V2版本的區塊中,除了需要以區塊高度開始外,其它資料可以任意填寫,用於extra nonce和挖礦標籤
4順序號值全部為1,0xFFFFFFFF
1-9輸出計數器包含的交易輸出數量
8總量用聰表示的比特幣值
1-9鎖定指令碼大小用位元組表示的後面的鎖定指令碼長度
不定鎖定指令碼一個定義了支付輸出所需條件的指令碼
4鎖定時間一個區塊號或UNIX時間戳

3.交易資訊記錄

下面來看下普通的交易記錄。

{
    "hash": "fff2525b8931402dd09222c50775608f75787bd2b87e56995a7bdd30f79702c4",
    "ver": 1,
    "vin_sz": 1,
    "vout_sz": 2,
    "lock_time": 0,
    "size": 259,
    "in": [{
        "prev_out": {
            "hash": "87a157f3fd88ac7907c05fc55e271dc4acdc5605d187d646604ca8c0e9382e03",
            "n": 0
        },
        "scriptSig": "3046022100c352d3dd993a981beba4a63ad15c209275ca9470abfcd57da93b58e4eb5dce82022100840792bc1f456062819f15d33ee7055cf7b5ee1af1ebcc6028d9cdb1c3af774801 04f46db5e9d61a9dc27b8d64ad23e7383a4e6ca164593c2527c038c0857eb67ee8e825dca65046b82c9331586c82e0fd1f633f25f87c161bc6f8a630121df2b3d3"
    }],
    "out": [{
            "value": "5.56000000",
            "scriptPubKey": "OP_DUP OP_HASH160 c398efa9c392ba6013c5e04ee729755ef7f58b32 OP_EQUALVERIFY OP_CHECKSIG",
            "address": "1JqDybm2nWTENrHvMyafbSXXtTk5Uv5QAn",
            "next_in": {
                "hash": "5aa8e36f9423ee5fcf17c1d0d45d6988b8a5773eae8ad25d945bf34352040009",
                "n": 6
            }
        },
        {
            "value": "44.44000000",
            "scriptPubKey": "OP_DUP OP_HASH160 948c765a6914d43f2a7ac177da2c2f6b52de3d7c OP_EQUALVERIFY OP_CHECKSIG",
            "address": "1EYTGtG4LnFfiMvjJdsU7GMGCQvsRSjYhx",
            "next_in": {
                "hash": "220ebc64e21abece964927322cba69180ed853bb187fbc6923bac7d010b9d87a",
                "n": 0
            }
        }
    ],
    "nid": "fc7704fdd7ec5e69163e51b827fea2133990a26defee2b475408b3c16fd9a968"
}複製程式碼

三、擴容問題如何解決

在比特幣誕生初期,中本聰為了比特幣系統的安全和穩定,防止比特幣系統被攻擊而把區塊大小設定為1M。在當時比特幣使用者量少,比特幣交易是不存在擁堵問題的。
隨著比特幣網路的發展,單個區塊儲存的交易資訊越來越多,1MB區塊僅能容納2000條左右交易,交易量大時需要排隊等待區塊寫入確認,交易網路擁堵問題越來越嚴重,為此也出現瞭解決容量問題的幾個方案。

1.區塊擴容

解決區塊過小問題,最直接的辦法就是擴容。區塊體積中位數在2015年裡得到了翻番,從1月份的292KB快速增長至12月份的749KB。
2015 年12月比特幣香港擴容會議由Pieter Wuille提出了隔離見證(Segregated Witness)之後,擴容問題甚至已經簡化為僅升級至2MB。

為什麼不把區塊設定的更大一些,比如30MB?
區塊儲存的是交易資訊,若提高區塊體積限制至30MB,最大的問題不是CPU計算能力瓶頸,而是塊的傳播與儲存。30MB的塊可能會導致全網孤塊率和空塊率大幅上升,一年產出1.5TB的區塊鏈資料也超出大部分節點機器的硬碟容量。基於這1.5TB的資料,區塊鏈瀏覽器、錢包服務商等則可能膨脹10倍達到15TB,對於目前來說已經遠超普通機器/資料庫的磁碟容量。

除了擴容,還有另外的解決方案就是隔離見證和閃電網路。

2.隔離見證和閃電網路

隔離見證(SegWit)是把交易的簽名資料從交易資料中剝離出來,用於解決延展性攻擊。

比特幣交易主要是由兩部分資料組成。其中一部分為交易資料,它負責記錄比特幣的來源和去處。而另外一部分則是見證資料,這部分資料由一些加密資料組成,用於證明這些交易請求是真實可信的。

中本聰在設計比特幣的時候直接把這兩部分資訊都放在了區塊內,所以一個區塊就承載不了更多的交易資訊。如果隔離了“見證資料”,那麼區塊鏈只記錄交易資料,那麼一個區塊可承載更多的交易。

閃電網路(Lightning Network)方案是在比特幣網路上再外加一個「閃電網路(Lightning Network)」,把原有比特幣鏈上金額較少的交易,轉移到這個閃電網路來處理,完成後再記錄到原鏈上。
這是一種鏈外交易(Off-chain transaction),目的是解決加快交易速度,以太坊(Ethereum)也有類似的方案叫Raiden Network。

用搭乘公共汽車的來假設,試想像比特幣的區塊是一輛公共汽車,每隔十分鐘,固定時間發車,當要乘車的人超過公共汽車容量,不能上車的人就要等待下一班。我們的目的就是讓更多的人可以乘車,即承載更多的交易。

公共汽車

比特幣區塊鏈本身是可以根據交易費率來優先完成交易的,如果你想快速完成轉賬等功能,可以設定較高的手續費。這就類似公共汽車讓出更高價格買票的人先上車,不願付高車票的人就要一直等下去,直到坐車的人變少。

隔離見證就是我們在公共汽車後面加掛一個貨車(SegWit車箱),所有乘車的人都要把揹包和行李放到這個貨車上面,因為少了隨身物品,每個人佔的空間變少了,公共汽車就可以多載一些人,乘載量就變多了。

閃電網路可以理解為在公交車路線旁邊再架一條鐵路,讓擠不上公共汽車的人直接去坐火車,解決掉太多人要搭乘車(交易),而汽車太小的問題。

隔離見證和閃電網路在技術上有可行性,但是同樣有許多質疑。
依賴於隔離見證的閃電網路等二層網路並不能被認為是比特幣的擴容方案,因為閃電網路的交易並不等價於比特幣的點對點的鏈上交易,大部分比特幣交易的場景並不適用於閃電網路。

假設閃電網路部署成功,也會存在大型支付中心的問題,這違背了比特幣做為點對點支付系統的初衷。

文章作者:邴越

原文連結


相關文章