首頁 >後端開發 >Python教學 >區塊鏈與 Vue、Python 和 Flask

區塊鏈與 Vue、Python 和 Flask

Mary-Kate Olsen
Mary-Kate Olsen原創
2024-10-27 08:18:02912瀏覽

Blockchain with Vue, Python & Flask

使用 Vue.js 前端和 Python 後端創建完整的區塊鏈應用程式。
讓我們概述基本組件並提供一些範例程式碼片段來幫助您入門。

概述

  • 1.後端(Python 與 Flask) 創建一個簡單的區塊鏈結構。 設定 Flask API 與區塊鏈互動。
  • 2.前端 (Vue.js)
  • 建立一個與 Flask API 通訊的 Vue.js 應用程式。
  • 顯示區塊鏈資料並允許使用者互動(例如新增區塊)。 第 1 步:設定後端
  • 安裝 Flask:確保已安裝 Flask。您可以使用 pip 來執行此操作:

設定環境

pip install Flask
  1. 創建一個基本的區塊鏈類別:
# 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)

第 2 步:設定前端

  1. 建立 Vue.js 應用程式:如果您尚未建立 Vue.js 項目,可以使用 Vue CLI 來建立:
vue create my-blockchain-app

  1. 安裝 Axios 進行 API 呼叫:
npm install axios
  1. 建立一個簡單的組件:
// 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>

第三步:將它們放在一起

運行 Flask 後端:確保您的 Python 伺服器正在運行:

python blockchain.py

運行 Vue.js 前端:現在,運行您的 Vue.js 應用程式:

npm run serve

讓我們透過添加更多高級功能來增強區塊鏈應用程序,例如:

  • 工作量證明機制:實作基本的工作量證明演算法。
  • 交易池:允許使用者建立交易並在挖礦之前在池中查看它們。 -節點發現:允許多個節點連接並共享區塊鏈。 -改進的前端:創建更具互動性的使用者介面來顯示區塊鏈和交易。 第 1 步:增強後端
  • 更新區塊鏈類 我們將實作基本的工作量證明演算法和交易池。
# 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)

第 2 步:增強前端

  1. 在 Vue.js 中建立交易表單 我們現在將建立一個表單供用戶提交交易。
// 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>

第三步:節點發現與共識

您可以透過在不同連接埠上執行 Flask 應用程式的多個實例來測試具有多個節點的區塊鏈。例如,您可以運行:

FLASK_RUN_PORT=5001 python blockchain.py

然後,您可以使用 POST 請求註冊節點:

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

這個更先進的區塊鏈應用程式包括:
-工作量證明:挖掘新區塊的基本機制。
-交易池:使用者可以在交易被開採之前建立交易。
-節點發現:支援多個節點和共識機制。
-互動式前端:用於提交交易和查看區塊鏈的 Vue.js UI。

編碼愉快!

以上是區塊鏈與 Vue、Python 和 Flask的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn