浩哥小课堂的实验,比较有收获的点就是工作量证明以及共识机制的设计,完整代码参考https://github.com/Ryuchen/BlockChain
一、总体框架
定义BlockChain类:
1. 初始化函数:__init__(self)
2. 添加新区块的函数:new_block(self)
3. 添加新交易的函数:new_transaction(self)
4. 生成区块哈希值的函数:hash(block)
5. 返回最后一个区块函数:last_block(self)
6. 工作量证明实现函数:proof_of_work(self, last_proof)
7. 检查一个链是否有效的函数:valid_chain()
8. 遍历所有邻居节点找到最长有效链条:resolve_conflicts()
利用flask在网页中进行模拟挖矿
1. 计算工作量证明 PoW
2. 通过新增一个交易授予矿工(自己)一个币
3. 构造新区块并将其添加到链中
二、工作量证明算法
- 如何保证你的区块能被其他人认可?--->共识机制---->工作量证明算法(POW:proof of work)
- 拜占庭将军问题--->解决方案:Raft算法
- 简易方案及代码实现
- 思路:找到一个数字 P ,使得它与前一个区块的 proof 拼接成的字符串的 Hash 值以 4个零开头
- 具体实现代码
@staticmethod
def valid_proof(last_proof, proof):
"""
Validates the Proof: Does hash(last_proof, proof) contain 4 leading zeroes?
:param last_proof: <int> Previous Proof
:param proof: <int> Current Proof
:return: <bool> True if correct, False if not.
"""
guess = f'{last_proof}{proof}'.encode()
guess_hash = hashlib.sha256(guess).hexdigest()
return guess_hash[:4] == "0000"
def proof_of_work(self, last_proof):
"""
Simple Proof of Work Algorithm:
- Find a number p' such that hash(pp') contains leading 4 zeroes, where p is the previous p'
- p is the previous proof, and p' is the new proof
:param last_proof: <int>
:return: <int>
"""
proof = 0
while self.valid_proof(last_proof, proof) is False:
proof += 1
return proof
三、共识机制设计
共识就是指节点之间要知道对方的存在,因此每个节点都需要保存一份包含网络中其它节点的记录。另外为了解决冲突问题,制定最长的有效链条是最权威的规则。
# 第一个方法 valid_chain() 负责检查一个链是否有效,方法是遍历每个块并验证散列和证明。
# 第二个方法 resolve_conflicts() 是一个遍历我们所有邻居节点的方法,下载它们的链并使用上面的方法验证它们。如果找到一个长度大于我们的有效链条,我们就取代我们的链条。
def valid_chain(self, chain):
"""
Determine if a given blockchain is valid
:param chain: <list> A blockchain
:return: <bool> True if valid, False if not
"""
last_block = chain[0]
current_index = 1
while current_index < len(chain):
block = chain[current_index]
print(f'{last_block}')
print(f'{block}')
print("\n-----------\n")
# Check that the hash of the block is correct
if block['previous_hash'] != self.hash(last_block):
return False
# Check that the Proof of Work is correct
if not self.valid_proof(last_block['proof'], block['proof']):
return False
last_block = block
current_index += 1
return True
def resolve_conflicts(self):
"""
This is our Consensus Algorithm, it resolves conflicts
by replacing our chain with the longest one in the network.
:return: <bool> True if our chain was replaced, False if not
"""
neighbours = self.nodes
new_chain = None
# We're only looking for chains longer than ours
max_length = len(self.chain)
# Grab and verify the chains from all the nodes in our network
for node in neighbours:
response = requests.get(f'http://{node}/chain')
if response.status_code == 200:
length = response.json()['length']
chain = response.json()['chain']
# Check if the length is longer and the chain is valid
if length > max_length and self.valid_chain(chain):
max_length = length
new_chain = chain
# Replace our chain if we discovered a new, valid chain longer than ours
if new_chain:
self.chain = new_chain
return True
return False
网友评论