Flask 区域块简单原理实现

简介: 看了好几个从零开始建区块链的文章, 只有以下这几个URL实在, 于是,花了一晚上, 妥妥的自已手打一次, 感觉棒棒哒~~:)

看了好几个从零开始建区块链的文章,

只有以下这几个URL实在,

于是,花了一晚上,

妥妥的自已手打一次,

感觉棒棒哒~~:)


https://www.jianshu.com/p/ecfb2a9040a3

https://www.jianshu.com/p/b39c361687c1

https://www.jianshu.com/p/1e247faf8a15


ChgBlockChain.py


# coding=utf-8

import hashlib
import json
import datetime

from typing import Optional, Dict, Any, List
from urllib.parse import urlparse
import requests


class ComplexEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, datetime.datetime):
            return obj.strftime('%Y-%m-%d %H:%M:%S')
        else:
            return json.JSONEncoder.default(self, obj)


class ChgBlockChain(object):
    def __init__(self):
        self.chain = []
        self.current_transactions = []
        self.nodes = set()
        self.new_block(proof=100, prev_hash=1)

    def new_block(self,
                  proof: int,
                  prev_hash: Optional[str]
                  )->Dict[str, Any]:
        block = {
            "index": len(self.chain) + 1,
            "timestamp": datetime.datetime.now(),
            "transactions": self.current_transactions,
            "proof": proof,
            "prev_hash": prev_hash or self.hash(self.chain[-1])
        }

        self.current_transactions = []
        self.chain.append(block)

        return block

    def new_transaction(self, sender: str, recipient: str, amount: int)->int:
        self.current_transactions.append({
            "sender": sender,
            "recipient": recipient,
            "amount": amount
        })

        return self.last_block["index"] + 1

    @staticmethod
    def hash(block: Dict[str, Any])->str:
        block_str = json.dumps(block, sort_keys=True,  indent=4, cls=ComplexEncoder).encode("utf-8")

        return hashlib.sha256(block_str).hexdigest()

    @property
    def last_block(self)->Dict[str, Any]:

        return self.chain[-1]

    def proof_of_work(self, last_block)->int:
        last_proof = last_block["proof"]
        # last_hash = self.hash(last_block)

        proof = 0
        while self.valid_proof(last_proof, proof) is False:
            proof += 1

        return proof

    @staticmethod
    def valid_proof(last_proof: int, proof: int)->bool:
        guess = f'{last_proof}{proof}'.encode("utf-8")
        guess_hash = hashlib.sha256(guess).hexdigest()

        return guess_hash[:4] == "0000"

    def register_node(self, addr: str)->None:
        parsed_url = urlparse(addr)
        if parsed_url.netloc:
            self.nodes.add(parsed_url.netloc)
        elif parsed_url.path:
            self.nodes.add(parsed_url.path)
        else:
            raise ValueError("url invalid!")

    def valid_chain(self, chain: List[Dict[str, Any]])->bool:
        last_block = chain[0]
        current_index = 1

        while current_index < len(chain):
            block = chain[current_index]
            if block["prev_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

    def resolve_conflicts(self)->bool:
        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:
            return True
        else:
            return False





ChgCoinBlockNode.py



# coding=utf-8

from uuid import uuid4
from flask import Flask, jsonify, request

from ChgBlockChain import ChgBlockChain

chgCoin = ChgBlockChain()
node_id = str(uuid4()).replace("-", "")
print("current node wallet address: ", node_id)

app = Flask(__name__)
app.config['DEBUG'] = True
app.config['JSONIFY_PRETTYPRINT_REGULAR'] = True


@app.route("/")
def index_page():
    return "welcome to ChgCoin..."


@app.route("/chain")
def index_chain():
    response = {
        "chain": chgCoin.chain,
        "length": len(chgCoin.chain)
    }
    return jsonify(response), 200


@app.route("/mine")
def index_mine():
    last_block = chgCoin.last_block
    proof = chgCoin.proof_of_work(last_block)

    chgCoin.new_transaction(
        sender=0,
        recipient=node_id,
        amount=12.5
    )
    block = chgCoin.new_block(proof, chgCoin.hash(last_block))
    response = {
        "message": "new block created...",
        "index": block["index"],
        "transactions": block["transactions"],
        "proof": block["proof"],
        "hash": chgCoin.hash(block),
        "prev_hash": block["prev_hash"]
    }
    return jsonify(response), 200


@app.route("/new_transactions", methods=["POST"])
def index_new_transactions():
    values = request.get_json()
    required = ["sender", "recipient", "amount"]

    if not all(key in values for key in required):
        return "data is invalid", 400
    index = chgCoin.new_transaction(values["sender"],
                                    values["recipient"],
                                    values["amount"])
    response = {"message": f"transaction added to block{index}"}

    return jsonify(response), 201


@app.route("/new_node", methods=["POST"])
def index_new_node():
    values = request.get_json()
    nodes = values.get("nodes")

    if nodes is None:
        return "It's empty node"
    for node in nodes:
        chgCoin.register_node(node)

    response = {
        "message": "new node added to block",
        "nodes": list(chgCoin.nodes)
    }

    return jsonify(response), 201


@app.route("/node_refresh")
def index_node_refresh():
    replaced = chgCoin.resolve_conflicts()
    print(replaced)

    if replaced:
        response = {
            "message": "block chain is replaced by longest chain",
            "new chain": chgCoin.chain
        }
    else:
        response = {
            "message": "block chain is no need replaced ",
            "chain": chgCoin.chain
        }
    return jsonify(response), 200


if __name__ == '__main__':
   app.run("127.0.0.1", port=5005)



4b00a2ed91818f2ed484831e8c62f517408354b6

目录
相关文章
|
2月前
|
前端开发 Python
Flask原理解析
Flask原理解析
|
监控 Unix Linux
Flask项目能打包为单个exe文件运行?知道原理后简直不要太简单!
Python打包工具主要有三种:py2exe、PyInstaller和cx_Freeze。虽然是三种工具,但是实现打包的方式都是大同小异。无非将Python运行所需的基础dll文件和源码依赖的模块筛选后聚合在一起,从而达到脱离环境单独运行的目的。但其中比较新奇的是它们居然可以将最终代码打包成单个文件去运行,简直不要太神奇。 清风常用的打包工具为pyinstaller,安装下载简单,网上的文档也很齐全。
1321 0
|
10天前
|
开发框架 前端开发 JavaScript
利用Python和Flask构建轻量级Web应用的实战指南
利用Python和Flask构建轻量级Web应用的实战指南
33 2
|
19天前
|
JSON API 数据格式
如何使用Python和Flask构建一个简单的RESTful API。Flask是一个轻量级的Web框架
本文介绍了如何使用Python和Flask构建一个简单的RESTful API。Flask是一个轻量级的Web框架,适合小型项目和微服务。文章从环境准备、创建基本Flask应用、定义资源和路由、请求和响应处理、错误处理等方面进行了详细说明,并提供了示例代码。通过这些步骤,读者可以快速上手构建自己的RESTful API。
25 2
|
21天前
|
JSON API 数据格式
构建RESTful APIs:使用Python和Flask
构建RESTful APIs:使用Python和Flask
27 1
|
1月前
|
JSON API 数据格式
构建RESTful APIs:使用Python和Flask
【10月更文挑战第12天】本文介绍了如何使用Python和Flask构建一个简单的RESTful API。首先概述了API的重要性及RESTful API的基本概念,接着详细讲解了Flask框架的特性和安装方法。通过创建一个基本的Flask应用,定义了处理“图书”资源的GET、POST、PUT和DELETE方法的路由,展示了如何处理请求和响应,以及如何进行错误处理。最后,提供了运行和测试API的方法,总结了Flask在构建RESTful API方面的优势。
34 1
|
1月前
|
JSON API 数据格式
构建RESTful APIs:使用Python和Flask
【10月更文挑战第10天】本文介绍了如何使用Python和Flask构建一个简单的RESTful API。Flask是一个轻量级的Web应用框架,适合小型项目和微服务。文章从环境准备、创建基本Flask应用、定义资源和路由、请求和响应处理、错误处理等方面进行了详细说明,并提供了代码示例。通过这些步骤,读者可以快速掌握使用Flask构建RESTful API的方法。
51 1
|
1月前
|
数据库 开发者 Python
使用Python和Flask构建Web应用
【10月更文挑战第2天】使用Python和Flask构建Web应用
26 2
|
1月前
|
API 数据库 开发者
Flask:Python的轻量级Web框架
Flask:Python的轻量级Web框架
34 2
|
2月前
|
数据采集 NoSQL 调度
flask celery python 每月定时任务
flask celery python 每月定时任务