当前位置:   article > 正文

创建一个区块链,是由三个节点组成的去中心化网络。

创建一个区块链,是由三个节点组成的去中心化网络。

目录

一、准备工作:

1、创建三个python文件:

2、创建nodes.json文件

3、transaction.json文件

4、打开三个控制台

二、在三个节点上进行交互。

二、添加交易发布请求(a向b发送10000coin)


一、准备工作:

1、创建三个python文件:

lancoin_node_5001.py、lancoin_node_5002.py、lancoin_node_5003.py。

它们每个都将连接到不同的端口,一个端口用于a,一个端口用于b,一个端口用于c。

a在端口5001上,b在端口5002上,c在端口5003上

代码示例(lancoin_node_5001.py):

  1. # Module 1 -Create a Cryptocurrency
  2. #To be installed:
  3. #Flask==0.12.2:pip install Flask==0.12.2
  4. #Postman HTrp Client:https://www.getpostman.com
  5. #requests==2.18.4:pip install requests=-2.18.4
  6. #时间戳
  7. import datetime
  8. import hashlib
  9. import json
  10. #Flask可以定义Web应用的路由(URL到Python函数的映射),并处理HTTP请求和响应。jsonify是一个函数,用于将Python对象转换为JSON格式的响应。当你在Flask路由函数中返回一个jsonify对象时,Flask会自动将该对象对应的数据转换为JSON格式,并设置合适的HTTP响应头,以便客户端可以正确解析响应内容。
  11. from flask import Flask, jsonify,request
  12. import requests
  13. from uuid import uuid4
  14. from urllib.parse import urlparse
  15. # 1******Building a Blockchain
  16. class Blockchain:
  17. def __init__(self):
  18. self.transactions=[]
  19. self.chain=[]
  20. self.create_block(proof=1,previous_hash='0')
  21. self.nodes=set()
  22. def create_block(self,proof,previous_hash):
  23. block={'index':len(self.chain)+1,
  24. 'timestamp':str(datetime.datetime.now()),
  25. 'proof':proof,
  26. 'previous_hash':previous_hash,
  27. 'transactions':self.transactions}
  28. self.transactions=[]
  29. self.chain.append(block)
  30. return block
  31. def get_previous_block(self):
  32. return self.chain[-1]
  33. def proof_of_work(self,previous_proof):
  34. new_proof=1
  35. check_proof=False
  36. while check_proof is False:
  37. hash_oparation=hashlib.sha256(str(new_proof**2-previous_proof**2).encode()).hexdigest()
  38. if hash_oparation[:4]=='0000':
  39. check_proof=True
  40. else:
  41. new_proof+=1
  42. return new_proof
  43. def hash(self, block):
  44. encode_block = json.dumps(block, sort_keys=True).encode()
  45. return hashlib.sha256(encode_block).hexdigest()
  46. def is_chain_valid(self,chain):
  47. previous_block=chain[0]
  48. block_index=1
  49. while block_index<len(chain):
  50. block=chain[block_index]
  51. if block['previous_hash'] !=self.hash(previous_block):
  52. return False
  53. previous_proof=previous_block['proof']
  54. proof=block['proof']
  55. hash_oparation=hashlib.sha256(str(proof**2-previous_proof**2).encode()).hexdigest()
  56. if hash_oparation[:4] !='0000':
  57. return False
  58. previous_block=block
  59. block_index+=1
  60. return True
  61. def add_transaction(self,sender,receiver,amount):
  62. self.transactions.append({'sender':sender,
  63. 'receiver':receiver,
  64. 'amount':amount})
  65. previous_block=self.get_previous_block()
  66. return previous_block['index']+1
  67. def add_node(self,address):
  68. parsed_url=urlparse(address)
  69. self.nodes.add(parsed_url.netloc)
  70. def replace_chain(self):
  71. network = self.nodes
  72. longest_chain = None
  73. max_length = len(self.chain)
  74. for node in network:
  75. try:
  76. response = requests.get(f'http://{node}/get_chain')
  77. response.raise_for_status() # 这将抛出异常,如果请求失败
  78. except requests.exceptions.RequestException as e:
  79. print(f"Failed to get the chain from {node}. Exception: {e}")
  80. continue
  81. if response.status_code == 200:
  82. length = response.json()['length']
  83. chain = response.json()['chain']
  84. if length > max_length and self.is_chain_valid(chain):
  85. max_length = length
  86. longest_chain = chain
  87. if longest_chain:
  88. self.chain = longest_chain
  89. return True
  90. return False
  91. #Part 2 -Mining our Blockchain
  92. #Creating a Web App
  93. app = Flask(__name__)
  94. #Creating an address for the node on Port 5000
  95. node_address=str(uuid4()).replace('-', '')
  96. #Creating a Blockchain
  97. blockchain=Blockchain()
  98. #Mining a new block
  99. @app.route('/mine_block',methods=['GET'])
  100. def mine_block():
  101. previous_block=blockchain.get_previous_block()
  102. previous_proof=previous_block['proof']
  103. proof=blockchain.proof_of_work(previous_proof)
  104. previous_hash=blockchain.hash(previous_block)
  105. blockchain.add_transaction(sender=node_address,receiver='a',amount=1)
  106. block=blockchain.create_block(proof, previous_hash)
  107. response={'message':'Congratulation,you just mined a block',
  108. 'index':block['index'],
  109. 'timestamp':block['timestamp'],
  110. 'proof':block['proof'],
  111. 'previous_hash':block['previous_hash'],
  112. 'transactions':block['transactions']}
  113. return jsonify(response),200
  114. #Getting the full Blockchain
  115. @app.route('/get_chain',methods=['GET'])
  116. def get_chain():
  117. response={'chain':blockchain.chain,
  118. 'length':len(blockchain.chain)}
  119. return jsonify(response),200
  120. #Checking if the Blockchain is valid
  121. @app.route('/is_valid',methods=['GET'])
  122. def get_valid():
  123. is_valid=blockchain.is_chain_valid(blockchain.chain)
  124. if is_valid:
  125. response={'message':'All good. The Blockchain is valid.'}
  126. else:
  127. response={'message':'Houston,we have a problem.The Blockchain is not valid.'}
  128. return jsonify(response),200
  129. #Addling a new transaction to the Blockchain
  130. @app.route('/add_transaction',methods=['POST'])
  131. def add_transaction():
  132. json =request.get_json()
  133. transaction_keys=['sender','receiver','amount']
  134. if not all(key in json for key in transaction_keys):
  135. return 'Some elements of the transaction are missing',400
  136. index=blockchain.add_transaction(json['sender'], json['receiver'],json['amount'])
  137. response={'message':f'This transaction will be added to Block {index}'}
  138. return jsonify(response),201
  139. #Connecting new nodes
  140. @app.route('/connect_node', methods=['POST'])
  141. def connect_node():
  142. json = request.get_json()
  143. nodes = json.get('nodes')
  144. if nodes is None:
  145. return "No nodes provided", 400
  146. for node in nodes:
  147. blockchain.add_node(node)
  148. # 将响应构建移到循环外,并在所有节点添加后才返回
  149. response = {
  150. 'message': 'All the nodes are now connected. The Lancoin Blockchain now contains the following nodes:',
  151. 'total_nodes': list(blockchain.nodes)
  152. }
  153. return jsonify(response), 201
  154. #Replacing the chain by the longest chain if needed
  155. @app.route('/replace_chain', methods=['GET'])
  156. def replace_chain():
  157. is_chain_replaced = blockchain.replace_chain()
  158. if is_chain_replaced:
  159. response = {
  160. 'message': 'The nodes had different chains so the chain was replaced by the longest one.',
  161. 'new_chain': blockchain.chain
  162. }
  163. else:
  164. response = {
  165. 'message': 'All good. the chain is the largest one.',
  166. 'actual_chain': blockchain.chain
  167. }
  168. return jsonify(response), 200
  169. app.run(host='0.0.0.0',port=5001)

lancoin_node_5002.py、lancoin_node_5003.py则是lancoin_node_5001.py中的mine_block函数的blockchain.add_transaction(sender=node_address,receiver='a',amount=1),a改为b、c,然后app.run(host='0.0.0.0',port=5001)中的5001改为5002、5003


2、创建nodes.json文件

  1. {
  2. "nodes":["http://127.0.0.1:5001",
  3. "http://127.0.0.1:5002",
  4. "http://127.0.0.1:5003"]
  5. }

3、transaction.json文件

  1. {
  2. "sender":"",
  3. "receiver":"",
  4. "amount":
  5. }

4、打开三个控制台

在这里我用的是Spyder编译器,打开三个控制台,分别在控制台是运行各节点,控制台1运行5001节点,控制台2运行5002节点,控制台3运行5003节点,如图所示


二、在三个节点上进行交互。

(1)跳转到postman,创建三个测试,分别对应5001、5002、5003节点


(2)获取链来查看创世区块是否创建良好http://127.0.0.1:5001/get_chainhttp://127.0.0.1:5002/get_chainhttp://127.0.0.1:5003/get_chain

以5001为例子


(3)发出第一个请求(post),将发出我们的第一个发布请求以将节点相互连接。

我们现在想做的是连接节点,因此我将返回到nodes.json文件,复制后返回postman发出请求,

按照图内,将三个都按照图上进行相应的修改


(4)测试共识

首先在5001节点(也就是a)上挖一个块

可以通过获取链请求(get_chain)来查看它,就会发现我的新链

然后在5002节点上(也就是b)、5003节点(也就是a)选择替换链请求。下面以5002为例子


二、添加交易发布请求(a向b发送10000coin)

(1)先选择post请求,点开transaction.json文件,复制以后回到postman,在5001节点上,如图


2)然后再5001界面get一个http://127.0.0.1:5001/mine_block。创建这个包含两笔交易的新区块,其中一笔交易与我刚刚开采了这个新区块并因此给我一个addcoin有关,当然还有a给b的交易,给b10000coin


(3)查看5001是否开采区块,3个区块,如图


(4)查看5002的区块,2个区块


(5)查看5003的区块,2个区块


(6)达成共识,以确保区块链中的每个节点都具有相同的链。在postman的5002节点界面再运行一遍http://127.0.0.1:5002/replace_chain(get),然后在5003节点界面运行http://127.0.0.1:5003/replace_chain,然后5002、5003节点也会有3个节点


(7)最后在三个节点中分别get请求一下get_chain,以检查是否具有相同的链。以5002为例


注:本篇用的代码解释都可在我以往的文章中找到

创建一个简单的区块链,并使用 Flask 框架提供一个简单的 Web 接口来与区块链交互。(持续更新)-CSDN博客

使用了Python语言和Flask框架。创建一个区块链网络,允许用户通过HTTP请求进行交互,如包括创建区块链、挖矿、验证区块链等功能。-CSDN博客

使用Python,结合Flask框架,创建一个可以处理交易、挖矿新区块、验证区块链有效性,并能在网络节点间同步的区块链网络。(持续更新)-CSDN博客

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/512493
推荐阅读
相关标签
  

闽ICP备14008679号