Python and Blockchain: Creating a Cryptocurrency

Table of Contents

  1. Introduction
  2. Prerequisites
  3. Setup
  4. Creating the Blockchain
  5. Creating a Cryptocurrency
  6. Conclusion

Introduction

In this tutorial, we will explore how to create a basic blockchain and then use it to create a simple cryptocurrency. Our goal is to provide a step-by-step guide for beginners to understand the concepts behind blockchain technology and its application in creating cryptocurrencies. By the end of this tutorial, you will have a basic understanding of how blockchain works and the ability to create your own digital currency.

Prerequisites

To follow along with this tutorial, you should have a basic understanding of Python programming and be familiar with concepts like lists, dictionaries, and functions. Additionally, a basic understanding of the command line interface will be helpful. You will need to have Python installed on your machine. You can download the latest version of Python from the official website (https://www.python.org/downloads/).

Setup

Before we start creating our blockchain and cryptocurrency, let’s set up a new Python project and install the required libraries. Open your command line interface and follow these steps:

  1. Create a new directory for your project:
     mkdir blockchain
     cd blockchain
    
  2. Create a virtual environment (optional but recommended):
     python -m venv venv
    
  3. Activate the virtual environment:
     venv\Scripts\activate  # for Windows
     source venv/bin/activate  # for macOS/Linux
    
  4. Install the required libraries:
     pip install flask
     pip install requests
    

    Now that we have our project set up and the necessary libraries installed, let’s dive into creating the blockchain.

Creating the Blockchain

  1. Create a new Python file called blockchain.py and open it in your favorite text editor.

  2. Import the necessary libraries:
     from hashlib import sha256
     import json
     import time
     from flask import Flask, request
     import requests
     from uuid import uuid4
    
  3. Define the Blockchain class:
     class Blockchain:
         def __init__(self):
             self.chain = []
             self.current_transactions = []
             self.nodes = set()
             self.new_block(previous_hash='1', proof=100)
    	
         def new_block(self, proof, previous_hash=None):
             block = {
                 'index': len(self.chain) + 1,
                 'timestamp': time.time(),
                 'transactions': self.current_transactions,
                 'proof': proof,
                 'previous_hash': previous_hash or self.hash(self.chain[-1])
             }
             self.current_transactions = []
             self.chain.append(block)
             return block
    	
         def new_transaction(self, sender, recipient, amount):
             self.current_transactions.append({
                 'sender': sender,
                 'recipient': recipient,
                 'amount': amount,
             })
             return self.last_block['index'] + 1
    	
         def register_node(self, address):
             parsed_url = urlparse(address)
             self.nodes.add(parsed_url.netloc)
    	
         def valid_chain(self, chain):
             last_block = chain[0]
             current_index = 1
             while current_index < len(chain):
                 block = chain[current_index]
                 if block['previous_hash'] != self.hash(last_block):
                     return False
                 if not self.valid_proof(last_block['proof'], block['proof']):
                     return False
                 last_block = block
                 current_index += 1
             return True
    	
         def resolve_conflicts(self):
             neighbors = self.nodes
             new_chain = None
             max_length = len(self.chain)
             for node in neighbors:
                 response = requests.get(f'http://{node}/chain')
                 if response.status_code == 200:
                     length = response.json()['length']
                     chain = response.json()['chain']
                     if length > max_length and self.valid_chain(chain):
                         max_length = length
                         new_chain = chain
             if new_chain:
                 self.chain = new_chain
                 return True
             return False
    	
         @staticmethod
         def hash(block):
             block_string = json.dumps(block, sort_keys=True).encode()
             return sha256(block_string).hexdigest()
    	
         @property
         def last_block(self):
             return self.chain[-1]
    
  4. Implement the proof-of-work algorithm:
     def proof_of_work(block):
         block_hash = blockchain.hash(block)
         while not block_hash.startswith('0000'):
             block['proof'] += 1
             block_hash = blockchain.hash(block)
         return block['proof']
    
  5. Set up a Flask server to interact with the blockchain:
     app = Flask(__name__)
     node_identifier = str(uuid4()).replace('-', '')
     blockchain = Blockchain()
    	
    	
     @app.route('/mine', methods=['GET'])
     def mine():
         last_block = blockchain.last_block
         proof = proof_of_work(last_block)
         blockchain.new_transaction(sender="0", recipient=node_identifier, amount=1)
         previous_hash = blockchain.hash(last_block)
         block = blockchain.new_block(proof, previous_hash)
         response = {
             'message': 'New block created',
             'index': block['index'],
             'transactions': block['transactions'],
             'proof': block['proof'],
             'previous_hash': block['previous_hash'],
         }
         return jsonify(response), 200
    	
    	
     @app.route('/transactions/new', methods=['POST'])
     def new_transaction():
         values = request.get_json()
         required = ['sender', 'recipient', 'amount']
         if not all(k in values for k in required):
             return 'Missing values', 400
         index = blockchain.new_transaction(values['sender'], values['recipient'], values['amount'])
         response = {'message': f'Transaction will be added to Block {index}'}
         return jsonify(response), 201
    	
    	
     @app.route('/chain', methods=['GET'])
     def full_chain():
         response = {
             'chain': blockchain.chain,
             'length': len(blockchain.chain),
         }
         return jsonify(response), 200
    	
    	
     @app.route('/nodes/register', methods=['POST'])
     def register_nodes():
         values = request.get_json()
         nodes = values.get('nodes')
         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': list(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
    	
    	
     if __name__ == '__main__':
         app.run(host='0.0.0.0', port=5000)
    
  6. Save the file and run the server by executing the following command in your command line interface:
     python blockchain.py
    

    Congratulations! You have now set up your own blockchain. In the next section, we will create a cryptocurrency on top of this blockchain.

Creating a Cryptocurrency

To create a cryptocurrency, we will extend the functionality of our existing blockchain. We will add a feature to handle transactions specific to our cryptocurrency and modify the mining process to incentivize miners with new cryptocurrency units.

  1. Open the blockchain.py file and add the following code below the Blockchain class definition:
     class Cryptocurrency:
         def __init__(self, blockchain):
             self.blockchain = blockchain
             self.transactions = []
    	
         def new_transaction(self, sender, recipient, amount):
             self.transactions.append({
                 'sender': sender,
                 'recipient': recipient,
                 'amount': amount,
             })
    	
         def mine(self, miner_address):
             self.transactions.append({
                 'sender': '0',
                 'recipient': miner_address,
                 'amount': 1,  # Reward for mining a block
             })
    	
             last_block = self.blockchain.last_block
             proof = proof_of_work(last_block)
             previous_hash = self.blockchain.hash(last_block)
             self.blockchain.new_block(proof, previous_hash)
    	
             self.transactions = []
    	
             return self.blockchain.last_block['index']
    
  2. Modify the /mine and /transactions/new routes in the Flask server to use the Cryptocurrency class:
     cryptocurrency = Cryptocurrency(blockchain)
    	
    	
     @app.route('/mine', methods=['GET'])
     def mine():
         last_block = blockchain.last_block
         index = cryptocurrency.mine(node_identifier)
         response = {
             'message': 'New block created',
             'index': index,
             'transactions': blockchain.current_transactions,
             'proof': last_block['proof'],
             'previous_hash': last_block['previous_hash'],
         }
         return jsonify(response), 200
    	
    	
     @app.route('/transactions/new', methods=['POST'])
     def new_transaction():
         values = request.get_json()
         required = ['sender', 'recipient', 'amount']
         if not all(k in values for k in required):
             return 'Missing values', 400
         index = cryptocurrency.new_transaction(values['sender'], values['recipient'], values['amount'])
         response = {'message': f'Transaction will be added to Block {index}'}
         return jsonify(response), 201
    
  3. Save the file and restart the server.

Now, you have successfully created a cryptocurrency on top of your blockchain. You can interact with the blockchain and cryptocurrency by making HTTP requests to the defined routes using tools like curl or through a web browser.

Conclusion

In this tutorial, we explored the process of creating a basic blockchain and then extended it to create a simple cryptocurrency. We started by setting up our project and installing the necessary libraries. Then, we implemented the blockchain and proof-of-work algorithm. Finally, we added features specific to our cryptocurrency and modified the mining process to incentivize miners with new cryptocurrency units. You now have a basic understanding of how blockchain technology works and how cryptocurrencies are created.

Feel free to experiment with the code and explore more advanced concepts like consensus algorithms, smart contracts, and decentralized applications (DApps). Happy coding!