手把手:用Python实现一个基于RSA算法的区块链客户端

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介:

区块链作为比特币和其他加密货币的核心技术,在最近几年引起了全世界的注意,但是各国这一颠覆性的技术态度不一,因为其去中心化的分布式结构,可以使用户之间直接进行交流,无需中心节点参与的这种技术模式对银行、证券等机构带来了极大影响。

区块链的技术模式和各国对区块链的态度:

而在本篇文章,抛开介绍区块链的技术特点和应用场景,文摘菌手把手的教大家如何用python实现一个基础的区块链,和一个区块链的客户端。

我们实现的区块链有如下几个特性:

  • 可以向区块链中添加多个节点。

  • 工作量证明(PoW)。

  • 简单的节点间冲突解决机制。

  • 使用RSA 加密进行交易。

我们的区块链客户端有如下几个功能:

  • 使用公钥/私钥加密技术生成钱包。(基于RSA算法)。

  • 使用RSA 加密算法生成交易。

我们还实现了2个展示界面:

  • 挖矿者使用的“区块链前端”

  • 用户生成钱包和发币的“区块链客户端”

我在原始代码的基础上进行了一些改动,向交易中加入了RSA加密,并实现了钱包生成和交易加密,两个界面使用HTML/CSS/JS 实现。

完整的项目代码:

https://github.com/adilmoujahid/blockchain-python-tutorial

请注意,这个实现是用于教学目的,所以它不适用于生产环境。因为它保密性不够,且缺乏一些重要的特性。

区块链客户端实现

你可以从终端启动区块链客户端。进入blockchain_client文件夹,并输入命令:python blockchain_client.py。

在浏览器中打开http://localhost:8080,接下来你会看到如下展示界面。

0eb50913043dd92a0f73e9ee57f5ca932e80571f

展示界面导航栏有3个标签:

  • 钱包生成器:使用RSA加密算法生成钱包(公钥/私钥对)。

  • 生成交易:生成交易并将其发送到区块链节点。

  • 查看交易:查看区块链上的交易。

要想生成交易或查看交易,至少需要一个区块链节点在运行(将在下一节中介绍)。

blockchain_client.py文件代码中一些重要部分的说明:我们定义了一个Python类,我们命名了4个属性字段:sender_address,sender_private_key,recipient_address,value。

这是发送方创建交易所需的4个信息。

to_dict()方法返回一个Python字典格式交易信息(没有发件人的私钥)。

sign_transaction()方法接收交易信息(没有发件人的私钥),然后使用发送者的私钥进行签名。

 
class Transaction:

   def __init__(self, sender_address, sender_private_key, recipient_address, value):

       self.sender_address = sender_address

       self.sender_private_key = sender_private_key

       self.recipient_address = recipient_address

       self.value = value



   def __getattr__(self, attr):

       return self.data[attr]



   def to_dict(self):

       return OrderedDict({'sender_address': self.sender_address,

                           'recipient_address': self.recipient_address,

                           'value': self.value})



   def sign_transaction(self):

       """

       Sign transaction with private key

       """

       private_key = RSA.importKey(binascii.unhexlify(self.sender_private_key))

       signer = PKCS1_v1_5.new(private_key)

       h = SHA.new(str(self.to_dict()).encode('utf8'))

       return binascii.hexlify(signer.sign(h)).decode('ascii')
AI 代码解读

下面是初始化一个Python Flask应用的代码行, 我们将用它来创建不同的API来与区块链及其客户进行交互。

 
app = Flask(__name__)
AI 代码解读

下面我们定义了3个返回HTML页面的Flask路径,其中每个标签都有一个html页面。

@app.route('/')

def index():

 return render_template('./index.html')



@app.route('/make/transaction')

def make_transaction():

   return render_template('./make_transaction.html')



@app.route('/view/transactions')

def view_transaction():

return render_template('./view_transactions.html')
AI 代码解读

下面我们定义一个生成钱包(私有/公钥对)的API。

@app.route('/wallet/new', methods=['GET'])

def new_wallet():

 random_gen = Crypto.Random.new().read

 private_key = RSA.generate(1024, random_gen)

 public_key = private_key.publickey()

 response = {

   'private_key': binascii.hexlify(private_key.exportKey(format='DER')).decode('ascii'),

   'public_key': binascii.hexlify(public_key.exportKey(format='DER')).decode('ascii')

 }

 return jsonify(response), 200
AI 代码解读

5c30e86b49a7bf9ff9845e9e989524661dac8873

下面我们定义一个API,将sender_address, sender_private_key, recipient_address, value字段作为输入,并返回交易(没有私钥)和签名。

@app.route('/generate/transaction', methods=['POST'])

