(一)区块链的基础概念:区块链是由一串使用密码学方法产生的数据块组成的,每一个区块都包含了上一个区块的哈希值(hash),从创始区块(genesis block)开始连接到当前区块,形成区块链。
(二)神秘的nonce值。
nonce:随机数,用来找到正确的哈希值。
挖矿的本质就是找到一个合适的nonce值使得区块的哈希值有效。
(1) 哈希值。
哈希值是通过哈希算法计算得到的一段二进制值,不同的数据得到不同的哈希值。
Python演示代码:
# 这里举个简单的例子
# 导入相关类库
import hashlib
# 定义数据
data="Hello World"
# 计算哈希值
msg=hashlib.sha256()
msg.update(data.encode('utf-8'))# 主要计算前必须将数据转成utf-8
msg.hexdigest()
演示结果:'a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e'
(2) nonce
如果修改数据,比如添加一个nonce值就可以产生不同的哈希值。
Python演示代码:
nonce = 0
msg = hashlib.sha256()
msg.update(data.encode('utf-8'))
msg.update(str(nonce).encode("utf-8"))
msg.hexdigest()
演示结果:'1370eeaaba7a6c7a234b1f82cc3b6d013a0088fd5e16408300f05b28b0015463'
(3)nonce与挖矿。
挖矿的本质就是寻找到一个合适的nonce值使得区块的哈希值有效。
在区块链中区块的哈希值必须满足一定条件才能算是有效的区块。这里设定区块的哈希值必须以0000开头才是有效的区块(设定其它条件也可以,例如:首先哈希运算,再将所得哈希值与目标哈希值进行比较,如果当前nonce值计算的哈希值小于目标哈希值,则挖矿成功。如果这个哈希值不小于目标值,矿工就会修改这个nonce(通常将之加1)然后再试)。为了得到以0000开头的哈希值,需要不断的修改nonce(挖矿)直到满足条件。下面定义一个函数来寻找该nonce值。
Python演示代码:
import hashlib
def mine(data):
nonce = 0 # nonce初始值为0
# 寻找正确的哈希值
while True:
msg = hashlib.sha256()
msg.update(data.encode("utf-8"))
msg.update(str(nonce).encode("utf-8"))
hash_code = msg.hexdigest()
# 如果满足条件,打印相应值并退出循环
if hash_code.startswith("0000"):
print("nonce:{}".format(nonce))
print("hash:{}".format(hash_code))
break
# 否则继续寻找
else:
nonce += 1
mine("Hello, World")
演示结果:
nonce:104803
hash:000022635160d3ae1c8c90261e0df5eb6538d7f6d42108d6ffdec17b585fb464
(三)定义区块链的块结构。
FishCoin(鱼币)区块结构如下:
identifier(唯一标识符)
nonce(nonce值)
data(区块内容)
previous_hash(父节点哈希值)
hash(新的哈希值)
Python代码: (python2.7 idle)
# -*- coding: utf-8 -*-
# block.py
import hashlib
import uuid
class Block(object):
def __init__(self, data=None,previous=None):
self.identifier =uuid.uuid4().hex #唯一标识符
self.previous =previous # 父节点
if previous:
self.previous_hash =previous.hash() # 父节点哈希值
else:
self.previous_hash = None
self.data = data # 区块内容
self.nonce = 0 # nonce值
def hash(self):
'''
计算区块的哈希值,包括区块的标示、数据、前一区块的哈希值和nonce值
'''
message = hashlib.sha256()
message.update(self.identifier.encode('utf-8'))
message.update(str(self.nonce).encode('utf-8'))
message.update(str(self.data).encode('utf-8'))
if self.previous:
message.update(str(self.previous_hash.encode('utf-8')))
return message.hexdigest()
def mine(self): #挖矿函数
# 初始化nonce为0
cur_nonce = self.nonce or 0
# 循环直到生成一个有效的哈希值
while True:
ifself.hash().startswith("0000"):# 如果生成的哈希值有效
print("nonce:{}".format(self.nonce))
print("hash:{}".format(self.hash()))
print("Congratulations,guy! I will give you fifty bitcoins as agift!")
break # 退出
else:
self.nonce += 1 # 若当前哈希值无效,更新nonce值,进行加1操作
block = Block('Hello World')
# 挖矿,循环直至找到合适的nonce
block.mine()
演示结果:
nonce:17628
hash:0000a29f6916a2e203ff6b5df49420d647fc7a12d360672460f50cd73c6e06c0
Congratulations,guy! I will give youfifty bitcoins as a gift!
至此,第一个有效的区块生成完成,下面开始实现区块链。
(四)定义区块链结构。
Python代码:(测试环境:winxp,python2.7 idle)
# -*- coding:utf-8 -*-
# block.py
import hashlib
import uuid
classBlock(object):
def __init__(self, data=None,previous=None):
self.identifier = uuid.uuid4().hex #唯一标识符
self.previous = previous # 父节点
if previous:
self.previous_hash =previous.hash() # 父节点哈希值
else:
self.previous_hash = None
self.data = data # 区块内容
self.nonce = 0 # nonce值
def hash(self):
'''
计算区块的哈希值,包括区块的标示、数据、前一区块的哈希值和nonce值
'''
message = hashlib.sha256()
message.update(self.identifier.encode('utf-8'))
message.update(str(self.nonce).encode('utf-8'))
message.update(str(self.data).encode('utf-8'))
if self.previous:
message.update(str(self.previous_hash.encode('utf-8')))
return message.hexdigest()
def mine(self): #挖矿函数
# 初始化nonce为0
cur_nonce = self.nonce or 0
# 循环直到生成一个有效的哈希值
while True:
ifself.hash().startswith("0000"):# 如果生成的哈希值有效
print("nonce:{}".format(self.nonce))
print("hash:{}".format(self.hash()))
print("Congratulations,guy! I will give you fifty bitcoins as agift!")
break # 退出
else:
self.nonce += 1 # 若当前哈希值无效,更新nonce值,进行加1操作
(五)初始化一条区块链。
Python代码:
# -*- coding: utf-8 -*-
# block.py
import hashlib
import uuid
class Block(object):
def __init__(self,data=None, previous=None):
self.identifier= uuid.uuid4().hex #唯一标识符
self.previous =previous # 父节点
if previous:
self.previous_hash = previous.hash() # 父节点哈希值
else:
self.previous_hash = None
self.data =data # 区块内容
self.nonce = 0 # nonce值
def hash(self):
'''
计算区块的哈希值,包括区块的标示、数据、前一区块的哈希值和nonce值
'''
message =hashlib.sha256()
message.update(self.identifier.encode('utf-8'))
message.update(str(self.nonce).encode('utf-8'))
message.update(str(self.data).encode('utf-8'))
ifself.previous:
message.update(str(self.previous_hash.encode('utf-8')))
returnmessage.hexdigest()
def mine(self): #挖矿函数
# 初始化nonce为0
cur_nonce =self.nonce or 0
# 循环直到生成一个有效的哈希值
while True:
ifself.hash().startswith("0000"):# 如果生成的哈希值有效
print("nonce:{}".format(self.nonce))
print("hash:{}".format(self.hash()))
print("Congratulations,guy! I will give you fifty bitcoins as agift!")
break # 退出
else:
self.nonce += 1 # 若当前哈希值无效,更新nonce值,进行加1操作
block = Block('Hello World')
#block.mine()
class BlockChain(object):
def __init__(self):
self.head =None # 指向最新的一个区块
self.blocks ={} # 包含所有区块的一个字典
'''
添加区块函数
'''
def add_block(self,new_block):
new_block.previous = new_block.previous
new_block.mine()
self.blocks[new_block.identifier] = block
self.head =new_block
defprint_chain(self):
num_existing_blocks = len(self.blocks)
print'Blockchain<{} Blocks, Head: {}>'.format(
num_existing_blocks,
self.head.identifier if self.head else None
)
# 初始化区块链
chain = BlockChain()
# 打印区块链头
chain.print_chain()
# 添加区块
for i in range(6):
new_block =Block(i)
chain.add_block(new_block)
# 打印区块链
chain.print_chain()
演示结果:
Blockchain<0 Blocks, Head: None>
nonce:116133
hash:0000415448716cfc80ed26655ad2e9519fe7201d21f4a1cb120331bc1ba49b43
Congratulations,guy! I will give youfifty bitcoins as a gift!
Blockchain<1 Blocks, Head:5c27588e35ec472c87889094d3844166>
nonce:35577
hash:00004c48024e83590fbbef03e00c7a5e147f2e35afe8e0cbd09f72a596e14270
Congratulations,guy! I will give youfifty bitcoins as a gift!
Blockchain<2 Blocks, Head:929a2dd96f8f4cbab1363659b7c31ebb>
nonce:117806
hash:0000ccfb13a6ee37dcd8ee8dc099741740cb2685c03f38a4e9ef9d8f901f24ce
Congratulations,guy! I will give youfifty bitcoins as a gift!
Blockchain<3 Blocks, Head:18c5acb0930045feb56d5977ff550e63>
nonce:11563
hash:000010a65c7a9ec231cfd5b848199ac22321484727c1141a2487d9d43bdc0aa0
Congratulations,guy! I will give youfifty bitcoins as a gift!
Blockchain<4 Blocks, Head:0d9bcd55a1ff40a498a58c7c65a8e3b0>
nonce:91674
hash:000066abc9a349e3607208d6675c60d4605b7bf37060c0cc08252a6ebdfc78ab
Congratulations,guy! I will give youfifty bitcoins as a gift!
Blockchain<5 Blocks, Head:6acb79c30d6c4b69b8c9e596b1d7a453>
nonce:86812
hash:0000502268d4387b23e8a9698d9e87877cadcd5f602ce3080f9aa91d3f663351
Congratulations,guy! I will give youfifty bitcoins as a gift!
Blockchain<6 Blocks, Head:37bef80cb7674d42a99ffd1e9d3f1026>
