Heim  >  Artikel  >  Backend-Entwicklung  >  Wie Python eine Blockchain aufbaut

Wie Python eine Blockchain aufbaut

WBOY
WBOYnach vorne
2023-05-12 17:55:061691Durchsuche

Blockchain

Blockchain ist ein Hauptbuch (verteilte Datenbank), das Daten zwischen Knoten in einem Computernetzwerk austauscht. Als Datenbank speichert die Blockchain Informationen in einem elektronischen Format. Die Innovation der Blockchain besteht darin, dass sie die Sicherheit, Authentizität und Glaubwürdigkeit von Datensätzen gewährleistet (ohne dass ein vertrauenswürdiger Dritter erforderlich ist).

Der Unterschied zwischen Blockchain und typischen Datenbanken ist die Datenstruktur. Blockchain sammelt Informationen in Form von Block. block的方式收集信息。

block

block是一种能永久记录加密货币交易数据(或其他用途)的一种数据结构。类似于链表。一个block记录了一些火所有尚未被验证的最新交易。验证数据后,block将关闭,之后会创建一个新的block来输入和验证新的交易。因此,一旦写入,永久不能更改和删除。

  • block是区块链中存储和加密信息的地方

  • block由长数字标识,其中包括先前加密块的加密交易信息和新的交易信息

  • 在创建之前,block以及其中的信息必须由网络验证

以下是一个简单的例子:

block = {
    'index': 1,
    'timestamp': 1506057125.900785,
    'transactions': [
        {
            'sender': "8527147fe1f5426f9dd545de4b27ee00",
            'recipient': "a77f5cdfa2934df3954a5c7c7da5df1f",
            'amount': 5,
        }
    ],
    'proof': 324984774000,
    'previous_hash': "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824"
}

目标

区块链的目标是允许数字信息被记录和分发,但不能编辑。通过这种方式,区块链成为了不可变分类账或无法更改、删除和销毁的交易记录的基础。

去中心化

想象一下,一家公司拥有10000台服务器,用于维护一个包含所有客户信息的数据库。公司的所有服务器都在一个仓库中,可以完全控制每台服务器。这就提供了单点故障。如果那个地方停电了怎么办?如果他的网络连接被切断了怎么办?在任何情况下,数据都会丢失或损坏。

构建

区块链类

我们将创建一个BlockChain类,构造函数创建一个空列表来存储区块链,再创建一个空列表来存储交易。创建block_chain.py

# block_chain.py
class Blockchain:
    def __init__(self) -> None:
        self.chain = []
        self.current_transactions = []
    def new_block(self):
        # Creates a new Block and adds it to the chain
        pass
    def new_transaction(self):
        # Adds a new transaction to the list of transactions
        pass
    @staticmethod
    def hash(block):
        # Hashes a Block
        pass
    @property
    def last_block(self):
        # Returns the last Block in the chain
        pass

添加交易

我们需要一种将交易添加到区块的方法。new_transaction负责这个

class Blockchain(object):
    ...
    def new_transaction(self, sender, recipient, amount) -> int:
        self.current_transactions.append({
            'sender': sender,
            'recipient': recipient,
            'amount': amount,
        })
        return self.last_block['index'] + 1

new_transaction 将交易添加到列表后,它返回交易将被添加到的块的索引——下一个要挖掘的块。这将在以后对提交交易的用户有用。

创建新blocks

当我们的区块链被实例化时,我们需要为它播种一个创世块——一个没有前辈的块。我们还需要向我们的创世块添加一个“证明”,这是挖掘的结果(或工作量证明)。除了在我们的构造函数中创建创世块之外,我们还将充实 new_block()、new_transaction() 和 hash() 的方法:

