首頁 > 後端開發 > Python教學 > Python基礎入門--區塊鏈

Python基礎入門--區塊鏈

巴扎黑
發布: 2017-08-13 14:55:16
原創
1882 人瀏覽過

區塊鏈的基礎概念很簡單:一個分散式資料庫,儲存一個不斷加長的 list,list 中包含著許多有序的記錄。以下這篇文章主要為大家介紹了關於Python學習入門之區塊鏈的相關資料,文中透過範例程式碼介紹的非常詳細,需要的朋友們下面來一起看看吧。

前言

本文將為大家簡單介紹關於區塊鏈(BlockChain)的相關知識,並用Python做一簡單實作。下面話不多說,來一起看看詳細的介紹:

什麼是區塊鏈

簡單來說,區塊鏈就是把加密資料(區塊)依照時間順序進行疊加(鏈)產生的永久、不可逆向修改的記錄。具體來說,它區塊鏈是由一串使用密碼學方法產生的資料區塊組成的,每個區塊都包含了上一個區塊的哈希值(hash),從創始區塊(genesis block)開始連接到當前區塊,形成塊鏈。每一個區塊都確保按照時間順序在上一個區塊之後產生,否則前一個區塊的哈希值是未知的。它是比特幣的一個重要概念。

特點

區塊鏈有以下特點:

  • 去中心化:區塊鏈不依賴某個中心節點,而是依賴分散式的各個節點。

  • 無須信任系統:區塊鏈中基於密碼學演算法,資料需要網路內其他使用者的批准,所以不需要一套第三方中介結構或信任機構背書。

  • 不可篡改和加密安全性:區塊鏈採取單向雜湊演算法,同時每個新產生的區塊嚴格按照時間線形順序推進,時間的不可逆性導致任何試圖入侵篡改區塊鏈內資料資訊的行為都很容易被追溯,導致被其他節點的排斥,從而可以限制相關不法行為。

以上特點使得區塊鏈在銀行、證券市場和金融等許多領域有著越來越多的應用。

區塊鏈運作原理

區塊鍊式一系列加密的資料區塊。這些區塊由一個包含元資料的區塊頭和緊接在後的構成區塊主體的一長串交易組成。比特幣中的區塊結構如下:

區塊頭

區塊頭中包含了與區塊鏈中其它區區塊中的連接資訊、時間戳記和nonce等信息,如下:

#區塊標識符

##區塊有兩個標示符,一是區塊頭的哈希值,二是區塊高度。區塊頭的雜湊值是透過SHA256演算法對區塊頭進行二次哈希計算而得到的數字。區塊哈希值可以唯一、明確地識別一個區塊,並且任何節點透過簡單地對區塊頭進行哈希計算都可以獨立地獲取該區塊哈希值。區塊高度是指該區塊在區塊鏈中的位置。區塊高度並不是唯一的識別碼。雖然一個單一的區塊總是會有一個明確的、固定的區塊高度,但反過來卻並不成立,一個區塊高度並不總是識別一個單一的區塊。兩個或兩個以上的區塊可能有相同的區塊高度,在區塊鏈裡爭奪相同位置。

了解了以上基礎後以下開始用Python實作一個簡單的區塊鏈。

區塊鏈的Python實作

#一、定義區塊結構

In [ 16]:


# block.py

import hashlib
import uuid


class Block(object):
 def __init__(self, data=None, previous_hash=None):
  self.identifier = uuid.uuid4().hex # 产生唯一标示
  self.nonce = None     # nonce值
  self.data = data      # 区块内容
  self.previous_hash = previous_hash # 父节点哈希值
  
 def hash(self, nonce=None):
  '''
  计算区块的哈希值
  '''
  message = hashlib.sha256()
  message.update(self.identifier.encode('utf-8'))
  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()

 def hash_is_valid(self, the_hash):
  '''
  校验区块哈希值有否有效
  '''
  return the_hash.startswith('0000')

 def __repr__(self):
  return &#39;Block<Hash: {}, Nonce: {}>&#39;.format(self.hash(), self.nonce)
登入後複製

以上就是一個區塊結構,這裡實現的是一個簡化版,沒有完全對應比特幣中的區塊。這裡的區塊包含一個唯一識別碼、父節點的哈希值、nonce值和該區塊的內容欄位。可以看到一個區塊的雜湊值必須滿足一定的條件才是有效的,例如以0000開始。下面對這個區塊結構進行初始化。

In [37]:


# 创建一个内容为hello world的内容块

block = Block(&#39;Hello World&#39;)
block
登入後複製

Out[37]:


Block<Hash: 238a65a101c8829d7fc406eb78a71cfc19ad702b437e2c1be8d9061ddb81e900, Nonce: None>
登入後複製

以上一個區塊雖然創建完成,但其哈希值不是有效的。

In [38]:


#

block.hash_is_valid(block.hash())
登入後複製

Out[38]:


False
登入後複製

改變nonce的值就可以得到一個新的雜湊值。

In [39]:


#

block.hash(1)
登入後複製

Out[39]:


&#39;a6431938ba10270dfcfdf7a2371312446914fedadf79632c2c0adb3b463f4838&#39;
登入後複製

哈希值更新了,但還不是有效的哈希值。為了得到有效哈希值,是一個不斷更新nonce值的過程,或者說一個挖礦(mine)過程。下面加入一個mine函數用來得到一個合適的nonce值。

In [78]:


# block.py

import hashlib
import uuid


class Block(object):
 def __init__(self, data=None, previous_hash=None):
  self.identifier = uuid.uuid4().hex # 产生唯一标示
  self.nonce = None     # nonce值
  self.data = data      # 区块内容
  self.previous_hash = previous_hash # 父节点哈希值
  
 def hash(self, nonce=None):
  &#39;&#39;&#39;
  计算区块的哈希值
  &#39;&#39;&#39;
  message = hashlib.sha256()
  message.update(self.identifier.encode(&#39;utf-8&#39;))
  message.update(str(nonce).encode(&#39;utf-8&#39;))
  message.update(str(self.data).encode(&#39;utf-8&#39;))
  message.update(str(self.previous_hash).encode(&#39;utf-8&#39;))

  return message.hexdigest()

 def hash_is_valid(self, the_hash):
  &#39;&#39;&#39;
  校验区块哈希值有否有效
  &#39;&#39;&#39;
  return the_hash.startswith(&#39;0000&#39;)

 def __repr__(self):
  return &#39;Block<Hash: {}, Nonce: {}>&#39;.format(self.hash(self.nonce), self.nonce)
 
 
 &#39;&#39;&#39;
  新增挖矿函数
 &#39;&#39;&#39;
 def mine(self):
  # 初始化nonce为0
  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   # 保持当前nonce值
    break       # 并退出
   else:
    cur_nonce += 1 # 若当前哈希值无效,更新nonce值,进行加1操作
登入後複製

In [75]:


block = Block(&#39;Hello World&#39;)

# 挖矿,循环直至找到合适的nonce
block.mine()

# 打印
block
登入後複製

Out[75]:


Block<Hash: 000087359d5264153d624556f0a0c6f25cba06e453975c1c02587862e823911b, Nonce: 64751>
登入後複製

至此,第一个有效的区块生成完成,下面开始定义区块链。

二、定义区块链结构

In [81]:


class BlockChain(object):
 def __init__(self):
  self.head = None # 指向最新的一个区块
  self.blocks = {} # 包含所有区块的一个字典

 &#39;&#39;&#39;
  添加区块函数
 &#39;&#39;&#39;
 def add_block(self, new_block):
  previous_hash = self.head.hash() if self.head else None
  new_block.previous_hash = previous_hash

  self.blocks[new_block.identifier] = {
   &#39;block&#39;: new_block,
   &#39;previous_hash&#39;: previous_hash,
   &#39;previous&#39;: self.head,
  }
  self.head = new_block

 def __repr__(self):
  num_existing_blocks = len(self.blocks)
  return &#39;Blockchain<{} Blocks, Head: {}>&#39;.format(
   num_existing_blocks,
   self.head.identifier if self.head else None
  )
登入後複製

定义好区块链结构后,下面就开始初始化一条区块链。

In [82]:


# 初始化
chain = BlockChain()

# 打印
chain
登入後複製

Out[82]:


Blockchain<0 Blocks, Head: None>
登入後複製

In [83]:


# 添加区块
chain.add_block(block)

# 打印
chain
登入後複製

Out[83]:


Blockchain<1 Blocks, Head: 364c0cf963384ca28a2763499a140405>
登入後複製

In [84]:


# 添加更多的区块

for i in range(6):
 new_block = Block(i)
 new_block.mine()
 chain.add_block(new_block)
 
# 打印
chain
登入後複製

Out[84]:


Blockchain<7 Blocks, Head: e7cb24ec7acd42a4aaebe7faee9e0713>
登入後複製

以上就是一个简单区块链,后面还会涉及到区块链的有效性。当区块链中一个区块被改变后,这个区块的哈希就会改变,从而影响到这块区块之后的区块,致使这个区块链不再有效。这些将在后续继续深入。

以上是Python基礎入門--區塊鏈的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板