def generate_transaction():

 sender_address = request.form['sender_address']

 sender_private_key = request.form['sender_private_key']

 recipient_address = request.form['recipient_address']

 value = request.form['amount']

 transaction = Transaction(sender_address, sender_private_key, recipient_address, value)

 response = {'transaction': transaction.to_dict(), 'signature': transaction.sign_transaction()}

 return jsonify(response), 200
AI 代码解读
0723f7646a0bf3f4ea8c16f5473e32ecebd1329b

区块链的实现

你可以从终端启动区块链节点,通过进入blockchain文件夹,并输入命令:python blockchain_client.py或python blockchain_client.py -p <PORT NUMBER> 。如果你未指定端口号,则会默认端口号为5000。在浏览器中打开http://localhost:<PORT NUMBER>可以看到区块链前端展示界面。

4a9cb78b36637ffbf7b11fe51cacfd6eb65d14e4

展示界面导航栏有两个标签:

  • 挖掘:用于查看交易和区块链数据,以及挖掘新的交易区块。

  • 配置:用于配置不同区块链节点之间的连接。

下面是blockchain.py文件代码中一些重要部分的说明。

我们首先定义一个具有以下属性的Blockchain类:

  • transactions:将被添加到下一区块的交易列表。

  • chain::实际的区块链,也就是一个区块数组。

  • nodes:一个包含节点URL的集合。区块链使用这些节点从其他节点中检索区块链数据并且在检查到它们没有同步时更新其区块链。

  • node_id:一个标识blockchain节点的随机字符串。

这个Blockchain类还实现了以下方法:

  • register_node(node_url): 将新的区块链节点添加到节点列表中。

  • verify_transaction_signature(sender_address, signature, transaction): 检查提供的签名是否与通过公钥(sender_address)签署的交易相符。

  • submit_transaction(sender_address, recipient_address, value, signature): 如果签名通过验证,则将交易添加到交易列表中。

  • create_block(nonce, previous_hash):向区块链添加一个交易块。

  • hash(block): 创建一个区块的SHA-256散列。

  • proof_of_work():工作算法的证明。寻找满足挖掘条件的随机数。

  • valid_proof(transactions, last_hash, nonce, difficulty=MINING_DIFFICULTY):检查散列值是否满足挖掘条件。该函数在proof_of_work函数中使用。

  • valid_chain(chain): 检查区块链是否有效。

  • resolve_conflicts():通过用网络中最长链代替链的方法解决区块链节点之间的冲突。

 
class Blockchain:

   def __init__(self):

       self.transactions = []

       self.chain = []

       self.nodes = set()

       #Generate random number to be used as node_id

       self.node_id = str(uuid4()).replace('-', '')

       #Create genesis block

       self.create_block(0, '00')



   def register_node(self, node_url):

       """

       Add a new node to the list of nodes

       """

       ...

       

   def verify_transaction_signature(self, sender_address, signature, transaction):

       """

       Check that the provided signature corresponds to transaction



       signed by the public key (sender_address)

       """

       ...



   def submit_transaction(self, sender_address, recipient_address, value, signature):

       """

       Add a transaction to transactions array if the signature verified

       """

       ...



   def create_block(self, nonce, previous_hash):

       """

       Add a block of transactions to the blockchain

       """

        ...



   def hash(self, block):

       """

       Create a SHA-256 hash of a block

       """

       ...



   def proof_of_work(self):

       """

       Proof of work algorithm

       """

       ...



   def valid_proof(self, transactions, last_hash, nonce, difficulty=MINING_DIFFICULTY):

       """

       Check if a hash value satisfies the mining conditions. This function is used within the proof_of_work function.

       """

       ...



   def valid_chain(self, chain):

       """

       check if a bockchain is valid

       """

       ...



   def resolve_conflicts(self):

       """

       Resolve conflicts between blockchain's nodes

       by replacing our chain with the longest one in the network.

       """

       ...
AI 代码解读

下面这一行,我们初始化了一个Python Flask 应用,用于创建和区块链交互的API。

app = Flask(__name__)

CORS(app)
AI 代码解读

下面,我们初始化一个区块链对象。

blockchain = Blockchain()
AI 代码解读

下面我们定义了2种返回我们区块链前端展示界面html页面的Flask路线。

@app.route('/')

def index():

   return render_template('./index.html')



@app.route('/configure')

def configure():

return render_template('./configure.html')
AI 代码解读

下面我们定义了Flask API来管理交易和挖掘区块链。

此API将'sender_address', 'recipient_address', 'amount' 和 'signature' 作为输入,并且如果签名有效,则将交易添加到将添加到下一个块的交易列表中。

  • '/transactions/get':此API返回所有将会添加到下一个块的交易。

  • '/chain':此API返回所有区块链数据。

  • '/mine': 此API运行工作算法的证明,同时添加新的交易块到区块链。

 

