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

简介:

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

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

而在本篇文章,抛开介绍区块链的技术特点和应用场景,文摘菌手把手的教大家如何用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')

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

 
app = Flask(__name__)

下面我们定义了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')

下面我们定义一个生成钱包(私有/公钥对)的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

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
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.

       """

       ...

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

app = Flask(__name__)

CORS(app)

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

blockchain = Blockchain()

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

@app.route('/')

def index():

   return render_template('./index.html')



@app.route('/configure')

def configure():

return render_template('./configure.html')

下面我们定义了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

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

d7daa29240f74ef871fe48e83f96287c7d9dc6d0


结论

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


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

本文作者:文摘菌

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

相关文章
|
1月前
|
算法 数据可视化 Python
Python中利用遗传算法探索迷宫出路
本文探讨了如何利用Python和遗传算法解决迷宫问题。迷宫建模通过二维数组实现,0表示通路,1为墙壁,&#39;S&#39;和&#39;E&#39;分别代表起点与终点。遗传算法的核心包括个体编码(路径方向序列)、适应度函数(评估路径有效性)、选择、交叉和变异操作。通过迭代优化,算法逐步生成更优路径,最终找到从起点到终点的最佳解决方案。文末还展示了结果可视化方法及遗传算法的应用前景。
|
1月前
|
存储 监控 算法
基于 Python 哈希表算法的局域网网络监控工具:实现高效数据管理的核心技术
在当下数字化办公的环境中,局域网网络监控工具已成为保障企业网络安全、确保其高效运行的核心手段。此类工具通过对网络数据的收集、分析与管理,赋予企业实时洞察网络活动的能力。而在其运行机制背后,数据结构与算法发挥着关键作用。本文聚焦于 PHP 语言中的哈希表算法,深入探究其在局域网网络监控工具中的应用方式及所具备的优势。
71 7
|
1月前
|
存储 监控 算法
员工电脑监控场景下 Python 红黑树算法的深度解析
在当代企业管理范式中,员工电脑监控业已成为一种广泛采用的策略性手段,其核心目标在于维护企业信息安全、提升工作效能并确保合规性。借助对员工电脑操作的实时监测机制,企业能够敏锐洞察潜在风险,诸如数据泄露、恶意软件侵袭等威胁。而员工电脑监控系统的高效运作,高度依赖于底层的数据结构与算法架构。本文旨在深入探究红黑树(Red - Black Tree)这一数据结构在员工电脑监控领域的应用,并通过 Python 代码实例详尽阐释其实现机制。
46 6
|
1月前
|
运维 监控 算法
基于 Python 迪杰斯特拉算法的局域网计算机监控技术探究
信息技术高速演进的当下,局域网计算机监控对于保障企业网络安全、优化资源配置以及提升整体运行效能具有关键意义。通过实时监测网络状态、追踪计算机活动,企业得以及时察觉潜在风险并采取相应举措。在这一复杂的监控体系背后,数据结构与算法发挥着不可或缺的作用。本文将聚焦于迪杰斯特拉(Dijkstra)算法,深入探究其在局域网计算机监控中的应用,并借助 Python 代码示例予以详细阐释。
57 6
|
2月前
|
人工智能 编解码 算法
如何在Python下实现摄像头|屏幕|AI视觉算法数据的RTMP直播推送
本文详细讲解了在Python环境下使用大牛直播SDK实现RTMP推流的过程。从技术背景到代码实现,涵盖Python生态优势、AI视觉算法应用、RTMP稳定性及跨平台支持等内容。通过丰富功能如音频编码、视频编码、实时预览等,结合实际代码示例,为开发者提供完整指南。同时探讨C接口转换Python时的注意事项,包括数据类型映射、内存管理、回调函数等关键点。最终总结Python在RTMP推流与AI视觉算法结合中的重要性与前景,为行业应用带来便利与革新。
126 5
|
2月前
|
存储 监控 算法
基于 Python 哈希表算法的员工上网管理策略研究
于当下数字化办公环境而言,员工上网管理已成为企业运营管理的关键环节。企业有必要对员工的网络访问行为予以监控,以此确保信息安全并提升工作效率。在处理员工上网管理相关数据时,适宜的数据结构与算法起着举足轻重的作用。本文将深入探究哈希表这一数据结构在员工上网管理场景中的应用,并借助 Python 代码示例展开详尽阐述。
55 3
|
2月前
|
人工智能 监控 算法
Python下的毫秒级延迟RTSP|RTMP播放器技术探究和AI视觉算法对接
本文深入解析了基于Python实现的RTSP/RTMP播放器,探讨其代码结构、实现原理及优化策略。播放器通过大牛直播SDK提供的接口,支持低延迟播放,适用于实时监控、视频会议和智能分析等场景。文章详细介绍了播放控制、硬件解码、录像与截图功能,并分析了回调机制和UI设计。此外,还讨论了性能优化方法(如硬件加速、异步处理)和功能扩展(如音量调节、多格式支持)。针对AI视觉算法对接,文章提供了YUV/RGB数据处理示例,便于开发者在Python环境下进行算法集成。最终,播放器凭借低延迟、高兼容性和灵活扩展性,为实时交互场景提供了高效解决方案。
155 4
|
2月前
|
存储 算法 文件存储
探秘文件共享服务之哈希表助力 Python 算法实现
在数字化时代,文件共享服务不可或缺。哈希表(散列表)通过键值对存储数据,利用哈希函数将键映射到特定位置,极大提升文件上传、下载和搜索效率。例如,在大型文件共享平台中,文件名等信息作为键,物理地址作为值存入哈希表,用户检索时快速定位文件,减少遍历时间。此外,哈希表还用于文件一致性校验,确保传输文件未被篡改。以Python代码示例展示基于哈希表的文件索引实现,模拟文件共享服务的文件索引构建与检索功能。哈希表及其分布式变体如一致性哈希算法,保障文件均匀分布和负载均衡,持续优化文件共享服务性能。
|
2月前
|
监控 算法 安全
公司电脑网络监控场景下 Python 广度优先搜索算法的深度剖析
在数字化办公时代,公司电脑网络监控至关重要。广度优先搜索(BFS)算法在构建网络拓扑、检测安全威胁和优化资源分配方面发挥重要作用。通过Python代码示例展示其应用流程,助力企业提升网络安全与效率。未来,更多创新算法将融入该领域,保障企业数字化发展。
77 10
|
2月前
|
监控 算法 安全
基于 Python 广度优先搜索算法的监控局域网电脑研究
随着局域网规模扩大,企业对高效监控计算机的需求增加。广度优先搜索(BFS)算法凭借其层次化遍历特性,在Python中可用于实现局域网内的计算机设备信息收集、网络连接状态监测及安全漏洞扫描,确保网络安全与稳定运行。通过合理选择数据结构与算法,BFS显著提升了监控效能,助力企业实现智能化的网络管理。
48 7

热门文章

最新文章