欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python學(xué)習(xí)入門之區(qū)塊鏈詳解

 更新時間:2017年07月25日 10:26:25   作者:101python  
區(qū)塊鏈的基礎(chǔ)概念很簡單:一個分布式數(shù)據(jù)庫,存儲一個不斷加長的 list,list 中包含著許多有序的記錄。下面這篇文章主要給大家介紹了關(guān)于Python學(xué)習(xí)入門之區(qū)塊鏈的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友們下面來一起看看吧。

前言

本文將給大家簡單介紹關(guān)于區(qū)塊鏈(BlockChain)的相關(guān)知識,并用Python做一簡單實現(xiàn)。下面話不多說,來一起看看詳細(xì)的介紹:

什么是區(qū)塊鏈

簡單來說,區(qū)塊鏈就是把加密數(shù)據(jù)(區(qū)塊)按照時間順序進(jìn)行疊加(鏈)生成的永久、不可逆向修改的記錄。具體來說,它區(qū)塊鏈?zhǔn)怯梢淮褂妹艽a學(xué)方法產(chǎn)生的數(shù)據(jù)塊組成的,每一個區(qū)塊都包含了上一個區(qū)塊的哈希值(hash),從創(chuàng)始區(qū)塊(genesis block)開始連接到當(dāng)前區(qū)塊,形成塊鏈。每一個區(qū)塊都確保按照時間順序在上一個區(qū)塊之后產(chǎn)生,否則前一個區(qū)塊的哈希值是未知的。它是比特幣的一個重要概念。

特點

區(qū)塊鏈有如下特點:

  • 去中心化:區(qū)塊鏈不依賴于某個中心節(jié)點,而是依賴于分布式的各個節(jié)點。
  • 無須信任系統(tǒng):區(qū)塊鏈中基于密碼學(xué)算法,數(shù)據(jù)需要網(wǎng)絡(luò)內(nèi)其他用戶的批準(zhǔn),所以不需要一套第三方中介結(jié)構(gòu)或信任機構(gòu)背書。
  • 不可篡改和加密安全性:區(qū)塊鏈采取單向哈希算法,同時每個新產(chǎn)生的區(qū)塊嚴(yán)格按照時間線形順序推進(jìn),時間的不可逆性導(dǎo)致任何試圖入侵篡改區(qū)塊鏈內(nèi)數(shù)據(jù) 信息的行為都很容易被追溯,導(dǎo)致被其他節(jié)點的排斥,從而可以限制相關(guān)不法行為。

以上特點使得區(qū)塊鏈在銀行、證券市場和金融等諸多領(lǐng)域有著越來越多的應(yīng)用。

區(qū)塊鏈工作原理

區(qū)塊鏈?zhǔn)揭幌盗屑用艿臄?shù)據(jù)塊。這些區(qū)塊由一個包含元數(shù)據(jù)的區(qū)塊頭和緊跟其后的構(gòu)成區(qū)塊主體的一長串交易組成。比特幣中的區(qū)塊結(jié)構(gòu)如下:

區(qū)塊頭

區(qū)塊頭中包含了與區(qū)塊鏈中其它區(qū)塊中的連接信息、時間戳和nonce等信息,具體如下:

區(qū)塊標(biāo)識符

區(qū)塊有兩個標(biāo)示符,一是區(qū)塊頭的哈希值,二是區(qū)塊高度。區(qū)塊頭的哈希值是通過SHA256算法對區(qū)塊頭進(jìn)行二次哈希計算而得到的數(shù)字。區(qū)塊哈希值可以唯一、明確地標(biāo)識一個區(qū)塊,并且任何節(jié)點通過簡單地對區(qū)塊頭進(jìn)行哈希計算都可以獨立地獲取該區(qū)塊哈希值。區(qū)塊高度是指該區(qū)塊在區(qū)塊鏈中的位置。區(qū)塊高度并不是唯一的標(biāo)識符。雖然一個單一的區(qū)塊總是會有一個明確的、固定的區(qū)塊高度,但反過來卻并不成立,一個區(qū)塊高度并不總是識別一個單一的區(qū)塊。兩個或兩個以上的區(qū)塊可能有相同的區(qū)塊高度,在區(qū)塊鏈里爭奪同一位置。

