区块链,大家或许都不陌生,或多或少都对它有一些了解。不过,这些了解可能都是支离破碎的。当问及其中一些概念是如何实现的,你可能就「蒙圈」了。那想了解其中的实现细节怎么办呢?
这篇文章可以手把手的教你搭建一个区块链程序,让你从技术层面,详细了解区块链的实现细节。我相信你把这篇文章的代码跑一遍,你会有一种「哦!原来是这么实现的」想法。下面,我们就来试试吧。
作者 | Daniel van Flymen
译者 | Aholiab、科科
你会点开这篇文章,说明你跟我一样,眼看加密货币价格的暴涨,很想弄清楚区块链到底是什么?背后有哪些技术。
不过,要完全理解区块链不是件容易的事,起码对我而言。为了搞懂区块链,我看过大量的视频、研究过各种教程和为数不多的几个案例,整个过程虐心之极。
所以,我决定在实践中学习。在实践中学习的一大好处是它能逼着你去理解区块链最底层的原理,并且容易让人坚持下去。如果你也想试试这个方法的话,建议你好好读完这篇文章,跟着步骤一步步地去操作。这样,你不仅可以亲自开发出一个功能完备的区块链,同时也搞清楚了区块链的机制到底是什么?
准备工作
在开始之前,我们需要做些准备工作,搞清楚一些问题。
什么是区块链?区块链是由不可变的、有顺序记录的区块组成。他们可以包含交易数据、文件数据或者其他你想要记录的数据。不过最重要的是这些区块通过哈希表链接在一起。
什么是散列?散列函数是一个输入值函数,从该输入创建一个确定输入值的输出值。更多解释可以点击下边这个链接:
https://learncryptography.com/hash-functions/what-are-hash-functions
这篇文章适合谁,首先Python程序员,你只要能轻松地读写一些基本的Python代码就可以了;第二是HTTP程序员,因为我们接下来讲到的区块链,是构建在HTTP上面的,这需要你起码要了解HTTP请求的工作原理。
我需要做什么?首先要确保安装了Python 3.6以上的环境和Flask,此外还需要安装一个碉堡的Requests库。版本信息如下:
pip install Flask==0.12.2 requests==2.18.4
哦对了,你还需要一个HTTP客户端,比如 Postman 或者 cURL
在哪里下载完整代码,请猛戳:
https://github.com/dvf/blockchain。
下面跟着我一步一步来操作吧。
第一步:创建区块链
打开你常用的编辑器,我个人比较喜欢PyCharm。创建一个新的文件,命名为 blockchain.py。整个项目,我们都只会用到这一个文件。有不清楚的地方,可以参考源代码。
表示一个区块链
我们将创建一个 Blockchain 类,它的构造函数里创建了一个初始为空的列表(用于存储我们的区块链),和一个存储交易的列表。下边是这个类的代码:
class Blockchain(object):
def __init__(self):
self.chain = []
self.current_transactions = []
def new_block(self):
# Creates a new Block and adds it to the chain
pass
def new_transaction(self):
# Adds a new transaction to the list of transactions
pass
@staticmethod
def hash(block):
# Hashes a Block
pass
@property
def last_block(self):
# Returns the last Block in the chain
pass
Blockchain参数的作用是管理区块链,也用于存储交易信息和添加区块的方式。
区块到底长什么样?
每一个区块包含一个索引、一个时间戳、一个交易列表、一个证明(之后更多)和前一个区块的哈希值。
以下是一个区块的例子:
block = {
'index': 1,
'timestamp': 1506057125.900785,
'transactions': [
{
'sender': "8527147fe1f5426f9dd545de4b27ee00",
'recipient': "a77f5cdfa2934df3954a5c7c7da5df1f",
'amount': 5,
}
],
'proof': 324984774000,
'previous_hash': "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824"
}
代码左滑可查看未显示部分(下同)
到这里,区块链的原理就很容易理解了:每一个区块包含它自己本身的一些变量,以及前一个区块的哈希值。这一点非常重要,因为哈希值保证了区块链不可篡改的特性。如果一个区块受到攻击哈希值变了,那么后面的所有区块的哈希值都会为之改变。
你可能想,我还是不太理解。没关系,先接着往下看。
在区块上添加交易
那么,我们怎么在区块上添加交易呢?可以使用new_transaction()参数。使用方法简单、直接,如下面代码所示:
class Blockchain(object):
...
def new_transaction(self, sender, recipient, amount):
"""
Creates a new transaction to go into the next mined Block
:param sender: <str> Address of the Sender
:param recipient: <str> Address of the Recipient
:param amount: <int> Amount
:return: <int> The index of the Block that will hold this transaction
"""
self.current_transactions.append({
'sender': sender,
'recipient': recipient,
'amount': amount,
})
return self.last_block['index'] + 1
在 new_transaction() 添加交易信息到列表中后,它会返回下一个将被开采区块的索引号,交易信息将被打包到这个区块上。这对稍后提交交易的用户有用。
创建新区块
在区块链创建完成后,我们需要创建一个创世区块(也就是区块链上的第一个区块)。当然,创世区块也需要被证明,这需要通过PoW的挖矿机制。后边我们会更多的介绍挖矿,这儿就不做过多的介绍了。
除了在构造函数中创建创始区块,我们还需要用new_block()、new_transaction() 和 hash()参数对其进行完善。代码如下:
import hashlib
import json
from time import time
class Blockchain(object):
def __init__(self):
self.current_transactions = []
&nb