浏览了一些区块链的基本资料,心血来潮,然后写了个tinyblockchains。于是乎,总结一下吧。关于自己对区块的一些认识。
区块链? 比特币 ? 傻傻分不清楚?
区块链(blockchains)是什么?通俗的解释就是一个分布式数据库。将区块高度、时间戳、存储数据、前一块区块哈希值用加密方法进行加密,(以sha256为例)通过哈希值建立链式连接。如果存储数据是记账数据,它便是一个分布式账本。
比特币(bitcoin)是一种加密虚拟货币,采取哈希加密、工作量证明机制(pow)是第一个采用了区块链技术的落地应用。根据全网算力,动态调节爆矿难度,通常出块时间是10分钟。
区块的基本结构是有区块高度、时间戳、存储数据、前一块区块哈希值、当前区块哈希值组成。
class Block(object):
index = None
previous_hash = None
timestamp = None
data = None
hash = None
新的区块产生:
class Block(object):
...
def create_start_block(self,index=0,previous_hash="",data="the block for gods"):
self.index = index
self.previous_hash = previous_hash
self.timestamp = date.datetime.now()
self.data = data
self.hash = Encrypt.hash_encrypt((str(self.index)+str(self.previous_hash)+str(self.timestamp)+str(self.data)).encode("utf-8"))
pass
def create_new_block(self,previous_block,data):
self.index = previous_block.index + 1
self.previous_hash = previous_block.hash
self.timestamp = date.datetime.now()
self.data = data
self.hash = Encrypt.hash_encrypt((str(self.index)+str(self.previous_hash)+str(self.timestamp)+str(self.data)).encode("utf-8"))
pass
注意:创世块即第一块区块是没有前一块的哈希值,为空。
加密数据生成(加密数据出来的哈希值有着生成慢,回验快的特性):
import hashlib
class Encrypt(object):
@staticmethod
def hash_encrypt(data_str):
sha = hashlib.sha256()
sha.update(data_str)
return sha.hexdigest()
封装一层,建立区块创建者,方便上层调用。
class BlockCreater(object):
@staticmethod
def create_start_block(cls):
block = Block()
block.create_start_block()
return block
@staticmethod
def create_new_block(cls,previous_block,data="new trade data"):
block = Block()
block.create_new_block(previous_block,data)
return block
区块链上一个区块接着一个区块
class BlockChain(object):
block_chains=[]
def create_blockchain(self):
self.block_chains.append(BlockCreater.create_start_block(BlockCreater))
def add_new_block(self,data):
while True:
tblock = BlockCreater.create_new_block(BlockCreater,self.block_chains[-1],data)
if Common_Recognise_POW.pow(tblock,self.block_chains[-1]):
break
print(Util.datetime2timestamp(tblock.timestamp) - Util.datetime2timestamp(self.block_chains[-1].timestamp))
print("前导0个数:\n",Common_Recognise_POW.level)
print("难度:\n",Common_Recognise_POW.difficulty)
print("爆矿块:\n",tblock)
self.block_chains.append(tblock)
return tblock
然后新生成的区块,想要加入链,是有条件、有门槛的。以btc为例,它采取工作量证明,算出满足条件的区块的哈希值,全网在竞争计算这个特定值,哪个节点先算出这个值,就拥有将新区块写入链的权限了。(所以说,要写入链式有成本的,pow假设花费大量本)根据出块间隔时间,动态调整,哈希值难度,控制出块速度。
class Common_Recognise(object):
pass
class Common_Recognise_POW(Common_Recognise):
level = 0
difficulty = ""
generate_time = 10
@staticmethod
def pow(new_block,previous_block):
flag = new_block.hash.startswith(Common_Recognise_POW.difficulty)
if flag == True:
Common_Recognise_POW.difficulty = ""
for i in range(0,Common_Recognise_POW.level):
Common_Recognise_POW.difficulty = Common_Recognise_POW.difficulty + "0"
time_dis = (Util.datetime2timestamp(new_block.timestamp) - Util.datetime2timestamp(previous_block.timestamp))
if time_dis < Common_Recognise_POW.generate_time:
Common_Recognise_POW.level = Common_Recognise_POW.level + 1
pass
elif time_dis > Common_Recognise_POW.generate_time:
Common_Recognise_POW.level = Common_Recognise_POW.level - 1
pass
return flag
pass
然后我们可以愉快运行下我们写的小型区块链
if __name__ == '__main__':
demo = BlockChain()
demo.create_blockchain()
for i in range(1,20):
demo.add_new_block("第"+str(i)+"笔交易")
print(demo)
pass
我们就可以看到:
0.0
前导0个数:
1
难度:
爆矿块:
index:1
previous_hash:a2404fb43bd66b34d223623ffcefc329f39e09796d18fcf933d08fccc1fb6def
timestamp:2018-03-18 11:03:45.632401
data:第1笔交易
hash:e947a936b39719c6851ac6f49bfb9c9a0f188f677c2f6477d4ab44f2b8cd04eb
0.0
前导0个数:
2
难度:
0
爆矿块:
index:2
previous_hash:e947a936b39719c6851ac6f49bfb9c9a0f188f677c2f6477d4ab44f2b8cd04eb
timestamp:2018-03-18 11:03:45.683404
data:第2笔交易
hash:8e8669f23d52d52c707b9665265c05454404f202dcd5a0e02faff42a2f146c65
是不是一颗赛艇。。。<-.<-
源代码(源代码下载,点击打开链接):
# -*- coding: utf-8 -*-
# @Date : 3:00 2018/3/18
# @Author : kucece
# @github : https://github.com/kucece
import hashlib
import datetime as date
import time
class Util(object):
@staticmethod
def datetime2timestamp(date_time):
return time.mktime(date_time.timetuple())
pass
class Encrypt(object):
@staticmethod
def hash_encrypt(data_str):
sha = hashlib.sha256()
sha.update(data_str)
return sha.hexdigest()
class Block(object):
index = None
previous_hash = None
timestamp = None
data = None
hash = None
def create_start_block(self,index=0,previous_hash="",data="the block for gods"):
self.index = index
self.previous_hash = previous_hash
self.timestamp = date.datetime.now()
self.data = data
self.hash = Encrypt.hash_encrypt((str(self.index)+str(self.previous_hash)+str(self.timestamp)+str(self.data)).encode("utf-8"))
pass
def create_new_block(self,previous_block,data):
self.index = previous_block.index + 1
self.previous_hash = previous_block.hash
self.timestamp = date.datetime.now()
self.data = data
self.hash = Encrypt.hash_encrypt((str(self.index)+str(self.previous_hash)+str(self.timestamp)+str(self.data)).encode("utf-8"))
pass
def __str__(self):
return "index:"+str(self.index)+"\nprevious_hash:"+self.previous_hash+"\ntimestamp:"+str(self.timestamp)+"\ndata:"+self.data+"\nhash:"+self.hash+"\n\n"
pass
class BlockCreater(object):
@staticmethod
def create_start_block(cls):
block = Block()
block.create_start_block()
return block
@staticmethod
def create_new_block(cls,previous_block,data="new trade data"):
block = Block()
block.create_new_block(previous_block,data)
return block
class BlockChain(object):
block_chains=[]
def create_blockchain(self):
self.block_chains.append(BlockCreater.create_start_block(BlockCreater))
def add_new_block(self,data):
while True:
tblock = BlockCreater.create_new_block(BlockCreater,self.block_chains[-1],data)
if Common_Recognise_POW.pow(tblock,self.block_chains[-1]):
break
print(Util.datetime2timestamp(tblock.timestamp) - Util.datetime2timestamp(self.block_chains[-1].timestamp))
print("前导0个数:\n",Common_Recognise_POW.level)
print("难度:\n",Common_Recognise_POW.difficulty)
print("爆矿块:\n",tblock)
self.block_chains.append(tblock)
return tblock
def get_full_block_chains(self):
return self.block_chains
def __str__(self):
content = ""
for item in self.block_chains:
content = content + str(item) + "\n"
return content
class Common_Recognise(object):
pass
class Common_Recognise_POW(Common_Recognise):
level = 0
difficulty = ""
generate_time = 10
@staticmethod
def pow(new_block,previous_block):
flag = new_block.hash.startswith(Common_Recognise_POW.difficulty)
if flag == True:
Common_Recognise_POW.difficulty = ""
for i in range(0,Common_Recognise_POW.level):
Common_Recognise_POW.difficulty = Common_Recognise_POW.difficulty + "0"
time_dis = (Util.datetime2timestamp(new_block.timestamp) - Util.datetime2timestamp(previous_block.timestamp))
if time_dis < Common_Recognise_POW.generate_time:
Common_Recognise_POW.level = Common_Recognise_POW.level + 1
pass
elif time_dis > Common_Recognise_POW.generate_time:
Common_Recognise_POW.level = Common_Recognise_POW.level - 1
pass
return flag
pass
if __name__ == '__main__':
demo = BlockChain()
demo.create_blockchain()
for i in range(1,20):
demo.add_new_block("第"+str(i)+"笔交易")
print(demo)
pass