>  기사  >  백엔드 개발  >  Vue, Python, Flask를 사용한 블록체인

Vue, Python, Flask를 사용한 블록체인

Mary-Kate Olsen
Mary-Kate Olsen원래의
2024-10-27 08:18:02902검색

Blockchain with Vue, Python & Flask

Vue.js 프런트엔드와 Python 백엔드를 사용하여 완전한 블록체인 애플리케이션 만들기
기본 구성 요소를 개략적으로 설명하고 시작하는 데 도움이 되는 몇 가지 예제 코드 조각을 제공하겠습니다.

개요

  • 1. 백엔드(Flask가 포함된 Python) 간단한 블록체인 구조를 만듭니다. 블록체인과 상호작용할 수 있도록 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단계: 백엔드 강화
  • 블록체인 클래스 업데이트 우리는 기본적인 작업 증명 알고리즘과 거래 풀을 구현할 것입니다.
# 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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.