@app.route('/transactions/new', methods=['POST'])

def new_transaction():

   values = request.form

   # Check that the required fields are in the POST'ed data

   required = ['sender_address', 'recipient_address', 'amount', 'signature']

   if not all(k in values for k in required):

       return 'Missing values', 400

   # Create a new Transaction

   transaction_result = blockchain.submit_transaction(values['sender_address'], values['recipient_address'], values['amount'], values['signature'])

   if transaction_result == False:

       response = {'message': 'Invalid Transaction!'}

       return jsonify(response), 406

   else:

       response = {'message': 'Transaction will be added to Block '+ str(transaction_result)}

       return jsonify(response), 201



@app.route('/transactions/get', methods=['GET'])

def get_transactions():

   #Get transactions from transactions pool

   transactions = blockchain.transactions

   response = {'transactions': transactions}

   return jsonify(response), 200



@app.route('/chain', methods=['GET'])

def full_chain():

   response = {

       'chain': blockchain.chain,

       'length': len(blockchain.chain),

   }

   return jsonify(response), 200

@app.route('/mine', methods=['GET'])

def mine():

   # We run the proof of work algorithm to get the next proof...

   last_block = blockchain.chain[-1]

   nonce = blockchain.proof_of_work()

   # We must receive a reward for finding the proof.

   blockchain.submit_transaction(sender_address=MINING_SENDER, recipient_address=blockchain.node_id, value=MINING_REWARD, signature="")

   # Forge the new Block by adding it to the chain

   previous_hash = blockchain.hash(last_block)

   block = blockchain.create_block(nonce, previous_hash)

   response = {

       'message': "New Block Forged",

       'block_number': block['block_number'],

       'transactions': block['transactions'],

       'nonce': block['nonce'],

       'previous_hash': block['previous_hash'],

   }

return jsonify(response), 200
AI 代码解读

629746aa24ba3c4a2ca83f743b41aa58ef4ca097

下面我们定义Flask API来管理区块链节点。

  • '/nodes/register':此API将节点URL列表作为输入,同时添加URL到节点列表。

  • '/nodes/resolve':此API通过使用网络中最长的可用链替代本地链的方式解决区块链节点间的冲突。

  • '/nodes/get':此API返回节点列表。

 

@app.route('/nodes/register', methods=['POST'])

def register_nodes():

   values = request.form

   nodes = values.get('nodes').replace(" ", "").split(',')

   if nodes is None:

       return "Error: Please supply a valid list of nodes", 400

   for node in nodes:

       blockchain.register_node(node)

   response = {

       'message': 'New nodes have been added',

       'total_nodes': [node for node in blockchain.nodes],

   }

   return jsonify(response), 201



@app.route('/nodes/resolve', methods=['GET'])

def consensus():

   replaced = blockchain.resolve_conflicts()

   if replaced:

       response = {

           'message': 'Our chain was replaced',

           'new_chain': blockchain.chain

       }

   else:

       response = {

           'message': 'Our chain is authoritative',

           'chain': blockchain.chain

       }

   return jsonify(response), 200

@app.route('/nodes/get', methods=['GET'])

def get_nodes():

   nodes = list(blockchain.nodes)

   response = {'nodes': nodes}

return jsonify(response), 200
AI 代码解读

d7daa29240f74ef871fe48e83f96287c7d9dc6d0


结论

在此篇文章中,我们介绍了涉及区块链背后一些核心概念,并且学习如何用Python实现一个区块链。为了简单起见,此文没有涉及一些技术细节,例如:钱包地址和Merkle树。如果你想了解有关该主题的更多信息,我建议阅读比特币白皮书原著,并跟着比特币维基和Andreas Antonopoulos的优秀书籍学习:掌握比特币:编程开放区块链。


原文发布时间为:2018-04-4

本文作者:文摘菌

本文来自云栖社区合作伙伴“大数据文摘”,了解相关信息可以关注“大数据文摘”微信公众号