了解了以上基礎(chǔ)后下面開始用Python實現(xiàn)一個簡單的區(qū)塊鏈。

區(qū)塊鏈的Python實現(xiàn)

一、定義區(qū)塊結(jié)構(gòu)

In [16]:

# block.py

import hashlib
import uuid


class Block(object):
 def __init__(self, data=None, previous_hash=None):
  self.identifier = uuid.uuid4().hex # 產(chǎn)生唯一標(biāo)示
  self.nonce = None     # nonce值
  self.data = data      # 區(qū)塊內(nèi)容
  self.previous_hash = previous_hash # 父節(jié)點哈希值
  
 def hash(self, nonce=None):
  '''
  計算區(qū)塊的哈希值
  '''
  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):
  '''
  校驗區(qū)塊哈希值有否有效
  '''
  return the_hash.startswith('0000')

 def __repr__(self):
  return 'Block<Hash: {}, Nonce: {}>'.format(self.hash(), self.nonce)

以上就是一個區(qū)塊結(jié)構(gòu),這里實現(xiàn)的是一個簡化版,沒有完全對應(yīng)比特幣中的區(qū)塊。這里的區(qū)塊包含一個唯一標(biāo)識符、父節(jié)點的哈希值、nonce值和該區(qū)塊的內(nèi)容字段??梢钥吹揭粋€區(qū)塊的哈希值必須滿足一定的條件才是有效的,比如以0000開始。下面對這個區(qū)塊結(jié)構(gòu)進(jìn)行初始化。

In [37]:

# 創(chuàng)建一個內(nèi)容為hello world的內(nèi)容塊

block = Block('Hello World')
block

Out[37]:

Block<Hash: 238a65a101c8829d7fc406eb78a71cfc19ad702b437e2c1be8d9061ddb81e900, Nonce: None>

以上一個區(qū)塊雖然創(chuàng)建完成,但其哈希值不是有效的。

In [38]:

block.hash_is_valid(block.hash())

Out[38]:

False

改變nonce的值就可以得到一個新的哈希值。

In [39]:

block.hash(1)

Out[39]:

'a6431938ba10270dfcfdf7a2371312446914fedadf79632c2c0adb3b463f4838'

哈希值更新了,但還不是有效的哈希值。為了得到有效哈希值,是一個不斷更新nonce值的過程,或者說一個挖礦(mine)過程。下面添加一個mine函數(shù)用來得到一個合適的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 # 產(chǎn)生唯一標(biāo)示
  self.nonce = None     # nonce值
  self.data = data      # 區(qū)塊內(nèi)容
  self.previous_hash = previous_hash # 父節(jié)點哈希值
  
 def hash(self, nonce=None):
  '''
  計算區(qū)塊的哈希值
  '''
  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):
  '''
  校驗區(qū)塊哈希值有否有效
  '''
  return the_hash.startswith('0000')

 def __repr__(self):
  return 'Block<Hash: {}, Nonce: {}>'.format(self.hash(self.nonce), self.nonce)
 
 
 '''
  新增挖礦函數(shù)
 '''
 def mine(self):
  # 初始化nonce為0
  cur_nonce = self.nonce or 0

  # 循環(huán)直到生成一個有效的哈希值
  while True:
   the_hash = self.hash(nonce=cur_nonce)
   if self.hash_is_valid(the_hash): # 如果生成的哈希值有效
    self.nonce = cur_nonce   # 保持當(dāng)前nonce值
    break       # 并退出
   else:
    cur_nonce += 1 # 若當(dāng)前哈希值無效,更新nonce值,進(jìn)行加1操作

In [75]:

block = Block('Hello World')

# 挖礦,循環(huán)直至找到合適的nonce
block.mine()

# 打印
block

Out[75]:

Block<Hash: 000087359d5264153d624556f0a0c6f25cba06e453975c1c02587862e823911b, Nonce: 64751>

至此,第一個有效的區(qū)塊生成完成,下面開始定義區(qū)塊鏈。

二、定義區(qū)塊鏈結(jié)構(gòu)

In [81]:

