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

Blockchain avec Vue, Python et Flask

Mary-Kate Olsen
Mary-Kate Olsenoriginal
2024-10-27 08:18:02796parcourir

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
  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)

É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

  1. Installez Axios pour les appels API :
npm install axios
  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>

É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

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

npm run serve

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)

É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>

É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

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

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:
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