在BlockChain如此火爆的年代,那么BlockChain到底是什么呢,在这里通过一个简单的示例来演示一下BlockChain的应用。
首先,BlockChain是什么呢?BlockChain的思想最早出现在大名鼎鼎的比特币 开源项目中。其借鉴了来自数字货币、密码学、博弈论、分布式系统、控制论等多个领域的技术成果而形成的。其显显著特征是:去中心化的共有账本、具有一致性、安全性和共识性等特点。目前在BlockChain中的应用中除比特币外,比较著名的还有以太坊以及超级记账本等。
虽然,BlockChain具有如此多的优点,可以应用在金融,征信,专利权,版权等各个方面。但是,目前最大的制约是,BlockChain不适用于高频交易的场景,由于金融系统的特殊性,业界比较关注BlockChain交易的吞吐量,同时降低交易的确认延迟。
但是,完全搞懂BlockChain并非易事,个人喜欢在实践中掌握知识,在这里就自己实现一个基于BlockChain的应用,来掌握区块链的概念。
第一步先定义一个BlockChain中区块的基本结构如下:
block = {
'index': 1,
'timestamp': 1506057125.900785,
'transactions': [{
'sender': "8527147fe1f5426f9dd545de4b27ee00",
'recipient': "a77f5cdfa2934df3954a5c7c7da5df1f",
'amount': 15,
}],
'proof': 324977400000,
'previous_hash': "00000dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824"
}
区块的结构定义之后,构建Flask的工程入下:
在application包的初始化中定义Flask的app,并创建views.py来定义试图,并在run中初始化app,并执行。代码结构如下:
run.py
fromapplicationimportapp
importapplication.views
if__name__ =='__main__':
app.run()
application/__init__.py
fromflaskimportFlask
app = Flask(__name__)
application/views.py
fromapplicationimportapp
@app.route('/')
defhello_world():
return'Hello World!'
这是工程的基本结构,接下来首先会实现BlockChain相关的操作代码。在application包中新建一个blockchain的包,并在其中创建一个blockchain.py文件,并在其中定义blockchian类,来完成blockchain相关的操作与计算。下面的示例是一个简单的blockchain的代码模版:
classBlockChain(object):
def__init__(self):
# 定义区块链列表
self.chain = []
# 当前的交易列表
self. current_transactions = []
# 创建新的区块
defnew_block(self):
pass
# 创建新的交易记录
defnew_transaction(self):
pass
# 计算区块的hash值
@staticmethod
defhash(block):
pass
# 查找最新的区块
@property
deflast_block(self):
pass
Blockchain类用来管理Blockchian相关的功能,可以存储交易,查找区块等。接下来将进一步完善这些操作。
区块结构:在前边已经介绍了一个简单的区块结构,每个区块包含属性:索引(index),时间戳(timestamp),交易列表(transactions),工作量证明(稍后解释)以及上一个区块的Hash值。到这里,区块链的概念就清楚了,每个新的区块都包含上一个区块的Hash,这是关键的一点,它保障了区块链不可变性。如果攻击者破坏了前面的某个区块,那么后面所有区块的Hash都会变得不正确。
加入交易:接下来完善new_transaction方法,来为BlockChain增加“加入交易”操作。代码如下:
# 创建新的交易记录
defnew_transaction(self, sender, recipient, amount):
"""
生成新交易信息,信息将加入到下一个待挖的区块中
:paramsender: Address of the Sender
:paramrecipient: Address of the Recipient
:paramamount: Amount
:return: The index of the Block that will hold this transaction
"""
self.current_transactions.append({
'sender': sender,
'recipient': recipient,
'amount': amount,
})
returnself.last_block['index'] +1
创建新区块:当Blockchain实例化后,需要构造一个创世块(没有前区块的第一个区块),并且给它加上一个工作量证明。 每个区块都需要经过工作量证明,俗称挖矿,稍后会继续讲解。为了构造创世块,还需要完善new_block(), last_block() 和hash() 方法:
classBlockChain(object):
def__init__(self):
# 定义区块链列表
self.chain = []
# 当前的交易列表
self. current_transactions = []
# 初始化创世区块
self.new_block(previous_hash=1,proof=100)
# 定义节点,使用集合避免重复
self.nodes =set()
# 创建新的区块
defnew_block(self, proof, previous_hash=None):
block = {
'index':len(self.chain) +1,
'timestamp': time(),
'transactions':self.current_transactions,
'proof': proof,
'previous_hash': previous_hashorself.hash(self.chain[-1]),
}
self.current_transactions = []
self.chain.append(block)
returnblock
# 创建新的交易记录
defnew_transaction(self, sender, recipient, amount):
"""
生成新交易信息,信息将加入到下一个待挖的区块中
:paramsender: Address of the Sender
:paramrecipient: Address of the Recipient
:paramamount: Amount
:return: The index of the Block that will hold this transaction
"""
self.current_transactions.append({
'sender': sender,
'recipient': recipient,
'amount': amount,
})
returnself.last_block['index'] +1
# 计算区块的hash值
@staticmethod
defhash(block):
block_string = json.dumps(block,sort_keys=True).encode()
returnhashlib.sha256(block_string).hexdigest()
# 查找最新的区块
@property
deflast_block(self):
returnself.chain[-1]
理解工作量证明: 新的区块依赖工作量证明算法(PoW)来构造。PoW的目标是找出一个符合特定条件的数字,这个数字很难计算出来,但容易验证。这就是工作量证明的核心思想。为了方便理解,举个例子:假设一个整数 x 乘以另一个整数 y 的积的 Hash 值必须以 0 结尾,即 hash(x * y) = ac23dc…0。设变量 x = 5,求 y 的值?
Python中的实现如下:
fromhashlibimportsha256
x =5
y =
whilesha256(str(x * y).encode()).hexdigest()[:4] !='0000':
y +=1
print(y, sha256(str(x * y).encode()).hexdigest()[:4])
print(y)
在比特币中,使用称为Hashcash的工作量证明算法,它和上面的问题很类似。矿工们为了争夺创建区块的权利而争相计算结果。通常,计算难度与目标字符串需要满足的特定字符的数量成正比,矿工算出结果后,会获得比特币奖励。 当然,在网络上非常容易验证这个结果。
实现工作量证明:接下来实现一个相似PoW算法,规则是:寻找一个数 p,使得它与前一个区块的 proof 拼接成的字符串的 Hash 值以 5 个零开头。在BlockChain类中增加两个方法:proof_of_work()和valid_proof(),代码如下:
# 工作量证明计算
defproof_of_work(self, last_proof):
proof =
whileself.valid_proof(last_proof, proof)is False:
proof +=1
returnproof
# 验证工作量证明是否符合要求
@staticmethod
defvalid_proof(last_proof, proof):
guess =str(last_proof * proof).encode()
guess_hash = hashlib.sha256(guess).hexdigest()
returnguess_hash[:5] =='00000'
衡量算法复杂度的办法是修改开头零的个数。使用5个来用于演示,你会发现多一个零都会大大增加计算出结果所需的时间。到这里BlockChain的主要概念和操作基本清洗了,接下来需要构建一个系统来使用BlockChain完成实际的交易,请期待下一章。
领取专属 10元无门槛券
私享最新 技术干货