关键词

区块链

Python区块链开发教程:从零开始构建自己的加密货币

随着比特币和其他加密货币的兴起,区块链技术变得越来越受欢迎。区块链是一种去中心化、安全、透明的分布式账本,可以记录交易和资产,而且不需要第三方机构进行验证。Python作为一种流行的编程语言,也被广泛应用于区块链开发。在这篇文章中,我们将介绍如何使用Python构建一个简单的区块链,并创建自己的加密货币。

简介

区块链是由一系列块组成的链,每个块都包含前一块的哈希值和当前块的交易信息。当新块添加到区块链中时,它需要通过工作量证明算法完成验证,并获得奖励。比特币是最著名的区块链之一,但有许多其他的加密货币和应用程序。下面是一些关键概念:

  • 哈希函数:这是将数据映射到固定长度数值的函数。在区块链中,哈希函数用于确保数据的完整性和安全性。
  • 工作量证明:在区块链中,为了添加新块,需要完成一些计算任务。这个过程被称为工作量证明,目的是防止欺诈和恶意行为。
  • 共识算法:在区块链中,共识算法用于确保所有节点都同意添加到区块链中的交易和数据。

步骤

我们将介绍如何从零开始使用Python构建一个简单的区块链,并创建自己的加密货币。

步骤 1: 安装必要的软件包

您需要安装Python 3。在安装了Python之后,您需要安装以下软件包:

pip install hashlib
pip install Flask

步骤 2: 创建块类

我们需要定义一个块类来表示区块链中的每个块。每个块都有一些属性,例如索引、时间戳、交易信息、前一块的哈希值等。下面是一个示例块类:

import hashlib
import json
from time import time

class Block:
    def __init__(self, index, transactions, timestamp, previous_hash):
        self.index = index
        self.transactions = transactions
        self.timestamp = timestamp
        self.previous_hash = previous_hash
        self.hash = self.calculate_hash()

    def calculate_hash(self):
        block_string = json.dumps(self.__dict__, sort_keys=True).encode()
        return hashlib.sha256(block_string).hexdigest()

步骤 3: 创建区块链类

我们需要定义一个区块链类来管理我们创建的所有块。这个类将具有添加新块、验证块、获取一个块等功能。下面是一个示例区块链类:

class Blockchain:
    def __init__(self):
        self.chain = [self.create_genesis_block()]

    def create_genesis_block(self):
        return Block(0, [], time(), "0")

    def get_latest_block(self):
        return self.chain[-1]

    def add_block(self, block):
        block.previous_hash = self.get_latest_block().hash
        block.hash = block.calculate_hash()
        self.chain.append(block)

    def is_valid(self):
        for i in range(1, len(self.chain)):
            current_block = self.chain[i]
            previous_block = self.chain[i - 1]

            if current_block.hash != current_block.calculate_hash():
                return False

            if current_block.previous_hash != previous_block.hash:
                return False

        return True

步骤 4: 创建交易类和节点

我们需要创建交易类来跟踪由一个地址发送到另一个地址的货币。这个类将具有发送方、接收方和金额等属性。下面是一个示例交易类:

class Transaction:
    def __init__(self, sender_address, recipient_address, amount):
        self.sender_address = sender_address
        self.recipient_address = recipient_address
        self.amount = amount

除了交易类之外,我们还需要创建一个节点类来充当区块链网络中的每个节点。节点将向其他节点广播新的块,并验证它们是否有效。以下是一个示例节点类:

import requests

class Node:
    def __init__(self, address):
        self.address = address

    def add_block(self, block):
        url = f"{self.address}/add_block"
        headers = {"Content-Type": "application/json"}
        data = json.dumps(block.__dict__, sort_keys=True)
        response = requests.post(url, headers=headers, data=data)

        if response.status_code == 200:
            return True
        else:
            return False

    def get_chain(self):
        url = f"{self.address}/get_chain"
        response = requests.get(url)

        if response.status_code == 200:
            chain_data = response.json()["chain"]
            chain = [Block(chain_data[i]["index"], 
                            chain_data[i]["transactions"],
                            chain_data[i]["timestamp"],
                            chain_data[i]["previous_hash"]) for i in range(len(chain_data))]
            return chain
        else:
            return None

步骤 5: 创建Flask应用程序

我们需要使用Flask框架创建一个Web应用程序来处理网络请求。这个应用程序将具有一些端点,例如添加新块、获取整个区块链等。以下是一个示例Flask应用程序:

from flask import Flask, jsonify, request

app = Flask(__name__)

# 创建节点列表
nodes = []

# 创建区块链实例
blockchain = Blockchain()

@app.route('/add_block', methods=['POST'])
def add_block():
    block_data = request.get_json()
    block = Block(block_data['index'],
                  block_data['transactions'],
                  block_data['timestamp'],
                  block_data['previous_hash'])
    blockchain.add_block(block)
    for node in nodes:
        node.add_block(block)
    return jsonify({'message': 'Block added successfully'}), 200

@app.route('/get_chain', methods=['GET'])
def get_chain():
    chain_data = []
    for block in blockchain.chain:
        chain_data.append(block.__dict__)
    return jsonify({"chain": chain_data})

@app.route('/register_node', methods=['POST'])
def register_node():
    node_address = request.get_json()["node_address"]
    if not node_address:
        return "Invalid data", 400
    node = Node(node_address)
    nodes.append(node)
    return jsonify({"message": "Node added successfully"}), 200

@app.route('/resolve_conflicts', methods=['GET'])
def resolve_conflicts():
    for node in nodes:
        chain = node.get_chain()
        if not chain:
            continue
        if len(chain) > len(blockchain.chain):
            blockchain.chain = chain
    return jsonify({"message": "Chain updated"}), 200

if __name__ == '__main__':
    app.run(port=8000)

步骤 6: 运行应用程序

我们可以运行我们的Flask应用程序并测试它是否正常工作。您可以使用Postman或任何其他Web API客户端测试不同的端点。

以下是一些测试交易和添加新块的示例代码:

# 创建两个节点
node1 = Node("http://localhost:8000")
node2 = Node("http://localhost:8001")

# 注册节点
node1.register_node(node2.address)
node2.register_node(node1.address)

# 添加交易
transaction = Transaction("address1", "address2", 10)

# 创建新块
block = Block(len(blockchain.chain), [transaction], time(), blockchain.get_latest_block().hash)

# 添加新块到区块链
node1.add_block(block)

恭喜!您已经成功创建了一个简单的区块链并创建了自己的加密货币。当然,这只是一个开始,还有许多其他功能可以添加,例如挖矿、共识算法、钱包等。但是,这个教程已经为您提供了一个很好的起点,让您开始理解如何使用Python构建一个区块链。

完整代码:

import hashlib
import json
from time import time
from urllib.parse import urlparse

import requests
from flask import Flask, jsonify, request


class Block:
    def __init__(self, index, transactions, timestamp, previous_hash):
        self.index = index
        self.transactions = transactions
        self.timestamp = timestamp
        self.previous_hash = previous_hash
        self.hash = self.calculate_hash()

    def calculate_hash(self):
        block_string = json.dumps(self.__dict__, sort_keys=True).encode()
        return hashlib.sha256(block_string).hexdigest()


class Blockchain:
    def __init__(self):
        self.chain = [self.create_genesis_block()]
        self.current_transactions = []
        self.nodes = set()

    def create_genesis_block(self):
        return Block(0, [], time(), "0")

    def add_transaction(self, transaction):
        self.current_transactions.append(transaction)

    def add_block(self, block):
        self.chain.append(block)
        self.current_transactions = []

    def get_latest_block(self):
        return self.chain[-1]

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

    def is_valid_proof(self, last_proof, proof):
        guess = f"{last_proof}{proof}".encode()
        guess_hash = hashlib.sha256(guess).hexdigest()
        return guess_hash[:4] == "0000"

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

    def is_valid_chain(self, chain):
        for i in range(1, len(chain)):
            current_block = chain[i]
            previous_block = chain[i - 1]

            if current_block.hash != current_block.calculate_hash():
                return False

            if current_block.previous_hash != previous_block.hash:
                return False

        return True

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

        for node in self.nodes:
            response = requests.get(f"http://{node}/get_chain")

            if response.status_code == 200:
                length = response.json()["length"]
                chain = response.json()["chain"]

                if length > max_length and self.is_valid_chain(chain):
                    max_length = length
                    new_chain = chain

        if new_chain:
            self.chain = new_chain
            return True

        return False


app = Flask(__name__)
blockchain = Blockchain()


@app.route("/mine_block", methods=["GET"])
def mine_block():
    last_block = blockchain.get_latest_block()
    last_proof = last_block.hash
    proof = blockchain.proof_of_work(last_proof)

    transaction = Transaction("0", "address1", 1)
    blockchain.add_transaction(transaction)

    block = Block(len(blockchain.chain), blockchain.current_transactions, time(), last_block.hash)
    blockchain.add_block(block)

    response = {"message": "New block mined",
                "index": block.index,
                "transactions": block.transactions,
                "timestamp": block.timestamp,
                "previous_hash": block.previous_hash,
                "hash": block.hash}

    return jsonify(response), 200


@app.route("/get_chain", methods=["GET"])
def get_chain():
    chain_data = []
    for block in blockchain.chain:
        chain_data.append(block.__dict__)

    response = {"length": len(chain_data),
                "chain": chain_data}
    return jsonify(response), 200


@app.route("/is_valid", methods=["GET"])
def is_valid():
    is_valid = blockchain.is_valid_chain(blockchain.chain)
    response = {"is_valid": is_valid}
    return jsonify(response), 200


class Transaction:
    def __init__(self, sender_address, recipient_address, amount):
        self.sender_address = sender_address
        self.recipient_address = recipient_address
        self.amount = amount


@app.route("/add_transaction", methods=["POST"])
def add_transaction():
    data = request.get_json()
    transaction = Transaction(data["sender_address"], data["recipient_address"], data["amount"])
    blockchain.add_transaction(transaction)

    response = {"message": "Transaction added",
                "transaction": {"sender_address": transaction.sender_address,
                                "recipient_address": transaction.recipient_address,
                                "amount": transaction.amount}}
    
    return jsonify(response), 201


@app.route("/connect_node", methods=["POST"])
def connect_node():
    data = request.get_json()
    node_address = data["node_address"]
if not node_address:
    return "Invalid data", 400

blockchain.register_node(node_address)

response = {"message": "Node added",
            "nodes": list(blockchain.nodes)}

return jsonify(response), 201
@app.route("/connect_network", methods=["POST"])
def connect_network():
data = request.get_json()
nodes = data["nodes"]
if nodes is None or len(nodes) == 0:
return "Invalid data", 400

for node in nodes:
    blockchain.register_node(node)

response = {"message": "Connected to network",
            "nodes": list(blockchain.nodes)}

return jsonify(response), 201
@app.route("/resolve_conflicts", methods=["GET"])
def resolve_conflicts():
conflicts_resolved = blockchain.resolve_conflicts()

if conflicts_resolved:
    response = {"message": "Chain updated",
                "chain": blockchain.chain}
else:
    response = {"message": "Chain authoritative",
                "chain": blockchain.chain}

return jsonify(response), 200
if name == "main":
app.run(host="0.0.0.0", port=5000)

这个代码实现了一个简单的区块链,其中包括创建新块、添加交易、连接网络节点和解决冲突等功能。您可以使用Postman或任何其他Web API客户端测试这些端点并查看它们的输出。

当然,这只是一个起点。随着您对区块链技术的理解和学习的深入,您可以将其扩展到更复杂的应用程序中,例如数字资产、智能合约等。

本文链接:http://task.lmcjl.com/news/11256.html

展开阅读全文