Advertisement
Guest User

Untitled

a guest
Jan 16th, 2018
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.20 KB | None | 0 0
  1. from flask import Flask
  2. from flask import request
  3. import json
  4. import requests
  5. import hashlib as hasher
  6. import datetime as date
  7. node = Flask(__name__)
  8.  
  9. # Define what a Snakecoin block is
  10. class Block:
  11. def __init__(self, index, timestamp, data, previous_hash):
  12. self.index = index
  13. self.timestamp = timestamp
  14. self.data = data
  15. self.previous_hash = previous_hash
  16. self.hash = self.hash_block()
  17.  
  18. def hash_block(self):
  19. sha = hasher.sha256()
  20. sha.update(str(self.index) + str(self.timestamp) + str(self.data) + str(self.previous_hash))
  21. return sha.hexdigest()
  22.  
  23. # Generate genesis block
  24. def create_genesis_block():
  25. # Manually construct a block with
  26. # index zero and arbitrary previous hash
  27. return Block(0, date.datetime.now(), {
  28. "proof-of-work": 9,
  29. "transactions": None
  30. }, "0")
  31.  
  32. # A completely random address of the owner of this node
  33. miner_address = "q3nf394hjg-random-miner-address-34nf3i4nflkn3oi"
  34. # This node's blockchain copy
  35. blockchain = []
  36. blockchain.append(create_genesis_block())
  37. # Store the transactions that
  38. # this node has in a list
  39. this_nodes_transactions = []
  40. # Store the url data of every
  41. # other node in the network
  42. # so that we can communicate
  43. # with them
  44. peer_nodes = []
  45. # A variable to deciding if we're mining or not
  46. mining = True
  47.  
  48. @node.route('/txion', methods=['POST'])
  49. def transaction():
  50. # On each new POST request,
  51. # we extract the transaction data
  52. new_txion = request.get_json()
  53. # Then we add the transaction to our list
  54. this_nodes_transactions.append(new_txion)
  55. # Because the transaction was successfully
  56. # submitted, we log it to our console
  57. print "New transaction"
  58. print "FROM: {}".format(new_txion['from'].encode('ascii','replace'))
  59. print "TO: {}".format(new_txion['to'].encode('ascii','replace'))
  60. print "AMOUNT: {}\n".format(new_txion['amount'])
  61. # Then we let the client know it worked out
  62. return "Transaction submission successful\n"
  63.  
  64. @node.route('/blocks', methods=['GET'])
  65. def get_blocks():
  66. chain_to_send = blockchain
  67. # Convert our blocks into dictionaries
  68. # so we can send them as json objects later
  69. for i in range(len(chain_to_send)):
  70. block = chain_to_send[i]
  71. block_index = str(block.index)
  72. block_timestamp = str(block.timestamp)
  73. block_data = str(block.data)
  74. block_hash = block.hash
  75. chain_to_send[i] = {
  76. "index": block_index,
  77. "timestamp": block_timestamp,
  78. "data": block_data,
  79. "hash": block_hash
  80. }
  81. chain_to_send = json.dumps(chain_to_send)
  82. return chain_to_send
  83.  
  84. def find_new_chains():
  85. # Get the blockchains of every
  86. # other node
  87. other_chains = []
  88. for node_url in peer_nodes:
  89. # Get their chains using a GET request
  90. block = requests.get(node_url + "/blocks").content
  91. # Convert the JSON object to a Python dictionary
  92. block = json.loads(block)
  93. # Add it to our list
  94. other_chains.append(block)
  95. return other_chains
  96.  
  97. def consensus():
  98. # Get the blocks from other nodes
  99. other_chains = find_new_chains()
  100. # If our chain isn't longest,
  101. # then we store the longest chain
  102. longest_chain = blockchain
  103. for chain in other_chains:
  104. if len(longest_chain) < len(chain):
  105. longest_chain = chain
  106. # If the longest chain isn't ours,
  107. # then we stop mining and set
  108. # our chain to the longest one
  109. blockchain = longest_chain
  110.  
  111. def proof_of_work(last_proof):
  112. # Create a variable that we will use to find
  113. # our next proof of work
  114. incrementor = last_proof + 1
  115. # Keep incrementing the incrementor until
  116. # it's equal to a number divisible by 9
  117. # and the proof of work of the previous
  118. # block in the chain
  119. while not (incrementor % 9 == 0 and incrementor % last_proof == 0):
  120. incrementor += 1
  121. # Once that number is found,
  122. # we can return it as a proof
  123. # of our work
  124. return incrementor
  125.  
  126. @node.route('/mine', methods = ['GET'])
  127. def mine():
  128. # Get the last proof of work
  129. last_block = blockchain[len(blockchain) - 1]
  130. last_proof = last_block.data['proof-of-work']
  131. # Find the proof of work for
  132. # the current block being mined
  133. # Note: The program will hang here until a new
  134. # proof of work is found
  135. proof = proof_of_work(last_proof)
  136. # Once we find a valid proof of work,
  137. # we know we can mine a block so
  138. # we reward the miner by adding a transaction
  139. this_nodes_transactions.append(
  140. { "from": "network", "to": miner_address, "amount": 1 }
  141. )
  142. # Now we can gather the data needed
  143. # to create the new block
  144. new_block_data = {
  145. "proof-of-work": proof,
  146. "transactions": list(this_nodes_transactions)
  147. }
  148. new_block_index = last_block.index + 1
  149. new_block_timestamp = this_timestamp = date.datetime.now()
  150. last_block_hash = last_block.hash
  151. # Empty transaction list
  152. this_nodes_transactions[:] = []
  153. # Now create the
  154. # new block!
  155. mined_block = Block(
  156. new_block_index,
  157. new_block_timestamp,
  158. new_block_data,
  159. last_block_hash
  160. )
  161. blockchain.append(mined_block)
  162. # Let the client know we mined a block
  163. return json.dumps({
  164. "index": new_block_index,
  165. "timestamp": str(new_block_timestamp),
  166. "data": new_block_data,
  167. "hash": last_block_hash
  168. }) + "\n"
  169.  
  170. node.run()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement