比特币数据结构

首先看一个区块

https://webbtc.com/block/000000000003ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506


比特币区块分为2部分,区块头和交易信息


从https://webbtc.com/block/000000000003ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506.hex可以看到这个区块的16进制表示

#0100000050120119172a610421a6c3011dd330d9df07b63616c2cc1f1cd00200000000006657a9252aacd5c0b2940996ecff952228c3067cc38d4885efb5a4ac4247e9f337221b4d4c86041b0f2b5710
#04
#01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff08044c86041b020602ffffffff0100f2052a010000004341041b0e8c2567c12536aa13357b79a073dc4444acb83c4ec7a0e2f99dd7457516c5817242da796924ca4e99947d087fedf9ce467cb9f7c6287078f801df276fdf84ac00000000
#0100000001032e38e9c0a84c6046d687d10556dcacc41d275ec55fc00779ac88fdf357a187000000008c493046022100c352d3dd993a981beba4a63ad15c209275ca9470abfcd57da93b58e4eb5dce82022100840792bc1f456062819f15d33ee7055cf7b5ee1af1ebcc6028d9cdb1c3af7748014104f46db5e9d61a9dc27b8d64ad23e7383a4e6ca164593c2527c038c0857eb67ee8e825dca65046b82c9331586c82e0fd1f633f25f87c161bc6f8a630121df2b3d3ffffffff0200e32321000000001976a914c398efa9c392ba6013c5e04ee729755ef7f58b3288ac000fe208010000001976a914948c765a6914d43f2a7ac177da2c2f6b52de3d7c88ac00000000
#0100000001c33ebff2a709f13d9f9a7569ab16a32786af7d7e2de09265e41c61d078294ecf010000008a4730440220032d30df5ee6f57fa46cddb5eb8d0d9fe8de6b342d27942ae90a3231e0ba333e02203deee8060fdc70230a7f5b4ad7d7bc3e628cbe219a886b84269eaeb81e26b4fe014104ae31c31bf91278d99b8377a35bbce5b27d9fff15456839e919453fc7b3f721f0ba403ff96c9deeb680e5fd341c0fc3a7b90da4631ee39560639db462e9cb850fffffffff0240420f00000000001976a914b0dcbf97eabf4404e31d952477ce822dadbe7e1088acc060d211000000001976a9146b1281eec25ab4e1e0793ff4e08ab1abb3409cd988ac00000000
#01000000010b6072b386d4a773235237f64c1126ac3b240c84b917a3909ba1c43ded5f51f4000000008c493046022100bb1ad26df930a51cce110cf44f7a48c3c561fd977500b1ae5d6b6fd13d0b3f4a022100c5b42951acedff14abba2736fd574bdb465f3e6f8da12e2c5303954aca7f78f3014104a7135bfe824c97ecc01ec7d7e336185c81e2aa2c41ab175407c09484ce9694b44953fcb751206564a9c24dd094d42fdbfdd5aad3e063ce6af4cfaaea4ea14fbbffffffff0140420f00000000001976a91439aa3d569e06a1d7926dc4be1193c99bf2eb9ee088ac00000000

第一行就是区块头,80字节

第二行04代表这个区块有4个交易信息

后面4行分别代表这个4个交易

把区块转成json格式看一下都有什么内容

{
  "hash": "000000000003ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506",
  "ver": 1,
  "prev_block": "000000000002d01c1fccc21636b607dfd930d31d01c3a62104612a1719011250",
  "mrkl_root": "f3e94742aca4b5ef85488dc37c06c3282295ffec960994b2c0d5ac2a25a95766",
  "time": 1293623863,
  "bits": 453281356,
  "nonce": 274148111,
  "n_tx": 4,
  "size": 957,
  "tx": [
    {
      "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"
    },
    {
      "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"
    },
    {
      "hash": "6359f0868171b1d194cbee1af2f16ea598ae8fad666d9b012c8ed2b79a236ec4",
      "ver": 1,
      "vin_sz": 1,
      "vout_sz": 2,
      "lock_time": 0,
      "size": 257,
      "in": [
        {
          "prev_out": {
            "hash": "cf4e2978d0611ce46592e02d7e7daf8627a316ab69759a9f3df109a7f2bf3ec3",
            "n": 1
          },
          "scriptSig": "30440220032d30df5ee6f57fa46cddb5eb8d0d9fe8de6b342d27942ae90a3231e0ba333e02203deee8060fdc70230a7f5b4ad7d7bc3e628cbe219a886b84269eaeb81e26b4fe01 04ae31c31bf91278d99b8377a35bbce5b27d9fff15456839e919453fc7b3f721f0ba403ff96c9deeb680e5fd341c0fc3a7b90da4631ee39560639db462e9cb850f"
        }
      ],
      "out": [
        {
          "value": "0.01000000",
          "scriptPubKey": "OP_DUP OP_HASH160 b0dcbf97eabf4404e31d952477ce822dadbe7e10 OP_EQUALVERIFY OP_CHECKSIG",
          "address": "1H8ANdafjpqYntniT3Ddxh4xPBMCSz33pj",
          "next_in": {
            "hash": "ae1933ba2b7dc9702c96b99fb00f1df1392d9dea998a24b88d61974e8da8d2ab",
            "n": 0
          }
        },
        {
          "value": "2.99000000",
          "scriptPubKey": "OP_DUP OP_HASH160 6b1281eec25ab4e1e0793ff4e08ab1abb3409cd9 OP_EQUALVERIFY OP_CHECKSIG",
          "address": "1Am9UTGfdnxabvcywYG2hvzr6qK8T3oUZT",
          "next_in": {
            "hash": "20ed3fc9688a13fceeae5fdd606266c351b1f15b90404d9df387644e4c3d5b90",
            "n": 3
          }
        }
      ],
      "nid": "fe8c78250fb2a8e5a91e60a93ca7ddaf048a0d0d7dfb5663456c2265a0a0aaea"
    },
    {
      "hash": "e9a66845e05d5abc0ad04ec80f774a7e585c6e8db975962d069a522137b80c1d",
      "ver": 1,
      "vin_sz": 1,
      "vout_sz": 1,
      "lock_time": 0,
      "size": 225,
      "in": [
        {
          "prev_out": {
            "hash": "f4515fed3dc4a19b90a317b9840c243bac26114cf637522373a7d486b372600b",
            "n": 0
          },
          "scriptSig": "3046022100bb1ad26df930a51cce110cf44f7a48c3c561fd977500b1ae5d6b6fd13d0b3f4a022100c5b42951acedff14abba2736fd574bdb465f3e6f8da12e2c5303954aca7f78f301 04a7135bfe824c97ecc01ec7d7e336185c81e2aa2c41ab175407c09484ce9694b44953fcb751206564a9c24dd094d42fdbfdd5aad3e063ce6af4cfaaea4ea14fbb"
        }
      ],
      "out": [
        {
          "value": "0.01000000",
          "scriptPubKey": "OP_DUP OP_HASH160 39aa3d569e06a1d7926dc4be1193c99bf2eb9ee0 OP_EQUALVERIFY OP_CHECKSIG",
          "address": "16FuTPaeRSPVxxCnwQmdyx2PQWxX6HWzhQ",
          "next_in": {
            "hash": "1ebf2dd645b815a59e35485dd4ceebc0587a1b7588b810e42085b479ce507bfa",
            "n": 1
          }
        }
      ],
      "nid": "9e763d097af86cb157abacc0bdb3e31db5968390d065f2af0453e3f03c9260b0"
    }
  ],
  "mrkl_tree": [
    "8c14f0db3df150123e6f3dbbf30f8b955a8249b62ac1d1ff16284aefa3d06d87",
    "fff2525b8931402dd09222c50775608f75787bd2b87e56995a7bdd30f79702c4",
    "6359f0868171b1d194cbee1af2f16ea598ae8fad666d9b012c8ed2b79a236ec4",
    "e9a66845e05d5abc0ad04ec80f774a7e585c6e8db975962d069a522137b80c1d",
    "ccdafb73d8dcd0173d5d5c3c9a0770d0b3953db889dab99ef05b1907518cb815",
    "8e30899078ca1813be036a073bbf80b86cdddde1c96e9e9c99e9e3782df4ae49",
    "f3e94742aca4b5ef85488dc37c06c3282295ffec960994b2c0d5ac2a25a95766"
  ],
  "next_block": "00000000000080b66c911bd5ba14a74260057311eaeb1982802f7010f1a9f090"
}

  • 计算区块hash

看一下

"hash": "000000000003ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506",

这个值怎么来的

import codecs
import hashlib
import struct

