輸出結果
代碼設計
Created on 2018年3月11日
@author: Jason niu
'''
import hashlib #該子產品實作了諸多安全哈希和消息摘要算法的通用接口,包括 FIPS 安全雜湊演算法: SHA1、SHA224、 SHA256、SHA384、RSA的 MD5 等等算法
import uuid #通用唯一辨別符 ( Universally Unique Identifier ), 對于所有的UUID它可以保證在空間和時間上的唯一性. 它是通過MAC位址, 時間戳, 命名空間, 随機數, 僞随機數來保證生成ID的唯一性, 有着固定的大小( 128 bit ). 它的唯一性和一緻性特點使得可以無需注冊過程就能夠産生一個新的UUID. UUID可以被用作多種用途, 既可以用來短時間内标記一個對象, 也可以可靠的辨識網絡中的持久性對象.
#該類實作簡化版的區塊包:一個唯一辨別符、父節點的哈希值、nonce值、該區塊的内容字段。
class Block(object):
def __init__(self, data=None, previous_hash=None):
self.identifier = uuid.uuid4().hex # uuid産生唯一标示
self.nonce = None
self.data = data
self.previous_hash = previous_hash
def hash(self, nonce=None): #利用sha256算法計算區塊的哈希值
message = hashlib.sha256()
message.update(self.identifier.encode('utf-8')) #以utf-8格式對identifier進行編碼,二進制從低位往高位取出二進制數字
message.update(str(nonce).encode('utf-8'))
message.update(str(self.data).encode('utf-8'))
message.update(str(self.previous_hash).encode('utf-8'))
return message.hexdigest() #hexdigest函數計算整個檔案的hash code,傳回摘要作為十六進制資料字元串值
def hash_is_valid(self, the_hash):
return the_hash.startswith('0000')
def __repr__(self):
return 'Block<Hash: {}, Nonce: {}>'.format(self.hash(self.nonce), self.nonce)
def mine(self):
cur_nonce = self.nonce or 0
while True:
the_hash = self.hash(nonce=cur_nonce)
if self.hash_is_valid(the_hash):
self.nonce = cur_nonce
break
else:
cur_nonce += 1
# 建立創世區塊
block = Block('Hello World')
block.mine()
print(block)
class BlockChain(object):
def __init__(self):
self.head = None
self.blocks = {}
def add_block(self, new_block):
previous_hash = self.head.hash(self.head.nonce) if self.head else None
new_block.previous_hash = previous_hash
self.blocks[new_block.identifier] = {
'block': new_block,'previous_hash': previous_hash,'previous': self.head,
}
self.head = new_block
num_existing_blocks = len(self.blocks)
return 'Blockchain<{} Blocks, Head: {}>'.format(
num_existing_blocks,
self.head.identifier if self.head else None
)
#定義好區塊鍊結構後,下面就開始初始化一條區塊鍊。
chain = BlockChain()
print(chain)
chain.add_block(block)
#for循環,添加更多的區塊
for i in range(6):
new_block = Block(i)
new_block.mine()
chain.add_block(new_block)
from datetime import datetime #導入時間日期子產品
#該類實作基于Block實作一個支援收支記錄格式
class AccountBill(Block):
def __init__(self, content, amount):
t = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
data = "{}|{}|{}".format(t, content, amount)
return super(AccountBill, self).__init__(data)
def get_amount(self):
amount = 0
if self.data:
amount = int(self.data.split('|')[2])
return amount
def get_content(self):
content = ''
content = self.data.split('|')[1]
return content
return 'Bill: {}>'.format(
self.data
AccountBill('測試', 100)
from collections import OrderedDict
class AccountBook(BlockChain):
self.blocks = OrderedDict()
def add_block(self, new_bill):
new_bill.mine()
super(AccountBook, self).add_block(new_bill)
def balance(self):
balance = 0
if self.blocks:
for k, v in self.blocks.items():
balance += v['block'].get_amount()
return balance
return 'AccountBook<{} Bills, Head: {}>'.format(
book = AccountBook()
b1 = AccountBill('月薪', 23000)
book.add_block(b1)
b2 = AccountBill('房租消費', -3000)
book.add_block(b2)
b3 = AccountBill('飲食消費', -1200)
book.add_block(b3)
b4 = AccountBill('娛樂消費', -1200)
book.add_block(b4)
b5 = AccountBill('token收入', 1000)
book.add_block(b5)
b6 = AccountBill('搬磚收入', 400)
book.add_block(b6)
b7 = AccountBill('扛水泥收入', 500)
book.add_block(b7)
b8 = AccountBill('學習AI', -1000)
book.add_block(b8)
b9 = AccountBill('學習BlockChain', -800)
book.add_block(b9)
b10 = AccountBill('學習ICO', -10)
book.add_block(b10)
print(book.balance())
for k,v in book.blocks.items():
print(v['block'].data)
import matplotlib
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei']
x_data = []
y_data = []
colors = []
bill = v['block']
y_data.append(bill.get_content())
amount = bill.get_amount()
if amount > 0:
x_data.append(amount)
colors.append('blue')
else:
x_data.append(-amount)
colors.append('red')
y_pos = np.arange(len(y_data))
plt.bar(y_pos, x_data, align='center', alpha=0.5, color=colors)
plt.xticks(y_pos, y_data)
plt.ylabel('金額')
plt.title('BlockChain:程式猿記錄在區塊裡的收支記錄圖——Jason niu')
plt.show()