import hashlib
import json
from time import time
class Blockchain:
    def __init__(self) -> None:
        self.chain = []
        self.current_transactions = []
        # Create the genesis block
        self.new_block(previous_hash=1, proof=100)
    def new_block(self, proof, previous_hash=None) -> dict:
        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) -> int:
        self.current_transactions.append(
            {
                'sender': sender,
                'recipient': recipient,
                'amount': amount,
            }
        )
        return self.last_block['index'] + 1
    @property
    def last_block(self) -> dict:
        # Returns the last Block in the chain
        return self.chain[-1]
    @staticmethod
    def hash(block) -> str:       
        block_string = json.dumps(block, sort_keys=True).encode()
        return hashlib.sha256(block_string).hexdigest()

到这里,我们几乎完成了代表我们的区块链。但此时,你一定想知道新区块是如何创建、锻造或开采的。

POW

工作量证明算法 (PoW) 是在区块链上创建或挖掘新块的方式,它的目标是发现一个解决问题的数字。这个数字必须很难找到但很容易被网络上的任何人验证。PoW广泛用于加密货币挖掘,用于验证交易和挖掘新代币。由于PoW,比特币和其他加密货币交易可以以安全的方式进行点对点处理,而无需受信任的第三方。

让我们实现一个类似的算法:

class Blockchain(object):
    def proof_of_work(self, last_proof) -> int:
        proof = 0
        while self.valid_proof(last_proof, proof) is False:
            proof += 1
        return proof
    @staticmethod
    def valid_proof(last_proof, proof) -> bool:
        guess = f'{last_proof}{proof}'.encode()
        guess_hash = hashlib.sha256(guess).hexdigest()
        return guess_hash[:4] == '0000'

API

为了使区块链能够交互,我们需要一个将其置于web服务器上。这里我们是用Flask框架。

如果没有安装,需要安装flask

pip install flask

我们的服务器将在我们的区块链网络中形成单一节点,在同级目录下创建一个app.py

block

block ist eine Datenstruktur, die Kryptowährungstransaktionsdaten (oder andere Zwecke) dauerhaft aufzeichnen kann. Ähnlich einer verknüpften Liste. Ein Block zeichnet alle letzten Transaktionen auf, die noch nicht verifiziert wurden. Nach der Überprüfung der Daten wird der Block geschlossen und ein neuer Block erstellt, um neue Transaktionen einzugeben und zu überprüfen. Daher kann es, sobald es geschrieben wurde, nicht dauerhaft geändert oder gelöscht werden.
  • block ist der Ort, an dem Informationen in der Blockchain gespeichert und verschlüsselt werden

block code> Wird durch eine lange Zahl identifiziert, die die verschlüsselten Transaktionsinformationen des zuvor verschlüsselten Blocks und die neuen Transaktionsinformationen enthält. <p></p> <li>Vor der Erstellung müssen der <code>Block und die darin enthaltenen Informationen angegeben werden durch die Netzwerkverifizierung bestimmt werden

Wie Python eine Blockchain aufbautHier ist ein einfaches Beispiel:
from uuid import uuid4
from time import time
from textwrap import dedent
from flask import Flask, jsonify, request
from block_chain import Blockchain
# 实例化应用
app = Flask(__name__)
# 创建随机节点名称
node_identifier = str(uuid4()).replace(&#39;_&#39;, &#39;&#39;)
# 实例化block_chain类
block_chain = Blockchain()
# 创建/mine端点
@app.route(&#39;/mine&#39;, methods=[&#39;GET&#39;])
def mine():
    block_chain.new_transaction(
        sender="0",
        recipient=node_identifier,
        amount=1,
    )
    last_block = block_chain.last_block
    last_proof = last_block[&#39;proof&#39;]
    proof = block_chain.proof_of_work(last_proof)
    previous_hash = block_chain.hash(last_block)
    block = block_chain.new_block(proof, previous_hash)
    response = {
        &#39;message&#39;: "New Block Forged",
        &#39;index&#39;: block[&#39;index&#39;],
        &#39;transactions&#39;: block[&#39;transactions&#39;],
        &#39;proof&#39;: block[&#39;proof&#39;],
        &#39;previous_hash&#39;: block[&#39;previous_hash&#39;],
    }
    return jsonify(response), 200
@app.route(&#39;/transactions/new&#39;, methods=[&#39;POST&#39;])
def new_transaction():
    return "We&#39;ll add a new transaction"
@app.route(&#39;/chain&#39;, methods=[&#39;GET&#39;])
def full_chain():
    response = {
        &#39;chain&#39;: block_chain.chain,
        &#39;length&#39;: len(block_chain.chain),
    }
    return jsonify(response), 200
# 修改端口号
if __name__ == &#39;__main__&#39;:
    app.run(host=&#39;0.0.0.0&#39;, port=5000)

Ziel Wie Python eine Blockchain aufbaut

Das Ziel der Blockchain ist es, die Aufzeichnung und Verteilung digitaler Informationen zu ermöglichen, diese sind jedoch nicht bearbeitbar. Auf diese Weise wird die Blockchain zur Grundlage für ein unveränderliches Hauptbuch oder eine Aufzeichnung von Transaktionen, die nicht geändert, gelöscht oder zerstört werden kann.

Dezentralisierung

Stellen Sie sich ein Unternehmen mit 10.000 Servern vor, das eine Datenbank mit allen Kundeninformationen verwaltet. Alle Server des Unternehmens befinden sich in einem Lager und haben die volle Kontrolle über jeden Server. Dies stellt einen Single Point of Failure dar. Was passiert, wenn dort der Strom ausfällt? Was passiert, wenn seine Internetverbindung unterbrochen wird? In jedem Fall können Daten verloren gehen oder beschädigt werden.

Building

Blockchain-Klasse🎜🎜Wir erstellen eine BlockChain-Klasse, der Konstruktor erstellt eine leere Liste zum Speichern der Blockchain und erstellt dann eine leere Liste zum Speichern der Transaktionen. Erstellen Sie block_chain.py🎜
...
from urllib.parse import urlparse
...
class Blockchain:
    def __init__(self) -> None:
        ...
        self.nodes = set()
        ...
    def register_node(self, address) -> None:    
        parsed_url = urlparse(address)
        self.nodes.add(parsed_url.netloc)
🎜Transaktionen hinzufügen🎜🎜Wir brauchen eine Möglichkeit, Transaktionen zum Block hinzuzufügen. new_transaction ist dafür verantwortlich 🎜
...
import requests
class Blockchain:
    ...
    def valid_chain(self, chain):
        last_block = chain[0]
        current_index = 1
        while current_index < len(chain):
            block = chain[current_index]
            print(f&#39;{last_block}&#39;)
            print(f&#39;{block}&#39;)
            print("\n-----------\n")
            # Check that the hash of the block is correct
            if block[&#39;previous_hash&#39;] != self.hash(last_block):
                return False
            # Check that the Proof of Work is correct
            if not self.valid_proof(last_block[&#39;proof&#39;], block[&#39;proof&#39;]):
                return False
            last_block = block
            current_index += 1
        return True
    def resolve_conflicts(self):
        """
        This is our Consensus Algorithm, it resolves conflicts
        by replacing our chain with the longest one in the network.
        :return: <bool> True if our chain was replaced, False if not
        """
        neighbours = self.nodes
        new_chain = None
        # We&#39;re only looking for chains longer than ours
        max_length = len(self.chain)
        # Grab and verify the chains from all the nodes in our network
        for node in neighbours:
            response = requests.get(f&#39;http://{node}/chain&#39;)
            if response.status_code == 200:
                length = response.json()[&#39;length&#39;]
                chain = response.json()[&#39;chain&#39;]
                # Check if the length is longer and the chain is valid
                if length > max_length and self.valid_chain(chain):
                    max_length = length
                    new_chain = chain
        # Replace our chain if we discovered a new, valid chain longer than ours
        if new_chain:
            self.chain = new_chain
            return True
        return False
🎜Nachdem new_transaction die Transaktion zur Liste hinzugefügt hat, wird der Index des Blocks zurückgegeben, zu dem die Transaktion hinzugefügt wird – der nächste Block abgebaut werden. Dies wird später für den Benutzer nützlich sein, der die Transaktion übermittelt hat. 🎜🎜Neue Blöcke erstellen🎜🎜Wenn unsere Blockchain instanziiert ist, müssen wir sie mit einem Genesis-Block versehen – einem Block ohne Vorgänger. Wir müssen unserem Genesis-Block auch einen „Beweis“ hinzufügen, der das Ergebnis des Minings (oder Arbeitsnachweises) ist. Zusätzlich zum Erstellen des Genesis-Blocks in unserem Konstruktor werden wir auch die Methoden new_block(), new_transaction() und hash() konkretisieren: 🎜
@app.route(&#39;/nodes/register&#39;, methods=[&#39;POST&#39;])
def register_nodes():
    values = request.get_json()
    nodes = values.get(&#39;nodes&#39;)
    if nodes is None:
        return "Error: Please supply a valid list of nodes", 400
    for node in nodes:
        blockchain.register_node(node)
    response = {
        &#39;message&#39;: &#39;New nodes have been added&#39;,
        &#39;total_nodes&#39;: list(blockchain.nodes),
    }
    return jsonify(response), 201
@app.route(&#39;/nodes/resolve&#39;, methods=[&#39;GET&#39;])
def consensus():
    replaced = blockchain.resolve_conflicts()
    if replaced:
        response = {
            &#39;message&#39;: &#39;Our chain was replaced&#39;,
            &#39;new_chain&#39;: blockchain.chain
        }
    else:
        response = {
            &#39;message&#39;: &#39;Our chain is authoritative&#39;,
            &#39;chain&#39;: blockchain.chain
        }
    return jsonify(response), 200
🎜An diesem Punkt sind wir fast fertig mit der Darstellung unserer Blockchain. Aber an diesem Punkt fragen Sie sich bestimmt, wie neue Blöcke erstellt, gefälscht oder abgebaut werden. 🎜🎜POW🎜🎜Proof-of-Work (PoW) ist eine Möglichkeit, neue Blöcke auf einer Blockchain zu erstellen oder abzubauen, mit dem Ziel, eine Zahl zu ermitteln, die ein Problem löst. Diese Nummer dürfte schwer zu finden sein, aber von jedem im Internet leicht überprüft werden können. PoW wird im Kryptowährungs-Mining häufig zur Validierung von Transaktionen und zum Mining neuer Münzen eingesetzt. Dank PoW können Bitcoin- und andere Kryptowährungstransaktionen sicher Peer-to-Peer abgewickelt werden, ohne dass ein vertrauenswürdiger Dritter erforderlich ist. 🎜🎜Lassen Sie uns einen ähnlichen Algorithmus implementieren: 🎜rrreee🎜API🎜🎜Damit die Blockchain interagieren kann, benötigen wir eine Möglichkeit, sie auf einen Webserver zu stellen. Hier verwenden wir das Flask-Framework. 🎜🎜Wenn es nicht installiert ist, müssen Sie flask installieren. 🎜🎜🎜pip install flask🎜🎜🎜Unser Server bildet einen einzelnen Knoten in unserem Blockchain-Netzwerk. Erstellen Sie einen im selben Verzeichnis >app.py:🎜rrreee🎜Dann ausführen🎜🎜🎜flask run🎜🎜🎜Senden Sie die Anfrage über die API-Software (diesmal mit API Fox):🎜🎜🎜🎜🎜🎜🎜🎜Registrieren Sie einen neuen Knoten🎜 🎜Der springende Punkt bei Blockchains ist, dass sie dezentralisiert sein sollten. Wenn Sie mehrere Knoten im Netzwerk haben möchten, müssen Sie einen Konsensalgorithmus verwenden. Bevor wir einen Konsensalgorithmus implementieren können, benötigen wir eine Möglichkeit für Knoten, ihre Nachbarknoten im Netzwerk zu kennen. Jeder Knoten in unserem Netzwerk sollte eine Registrierung anderer Knoten im Netzwerk führen. Deshalb brauchen wir mehr Endpunkte: 🎜rrreee🎜Konflikte🎜🎜Ein Konflikt liegt vor, wenn ein Knoten eine andere Kette hat als ein anderer Knoten. Um dieses Problem zu lösen, werden wir die Regel entwickeln, dass die längste gültige Kette die Autorität ist. Mit diesem Algorithmus erreichen wir einen Konsens zwischen den Knoten im Netzwerk. 🎜
...
import requests
class Blockchain:
    ...
    def valid_chain(self, chain):
        last_block = chain[0]
        current_index = 1
        while current_index < len(chain):
            block = chain[current_index]
            print(f&#39;{last_block}&#39;)
            print(f&#39;{block}&#39;)
            print("\n-----------\n")
            # Check that the hash of the block is correct
            if block[&#39;previous_hash&#39;] != self.hash(last_block):
                return False
            # Check that the Proof of Work is correct
            if not self.valid_proof(last_block[&#39;proof&#39;], block[&#39;proof&#39;]):
                return False
            last_block = block
            current_index += 1
        return True
    def resolve_conflicts(self):
        """
        This is our Consensus Algorithm, it resolves conflicts
        by replacing our chain with the longest one in the network.
        :return: <bool> True if our chain was replaced, False if not
        """
        neighbours = self.nodes
        new_chain = None
        # We&#39;re only looking for chains longer than ours
        max_length = len(self.chain)
        # Grab and verify the chains from all the nodes in our network
        for node in neighbours:
            response = requests.get(f&#39;http://{node}/chain&#39;)
            if response.status_code == 200:
                length = response.json()[&#39;length&#39;]
                chain = response.json()[&#39;chain&#39;]
                # Check if the length is longer and the chain is valid
                if length > max_length and self.valid_chain(chain):
                    max_length = length
                    new_chain = chain
        # Replace our chain if we discovered a new, valid chain longer than ours
        if new_chain:
            self.chain = new_chain
            return True
        return False

第一个方法 valid_chain() 负责通过遍历每个块并验证哈希和证明来检查链是否有效。resolve_conflicts() 是一种循环遍历我们所有相邻节点、下载它们的链并使用上述方法验证它们的方法。如果找到一个有效的链,其长度大于我们的,我们将替换我们的。

让我们将两个端点注册到我们的 API,一个用于添加相邻节点,另一个用于解决冲突:

@app.route(&#39;/nodes/register&#39;, methods=[&#39;POST&#39;])
def register_nodes():
    values = request.get_json()
    nodes = values.get(&#39;nodes&#39;)
    if nodes is None:
        return "Error: Please supply a valid list of nodes", 400
    for node in nodes:
        blockchain.register_node(node)
    response = {
        &#39;message&#39;: &#39;New nodes have been added&#39;,
        &#39;total_nodes&#39;: list(blockchain.nodes),
    }
    return jsonify(response), 201
@app.route(&#39;/nodes/resolve&#39;, methods=[&#39;GET&#39;])
def consensus():
    replaced = blockchain.resolve_conflicts()
    if replaced:
        response = {
            &#39;message&#39;: &#39;Our chain was replaced&#39;,
            &#39;new_chain&#39;: blockchain.chain
        }
    else:
        response = {
            &#39;message&#39;: &#39;Our chain is authoritative&#39;,
            &#39;chain&#39;: blockchain.chain
        }
    return jsonify(response), 200

在这一点上,如果你愿意,你可以拿一台不同的机器,并在你的网络上启动不同的节点。或者在同一台机器上使用不同的端口启动进程。比如创建两个端口5000和6000来进行尝试。

Das obige ist der detaillierte Inhalt vonWie Python eine Blockchain aufbaut. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:yisu.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen