ホームページ > バックエンド開発 > Python チュートリアル > Vue、Python、Flask を使用したブロックチェーン

Vue、Python、Flask を使用したブロックチェーン

Mary-Kate Olsen
リリース: 2024-10-27 08:18:02
オリジナル
911 人が閲覧しました

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. API 呼び出し用に Axios をインストールします。
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>
ログイン後にコピー

ステップ 3: すべてをまとめる

Flask バックエンドを実行します: Python サーバーが実行されていることを確認してください:

python blockchain.py

ログイン後にコピー

Vue.js フロントエンドを実行します: 次に、Vue.js アプリケーションを実行します:

npm run serve
ログイン後にコピー

次のような高度な機能を追加して、ブロックチェーン アプリケーションを強化しましょう。

  • プルーフ・オブ・ワークのメカニズム: 基本的なプルーフ・オブ・ワークのアルゴリズムを実装します。
  • トランザクション プール: ユーザーがトランザクションを作成し、マイニングする前にプール内でトランザクションを確認できるようにします。 -ノード検出: 複数のノードが接続してブロックチェーンを共有できるようにします。 - フロントエンドの改善: ブロックチェーンとトランザクションを表示するための、よりインタラクティブな UI を作成します。 ステップ 1: バックエンドの強化
  • ブロックチェーンクラスを更新する 基本的な Proof of Work アルゴリズムとトランザクション プールを実装します。
# 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>
ログイン後にコピー

ステップ 3: ノードの検出とコンセンサス

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 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート