Maison > développement back-end > Tutoriel Python > Blockchain avec Vue, Python et Flask

Blockchain avec Vue, Python et Flask

Mary-Kate Olsen
Libérer: 2024-10-27 08:18:02
original
1041 Les gens l'ont consulté

Blockchain with Vue, Python & Flask

Création d'une application blockchain complète avec un frontend Vue.js et un backend Python.
Décrivons les composants de base et fournissons quelques exemples d'extraits de code pour vous aider à démarrer.

Aperçu

  • 1. Back-end (Python avec Flask) Créez une structure blockchain simple. Configurez une API Flask pour interagir avec la blockchain.
  • 2. Frontend (Vue.js)
  • Créez une application Vue.js qui communique avec l'API Flask.
  • Affichez les données de la blockchain et autorisez les interactions des utilisateurs (comme l'ajout d'un nouveau bloc). Étape 1 : Configuration du backend
  • Installer Flask : assurez-vous que Flask est installé. Vous pouvez le faire en utilisant pip :

Mise en place de l'environnement

pip install Flask
Copier après la connexion
  1. Créez une classe Blockchain de base :
# blockchain.py
import hashlib
import json
from time import time
from flask import Flask, jsonify, request

class Blockchain:
    def __init__(self):
        self.chain = []
        self.current_transactions = []
        self.new_block(previous_hash='1', proof=100)

    def new_block(self, proof, previous_hash=None):
        block = {
            'index': len(self.chain) + 1,
            'timestamp': 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

    @staticmethod
    def hash(block):
        block_string = json.dumps(block, sort_keys=True).encode()
        return hashlib.sha256(block_string).hexdigest()

    @property
    def last_block(self):
        return self.chain[-1]

app = Flask(__name__)
blockchain = Blockchain()

@app.route('/mine', methods=['POST'])
def mine():
    values = request.get_json()
    required = ['proof', 'sender', 'recipient']
    if not all(k in values for k in required):
        return 'Missing values', 400

    index = blockchain.new_transaction(values['sender'], values['recipient'], values['amount'])
    blockchain.new_block(values['proof'])
    response = {
        'message': f'New Block Forged',
        'index': index,
        'block': blockchain.last_block,
    }
    return jsonify(response), 200

@app.route('/chain', methods=['GET'])
def full_chain():
    response = {
        'chain': blockchain.chain,
        'length': len(blockchain.chain),
    }
    return jsonify(response), 200

if __name__ == '__main__':
    app.run(debug=True)

Copier après la connexion

Étape 2 : Configuration du frontend

  1. Créer une application Vue.js : si vous n'avez pas encore créé de projet Vue.js, vous pouvez le faire à l'aide de Vue CLI :
vue create my-blockchain-app

Copier après la connexion
  1. Installez Axios pour les appels API :
npm install axios
Copier après la connexion
  1. Créer un composant simple :
// src/components/Blockchain.vue
<template>
  <div>
    <h1>Blockchain</h1>
    <button @click="fetchChain">Fetch Blockchain</button>
    <ul>
      <li v-for="block in blockchain" :key="block.index">
        Block #{{ block.index }} - {{ block.timestamp }}
      </li>
    </ul>
  </div>
</template>

<script>
import axios from 'axios';

export default {
  data() {
    return {
      blockchain: []
    };
  },
  methods: {
    fetchChain() {
      axios.get('http://localhost:5000/chain')
        .then(response => {
          this.blockchain = response.data.chain;
        })
        .catch(error => {
          console.error(error);
        });
    }
  }
};
</script>
Copier après la connexion

Étape 3 : Assembler le tout

Exécutez le backend Flask : assurez-vous que votre serveur Python est en cours d'exécution :

python blockchain.py

Copier après la connexion

Exécutez le frontend Vue.js : maintenant, exécutez votre application Vue.js :

npm run serve
Copier après la connexion

Améliorons l'application blockchain en ajoutant des fonctionnalités plus avancées telles que :

  • Mécanisme de preuve de travail : implémentez un algorithme de preuve de travail de base.
  • Pool de transactions : permet aux utilisateurs de créer des transactions et de les voir dans un pool avant l'extraction. -Découverte de nœuds : autorisez plusieurs nœuds à se connecter et à partager la blockchain. -Frontend amélioré : créez une interface utilisateur plus interactive pour afficher la blockchain et les transactions. Étape 1 : Amélioration du backend
  • Mettre à jour la classe Blockchain Nous mettrons en œuvre un algorithme de preuve de travail de base et un pool de transactions.
# blockchain.py
import hashlib
import json
from time import time
from flask import Flask, jsonify, request
from urllib.parse import urlparse
import requests

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(),
            '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

    @staticmethod
    def hash(block):
        block_string = json.dumps(block, sort_keys=True).encode()
        return hashlib.sha256(block_string).hexdigest()

    @property
    def last_block(self):
        return self.chain[-1]

    def proof_of_work(self, last_proof):
        proof = 0
        while not self.valid_proof(last_proof, proof):
            proof += 1
        return proof

    @staticmethod
    def valid_proof(last_proof, proof):
        guess = f'{last_proof}{proof}'.encode()
        guess_hash = hashlib.sha256(guess).hexdigest()
        return guess_hash[:4] == "0000"  # Adjust difficulty here

    def register_node(self, address):
        parsed_url = urlparse(address)
        self.nodes.add(parsed_url.netloc)

    def resolve_conflicts(self):
        neighbours = self.nodes
        new_chain = None
        max_length = len(self.chain)

        for node in neighbours:
            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

    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

app = Flask(__name__)
blockchain = Blockchain()

@app.route('/mine', methods=['POST'])
def mine():
    values = request.get_json()
    required = ['sender', 'recipient']

    if not all(k in values for k in required):
        return 'Missing values', 400

    last_block = blockchain.last_block
    last_proof = last_block['proof']
    proof = blockchain.proof_of_work(last_proof)

    blockchain.new_transaction(sender=values['sender'], recipient=values['recipient'], amount=1)
    previous_hash = blockchain.hash(last_block)
    block = blockchain.new_block(proof, previous_hash)

    response = {
        'message': 'New Block Forged',
        'index': block['index'],
        'block': block,
    }
    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(debug=True)

Copier après la connexion

Étape 2 : Améliorer le frontend

  1. Créer un formulaire de transaction dans Vue.js Nous allons maintenant créer un formulaire permettant aux utilisateurs de soumettre des transactions.
// src/components/Blockchain.vue
<template>
  <div>
    <h1>Blockchain</h1>
    <button @click="fetchChain">Fetch Blockchain</button>

    <h2>Transactions</h2>
    <form @submit.prevent="submitTransaction">
      <input type="text" v-model="sender" placeholder="Sender" required />
      <input type="text" v-model="recipient" placeholder="Recipient" required />
      <input type="number" v-model="amount" placeholder="Amount" required />
      <button type="submit">Send Transaction</button>
    </form>

    <h2>Blockchain</h2>
    <ul>
      <li v-for="block in blockchain" :key="block.index">
        Block #{{ block.index }} - {{ block.timestamp }}
        <ul>
          <li v-for="transaction in block.transactions" :key="transaction.sender">
            {{ transaction.sender }} -> {{ transaction.recipient }}: {{ transaction.amount }}
          </li>
        </ul>
      </li>
    </ul>
  </div>
</template>

<script>
import axios from 'axios';

export default {
  data() {
    return {
      blockchain: [],
      sender: '',
      recipient: '',
      amount: 0,
    };
  },
  methods: {
    fetchChain() {
      axios.get('http://localhost:5000/chain')
        .then(response => {
          this.blockchain = response.data.chain;
        })
        .catch(error => {
          console.error(error);
        });
    },
    submitTransaction() {
      const transaction = {
        sender: this.sender,
        recipient: this.recipient,
        amount: this.amount,
      };

      axios.post('http://localhost:5000/transactions/new', transaction)
        .then(response => {
          alert(response.data.message);
          this.fetchChain(); // Refresh the blockchain view
        })
        .catch(error => {
          console.error(error);
        });
    }
  }
};
</script>
Copier après la connexion

Étape 3 : Découverte de nœuds et consensus

Vous pouvez tester votre blockchain avec plusieurs nœuds en exécutant plusieurs instances de votre application Flask sur différents ports. Par exemple, vous pouvez exécuter :

FLASK_RUN_PORT=5001 python blockchain.py
Copier après la connexion

Ensuite, vous pouvez enregistrer des nœuds à l'aide d'une requête POST :

curl -X POST -H "Content-Type: application/json" -d '{"nodes": ["localhost:5001"]}' http://localhost:5000/nodes/register

Copier après la connexion

Cette application blockchain plus avancée comprend :
-Preuve de travail : un mécanisme de base pour extraire de nouveaux blocs.
-Pool de transactions : les utilisateurs peuvent créer des transactions avant qu'elles ne soient extraites.
-Node Discovery : prise en charge de plusieurs nœuds et d'un mécanisme de consensus.
-Interactive Frontend : une interface utilisateur Vue.js pour soumettre des transactions et visualiser la blockchain.

Bon codage !

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal