Python の基礎入門 -- ブロックチェーン

巴扎黑
リリース: 2017-08-13 14:55:16
オリジナル
1828 人が閲覧しました

ブロックチェーンの基本概念はシンプルです。多くの順序付けされたレコードを含む増大するリストを保存する分散データベースです。次の記事では、Python を学習するためのブロックチェーンに関する情報を中心に、サンプルコードを通じて詳しく紹介しています。必要な方は以下をご覧ください。

はじめに

この記事では、ブロックチェーン (BlockChain) に関する関連知識と、Python を使用した簡単な実装について簡単に紹介します。これ以上の苦労はせずに、詳細な紹介を見てみましょう:

ブロックチェーンとは

簡単に言えば、ブロックチェーンは暗号化されたデータ (ブロック) を時系列に重ね合わせたもの (チェーン) 結果として得られる永続的で、不可逆的に変更された記録です。具体的には、ブロックチェーンは、暗号化手法を使用して生成された一連のデータ ブロックで構成されます。各ブロックには、ジェネシス ブロックから開始して、現在のブロックに接続してブロック チェーンを形成します。各ブロックは、時系列で前のブロックの後に生成されることが保証されています。そうでない場合、前のブロックのハッシュ値は不明です。ビットコインでは重要な概念です。

特徴

ブロックチェーンには次の特徴があります:

  • 分散化: ブロックチェーンは中央ノードに依存せず、分散ノードに依存します。

  • 信頼システムは不要: ブロックチェーンは暗号アルゴリズムに基づいており、データはネットワーク内の他のユーザーによって承認される必要があるため、サードパーティの仲介構造や信頼組織による承認は必要ありません。

  • 改ざん不可能な暗号化されたセキュリティ: ブロックチェーンは一方向ハッシュアルゴリズムを採用しており、新しく生成された各ブロックは厳密に線形順序で進みます。時間の不可逆性により、ブロックチェーン内のデータに侵入して改ざんする試みが行われます。情報の動作は簡単に追跡できるため、他のノードによる拒否につながり、関連する違法行為を制限できます。

上記の特性により、ブロックチェーンは銀行、証券市場、金融などの多くの分野でますます多くの応用が可能になります。

ブロックチェーンの仕組み

ブロックチェーンは、一連の暗号化されたデータブロックです。これらのブロックは、メタデータを含むブロック ヘッダーと、それに続くブロックの本体を構成するトランザクションの長いリストで構成されます。ビットコインのブロック構造は次のとおりです。

ブロック ヘッダー

ブロック ヘッダーには、次のように、ブロックチェーン内の他のブロックとの接続情報、タイムスタンプ、ノンス、その他の情報が含まれます。識別子

ブロックには 2 つの識別子があり、1 つはブロックヘッダーのハッシュ値、もう 1 つはブロックの高さです。ブロックヘッダのハッシュ値は、ブロックヘッダをSHA256アルゴリズムで2回ハッシュ化した数値です。ブロック ハッシュ値はブロックを一意かつ明確に識別し、どのノードもブロック ヘッダーをハッシュするだけでブロック ハッシュ値を独立して取得できます。ブロックの高さは、ブロックチェーン内のブロックの位置を指します。ブロックの高さは一意の識別子ではありません。単一のブロックは常に明確で固定されたブロックの高さを持ちますが、その逆は当てはまらず、ブロックの高さが必ずしも単一のブロックを識別するとは限りません。 2 つ以上のブロックが同じブロック高さを持ち、ブロックチェーン内の同じ位置をめぐって競合する場合があります。

上記の基本を理解したら、Python を使用して簡単なブロックチェーンを実装してみましょう。

ブロックチェーンのPython実装

1. ブロック構造を定義します[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)
ログイン後にコピー

上記はブロック構造であり、ここで実装されているのは簡易版です。ビットコインのブロックに正確に対応するものはありません。ここでのブロックには、一意の識別子、親ノードのハッシュ値、ノンス値、およびブロックのコンテンツ フィールドが含まれます。ブロックのハッシュ値が有効であるためには、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;
ログイン後にコピー
ハッシュは更新されましたが、まだ有効なハッシュではありません。有効なハッシュ値を取得するには、ノンス値を継続的に更新する処理、つまりマイニング処理が必要です。以下の 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 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート