链客,专为开发者而生,有问必答!
此文章来自区块链技术社区,未经允许拒绝转载。
“区块链”是什么?
区块链是一种存储数字数据的方式。数据可以是任何内容。对于比特币,它是事务(在帐户之间转移比特币),它甚至可以是文件;这都无关紧要。数据是以区块形式进行存储的,区块使用哈希值链接在一起。因此得名“区块链”。
区块链的神奇之处是在其中添加和存储此类数据的方式,该方式造就了一些非常理想的特征:
历史记录无法更改
系统无法攻破
数据的持久保存
没有单点故障
那么区块链如何能够实现这些特征呢?我们将通过实现一个区块链来深入剖析它。让我们开始吧。
关于该应用程序
首先定义一下我们将要构建的应用程序的用途。我们的目的是构建一个允许用户共享信息的简单网站。因为内容将存储在区块链中,所以它无法更改且会永远存在。
我们将采用自下而上的实现方式。首先定义我们将存储在区块链中的数据的结构。 一篇帖子(任何用户在我们的应用程序上发布的一条消息)将由 3 个基本要素来标识:
1
将事务存储到区块中
我们将采用一种广泛使用的格式来将数据存储在区块链中:JSON。以下是一篇存储在区块链中的帖子的格式:
{
"author": "some_author_name",
"content": "Some thoughts that author wants to share",
"timestamp": "The time at which the content was created"
}
术语“数据”通常在互联网上被“事务”一词所取代。所以,为了避免混淆并保持一致,我们将使用术语“事务”来表示在我们的示例应用程序中发布的数据。
事务被打包到区块中。一个区块可以包含一个或许多个事务。包含事务的区块频繁地生成并添加到区块链中。因为可能有多个区块,所以每个区块都应有一个唯一 ID:
class Block:
def __init__(self, index, transactions, timestamp):
self.index = []
self.transactions = transactions
self.timestamp = timestamp
2
让区块不可更改
我们希望检测出对区块内存储的数据的任何篡改。在区块链中,这是使用一个哈希函数来实现的。
哈希函数接受任何大小的数据并生成固定大小的数据,该结果通常用于识别输入。下面是 Python 中的一个使用 sha256 哈希函数的示例:
from hashlib import sha256
data = “Some variable length data”
sha256(data).hexdigest()
‘b919fbbcae38e2bdaebb6c04ed4098e5c70563d2dc51e085f784c058ff208516’
sha256(data).hexdigest() # no matter how many times you run it, the
result is going to be the same 256 character string
‘b919fbbcae38e2bdaebb6c04ed4098e5c70563d2dc51e085f784c058ff208516’
一个理想的哈希函数包括以下特征:
它应该很容易计算。
哪怕只更改数据中的一个位,哈希值也应该完全发生变化。
应该无法根据输出哈希值猜出输入。
您现在知道哈希函数是什么了吧。我们将每个区块的哈希值都存储在 Block 对象内的一个字段中,其作用类似于它所包含的数据的数字指纹:
from hashlib import sha256
import json
def compute_hash(block):
"""
A function that creates the hash of the block.
"""
block_string = json.dumps(self.__dict__, sort_keys=True)
return sha256(block_string.encode()).hexdigest()
备注:在大多数加密货币中,甚至对区块中的各个事务也进行了哈希运算,从而形成一棵哈希树(也称为二进制哈希树),这棵树的根可以用作区块的哈希值。它不是区块链正常运作的必要条件,所以我们将省略它,以保持代码简洁。
3
链接区块
我们已设置了区块。区块链应该是一个区块集合。我们可以将所有区块都存储在 Python 列表中(等效于数组)。但这还不够,因为如果有人故意替换了集合中的一个区块该怎么办?用修改过的事务创建一个新的区块,计算哈希值,然后替换任何旧区块,这在我们的当前实现中并不是什么难事,因为我们