ver = 1
prev_block = "000000000002d01c1fccc21636b607dfd930d31d01c3a62104612a1719011250"
mrkl_root = "f3e94742aca4b5ef85488dc37c06c3282295ffec960994b2c0d5ac2a25a95766"
time = 1293623863
bits = 453281356
nonce = 274148111

coefficient = bits & 0xffffff
exponent = bits >> 24
target = coefficient * (256 ** (exponent - 3))
# < 代表小端序    # L 代表 unsigned long
hex_str = struct.pack("<L", ver) + codecs.decode(prev_block, 'hex_codec')[::-1] + codecs.decode(mrkl_root, 'hex_codec')[
                                                                                  ::-1] + struct.pack("<LLL", time,
                                                                                                      bits, nonce)

hash_str = hashlib.sha256(hashlib.sha256(hex_str).digest()).digest()
# 这就是bitcoin矿机的工作 , 找到一个合适的nonce
# 使得做2次sha256运算的结果符合某个条件

block_hash = hash_str[::-1].hex()
print(block_hash) #output:000000000003ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506

计算过程:


首先把 verprev_blockmrkl_roottimebitsnonce 拼接起来,得到 header_hex

在拼接之前需要先把 vertimebitsnonce 转换为十六进制字符串,然后将这六个属性由大端序转换为小端序,最后才拼接成一个字符串。

然后做两次 sha256 计算,这一步也就是挖矿做的工作:找到一个 nonce 使得这个结果满足某个条件(比如前八位都是 0)。

hash = hashlib.sha256(hashlib.sha256(header_bin).digest()).digest()

最后将结果转回大端序,即为当前区块的地址。

  • 计算merkle tree root

mrkl_root怎么出来的呢?

接着算


"mrkl_tree": [
    "8c14f0db3df150123e6f3dbbf30f8b955a8249b62ac1d1ff16284aefa3d06d87", H1
    "fff2525b8931402dd09222c50775608f75787bd2b87e56995a7bdd30f79702c4", H2
    "6359f0868171b1d194cbee1af2f16ea598ae8fad666d9b012c8ed2b79a236ec4", H3
    "e9a66845e05d5abc0ad04ec80f774a7e585c6e8db975962d069a522137b80c1d", H4
    "ccdafb73d8dcd0173d5d5c3c9a0770d0b3953db889dab99ef05b1907518cb815", H12
    "8e30899078ca1813be036a073bbf80b86cdddde1c96e9e9c99e9e3782df4ae49", H34
    "f3e94742aca4b5ef85488dc37c06c3282295ffec960994b2c0d5ac2a25a95766"  Hroot
  ],
tx1 = "8c14f0db3df150123e6f3dbbf30f8b955a8249b62ac1d1ff16284aefa3d06d87"
tx2 = "fff2525b8931402dd09222c50775608f75787bd2b87e56995a7bdd30f79702c4"
tx3 = "6359f0868171b1d194cbee1af2f16ea598ae8fad666d9b012c8ed2b79a236ec4"
tx4 = "e9a66845e05d5abc0ad04ec80f774a7e585c6e8db975962d069a522137b80c1d"
tx1 = codecs.decode(tx1, 'hex_codec')[::-1]
tx2 = codecs.decode(tx2, 'hex_codec')[::-1]
tx3 = codecs.decode(tx3, 'hex_codec')[::-1]
tx4 = codecs.decode(tx4, 'hex_codec')[::-1]
tx12 = hashlib.sha256(hashlib.sha256(tx1 + tx2).digest()).digest()
print(tx12[::-1].hex()) #output:ccdafb73d8dcd0173d5d5c3c9a0770d0b3953db889dab99ef05b1907518cb815
tx34 = hashlib.sha256(hashlib.sha256(tx3 + tx4).digest()).digest()
print(tx34[::-1].hex()) #output:8e30899078ca1813be036a073bbf80b86cdddde1c96e9e9c99e9e3782df4ae49
tx1234 = hashlib.sha256(hashlib.sha256(tx12 + tx34).digest()).digest()
print(tx1234[::-1].hex()) #output:f3e94742aca4b5ef85488dc37c06c3282295ffec960994b2c0d5ac2a25a95766

  • 计算交易hash

那么

tx1 = "8c14f0db3df150123e6f3dbbf30f8b955a8249b62ac1d1ff16284aefa3d06d87"
tx2 = "fff2525b8931402dd09222c50775608f75787bd2b87e56995a7bdd30f79702c4"
tx3 = "6359f0868171b1d194cbee1af2f16ea598ae8fad666d9b012c8ed2b79a236ec4"
tx4 = "e9a66845e05d5abc0ad04ec80f774a7e585c6e8db975962d069a522137b80c1d"

这几个值又是从哪儿来的呢?最开始的原始数据说了有4条交易数据

#0100000050120119172a610421a6c3011dd330d9df07b63616c2cc1f1cd00200000000006657a9252aacd5c0b2940996ecff952228c3067cc38d4885efb5a4ac4247e9f337221b4d4c86041b0f2b5710
#04
#01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff08044c86041b020602ffffffff0100f2052a010000004341041b0e8c2567c12536aa13357b79a073dc4444acb83c4ec7a0e2f99dd7457516c5817242da796924ca4e99947d087fedf9ce467cb9f7c6287078f801df276fdf84ac00000000
#0100000001032e38e9c0a84c6046d687d10556dcacc41d275ec55fc00779ac88fdf357a187000000008c493046022100c352d3dd993a981beba4a63ad15c209275ca9470abfcd57da93b58e4eb5dce82022100840792bc1f456062819f15d33ee7055cf7b5ee1af1ebcc6028d9cdb1c3af7748014104f46db5e9d61a9dc27b8d64ad23e7383a4e6ca164593c2527c038c0857eb67ee8e825dca65046b82c9331586c82e0fd1f633f25f87c161bc6f8a630121df2b3d3ffffffff0200e32321000000001976a914c398efa9c392ba6013c5e04ee729755ef7f58b3288ac000fe208010000001976a914948c765a6914d43f2a7ac177da2c2f6b52de3d7c88ac00000000
#0100000001c33ebff2a709f13d9f9a7569ab16a32786af7d7e2de09265e41c61d078294ecf010000008a4730440220032d30df5ee6f57fa46cddb5eb8d0d9fe8de6b342d27942ae90a3231e0ba333e02203deee8060fdc70230a7f5b4ad7d7bc3e628cbe219a886b84269eaeb81e26b4fe014104ae31c31bf91278d99b8377a35bbce5b27d9fff15456839e919453fc7b3f721f0ba403ff96c9deeb680e5fd341c0fc3a7b90da4631ee39560639db462e9cb850fffffffff0240420f00000000001976a914b0dcbf97eabf4404e31d952477ce822dadbe7e1088acc060d211000000001976a9146b1281eec25ab4e1e0793ff4e08ab1abb3409cd988ac00000000
#01000000010b6072b386d4a773235237f64c1126ac3b240c84b917a3909ba1c43ded5f51f4000000008c493046022100bb1ad26df930a51cce110cf44f7a48c3c561fd977500b1ae5d6b6fd13d0b3f4a022100c5b42951acedff14abba2736fd574bdb465f3e6f8da12e2c5303954aca7f78f3014104a7135bfe824c97ecc01ec7d7e336185c81e2aa2c41ab175407c09484ce9694b44953fcb751206564a9c24dd094d42fdbfdd5aad3e063ce6af4cfaaea4ea14fbbffffffff0140420f00000000001976a91439aa3d569e06a1d7926dc4be1193c99bf2eb9ee088ac00000000

所以直接对这每条交易数据的原始hex进行hash就得到了merkle tree的最下面一层的hash值

txHex = '01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff08044c86041b020602ffffffff0100f2052a010000004341041b0e8c2567c12536aa13357b79a073dc4444acb83c4ec7a0e2f99dd7457516c5817242da796924ca4e99947d087fedf9ce467cb9f7c6287078f801df276fdf84ac00000000'
txHash = hashlib.sha256(hashlib.sha256(codecs.decode(txHex, 'hex_codec')).digest()).digest()
print(txHash[::-1].hex()) #output:8c14f0db3df150123e6f3dbbf30f8b955a8249b62ac1d1ff16284aefa3d06d87
txHex = '0100000001032e38e9c0a84c6046d687d10556dcacc41d275ec55fc00779ac88fdf357a187000000008c493046022100c352d3dd993a981beba4a63ad15c209275ca9470abfcd57da93b58e4eb5dce82022100840792bc1f456062819f15d33ee7055cf7b5ee1af1ebcc6028d9cdb1c3af7748014104f46db5e9d61a9dc27b8d64ad23e7383a4e6ca164593c2527c038c0857eb67ee8e825dca65046b82c9331586c82e0fd1f633f25f87c161bc6f8a630121df2b3d3ffffffff0200e32321000000001976a914c398efa9c392ba6013c5e04ee729755ef7f58b3288ac000fe208010000001976a914948c765a6914d43f2a7ac177da2c2f6b52de3d7c88ac00000000'
txHash = hashlib.sha256(hashlib.sha256(codecs.decode(txHex, 'hex_codec')).digest()).digest()
print(txHash[::-1].hex()) #output:fff2525b8931402dd09222c50775608f75787bd2b87e56995a7bdd30f79702c4
txHex = '0100000001c33ebff2a709f13d9f9a7569ab16a32786af7d7e2de09265e41c61d078294ecf010000008a4730440220032d30df5ee6f57fa46cddb5eb8d0d9fe8de6b342d27942ae90a3231e0ba333e02203deee8060fdc70230a7f5b4ad7d7bc3e628cbe219a886b84269eaeb81e26b4fe014104ae31c31bf91278d99b8377a35bbce5b27d9fff15456839e919453fc7b3f721f0ba403ff96c9deeb680e5fd341c0fc3a7b90da4631ee39560639db462e9cb850fffffffff0240420f00000000001976a914b0dcbf97eabf4404e31d952477ce822dadbe7e1088acc060d211000000001976a9146b1281eec25ab4e1e0793ff4e08ab1abb3409cd988ac00000000'
txHash = hashlib.sha256(hashlib.sha256(codecs.decode(txHex, 'hex_codec')).digest()).digest()
print(txHash[::-1].hex()) #output:6359f0868171b1d194cbee1af2f16ea598ae8fad666d9b012c8ed2b79a236ec4
txHex = '01000000010b6072b386d4a773235237f64c1126ac3b240c84b917a3909ba1c43ded5f51f4000000008c493046022100bb1ad26df930a51cce110cf44f7a48c3c561fd977500b1ae5d6b6fd13d0b3f4a022100c5b42951acedff14abba2736fd574bdb465f3e6f8da12e2c5303954aca7f78f3014104a7135bfe824c97ecc01ec7d7e336185c81e2aa2c41ab175407c09484ce9694b44953fcb751206564a9c24dd094d42fdbfdd5aad3e063ce6af4cfaaea4ea14fbbffffffff0140420f00000000001976a91439aa3d569e06a1d7926dc4be1193c99bf2eb9ee088ac00000000'
txHash = hashlib.sha256(hashlib.sha256(codecs.decode(txHex, 'hex_codec')).digest()).digest()
print(txHash[::-1].hex()) #output:e9a66845e05d5abc0ad04ec80f774a7e585c6e8db975962d069a522137b80c1d

  • 挖矿难度

"bits": 453281356,

计算区块hash的使用用到一个bits,这个bits就代表了挖矿的难度

coefficient = bits & 0xffffff
exponent = bits >> 24
target = coefficient * (256 ** (exponent - 3))
简单说
453281356二进制为0x1b04864c,前2个字节为exponent,后6个字节为coefficient。
为了使区块头的SHA256结果小于某个目标值(target),平均要尝试的计算次数,定义为难度(difficulty),
1 difficulty ≈ 2^32次 = 4294967296次 ≈ 4.2 * 10^9次 ≈ 4G次运算
创世区块的bits为 0x1d00ffff
难度 difficulty_当前 = target_创世区块 / target_当前
出块时间(单位:秒) ≈ difficulty_当前 * 2^32 / 全网算力

难度调节

 Difficulty_新 = Difficulty_原 * ( 20160分钟 / 产生2016个区块的实际花费时长 )
从创世区块起,每产生2016个区块,网络中的所有全节点都会自动调整难度,以保证比特币约十分钟的出块速度

挖矿的过程本质就是找到一个nonce,使算出来的hash小于target。那为什么通常说的比特币就是算以多少个0开头的hash是什么意思呢

print(hex(bits))  # 0x1b04864c
print(hex(coefficient))
print(hex(exponent))
print("{0:#0{1}x}".format(target, 64 + 2))

output:

0x000000000004864c000000000000000000000000000000000000000000000000

因为区块的hash是64位,所以比0x000000000004864c000000000000000000000000000000000000000000000000小的话,必然前面是0x00000000000开头。




猜你喜欢

转载自blog.csdn.net/problc/article/details/79666386