在搭建区块链中学习
参考教材:Learn Blockchains by Building One
【注:仅仅个人心得体会】
区块链
的大致样子
block = {
'index': 1,
'timestamp': 1506057125.900785,
'transactions': [
{
'sender': "8527147fe1f5426f9dd545de4b27ee00",
'recipient': "a77f5cdfa2934df3954a5c7c7da5df1f",
'amount': 5,
}
],
'proof': 324984774000,
'previous_hash': "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824"
}
一些名词
区块:一个区块链由许多个区块组成,每个区块中会包含若干元素。
交易:sender发送给recipienter的内容的记录,记录在区块的交易信息中
哈希值:一个区块中包含的前一个区块的哈希值,使得区块之间连接。
时间戳:区块被挖出来的时刻
挖矿:根据算力来进行一系列数学操作,做到符合工作量证明机制的的时候算是挖到矿,收到奖励,并形成新的区块连接到区块链的末端
工作量证明:根据规则,找到满足规则的所需条件,作为挖到矿的证明
从创造一个新的区块并添加到区块链上说起吧
通常情况下当挖到矿时才创建一个新的区块,挖到矿后会进行一笔交易,相当于获得一个比特币
而挖到矿的规则制定则需要工作量证明机制来实现(自己制定)
这里工作量证明机制是
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
找到一个数p‘使得hash(pp')的前四位都是零
创建新区块
def new_block(self, proof, previous_hash=None):
"""
Create a new Block in the Blockchain
:param proof: <int> The proof given by the Proof of Work algorithm
:param previous_hash: (Optional) <str> Hash of previous Block
:return: <dict> New Block
"""
block = {
'index': len(self.chain) + 1,
'timestamp': time(),
'transactions': self.currrent_transactions,
'proof': proof,
'previous_hash': previous_hash or self.hash(self.chain[-1]),
}
# Reset the current list of transactions
self.current_transactions = []
self.chain.append(block)
return block
不断尝试找到那个p'(挖矿行为)
简单的工作量证明机制
def valid_proof(last_proof,proof):
guess = f'{last_proof}{proof}'.encode()
guess_hash = hashlib.sha256(guess).hexdigest()
return guess_hash[:4] == "0000"
def proof_of_work(self,last_proof):
proof = 0
while self.valid_proof(last_proof, proof) is False:
proof += 1
return proof
挖矿
def mine():
last_block = blockchain.last_block
last_proof = last_block['proof']
proof = blockchain.proof_of_work(last_proof)
#reward for find the proof
# The sender is "0" to signify that this node has mined a new coin.
blockchain.new_transaction(
sender="0",
recipient=node_identifier,
amount=1,
)
# 调用之前的创建区块并连接到原区块链上
previous_hash = blockchain.hash(last_block)
block = blockchain.new_block(proof,previous_hash)
创建新的交易的代码,在当前区块中,会有许多交易,而这些交易的信息都将会存储到当前区块链的区块中以便于追溯查证,并返回下一个需要挖的区块索引。
def new_transaction(self, sender, recipient, amount):
self.currrent_transactions.append({
'sender': sender,
'recipient': recipient,
'amount': amount,
})
return self.last_block['index'] + 1
共识机制,当然,区块链本就是去中心化思想,不会只有一个人保存区块链,而是一群人都保存有区块链(账本),这时候,到了联机模式。就需要制定一些大家都同意的公平规则,所谓的共识机制,进行共识机制前,会先验证你的区块链的链接是否正确,你是否随意篡改过你的区块链(账本)
def valid_chain(self, chain):
last_block = chain[0]
current_index = 1
逐个验证每个区块(也就是是否符合工作量证明机制,是否每个块是靠努力挖矿得来的)
while current_index < len(chain):
block = chain[current_index]
#Check the hash
if block['previous_hash'] != self.hash(last_block):
return False
#Check the proof of work
if not self.valid_proof(last_block['proof'], block['proof']):
return False
last_block = block
current_index += 1
return True
当然,如果出现了错误,某些人恶意篡改区块链(账本),我们必须纠正这些错误,这时候就需要制定合适的共识机制来进行处理,我们这次选择最长的验证通过的区块链作为大家的共识,如果有某个人的区块链长度小于共识区块链,就用共识区块链来代替他的区块链,来实现安全性、统一性。
def resolve_conflicts(self):
每个人的neighbors中都保存了所有用户的信息,以便于实现共识
neighbors = self.nodes
new_chain = None
## We're only looking for chains longer than ours
max_length = len(self.chain)
先找到最长的链(共识链)
for node in neighbors:
response = requests.get(f'http://{node}/chain')
if response.status_code == 200:
length = response.json()['length']
chain = response.json()['chain']
#Check if the lengthis longer and the chain is valid
if length > max_length:
max_length = length
new_chain = chain
决定是否更新自己的链(是否符合共识机制)
if new_chain:
self.chain = new_chain
return True
return False
最后再总结一下遇到的问题和解决方式
1 已解决
2 Json.dumps详解
https://blog.csdn.net/weixin_38842821/article/details/108359551
3 hashcash详解
https://blog.csdn.net/pony_maggie/article/details/54170349
4 UUID详解
https://baike.baidu.com/item/UUID/5921266?fr=aladdin
5 Python f'' 详解
https://blog.csdn.net/qq_35290785/article/details/90634344
6 Python textwrap 详解
https://blog.csdn.net/qq_33169543/article/details/82840719
7 postman一种模拟浏览器请求的脚本,我用的是火狐的RESTED插件
8 netloc详解