<jupyter_start><jupyter_text>根据Bitcoin白皮书中，我们可以知道区块链的每个区块至少包括：区块索引index、时间戳timestamp、交易数据data和前一区块所有内容的一个哈希值previous_hash由此，建立一个最简单的Block类<jupyter_code>import hashlib

class Block():
    def __init__(self, index, timestamp, data, previous_hash):
        self.index = index
        self.timestamp = timestamp
        self.data = data
        self.previous_hash = previous_hash
        self.hash = self.hash_block()
        
    def hash_block(self):
        # 对本区块生成hash值，实际上会有更多条件，更复杂一些。
        sha = hashlib.sha256()
        sha.update(bytes(str(self.index) + str(self.timestamp) +
                   str(self.data) + str(self.previous_hash), 'utf-8'))
        return sha.hexdigest()<jupyter_output><empty_output><jupyter_text>每个区块都需要前一个区块的信息如此一来，就出现了一个问题：区块链中的第一个区块是如何而来？ 第一个区块，或者一般叫做创始块(genesis block), 这是一个十分特殊的块。在很多情况下，它是通过手动或是一些特殊的逻辑添加到区块链中。<jupyter_code>import datetime
# 创建创世块
def create_genesis_block():
    return Block(0, datetime.datetime.now(), "Genesis Block", "0")<jupyter_output><empty_output><jupyter_text>创建了创世块之后，我们就可以根据**前一区块**可以生成更多的区块，并形成一个区块链了<jupyter_code>def next_block(last_block):
    index = last_block.index + 1
    timestamp = datetime.datetime.now()
    data = "This is Block " + str(index)
    hash_ = last_block.hash
    return Block(index, timestamp, data, hash_)<jupyter_output><empty_output><jupyter_text>接下来，就可以生成一序列的Block Chain了（尽管在我们这个简单的例子中只是一个列表）<jupyter_code>blockchain = [create_genesis_block()]
print('Genesis block #0 has been added to the blockchain!')
print("Hash: {}\n".format(blockchain[0].hash))

previous_block = blockchain[0]

num_of_blocks = 7
for i in range(1,num_of_blocks):
    block_to_add = next_block(previous_block)
    blockchain.append(block_to_add)
    previous_block = block_to_add

    print('Block #{} has been added to the blockchain!'.format(block_to_add.index))
    print("Hash: {}\n".format(block_to_add.hash))<jupyter_output>Genesis block #0 has been added to the blockchain!
Hash: f8e352eef7689fd472b2aff1e583dcb11b9cd8e5e5e8ef317addf3534e1d4b33

Block #1 has been added to the blockchain!
Hash: d361dff79f23ca2a2669386270a575d552ed2c82e257979c72aabe1e3a720f1a

Block #2 has been added to the blockchain!
Hash: be7b7b846443d17b31477a50eacbdaddf2a607df5581e683f42bf2eb7db053c3

Block #3 has been added to the blockchain!
Hash: 1f642e3c6e52082a96d877916f75e3189e125f8148cbb7551f3bb8a1125c872c

Block #4 has been added to the blockchain!
Hash: cfaf832a65296c2cea1e76ceed46098ba5e719e09d2b801fc75b196462472b33

Block #5 has been added to the blockchain!
Hash: 348424f4cfcc81aa2c78950107536252f943ac278b1460e4fcadc96b7d7aa5ec

Block #6 has been added to the blockchain!
Hash: b35056c31d01cf824393abbf3866c054384e8dde7e5d6d7e34195fc1a52dffe3
{'fraction_non_alphanumeric': 0.08973412112259971, 'fraction_numerical': 0.1085672082717873, 'mean_word_length': 6.073107049608355, 'pattern_counts': {'":': 0, '<': 16, '<?xml version=': 0, '>': 16, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '4', 'dir': 'jupyter-structured-clean-dedup', 'id': '324076', 'license': 'Apache-2.0', 'n_tokens_mistral': 1331, 'n_tokens_neox': 1248, 'n_words': 168, 'path': 'a_simple_explain_of_blockchain.ipynb', 'repo_name': 'echo-ray/my-first-bitcoin-miner', 'size': '2708'}