class BlockChain(object):
 def __init__(self):
  self.head = None # 指向最新的一個區(qū)塊
  self.blocks = {} # 包含所有區(qū)塊的一個字典

 '''
  添加區(qū)塊函數(shù)
 '''
 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] = {
   'block': new_block,
   'previous_hash': previous_hash,
   'previous': self.head,
  }
  self.head = new_block

 def __repr__(self):
  num_existing_blocks = len(self.blocks)
  return 'Blockchain<{} Blocks, Head: {}>'.format(
   num_existing_blocks,
   self.head.identifier if self.head else None
  )

定義好區(qū)塊鏈結(jié)構(gòu)后,下面就開始初始化一條區(qū)塊鏈。

In [82]:

# 初始化
chain = BlockChain()

# 打印
chain

Out[82]:

Blockchain<0 Blocks, Head: None>

In [83]:

# 添加區(qū)塊
chain.add_block(block)

# 打印
chain

Out[83]:

Blockchain<1 Blocks, Head: 364c0cf963384ca28a2763499a140405>

In [84]:

# 添加更多的區(qū)塊

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>

以上就是一個簡單區(qū)塊鏈,后面還會涉及到區(qū)塊鏈的有效性。當(dāng)區(qū)塊鏈中一個區(qū)塊被改變后,這個區(qū)塊的哈希就會改變,從而影響到這塊區(qū)塊之后的區(qū)塊,致使這個區(qū)塊鏈不再有效。這些將在后續(xù)繼續(xù)深入。

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。

相關(guān)文章

  • 應(yīng)用OpenCV和Python進(jìn)行SIFT算法的實現(xiàn)詳解

    應(yīng)用OpenCV和Python進(jìn)行SIFT算法的實現(xiàn)詳解

    這篇文章主要介紹了應(yīng)用OpenCV和Python進(jìn)行SIFT算法的實現(xiàn)詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • Python判斷某個用戶對某個文件的權(quán)限

    Python判斷某個用戶對某個文件的權(quán)限

    這篇文章主要為大家詳細(xì)介紹了Python如何判斷某個用戶對某個文件的權(quán)限,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-10-10
  • python中l(wèi)ogging庫的使用總結(jié)

    python中l(wèi)ogging庫的使用總結(jié)

    Python的logging模塊提供了通用的日志系統(tǒng),可以方便第三方模塊或者是應(yīng)用使用,下面這篇文章主要給大家介紹了關(guān)于python中l(wèi)ogging庫使用的一些知識總結(jié),文中給出了詳細(xì)的示例代碼,需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-10-10
  • python編程實現(xiàn)清理微信重復(fù)緩存文件

    python編程實現(xiàn)清理微信重復(fù)緩存文件

    這篇文章主要為大家介紹了使用python編程來實現(xiàn)清理微信重復(fù)緩存文件的示例代碼過程,有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2021-11-11
  • Python3讀取Excel數(shù)據(jù)存入MySQL的方法

    Python3讀取Excel數(shù)據(jù)存入MySQL的方法

    今天小編就為大家分享一篇Python3讀取Excel數(shù)據(jù)存入MySQL的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-05-05
  • Python按鈕的響應(yīng)事件詳解

    Python按鈕的響應(yīng)事件詳解

    今天小編就為大家分享一篇關(guān)于Python按鈕的響應(yīng)事件詳解,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-03-03
  • Python全棧之迭代器和高階函數(shù)

    Python全棧之迭代器和高階函數(shù)

    這篇文章主要為大家介紹了Python之迭代器和高階函數(shù),具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2021-12-12
  • python可視化實現(xiàn)KNN算法

    python可視化實現(xiàn)KNN算法

    這篇文章主要為大家詳細(xì)介紹了python可視化實現(xiàn)KNN算法,通過繪圖工具M(jìn)atplotlib包可視化實現(xiàn)機器學(xué)習(xí)中的KNN算法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-10-10
  • windows下 兼容Python2和Python3的解決方法

    windows下 兼容Python2和Python3的解決方法

    這篇文章主要介紹了windows下 兼容Python2和Python3的解決方法,需要的朋友可以參考下
    2018-12-12
  • Python實現(xiàn)京東秒殺功能代碼

    Python實現(xiàn)京東秒殺功能代碼

    這篇文章主要介紹了Python實現(xiàn)京東秒殺功能,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05

最新評論