日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

Create your own blockchain amp; cryptocurrency! - understand blockchains by creating one in python

發布時間:2025/3/15 python 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Create your own blockchain amp; cryptocurrency! - understand blockchains by creating one in python 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

What exactly is a blockchain?

  • How does a blockchain work?
  • What is Bitcoin or STEEM exactly?
  • How does a blockchain make sure of its correctness
  • What is?mining?exactly?

These are only some questions, probably many of you are asking yourselves.
I'm here to provide you with kind of an unusual answer.
My goal is to help you undestand the whole system behind blockchains, by actually creating a small blockchain yourself!

With the rise of cryptocurrencies and decentralized systems like Bitcoin or STEEM, many people want to really undestand, what this is all about. I will show you how the system works, by coding a blockchain from scratch in python with you. The guide will be mainly for Windows, but I will also add comments regarding Linux. You don't know a whole of python, to follow this guide, but it is advised to know the most basic basics.

Get ready

Setup Python and pip

First off, we need to install Python 3.6+ along with pip, with which you can install python packages.

  • On?Linux, you can install python, by simply typing?sudo apt-get install python3.6?into the terminal. If you encounter errors, please try?sudo apt-get update?and then try to execute the command again. If it still doesn't work, please search for installation instructions for your specific system on your preferred search engine.
  • On?Windows,
  • first download the binary, that suits your system best, under the?official python download page for windows.. Make sure you grab at least the?version 3.6?or higher.
  • Install the file you just downloaded. Make sure you check the option to install pip, when provided with an option to do so. If not, don't worry, it probably is enabled by default.

IDE or not?

As a next step, you want to decide, whether to utilize an?IDE?or not. An IDE is an environment, which supports you in the creation process of your application, by providing many features, with for example syntax highlighting, or code completion, to name just 2 possible features. My favorite IDE for Python development is probably PyCharm, which you can fetch from?this link.?Setting up PyCharm on Windows is as simple, as downloading the executable installer and installing it with the provided setup utility. PyCharm is free tu use, as long as you use the Community Edition.
You can also use your coding notepad of choice. We will only work in one file, which you have to execute, so as long as your text-editing software is able to produce files with the ending?.py, it will work fine.

Setup your workspace (PyCharm)

If you decided to use PyCharm, simply open it up and click on?Create Project?in the popup dialogue. In the next dialogue you want to specify your project's name. I chose to use?MyBlockChain?as my project name. Finally click on?create?in the bottom right corner. On your left hand side, you're now provided with a file tree.

  • Right-Click on the folder which consists of your project's name, in my case?MyBlockChain
  • Go to?new
  • Finally click on?Python File?and
  • Define a Filename. I chose?MyBlockChain.py?as my filename.
  • Create your file (Simple Text Editor)

    If you use a simple text editor, just create a file anywhere you like with the file extension?.py. In my case I chose to use the filename?MyBlockChain.py.

    Install the needed packages

    PyCharm

    In PyCharm you can install packages very easily and add them to your project:

  • Make sure, you have your project open
  • Go to?File?->?Settings?->?Project: [your project name]?->?Project Interpreter
  • Then click on the green plus symbol.
  • In the search field type in?Flask?first. Select the first entry, which simply says?Flask. Then click on Install Package in the bottom left corner.
  • Do the same thing for?Requests.
  • Pip

    If you chose not to use PyCharm, you simply need to open up the terminal on linux or the command prompt, or PowerShell on Windows?(simply press?Windows+R?and type in cmd)?and then execute?pip install Flask==0.12.2 requests==2.18.4. If this gives you an error, please double check that you have?pip?installed. If the problem still occurs, please troubleshoot the error message using google, as there are too many possibilities, what the error could be caused by, for me to discuss every one of them here.

    Getting a HTTP-Client

    You will also need a HTTP-Client, as we need to make?GET?and?POSTrequests to our Flask instance, at some Point in time. Mainly, there are two options -?Postman?or?cURL. I highly recommend?Postman, as it is easy and intuitive to use, but if you just want a simple and quick solution, without having to register for an account, just use?cURL. Online solutions, probably won't work, as the webserver you are going to be trying to access, is just on your local machine.

    Just gimme the source code!

    If you just want the source code and don't want to follow my instructions, please scroll down, to the very end of this post, where I will add the source code in its complete beauty.

    The Blockchain - Your Blockchain

    Step 1: Creating a simplistic Blockchain

    A block chain is basically a chain of blocks that are linked together in some way, as you have already figured. In this case, every block contains a hash of the previous block. A hash is a hexadecimal number that is determined by a specific algorithm. Imagine a hash being a digital fingerprint of an item. A good hash algorithm will never return the same hash for two different items, so every hash is individual. In our case we will be using the?SHA-256?algorithm. Furthermore the hash algorithm is not reversible, so you can't determine the object, by having its hash, but you can always apply the hash algorithm on the object, to get its hash. As every item has the hash of its previous item, the blockchain is protected against violation, as one would have to change every following block, as the hash changes with every change, as two different items can't have the same hash.

    The Blockchain class

    Our Blockchain class basically consists of a constructor and some functions. In the constructor, we will create two empty lists - one to store our blockchain in and another, for our transactions. As for now, our class will have several functions:

    • A function to create new blocks
    • A function to create new transactions
    • A function, which hashes a block
    • A function to fetch the last block
      The python template looks like this:
    class MyBlockChain(object):def __init__(self):self.blockchain = []self.transactions = []def create_new_block(self):# This function creates a new block and appends it to the chainpassdef create_new_transaction(self):# This function creates a new transaction and adds it to the list of transactionspass@staticmethoddef hash(block):# This method hashes the passed blockpass@propertydef last_block(self):# This function returns the last block in the chainpass

    Step 2: The blocks

    As described earlier, a blockchain consists of blocks. So I will cover them first.
    Each Block has 5 fields:

    • An index,
    • an Unix timestamp,
    • a list of transactions,
    • a proof,
    • and finally the hash of the previous block.
      Just to clarify things, here is an example of a block
    example_block = {'index': 5,'timestamp': 1515110045.123456,'transactions': [{'sender': "154d8554f9541e12354e1234f512a001",'recipient': "8654e21254c6512a51bce156542d1e5c",'amount': 212,}],'proof': 488612354568,'previous_hash': "c7be1ed902fb8dd4d48997c6452f5d7e509fbcdbe2808b16bcf4edce4c07d14e" }

    Step 3: Hashing it

    As every block needs the hash of the previous block, we need a function, that calculates the hash of a block. To accomplish this, we simply modify our empty?hash?function

    import hashlib import jsonclass MyBlockChain(object):[...]@staticmethoddef hash(block):"""This function hashes the block using the SHA-256 hash algorithmThe function is given a block and returns a string, consisting of the hash:param block: <dict> Block:return: <str>"""# As every change in an item changes the hash, we first have to do a little sort operation, or else we would get inconsistent hashesblock_sorted = json.dumps(block, sort_keys=True).encode()return hashlib.sha256(block_sorted).hexdigest()

    Step 4: Transactions

    Our?create_new_transaction?method is responsible for adding new transactions to the?transactions?list, which will then be stored inside a block. The whole function is pretty self explanatory. But first we need a function to return the last block of the chain, as we will calculate the new index, at which the transaction will be stored, by increasing the index of the last block by 1

    class MyBlockChain(object):[...]@propertydef last_block(self):return self.blockchain[-1]

    Now we can fill out the?create_new_transaction?function

    class MyBlockChain(object):[...]def create_new_transaction(self, sender, recipient, amount):"""This function creates a new transaction that will then be placed in a new block, alone or bundled together with other transactions.:param sender: <str> Sender's address:param recipient: <str> Recipient's address:param amount: <int> Amount to be transferred:return: <int> This is the index of the block that will contain this transaction"""self.transactions.append({'sender': sender,'recipient': recipient,'amount': amount,})return self.last_block['index'] + 1

    Step 5: Creating new Blocks

    By now we almost have everything at our hands, what we need in order to make a new block. The only thing missing is the?proof?field. As this is a little harder to understand, I will explain it later.
    But we still have one problem - if every block has the hash of the previous block, what shall we do with our first block, as there is no previous block for us to hash.
    This first block is called the?genesis?block.

    import hashlib import json from time import timeclass MyBlockChain(object):def __init__(self):self.blockchain = []self.transactions = []# Creation of the mentioned genesis blockself.create_new_block(previous_hash=1, proof=100)def create_new_block(self, proof, previous_hash=None):"""Creates a new block and adds it to the blockchain:param proof: <int> This is generated by the proof of work algorithm:param previous_hash: (Optional) <str> Hash of the preleading Block:return: <dict> Return the new block"""new_block = {'index': len(self.blockchain) + 1,'timestamp': time(),'transactions': self.transactions,'proof': proof,'previous_hash': previous_hash or self.hash(self.blockchain[-1]),}# As all pending transactions have been processed and added to the block, the list can be resettedself.transactions = []# Add the new block to the blockchainself.blockchain.append(new_block)return new_block

    Step 6: What's up with the proof?!

    The?Proof of Work (PoW) algorithm

    This system wants to?proof?that work has been done. Now a little bit less abstract. Basically we are searching for a number that matches a specific criteria. The thing is, for the system to work, the process of finding a number matching the criteria has to be?difficult, but the verification process has to be?quick and easy. This is how new blocks are created, or expressed in another, more commonly used term,?mined.

    Still too abstract? Ok here is an example:

    We are looking for a hash of a product of two integers that ends with a 1.
    So the result of the multiplication of?a?and?b?gets hashed and has to end with a 1. If we set a to?a?static value, our algorithm will determine a value for?b, for which this criteria is matched.

    from hashlib import sha256 a = 12 b = 0 # We don't know what b has to be. It will be determined by the algorithm while sha256(f'{a*b}'.encode()).hexdigest()[-1] != "1":b += 1 print(f'The solution is b = ')

    This example outputs

    The solution is b = 4

    This means that the hash of?12*4?ends with a 1

    hash(48) = 98010bd9270f9b100b6214a21754fd33bdc8d41b2bc9f9dd16ff54d3c34ffd71

    As you can tell, the verification process doesn't need countless loops, until it finds a matching pair. You just have to run the hash algorithm once on the numbers and you can easily determine, whether the numbers match the criteria, or not.

    Step 7: Implementing PoW

    Firstoff, we need a criteria, or commonly referred to as a rule. For now, our rule is that the hash has to have 5 leading zeroes, so?000005bc845e...would be a valid result, but?000019ea76c4?would not. As the difficulty rises extremely, if we would require 6 leading zeros, the difficulty of our simple algorithm can be adjusted by changing the amount of leading zeroes required. This is the implementation in python:

    [...] from uuid import uuid4class MyBlockChain(object):[...]def pow(self, last_proof):"""Simple PoW Algorithm:- Find a number y, so that hash(xy) starts with 5 zeroes. x is the last y aka last_proof. y is then the new proof.:param last_proof: <int>:return: <int>"""current_proof = 0while self.validate_proof(last_proof, current_proof) is False:current_proof += 1return current_proof@staticmethoddef validate_proof(last_proof, current_proof):"""Returns, whether the hash of the lastproof and the current_proof contains 5 leading zeroes.:param last_proof: <int> Previous Proof Number:param current_proof: <int> Current Proof Number:return: <bool>"""possible_hash = hashlib.sha256(f'{last_proof}{current_proof}'.encode()).hexdigest()return possible_hash[:5] == "00000"

    Step 8: Interacting with our class

    Now we are able to create a blockchain. But we can't really interact with it, as we have only interacted with the functions and variables of our class.
    We are going to use HTTP requests to interact with our blockchain. So let's set it up!

    HTTP in the house!

    To talk to our blockchain using Http requests, we need some help - which comes in the form of the?Flask Framework. We will create and implement 3 basic methods for now:

    • /blockchain?to retrieve the full blockchain
    • /mining?to make our simple server mine a block
    • /transactions/add?to add a new transaction to the blockchain.

    Step 9: Flask

    First we need to implement Flask. Here is the code:

    [...] from textwrap import dedent from flask import Flask, jsonify, requestclass MyBlockChain(object):[...]app = Flask(__name__) node_identifier = str(uuid4()).replace('-', '')myblockchain = MyBlockChain()@app.route('/blockchain', methods=['GET']) def get_full_chain():output = {'chain': myblockchain.blockchain,'length': len(myblockchain.blockchain),}return jsonify(output), 200@app.route('/mining', methods=['GET']) def mining():pass @app.route('/transactions/add', methods=['POST']) def add_transaction():pass if __name__ == '__main__':app.run(host='0.0.0.0', port=5000)

    Step 10: Adding Transactions

    As this is commonly the main task of a block chain and also required for a new block, I will cover this first. The user sends a?POST request?to?/transactions/add?with a JSON object, containing all required fields. This is an example, for a possible, valid request:

    {"sender": "154d8554f9541e12354e1234f512a001","recipient": "8654e21254c6512a51bce156542d1e5c","amount": 212 }

    As you can see, a request has three fields:

    • A?sender?field, with the sender id,
    • a?recipient?field, with the recipient id
    • and an amount, which defines how many units are to be transferred
      Now we just need to implement this function
    [...]@app.route('/transactions/add', methods=['POST']) def add_transaction():values = request.get_json()# The POST request has to have the following required fieldsrequired = ['sender', 'recipient', 'amount']if not all(k in values for k in required):return 'There are values missing', 400# Adds a new transaction by utilizing our functionindex = myblockchain.create_new_transaction(values['sender'], values['recipient'], values['amount'])output = {'message': f'Your registered Transaction is going to be a part of the block with the index of {index}'}return jsonify(output), 201

    This function simply calls the?create_new_transaction?method with the parameters of the POST request

    Step 11: Setup your mines

    As discussed earlier, future blocks have to be mined. If a new block is found/mined, all pending transactions are added to this block. To 'mine' a new block, our function hast to do three things

  • Calculate the proof
  • Reward the miner with a specific amount of coins (in our example 1 coin)
  • Add the new mined block to the blockchain
    (The fact that the recipient is our current node, will make more sense, as we will talk about decentralization later on.)
  • @app.route('/mining', methods=['GET']) def mining():# Calculate the new proof by using our PoW algorithmlast_block = myblockchain.last_blocklast_proof = last_block['proof']proof = myblockchain.pow(last_proof)# For finding/mining the proof, the miner is granted a reward# The sender is nobody, as this coin is coming out of the voidmyblockchain.create_new_transaction(sender="0",recipient=node_identifier,amount=1,)# Add the new created block to the chainprevious_hash = myblockchain.hash(last_block)newblock = myblockchain.create_new_block(proof, previous_hash)output = {'message': "A new block was mined",'index': newblock['index'],'transactions': newblock['transactions'],'proof': newblock['proof'],'previous_hash': newblock['previous_hash'],}return jsonify(output), 200

    Hello World!

    Now,?finally?we will be interacting with our blockchain API. Grab your HTTP client of choice and get going! I will explain the procedure for Postman and cURL.

    Step 12: Start up the chain

    First off fire up your server.
    In PyCharm simply click on?Run?->?Run...?and select?[your filename].py?as the file to run, in my case?myblockchain.py.
    If you chose to use a simple python file without an IDE, fire up a terminal or command prompt window inside the directory your file is located in and execute the following command

    python blockchain.py

    as a result you will see something similar to this

    $ python blockchain.py * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

    Note that you may be prompted with a dialogue of your firewall. Just accept it.

    Step 13: Mining it all!

    Ok let's try the most exciting thing first,?mining. I'm sure you can't wait to mine your first block, so let's do it!
    As you can see in the code

    [...] @app.route('/mining', methods=['GET']) def mining():[...]

    we will be interacting with the?mining?part of our API through?GETrequests. This makes sense, as our only goal with this part of the API is, to mine a new block. We don't have to pass anything to the function at all, so a?GET?request is the way to go.

    Postman

    If you chose to use Postman, here is a quick tutorial on how to make a post request.

  • First you have to register for an account, if you haven't already done that
  • and login after that.
  • If you are logged in, you shoudl be provided with several options such as?Request,?Collection,?Environment.
  • You could simply use the option?Request, but to keep things organized, we are going to select the?Collection?option.
  • After that simply choose a name for your collection, in my case I'm using?MyBlockChain?as my name.
  • Now click on the?New?Button, located in the top left corner and select?Request?this time. We are now going to be creating 3 requests.
  • The first request is going to be our?mining?request, second is a?new transaction?request and finally we will have a?get whole blockchain?request. Of course you can customize the request names as you like.
  • Make sure, as you create these 3 requests, that you select our newly created Collection in the bottom section of the dialogue!
  • Now click on our Collection's folder in the left sidebar. You should see your 3 newly created requests. Select the?mining?request first.
  • On the right you are now provided with an interface. As you can see by the selected item from the dropdown box, left to the text field, a?GETrequest is the standard request type, so we don't have to change that yet.
  • In the text field?Enter request URL?we are now going to enter the?mining?URL of our API, so enter?http://localhost:5000/mining?as the request URL.
  • cURL

    If you chose to use cURL as your HTTP client, simply type?curl -i -H "Content-Type: application/json" -X GET http://localhost:5000/mining?in a terminal window

    Either way

    With both methods you should see something similar to this as a result

    {"index": 2,"message": "New Block Forged","previous_hash": "0f9cb2f06100899cb31b85fef221e243d1088c0aa6840a568e58d4a27dbd186a","proof": 888273,"transactions": [{"amount": 1,"recipient": "491002ea048a42609d967027cc46a07b","sender": "0"}] }

    Step 14: Transactions are great!

    As our mining algorithm seems to be working fine, let's create a new transaction, to be stored in a fresh mined block. To do that in

    Postman

  • Click on the?new transaction?request in the left sidebar.
  • Click on the?GET?button with the small arrow pointing down.
  • Select?POST?from the drop-down list.
  • In the navbar below the text field, select?Body
  • and then mark the?raw?option.
  • You should now be provided with an editor like text area, and another drop-down menu next to the?binary?option, where?Text?is currently selected. Select?JSON (application/json)?from this list.
  • Now type in the following into the text area.
  • {"sender": "your-node-address","recipient": "another-node-address","amount": 212 }

    cURL

    Just execute?curl -X POST -H "Content-Type: application/json" -d '{"sender": "your-node-address", "recipient": "another-node-address", "amount": 212}' "http://localhost:5000/transactions/add"?in a terminal window.

    In both cases

    Replace?your-node-address?with the?recipient?address from you mining request, as this is your node address. You can also select any other 32 digit hexadezimal number, for now. Furthermore replace?another-node-address?with a random 32 digit hexadezimal number for now, as we currently don't have any other nodes.
    Adjust the?amount?to your liking.
    And?voilà! You have registered your first transaction!

    Step 15: The Chain...

    So let's inspect our chain! If you're using

    Postman

    Click on the?get whole blockchain?request in the left sidebar and simply enter?http://localhost:5000/blockchain?in the?Enter request URL?text field, as?GET?should be preselected. If not, please change it to the?GET?option.

    cURL

    just execute?curl -i -H "Content-Type: application/json" -X GET http://localhost:5000/blockchain?in a terminal window.

    Either way

    you should get your whole blockchain in form of a JSON-Object. In my case, my blockchain looks like this, after mining 2 times, adding 3 transactions and mining another block:

    {"chain": [{"index": 1,"previous_hash": "1","proof": 100,"timestamp": 1515156902.4502413,"transactions": []},{"index": 2,"previous_hash": "0f9cb2f06100899cb31b85fef221e243d1088c0aa6840a568e58d4a27dbd186a","proof": 888273,"timestamp": 1515156913.2686973,"transactions": [{"amount": 1,"recipient": "491002ea048a42609d967027cc46a07b","sender": "0"}]},{"index": 3,"previous_hash": "1d2ae4a41f4a82ce6f04944e8227bf9c4d951d560f8763b910d7314634dfe09c","proof": 1156297,"timestamp": 1515158367.3596537,"transactions": [{"amount": 212,"recipient": "d4ee26eee15148ee92c6cd394edd974e","sender": "491002ea048a42609d967027cc46a07b"},{"amount": 212,"recipient": "5654c5654e1b551a65e15f5e4651c156","sender": "491002ea048a42609d967027cc46a07b"},{"amount": 111,"recipient": "491002ea048a42609d967027cc46a07b","sender": "5654c5654e1b551a65e15f5e4651c156"},{"amount": 1,"recipient": "491002ea048a42609d967027cc46a07b","sender": "0"}]}],"length": 3 }

    Decentralizing it

    Ok, so we got a blockchain, that's working fine and we can interact with it. But one very important thing is still missing:?Decentralization.
    This is a core element of the blockchain idea.
    First off by decentralizing the whole thing, safety and integrity of the blockchain is guaranteed, as a change in the blockchain will be recognized, by the other nodes, as they also have a copy of the blockchain, and discarded.
    The second reason is that we somehow have to make sense of our transactions. For this we need other nodes and why shouldn't they contribute to our network, by being a part of the blockchain system?!
    But we still have a conflict there: What if a node has a blockchain that differs from all the others?
    For our simple blockchain we will always make the?longest valid?blockchain authorative.

    Step 16: Someone out there?!

    But first things first.
    To get started, we first have to implement other nodes into our system.
    To accomplish this task, we have to adjust a few things in our API. First off, we are going to implement some new endpoints:

  • /nodes/add?to add new nodes in form of a list of URLs
  • /nodes/resolve?to resolve the conflict we discussed previously by using a consensus algorithm.
    To do this, we have to modify our Blockchain class first:
  • [...] from urllib.parse import urlparseclass MyBlockChain(object):def __init__(self):[...]self.nodes = set()def add_node(self, address):"""Register a new node:param address: <str> This is the new node's address, for example 'http://192.168.1.112:5000':return: None"""node_url = urlparse(address)self.nodes.add(node_url.netloc)

    Step 17: We need Consensus

    To resolve the conflict of differing blockchains between the nodes, we are going to implement a consensus algorithm. As we discussed earlier, we are always utilizing the longest valid blockchain.
    First we are implementing a function that validates a blockchain:

    [...] import requestsclass MyBlockChain(object)[...]def validate_blockchain(self, test_chain):"""Evaluate, whether a blockchain is valid:param chain: <list> The blockchain that shall be tested:return: <bool> Returns true if the blockchain is valid"""last_block = test_chain[0]current_index = 1while current_index < len(test_chain):block = test_chain[current_index]# Determine, whether the hash is correctif block['previous_hash'] != self.hash(last_block):return False# Determine, wheter the proof of work is correctif not self.validate_proof(last_block['proof'], block['proof']):return Falselast_block = blockcurrent_index += 1return True

    Now we just have to run every blockchain in our surrounding network through this consensus algorithm:

    [...]class MyBlockChain(object)[...]def resolve(self):"""This algorithm resolves conflicts between our nodes. It is the consensus algorithm which I mentioned previously.:return: <bool> Returns true, if our chain was substituted with an updated version"""surrounding_nodes = self.nodesupdated_chain = None# If we follow our consensus algorithm description, we only want blockchains that are longer, than our current chainmax_length = len(self.blockchain)# Iterate every surrounding nodes in our network through the consensus algorithm, which means checking if the node's blockchain is longer than our current blockchain and valid and set it as our new blockchain and continue checking, as there could be an even longer and valid blockchain.for node_iterator in surrounding_nodes:response = requests.get(f'http://{node_iterator}/blockchain')if response.status_code == 200:length = response.json()['length']chain_iterator = response.json()['chain']if length > max_length and self.validate_blockchain(chain_iterator):max_length = lengthupdated_chain = chain_iterator# If we found a new blockchain, replace our current blockchain with the new oneif updated_chain:self.blockchain = updated_chainreturn Truereturn False

    Now we just have to register our new functions as new endpoints in the API:

    @app.route('/nodes/add', methods=['POST']) def add_nodes():values = request.get_json()nodes = values.get('nodes')if nodes is None:return "You didn't post a valid list of nodes. Please double check your input!", 400for node in nodes:myblockchain.add_node(node)response = {'message': 'All of your specified nodes have been added to the network!','total_nodes': list(myblockchain.nodes),}return jsonify(response), 201@app.route('/nodes/resolve', methods=['GET']) def consensus():replaced = myblockchain.resolve()if replaced:response = {'message': 'There was a longer valid chain within the network. The blockchain of this node has been replaced.','new_chain': myblockchain.blockchain}else:response = {'message': 'The blockchain of this node is already the longest valid chain within the network.','chain': myblockchain.blockchain}return jsonify(response), 200

    Step 18: Friends are great. Even if they're virtual...

    To test our decentralization algorithms, either grab some friends, to run some nodes for you, or just run the same program on different ports, so you would have to start up an instance of our blockchain-program, then change to port to 5001 for example, save, fire up an instance of this?modified?program, change the port to 5002, etc.

    Step 19: Add them to your friends list

    If you got some instances, you just have to register them. To do this, simply send a?POST?request with the following content

    {"nodes": ["http://[ip-of-another-node-or-127.0.0.1-for-your-local-machine]:[the-port-number]"] }

    to?http://[the-node-ip-you-want-to-register-it-to]:[port]/nodes/add

    Step 20: Consensus check

    After that try to mine some blocks and even add some transactions on let's say node 2 and then run?http://[a-node-ip]:[port]/nodes/resolve?on let's say node 1. The consensus algorithm should step into action and update the blockchain of node 1.

    The whole thang

    I keep my promises

    import hashlib import json import requests from time import time from uuid import uuid4 from textwrap import dedent from flask import Flask, jsonify, request from urllib.parse import urlparseclass MyBlockChain(object):def __init__(self):self.blockchain = []self.transactions = []# Creation of the mentioned genesis blockself.create_new_block(previous_hash=1, proof=100)self.nodes = set()def create_new_block(self, proof, previous_hash=None):"""Creates a new block and adds it to the blockchain:param proof: <int> This is generated by the proof of work algorithm:param previous_hash: (Optional) <str> Hash of the preleading Block:return: <dict> Return the new block"""new_block = {'index': len(self.blockchain) + 1,'timestamp': time(),'transactions': self.transactions,'proof': proof,'previous_hash': previous_hash or self.hash(self.blockchain[-1]),}# As all pending transactions have been processed and added to the block, the list can be resettedself.transactions = []# Add the new block to the blockchainself.blockchain.append(new_block)return new_blockdef create_new_transaction(self, sender, recipient, amount):"""This function creates a new transaction that will then be placed in a new block, alone or bundled together with other transactions.:param sender: <str> Sender's address:param recipient: <str> Recipient's address:param amount: <int> Amount to be transferred:return: <int> This is the index of the block that will contain this transaction"""self.transactions.append({'sender': sender,'recipient': recipient,'amount': amount,})return self.last_block['index'] + 1@staticmethoddef hash(block):"""This function hashes the block using the SHA-256 hash algorithmThe function is given a block and returns a string, consisting of the hash:param block: <dict> Block:return: <str>"""# As every change in an item changes the hash, we first have to do a little sort operation, or else we would get inconsistent hashesblock_sorted = json.dumps(block, sort_keys=True).encode()return hashlib.sha256(block_sorted).hexdigest()@propertydef last_block(self):return self.blockchain[-1]def pow(self, last_proof):"""Simple PoW Algorithm:- Find a number y, so that hash(xy) starts with 5 zeroes. x is the last y aka last_proof. y is then the new proof.:param last_proof: <int>:return: <int>"""current_proof = 0while self.validate_proof(last_proof, current_proof) is False:current_proof += 1return current_proof@staticmethoddef validate_proof(last_proof, current_proof):"""Returns, whether the hash of the lastproof and the current_proof contains 5 leading zeroes.:param last_proof: <int> Previous Proof Number:param current_proof: <int> Current Proof Number:return: <bool>"""possible_hash = hashlib.sha256(f'{last_proof}{current_proof}'.encode()).hexdigest()return possible_hash[:5] == "00000"def add_node(self, address):"""Register a new node:param address: <str> This is the new node's address, for example 'http://192.168.1.112:5000':return: None"""node_url = urlparse(address)self.nodes.add(node_url.netloc)def validate_blockchain(self, test_chain):"""Evaluate, whether a blockchain is valid:param chain: <list> The blockchain that shall be tested:return: <bool> Returns true if the blockchain is valid"""last_block = test_chain[0]current_index = 1while current_index < len(test_chain):block = test_chain[current_index]# Determine, whether the hash is correctif block['previous_hash'] != self.hash(last_block):return False# Determine, wheter the proof of work is correctif not self.validate_proof(last_block['proof'], block['proof']):return Falselast_block = blockcurrent_index += 1return Truedef resolve(self):"""This algorithm resolves conflicts between our nodes. It is the consensus algorithm which I mentioned previously.:return: <bool> Returns true, if our chain was substituted with an updated version"""surrounding_nodes = self.nodesupdated_chain = None# If we follow our consensus algorithm description, we only want blockchains that are longer, than our current chainmax_length = len(self.blockchain)# Iterate every surrounding nodes in our network through the consensus algorithm, which means checking if the node's blockchain is longer than our current blockchain and valid and set it as our new blockchain and continue checking, as there could be an even longer and valid blockchain.for node_iterator in surrounding_nodes:response = requests.get(f'http://{node_iterator}/blockchain')if response.status_code == 200:length = response.json()['length']chain_iterator = response.json()['chain']if length > max_length and self.validate_blockchain(chain_iterator):max_length = lengthupdated_chain = chain_iterator# If we found a new blockchain, replace our current blockchain with the new oneif updated_chain:self.blockchain = updated_chainreturn Truereturn Falseapp = Flask(__name__) node_identifier = str(uuid4()).replace('-', '')myblockchain = MyBlockChain()@app.route('/blockchain', methods=['GET']) def get_full_chain():output = {'chain': myblockchain.blockchain,'length': len(myblockchain.blockchain),}return jsonify(output), 200@app.route('/mining', methods=['GET']) def mining():# Calculate the new proof by using our PoW algorithmlast_block = myblockchain.last_blocklast_proof = last_block['proof']proof = myblockchain.pow(last_proof)# For finding/mining the proof, the miner is granted a reward# The sender is nobody, as this coin is coming out of the voidmyblockchain.create_new_transaction(sender="0",recipient=node_identifier,amount=1,)# Add the new created block to the chainprevious_hash = myblockchain.hash(last_block)newblock = myblockchain.create_new_block(proof, previous_hash)output = {'message': "A new block was mined",'index': newblock['index'],'transactions': newblock['transactions'],'proof': newblock['proof'],'previous_hash': newblock['previous_hash'],}return jsonify(output), 200@app.route('/transactions/add', methods=['POST']) def add_transaction():values = request.get_json()# The POST request has to have the following required fieldsrequired = ['sender', 'recipient', 'amount']if not all(k in values for k in required):return 'There are values missing', 400# Adds a new transaction by utilizing our functionindex = myblockchain.create_new_transaction(values['sender'], values['recipient'], values['amount'])output = {'message': f'Your registered Transaction is going to be a part of the block with the index of {index}'}return jsonify(output), 201@app.route('/nodes/add', methods=['POST']) def add_nodes():values = request.get_json()nodes = values.get('nodes')if nodes is None:return "You didn't post a valid list of nodes. Please double check your input!", 400for node in nodes:myblockchain.add_node(node)response = {'message': 'All of your specified nodes have been added to the network!','total_nodes': list(myblockchain.nodes),}return jsonify(response), 201@app.route('/nodes/resolve', methods=['GET']) def consensus():replaced = myblockchain.resolve()if replaced:response = {'message': 'There was a longer valid chain within the network. The blockchain of this node has been replaced.','new_chain': myblockchain.blockchain}else:response = {'message': 'The blockchain of this node is already the longest valid chain within the network.','chain': myblockchain.blockchain}return jsonify(response), 200if __name__ == '__main__':app.run(host='0.0.0.0', port=5000)

    Final thoughts

    And there you have it!
    Your very own blockchain. Wasn't very hard, was it?
    I sincerely hope you had fun thorughout this tutorial and were able to understand the concept and system behind it better. If you have any questions, please ask them in the comments and I'll try my best to answer them.

    The obligatory begging

    As this whole tutorial took me over 2 days to finish, I would love to see a lot of comments and feedback under this post. Also if you find any typos, grammar mistakes, etc. and care to tell me, i would be mor than happy about it, as English is not my native language. So please excuse any mistakes I made. I tried my very best.
    Of course please upvote, if you worship my effort to enrich the community, and if you want to see more such content, consider following me.

    I wish you only the best - See ya!

    https://steemit.com/steemit/@dustvoice/create-your-own-blockchain-and-cryptocurrency-understand-blockchains-by-creating-one-in-python-no-knowledge-required

    總結

    以上是生活随笔為你收集整理的Create your own blockchain amp; cryptocurrency! - understand blockchains by creating one in python的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 麻豆网站在线观看 | 一久久 | 99久久久国产精品免费蜜臀 | 91精品啪 | 男生看的污网站 | 人人舔人人干 | 日本黄动漫 | 国产av人人夜夜澡人人爽麻豆 | 免费精品视频一区二区三区 | 国产精品精品国产色婷婷 | 国产5区 | 国产精品电影一区 | 国产三级在线看 | 葵司免费一区二区三区四区五区 | 98av视频 | 自拍第1页 | 国产日韩欧美中文 | 奇米影视第四色777 波多野结衣一区二区三区免费视频 | 欧洲精品视频在线 | 精品在线视频免费观看 | 天堂中文字幕av | 神马午夜电影一区二区三区在线观看 | 久久免费视频3 | 国产精品国产a级 | 国产精品色片 | 久久夜靖品2区 | 亚洲一区二区高清 | 在线免费观看小视频 | 欧美三级在线观看视频 | 天天干天天做 | 特级西西人体 | 黄色一级视频免费看 | 国产在线视频一区二区 | 瑟瑟视频网站 | 国模小丫大尺度啪啪人体 | 日韩一区二区三区电影 | 动漫艳母在线观看 | 激情九月天| 禁断介护老人中文字幕 | 一区两区小视频 | 三级国产三级在线 | 久久久久一| 在线免费视频你懂的 | 96av视频 | 久久久精品欧美 | 九月婷婷色 | 日日夜夜操操操 | 亚洲第一视频区 | 午夜免费激情视频 | 欧美一级性生活视频 | 午夜在线观看免费视频 | 狼人精品一区二区三区在线 | 日本熟女毛茸茸 | 色综合激情| 欧美黄色录像 | 久久99日韩 | 亚洲一区二区天堂 | 天天综合网久久综合网 | 天天射天天射 | 亚洲国产色图 | 精品国产一区二 | 久久国产精品电影 | 神马午夜电影一区二区三区在线观看 | 亚洲黄色一区二区三区 | 亚洲天堂网一区二区 | 交专区videossex另类 | 国产一区美女 | 肉色丝袜小早川怜子av | 亚洲欧美不卡 | jiizzyou性欧美老片 | 欧美播放 | 91精品人妻一区二区三区果冻 | 亚洲天堂少妇 | 秋霞黄色片| 亚洲国产精品综合久久久 | 成人午夜又粗又硬又大 | 秋霞午夜| 99热青青草| 中文字幕3区 | 久久精品无码一区二区三区毛片 | 成年人的视频网站 | jizz性欧美15| 香蕉视频亚洲一级 | 国产视频三区 | 69激情网 | 无码精品一区二区三区AV | 国产3级在线 | 国产二区精品视频 | 91免费播放| 免费黄色网址观看 | 中文字幕一区二区三区电影 | 少妇人妻在线视频 | 制服丝袜先锋影音 | 国产伦精品一区二区三区88av | 手机看片福利视频 | 免费a在线观看 | 黄色片视频免费 | 色综合视频在线观看 | 免费中文字幕在线观看 |