目录
打赏
0
0
0
0
73515
分享
相关文章
深度洞察内网监控电脑:基于Python的流量分析算法
在当今数字化环境中,内网监控电脑作为“守城卫士”,通过流量分析算法确保内网安全、稳定运行。基于Python的流量分析算法,利用`scapy`等工具捕获和解析数据包,提取关键信息,区分正常与异常流量。结合机器学习和可视化技术,进一步提升内网监控的精准性和效率,助力企业防范潜在威胁,保障业务顺畅。本文深入探讨了Python在内网监控中的应用,展示了其实战代码及未来发展方向。
基于Python深度学习的眼疾识别系统实现~人工智能+卷积网络算法
眼疾识别系统,本系统使用Python作为主要开发语言,基于TensorFlow搭建卷积神经网络算法,并收集了4种常见的眼疾图像数据集(白内障、糖尿病性视网膜病变、青光眼和正常眼睛) 再使用通过搭建的算法模型对数据集进行训练得到一个识别精度较高的模型,然后保存为为本地h5格式文件。最后使用Django框架搭建了一个Web网页平台可视化操作界面,实现用户上传一张眼疾图片识别其名称。
82 4
基于Python深度学习的眼疾识别系统实现~人工智能+卷积网络算法
局域网屏幕监控系统中的Python数据结构与算法实现
局域网屏幕监控系统用于实时捕获和监控局域网内多台设备的屏幕内容。本文介绍了一种基于Python双端队列(Deque)实现的滑动窗口数据缓存机制,以处理连续的屏幕帧数据流。通过固定长度的窗口,高效增删数据,确保低延迟显示和存储。该算法适用于数据压缩、异常检测等场景,保证系统在高负载下稳定运行。 本文转载自:https://www.vipshare.com
124 66
控制局域网上网软件之 Python 字典树算法解析
控制局域网上网软件在现代网络管理中至关重要,用于控制设备的上网行为和访问权限。本文聚焦于字典树(Trie Tree)算法的应用,详细阐述其原理、优势及实现。通过字典树,软件能高效进行关键词匹配和过滤,提升系统性能。文中还提供了Python代码示例,展示了字典树在网址过滤和关键词屏蔽中的具体应用,为局域网的安全和管理提供有力支持。
33 17
|
11天前
|
员工电脑监控屏幕场景下 Python 哈希表算法的探索
在数字化办公时代,员工电脑监控屏幕是保障信息安全和提升效率的重要手段。本文探讨哈希表算法在该场景中的应用,通过Python代码例程展示如何使用哈希表存储和查询员工操作记录,并结合数据库实现数据持久化,助力企业打造高效、安全的办公环境。哈希表在快速检索员工信息、优化系统性能方面发挥关键作用,为企业管理提供有力支持。
37 20
深度解密:员工飞单需要什么证据之Python算法洞察
员工飞单是企业运营中的隐性风险,严重侵蚀公司利润。为应对这一问题,精准搜集证据至关重要。本文探讨如何利用Python编程语言及其数据结构和算法,高效取证。通过创建Transaction类存储交易数据,使用列表管理订单信息,结合排序算法和正则表达式分析交易时间和聊天记录,帮助企业识别潜在的飞单行为。Python的强大功能使得从交易流水和沟通记录中提取关键证据变得更加系统化和高效,为企业维权提供有力支持。
U 盘管控情境下 Python 二叉搜索树算法的深度剖析与探究
在信息技术高度发达的今天,数据安全至关重要。U盘作为常用的数据存储与传输工具,其管控尤为关键。本文探讨Python中的二叉搜索树算法在U盘管控中的应用,通过高效管理授权U盘信息,防止数据泄露,保障信息安全。二叉搜索树具有快速插入和查找的优势,适用于大量授权U盘的管理。尽管存在一些局限性,如树结构退化问题,但通过优化和改进,如采用自平衡树,可以有效提升U盘管控系统的性能和安全性。
17 3
剖析文件共享工具背后的Python哈希表算法奥秘
在数字化时代,文件共享工具不可或缺。哈希表算法通过将文件名或哈希值映射到存储位置,实现快速检索与高效管理。Python中的哈希表可用于创建简易文件索引,支持快速插入和查找文件路径。哈希表不仅提升了文件定位速度,还优化了存储管理和多节点数据一致性,确保文件共享工具高效运行,满足多用户并发需求,推动文件共享领域向更高效、便捷的方向发展。
探秘Win11共享文件夹之Python网络通信算法实现
本文探讨了Win11共享文件夹背后的网络通信算法,重点介绍基于TCP的文件传输机制,并提供Python代码示例。Win11共享文件夹利用SMB协议实现局域网内的文件共享,通过TCP协议确保文件传输的完整性和可靠性。服务器端监听客户端连接请求,接收文件请求并分块发送文件内容;客户端则连接服务器、接收数据并保存为本地文件。文中通过Python代码详细展示了这一过程,帮助读者理解并优化文件共享系统。
探索企业文件管理软件:Python中的哈希表算法应用
企业文件管理软件依赖哈希表实现高效的数据管理和安全保障。哈希表通过键值映射,提供平均O(1)时间复杂度的快速访问,适用于海量文件处理。在Python中,字典类型基于哈希表实现,可用于管理文件元数据、缓存机制、版本控制及快速搜索等功能,极大提升工作效率和数据安全性。
65 0

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等