Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Bagaimana Python membina rantaian blok

Bagaimana Python membina rantaian blok

WBOY
WBOYke hadapan
2023-05-12 17:55:061687semak imbas

Blockchain

Blockchain ialah lejar (pangkalan data teragih) yang berkongsi data antara nod dalam rangkaian komputer. Sebagai pangkalan data, blockchain menyimpan maklumat dalam format elektronik. Inovasi blockchain ialah ia menjamin keselamatan, ketulenan dan kredibiliti rekod data (tanpa memerlukan pihak ketiga yang dipercayai).

Perbezaan antara blockchain dan pangkalan data biasa ialah struktur data. Blockchain mengumpul maklumat dengan cara block.

sekat

block ialah struktur data yang boleh merekodkan data transaksi mata wang kripto (atau tujuan lain) secara kekal. Sama seperti senarai terpaut. A block merekodkan beberapa transaksi terbaharu kebakaran yang masih belum disahkan. Setelah data telah disahkan, block akan ditutup dan block baharu akan dibuat untuk memasuki dan mengesahkan transaksi baharu. Oleh itu, apabila ditulis, ia tidak boleh diubah atau dipadamkan secara kekal.

  • block ialah tempat maklumat disimpan dan disulitkan dalam rantaian blok

  • block dikenal pasti dengan nombor panjang yang termasuk yang sebelumnya penyulitan Maklumat transaksi yang disulitkan bagi blok dan maklumat transaksi baharu

  • sebelum dibuat, block dan maklumat di dalamnya mesti disahkan oleh rangkaian

di bawah ialah contoh mudah:

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

Matlamat

Matlamat blockchain adalah untuk membenarkan maklumat digital direkodkan dan diedarkan, tetapi tidak diedit. Dengan cara ini, blockchain menjadi asas untuk lejar tidak berubah, atau rekod transaksi yang tidak boleh diubah, dipadam dan dimusnahkan.

Desentralisasi

Bayangkan sebuah syarikat dengan 10,000 pelayan mengekalkan pangkalan data yang mengandungi semua maklumat pelanggan. Semua pelayan syarikat berada dalam satu gudang, dengan kawalan penuh ke atas setiap pelayan. Ini memberikan satu titik kegagalan. Bagaimana jika kuasa padam di tempat itu? Bagaimana jika sambungan internetnya terputus? Walau apa pun, data boleh hilang atau rosak.

Membina

Kelas Blockchain

Kami akan mencipta kelas BlockChain, pembina mencipta senarai kosong untuk menyimpan blokchain, dan kemudian mencipta senarai kosong untuk Simpan transaksi . Cipta 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

Tambah transaksi

Kami memerlukan cara untuk menambah transaksi pada blok. new_transaction bertanggungjawab untuk ini

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

Selepas new_transaction menambah urus niaga pada senarai, ia mengembalikan indeks blok urus niaga akan ditambah kepada - blok seterusnya untuk dilombong. Ini akan berguna kemudian kepada pengguna yang menyerahkan transaksi.

Buat blok baharu

Apabila blockchain kami diwujudkan, kami perlu menyemainya dengan blok genesis - blok tanpa pendahulu. Kami juga perlu menambah "bukti" pada blok genesis kami, yang merupakan hasil perlombongan (atau bukti kerja). Selain mencipta blok genesis dalam pembina kami, kami juga akan menyempurnakan kaedah new_block(), new_transaction(), dan 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()

Pada ketika ini, kami hampir selesai mewakili Blockchain kawasan kami . Tetapi pada ketika ini, anda mesti tertanya-tanya bagaimana blok baharu dicipta, dipalsukan atau dilombong.

POW

Proof of Work (PoW) ialah satu cara untuk mencipta atau melombong blok baharu pada blockchain dengan matlamat untuk menemui nombor yang menyelesaikan masalah. Nombor ini mesti sukar dicari tetapi mudah disahkan oleh sesiapa sahaja di web. PoW digunakan secara meluas dalam perlombongan mata wang kripto untuk mengesahkan transaksi dan melombong syiling baharu. Terima kasih kepada PoW, Bitcoin dan urus niaga mata wang kripto lain boleh diproses peer-to-peer dengan cara yang selamat tanpa memerlukan pihak ketiga yang dipercayai.

Mari kita laksanakan algoritma yang serupa:

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

Untuk membolehkan blockchain berinteraksi, kami memerlukan pelayan web untuk mengehoskannya. Di sini kami menggunakan bingkai Flask.

Jika tidak dipasang, anda perlu memasangnyaflask

pip install flask

Pelayan kami akan membentuk satu unit dalam rangkaian blockchain kami Nod, buat app.py:

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('_', '')
# 实例化block_chain类
block_chain = Blockchain()
# 创建/mine端点
@app.route('/mine', methods=['GET'])
def mine():
    block_chain.new_transaction(
        sender="0",
        recipient=node_identifier,
        amount=1,
    )
    last_block = block_chain.last_block
    last_proof = last_block['proof']
    proof = block_chain.proof_of_work(last_proof)
    previous_hash = block_chain.hash(last_block)
    block = block_chain.new_block(proof, previous_hash)
    response = {
        'message': "New Block Forged",
        'index': block['index'],
        'transactions': block['transactions'],
        'proof': block['proof'],
        'previous_hash': block['previous_hash'],
    }
    return jsonify(response), 200
@app.route('/transactions/new', methods=['POST'])
def new_transaction():
    return "We'll add a new transaction"
@app.route('/chain', methods=['GET'])
def full_chain():
    response = {
        'chain': block_chain.chain,
        'length': len(block_chain.chain),
    }
    return jsonify(response), 200
# 修改端口号
if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

dalam direktori tahap yang sama dan kemudian jalankan

flask run

melalui perisian api (menggunakan ini masa adalah api fox) untuk menghantar permintaan:

Bagaimana Python membina rantaian blok

Bagaimana Python membina rantaian blok

Daftar nod baharu

Inti utama blockchain ialah mereka harus Desentralisasi. Jika anda ingin mempunyai berbilang nod dalam rangkaian, anda mesti menggunakan algoritma konsensus. Sebelum kita boleh melaksanakan algoritma konsensus, kita memerlukan cara untuk nod mengetahui nod jiran mereka pada rangkaian. Setiap nod pada rangkaian kami harus mengekalkan pendaftaran nod lain pada rangkaian. Oleh itu, kita memerlukan lebih banyak titik akhir:

...
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)

Konflik

Konflik ialah apabila satu nod mempunyai rantaian yang berbeza daripada nod yang lain. Untuk menyelesaikan masalah ini, kami akan membangunkan peraturan bahawa rantaian sah terpanjang ialah pihak berkuasa. Menggunakan algoritma ini, kami mencapai konsensus antara nod dalam rangkaian.

...
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来进行尝试。

Atas ialah kandungan terperinci Bagaimana Python membina rantaian blok. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:yisu.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam