Flask实现BlockChain应用之一

在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完成实际的交易,请期待下一章。

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180312G0JS4100?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券