天天看點

BlockChain:Py實作區塊鍊簡單場景應用:程式猿記錄在區塊裡的收入記錄圖

輸出結果

BlockChain:Py實作區塊鍊簡單場景應用:程式猿記錄在區塊裡的收入記錄圖

BlockChain:Py實作區塊鍊簡單場景應用:程式猿記錄在區塊裡的收入記錄圖

BlockChain:Py實作區塊鍊簡單場景應用:程式猿記錄在區塊裡的收入記錄圖

代碼設計

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()