Python学习入门之区块链详解

作者:101python 时间:2021-07-15 18:21:55 

前言

本文将给大家简单介绍关于区块链(BlockChain)的相关知识,并用Python做一简单实现。下面话不多说,来一起看看详细的介绍:

什么是区块链

简单来说,区块链就是把加密数据(区块)按照时间顺序进行叠加(链)生成的永久、不可逆向修改的记录。具体来说,它区块链是由一串使用密码学方法产生的数据块组成的,每一个区块都包含了上一个区块的哈希值(hash),从创始区块(genesis block)开始连接到当前区块,形成块链。每一个区块都确保按照时间顺序在上一个区块之后产生,否则前一个区块的哈希值是未知的。它是比特币的一个重要概念。

特点

区块链有如下特点:

  • 去中心化:区块链不依赖于某个中心节点,而是依赖于分布式的各个节点。

  • 无须信任系统:区块链中基于密码学算法,数据需要网络内其他用户的批准,所以不需要一套第三方中介结构或信任机构背书。

  • 不可篡改和加密安全性:区块链采取单向哈希算法,同时每个新产生的区块严格按照时间线形顺序推进,时间的不可逆性导致任何试图入侵篡改区块链内数据 信息的行为都很容易被追溯,导致被其他节点的排斥,从而可以限制相关不法行为。

以上特点使得区块链在银行、证券市场和金融等诸多领域有着越来越多的应用。

区块链工作原理

区块链式一系列加密的数据块。这些区块由一个包含元数据的区块头和紧跟其后的构成区块主体的一长串交易组成。比特币中的区块结构如下:

Python学习入门之区块链详解

区块头

区块头中包含了与区块链中其它区块中的连接信息、时间戳和nonce等信息,具体如下:

Python学习入门之区块链详解

区块标识符

区块有两个标示符,一是区块头的哈希值,二是区块高度。区块头的哈希值是通过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 'Block<Hash: {}, Nonce: {}>'.format(self.hash(), self.nonce)

In [37]:


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

block = Block('Hello World')
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]:


'a6431938ba10270dfcfdf7a2371312446914fedadf79632c2c0adb3b463f4838'

哈希值更新了,但还不是有效的哈希值。为了得到有效哈希值,是一个不断更新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):
 '''
 计算区块的哈希值
 '''
 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 'Block<Hash: {}, Nonce: {}>'.format(self.hash(self.nonce), self.nonce)

'''
 新增挖矿函数
'''
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('Hello World')

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

# 打印
block

Out[75]:


Block<Hash: 000087359d5264153d624556f0a0c6f25cba06e453975c1c02587862e823911b, Nonce: 64751>

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

二、定义区块链结构

In [81]:


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

'''
 添加区块函数
'''
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
 )

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

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>

来源:https://ask.hellobi.com/blog/101python/8978

标签:python,区块链
0
投稿

猜你喜欢

  • 如何实现vue的tree组件

    2024-05-09 15:17:32
  • URL编码“陷阱”

    2008-03-04 16:57:00
  • django+celery+RabbitMQ自定义多个消息队列的实现

    2021-01-21 16:52:10
  • python实现录音功能(可随时停止录音)

    2023-07-29 05:15:06
  • python脚本调用iftop 统计业务应用流量的思路详解

    2022-02-07 02:37:12
  • MySQL事务控制流与ACID特性

    2024-01-24 23:03:50
  • 用ASP木马实现FTP和解压缩

    2008-02-13 08:47:00
  • SQL Server和MySql中创建临时表

    2008-06-19 13:31:00
  • 用python对excel查重

    2022-03-09 05:21:47
  • vue 打包后的文件部署到express服务器上的方法

    2024-05-09 09:33:05
  • 解析:快速的掌握 MySQL支持的操作系统

    2008-12-31 17:18:00
  • Sql Server 索引使用情况及优化的相关Sql语句分享

    2012-06-06 19:49:36
  • tensorflow之获取tensor的shape作为max_pool的ksize实例

    2022-10-09 01:41:53
  • Python 内置函数速查表一览

    2021-10-30 07:43:06
  • opencv+pyQt5实现图片阈值编辑器/寻色块阈值利器

    2023-09-10 11:22:34
  • 用Python写飞机大战游戏之pygame入门(4):获取鼠标的位置及运动

    2023-09-28 11:01:21
  • Pytorch Tensor的索引与切片例子

    2022-12-08 16:28:10
  • 基于Python-Pycharm实现的猴子摘桃小游戏(源代码)

    2023-07-07 06:31:22
  • asp.net cookie清除的代码

    2023-07-19 15:24:37
  • MYSQL建立外键失败几种情况记录Can't create table不能创建表

    2024-01-22 19:57:22
  • asp之家 网络编程 m.aspxhome.com