python3.5下调试区块链代码记录
最近因为想将之前写的工具生成的脚本进行集中管理,就想建立一个后台管理,恰好对区块链有些想法,就想后台在存储管理文件上实现区块链。
从网上找了一些大神的代码,python3.5的版本,调试后可以正常创建链表,添加数据了,分享给大家。
代码如下:
from flask import Flask
from flask import request
import hashlib as hasher
import datetime as date
import json
class Block:
def __init__(self, index, timestamp, data, previous_hash):
self.index = index
self.timestamp = timestamp
self.data = data
self.previous_hash = previous_hash
self.hash = self.hash_block()
def hash_block(self):
sha = hasher.sha256()
sha.update(b'str(self.index)' +
b'str(self.timestamp)' +
b'str(self.data)' +
b'str(self.previous_hash)')
#sha.update(b'str(self.index)')
return sha.hexdigest()
def create_genesis_block():
# Manually construct ablock with
# index zero andarbitrary previous hash
return Block(0, date.datetime.now(), "GenesisBlock", "0")
def next_block(last_block):
this_index =last_block.index + 1
this_timestamp =date.datetime.now()
this_data = "Hey! I'm block " +str(this_index)
this_hash = last_block.hash
return Block(this_index, this_timestamp, this_data, this_hash)
# Create the blockchain and add the genesis block
blockchain = [create_genesis_block()]
previous_block = blockchain[0]
# How many blocks should we add to the chain
#after the genesis block
num_of_blocks_to_add= 20
# Addblocks to the chain
for i in range(0, num_of_blocks_to_add):
block_to_add= next_block(previous_block)
blockchain.append(block_to_add)
previous_block = block_to_add
# Telleveryone about it!
print("Block #{} has been added to theblockchain!".format(block_to_add.index))
print("Hash:{}\n".format(block_to_add.hash))
node = Flask(__name__)
# Store the transactions that
# this node has in a list
this_nodes_transactions = []
@node.route('/txion',methods=['POST'])
def transaction():
if request.method == 'POST':
# On each new POST request,
# we extract the transaction data
new_txion = request.get_json()
# Then we add the transaction to our list
this_nodes_transactions.append(new_txion)
# Because the transaction was successfully
# submitted, we log it to our console
print("New transaction")
print("FROM:{}".format(new_txion['from']))
print("TO:{}".format(new_txion['to']))
print("AMOUNT:{}\n".format(new_txion['amount']))
# Then we let the client know it worked out
return "Transaction submissionsuccessful\n"
#node.run()
# ...blockchain
# ...Block class definition
miner_address ="q3nf394hjg-random-miner-address-34nf3i4nflkn3oi"
def proof_of_work(last_proof):
# Create a variable that wewill use to find
# our next proof of work
incrementor = last_proof + 1
# Keep incrementing the incrementor until
# it's equal to a number divisible by 9
# and the proof of work of the previous
# block in the chain
while not (incrementor % 9 == 0 and incrementor % last_proof == 0):
incrementor += 1
# Once that number is found,
# we can return it as a proof
# of our work
print(type(incrementor))
return incrementor
@node.route('/mine', methods =['GET'])
def mine():
# Get the last proof of work
last_block = blockchain[len(blockchain) - 1]
#last_proof = last_block.data['proof-of-work']
last_proof = last_block.index
# Find the proof of work for
# the current block being mined
# Note: The program will hang here until a new
# proof of work is found
proof = proof_of_work(last_proof)
# Once we find a valid proof of work,
# we know we can mine a blockso
# we reward the miner by addinga transaction
this_nodes_transactions.append(
{ "from":"network", "to": miner_address, "amount": 1 })
# Now we can gather the dataneeded
# to create the new block
new_block_data = {
"proof-of-work":proof,
"transactions":list(this_nodes_transactions)
}
new_block_index = last_block.index + 1
new_block_timestamp = this_timestamp =date.datetime.now()
last_block_hash = last_block.hash
# Empty transaction list
this_nodes_transactions[:] = []
# Now create the
# new block!
mined_block = Block(
new_block_index,
new_block_timestamp,
new_block_data,
last_block_hash)
blockchain.append(mined_block)
# Let the client know we mined a block
return json.dumps({
"index":new_block_index,
"timestamp":str(new_block_timestamp),
"data": new_block_data,
"hash": last_block_hash
}) + "\n"
@node.route('/blocks',methods=['GET'])
def get_blocks():
chain_to_send = blockchain
# Convert our blocks into dictionaries
# so we can send them as json objects later
for block in chain_to_send:
block_index = str(block.index)
block_timestamp =str(block.timestamp)
block_data = str(block.data)
block_hash = block.hash
block = {
"index": block_index,
"timestamp": block_timestamp,
"data": block_data,
"hash": block_hash
}
# Send our chain to whomever requested it
#print(chain_to_send)
#chain_to_send = json.dumps(chain_to_send)
chain_to_send = json.dumps(block)
return chain_to_send
def find_new_chains():
# Get the blockchains of every
# other node
other_chains = []
for node_url in peer_nodes:
# Get their chains using a GETrequest
block = requests.get(node_url +"/blocks").content
# Convert the JSON object to aPython dictionary
block = json.loads(block)
# Add it to our list
other_chains.append(block)
return other_chains
def consensus():
# Get the blocks from other nodes
other_chains =find_new_chains()
# If our chain isn't longest,
# then we store the longest chain
longest_chain = blockchain
for chain in other_chains:
if len(longest_chain) < len(chain):
longest_chain = chain
# If the longest chain wasn't ours,
# then we set our chain to the longest
blockchain = longest_chain
node.run(host = '0.0.0.0', port=5000)
使用一个Ubuntu的终端,因为有自带的curl服务,先后按照如下顺序发送:
1、curl "http://168.130.9.126:5000/txion" -H "Content-Type:application/json" -d '{"from": "akjflw","to":"fjlakdj", "amount": 3}'
2、curl "http://168.130.9.126:5000/blocks"
3、curl "http://168.130.9.126:5000/mine"
4、curl "http://168.130.9.126:5000/blocks"
调试信息如下:
root@rzt-Default-string:~# curl "http://168.130.9.126:5000/txion" -H "Content-Type:application/json" -d '{"from": "akjflw","to":"fjlakdj", "amount": 3}'
Transaction submissionsuccessful
root@rzt-Default-string:~#
root@rzt-Default-string:~# curl "http://168.130.9.126:5000/blocks"
{"hash": "13d1090a3a3460bdfd50d96bf4616fb86e33c4a4579ac64865e61efba509ab19", "data": "Hey! I'm block 20", "timestamp": "2020-11-24 19:46:26.834099", "index": "20"}root@rzt-Default-string:~#
root@rzt-Default-string:~#
root@rzt-Default-string:~# curl "http://168.130.9.126:5000/mine"
{"hash": "13d1090a3a3460bdfd50d96bf4616fb86e33c4a4579ac64865e61efba509ab19", "data": {"transactions": [{"amount": 3, "to": "fjlakdj", "from": "akjflw"}, {"amount": 1, "to": "q3nf394hjg-random-miner-address-34nf3i4nflkn3oi", "from": "network"}], "proof-of-work": 180}, "timestamp": "2020-11-24 19:46:47.819299", "index": 21}
root@rzt-Default-string:~#
root@rzt-Default-string:~# curl "http://168.130.9.126:5000/blocks"
{"hash": "13d1090a3a3460bdfd50d96bf4616fb86e33c4a4579ac64865e61efba509ab19", "data": "{'transactions': [{'amount': 3, 'to': 'fjlakdj', 'from': 'akjflw'}, {'amount': 1, 'to': 'q3nf394hjg-random-miner-address-34nf3i4nflkn3oi', 'from': 'network'}], 'proof-of-work': 180}", "timestamp": "2020-11-24 19:46:47.819299", "index": "21"}root@rzt-Default-string:~#
root@rzt-Default-string:~#