0

0

Python如何制作区块链浏览器?Flask+Web3.py

蓮花仙者

蓮花仙者

发布时间:2025-08-14 16:49:02

|

489人浏览过

|

来源于php中文网

原创

python制作区块链浏览器的核心是结合flask和web3.py库,1. 安装flask和web3库;2. 使用web3.py连接以太坊节点(如infura或本地ganache);3. 通过flask创建路由展示最新区块、区块详情、交易详情和地址信息;4. 利用jinja2模板渲染前端页面;5. 实现搜索功能跳转至对应数据页面;最终实现一个可查询区块链数据的简易浏览器,完整且可运行。

Python如何制作区块链浏览器?Flask+Web3.py

用Python制作一个区块链浏览器,核心在于巧妙结合Flask这个轻量级Web框架和Web3.py库,后者是Python与以太坊区块链交互的强大桥梁。这套组合能让你从零开始,搭建一个能查看区块、交易和地址信息的简易版浏览器。说起来,这事儿比想象中要“接地气”,并非高不可攀,更多是数据获取与前端展示的串联。

解决方案

要动手干这事儿,我们得先搭好架子。Flask负责骨架,Web3.py负责血肉,它们俩得配合得天衣无缝。

首先,确保你的Python环境准备妥当,然后安装必要的库:

立即学习Python免费学习笔记(深入)”;

pip install Flask web3

接下来,我们来构建核心逻辑。一个简单的Flask应用,它会连接到以太坊节点,并尝试获取最新的区块信息。

1. 后端核心 (

app.py
)

PathFinder
PathFinder

AI驱动的销售漏斗分析工具

下载
from flask import Flask, render_template, request, redirect, url_for
from web3 import Web3
from web3.exceptions import Web3Exception # 引入异常处理

app = Flask(__name__)

# 连接到以太坊节点
# 推荐使用Infura、Alchemy等服务,它们提供稳定的API接口
# 记得替换 YOUR_INFURA_PROJECT_ID 为你自己的项目ID
# infura_url = "https://mainnet.infura.io/v3/YOUR_INFURA_PROJECT_ID"
# w3 = Web3(Web3.HTTPProvider(infura_url))

# 开发测试时,也可以连接本地Ganache或Geth节点
# w3 = Web3(Web3.HTTPProvider('http://127.0.0.1:8545')) # Ganache默认端口

# 确保连接成功,如果连接失败,这里会抛出异常或返回False
try:
    # 尝试连接到Infura公共节点,如果你的Infura ID是空的,这里会失败
    # 也可以直接用一个公共的测试网节点,例如 Goerli
    w3 = Web3(Web3.HTTPProvider('https://goerli.infura.io/v3/YOUR_INFURA_PROJECT_ID'))
    if not w3.is_connected():
        print("警告:未能连接到以太坊节点,请检查网络或Infura ID。")
        w3 = None # 设置为None,后续逻辑会处理
except Web3Exception as e:
    print(f"连接Web3时发生错误: {e}")
    w3 = None


@app.route('/')
def index():
    if not w3 or not w3.is_connected():
        return "未能连接到区块链网络,请检查后端服务配置或网络连接。", 500

    try:
        latest_block_number = w3.eth.block_number
        latest_block = w3.eth.get_block(latest_block_number)
        # 简化处理,只传递部分信息给模板
        block_info = {
            'number': latest_block.number,
            'hash': latest_block.hash.hex(),
            'timestamp': latest_block.timestamp,
            'transactions_count': len(latest_block.transactions),
            'miner': latest_block.miner,
            'gas_used': latest_block.gasUsed,
            'gas_limit': latest_block.gasLimit,
            'parent_hash': latest_block.parentHash.hex()
        }
        return render_template('index.html', block=block_info)
    except Exception as e:
        return f"获取最新区块信息失败: {e}", 500

@app.route('/block/<int:block_number>')
def get_block_details(block_number):
    if not w3 or not w3.is_connected():
        return "未能连接到区块链网络。", 500
    try:
        block = w3.eth.get_block(block_number, full_transactions=False) # full_transactions=False 减少数据量
        if not block:
            return "区块未找到。", 404

        block_info = {
            'number': block.number,
            'hash': block.hash.hex(),
            'timestamp': block.timestamp,
            'transactions_count': len(block.transactions),
            'miner': block.miner,
            'gas_used': block.gasUsed,
            'gas_limit': block.gasLimit,
            'parent_hash': block.parentHash.hex(),
            'transactions': [tx.hex() for tx in block.transactions] # 只显示交易哈希
        }
        return render_template('block_details.html', block=block_info)
    except Exception as e:
        return f"获取区块 {block_number} 详情失败: {e}", 500

@app.route('/tx/<string:tx_hash>')
def get_transaction_details(tx_hash):
    if not w3 or not w3.is_connected():
        return "未能连接到区块链网络。", 500
    try:
        # 确保哈希格式正确
        if not tx_hash.startswith('0x') or len(tx_hash) != 66:
            return "无效的交易哈希格式。", 400

        tx = w3.eth.get_transaction(tx_hash)
        if not tx:
            return "交易未找到。", 404

        tx_receipt = w3.eth.get_transaction_receipt(tx_hash) # 获取交易收据以获得状态、gas消耗等

        tx_info = {
            'hash': tx.hash.hex(),
            'block_number': tx.blockNumber,
            'from': tx['from'],
            'to': tx['to'],
            'value': w3.from_wei(tx.value, 'ether'), # 转换为ETH
            'gas_price': w3.from_wei(tx.gasPrice, 'gwei'), # 转换为Gwei
            'gas_limit': tx.gas,
            'nonce': tx.nonce,
            'input': tx.input, # 智能合约调用数据
            'status': '成功' if tx_receipt and tx_receipt.status == 1 else '失败',
            'gas_used': tx_receipt.gasUsed if tx_receipt else 'N/A'
        }
        return render_template('transaction_details.html', tx=tx_info)
    except Exception as e:
        return f"获取交易 {tx_hash} 详情失败: {e}", 500

@app.route('/address/<string:address>')
def get_address_details(address):
    if not w3 or not w3.is_connected():
        return "未能连接到区块链网络。", 500
    try:
        # 确保地址格式正确
        if not w3.is_address(address):
            return "无效的以太坊地址格式。", 400

        balance_wei = w3.eth.get_balance(address)
        balance_eth = w3.from_wei(balance_wei, 'ether')

        # 简单展示,不获取所有交易(这会非常慢且消耗资源)
        # 实际项目中,需要通过第三方API或索引服务获取地址交易历史
        address_info = {
            'address': address,
            'balance': balance_eth
        }
        return render_template('address_details.html', address=address_info)
    except Exception as e:
        return f"获取地址 {address} 详情失败: {e}", 500

# 搜索功能
@app.route('/search', methods=['GET'])
def search():
    query = request.args.get('query', '').strip()
    if not query:
        return redirect(url_for('index'))

    # 尝试作为区块号
    if query.isdigit():
        return redirect(url_for('get_block_details', block_number=int(query)))
    # 尝试作为交易哈希
    elif query.startswith('0x') and len(query) == 66:
        return redirect(url_for('get_transaction_details', tx_hash=query))
    # 尝试作为地址
    elif query.startswith('0x') and len(query) == 42: # 以太坊地址长度
        return redirect(url_for('get_address_details', address=query))
    else:
        return "未识别的查询类型(请输入区块号、交易哈希或地址)。", 400

if __name__ == '__main__':
    app.run(debug=True)

2. 前端模板 (

templates/index.html
,
block_details.html
,
transaction_details.html
,
address_details.html
)

在项目根目录下创建

templates
文件夹,并放入以下HTML文件。

templates/base.html
(基础布局,方便复用)

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{% block title %}简易区块链浏览器{% endblock %}</title>
    <style>
        body { font-family: sans-serif; margin: 20px; background-color: #f4f7f6; color: #333; }
        .container { max-width: 900px; margin: 0 auto; background-color: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
        h1, h2 { color: #007bff; }
        .data-item { margin-bottom: 10px; border-bottom: 1px dashed #eee; padding-bottom: 5px; }
        .data-item strong { display: inline-block; width: 120px; color: #555; }
        a { color: #007bff; text-decoration: none; }
        a:hover { text-decoration: underline; }
        .search-box { margin-bottom: 20px; padding: 15px; background-color: #e9ecef; border-radius: 5px; display: flex; align-items: center; }
        .search-box input[type="text"] { flex-grow: 1; padding: 8px; border: 1px solid #ccc; border-radius: 4px; margin-right: 10px; }
        .search-box button { padding: 8px 15px; background-color: #28a745; color: white; border: none; border-radius: 4px; cursor: pointer; }
        .search-box button:hover { background-color: #218838; }
        .error-message { color: red; font-weight: bold; }
    </style>
</head>
<body>
    <div class="container">
        <header>
            <h1><a href="/">简易区块链浏览器</a></h1>
            <div class="search-box">
                <form action="/search" method="GET" style="display: flex; width: 100%;">
                    <input type="text" name="query" placeholder="搜索区块号 / 交易哈希 / 地址" size="50">
                    <button type="submit">搜索</button>
                </form>
            </div>
        </header>
        <main>
            {% block content %}{% endblock %}
        </main>
    </div>
</body>
</html>

templates/index.html
(首页)

{% extends "base.html" %}

{% block title %}最新区块 - 简易区块链浏览器{% endblock %}

{% block content %}
    <h2>最新区块信息</h2>
    {% if block %}
    <div class="data-item"><strong>区块号:</strong> <a href="{{ url_for('get_block_details', block_number=block.number) }}">{{ block.number }}</a></div>
    <div class="data-item"><strong>哈希:</strong> {{ block.hash }}</div>
    <div class="data-item"><strong>时间戳:</strong> {{ block.timestamp | int | timestamp_to_datetime }}</div>
    <div class="data-item"><strong>交易数量:</strong> {{ block.transactions_count }}</div>
    <div class="data-item"><strong>矿工:</strong> <a href="{{ url_for('get_address_details', address=block.miner) }}">{{ block.miner }}</a></div>
    <div class="data-item"><strong>Gas使用量:</strong> {{ block.gas_used }}</div>
    <div class="data-item"><strong>Gas限制:</strong> {{ block.gas_limit }}</div>
    <div class="data-item"><strong>父区块哈希:</strong> {{ block.parent_hash }}</div>
    {% else %}
    <p class="error-message">未能加载区块信息。</p>
    {% endif %}

    <script>
        // 简单的过滤器,将Unix时间戳转换为可读日期
        // 在实际Flask应用中,你可能需要在Python后端处理或使用Jinja2的过滤器
        // 这里只是一个前端的简单示例,实际需要后端处理或更复杂的JS库
        if (typeof Jinja2 === 'undefined') { // 避免重复定义
            var Jinja2 = {};
            Jinja2.filters = {
                timestamp_to_datetime: function(timestamp) {
                    const date = new Date(timestamp * 1000);
                    return date.toLocaleString();
                }
            };
        }
        // 为了让Jinja2过滤器在HTML中生效,通常需要在Python后端注册
        // 例如:app.jinja_env.filters['timestamp_to_datetime'] = lambda ts: datetime.fromtimestamp(ts).strftime('%Y-%m-%d %H:%M:%S')
    </script>
{% endblock %}

**注意:

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
Python Flask框架
Python Flask框架

本专题专注于 Python 轻量级 Web 框架 Flask 的学习与实战,内容涵盖路由与视图、模板渲染、表单处理、数据库集成、用户认证以及RESTful API 开发。通过博客系统、任务管理工具与微服务接口等项目实战,帮助学员掌握 Flask 在快速构建小型到中型 Web 应用中的核心技能。

106

2025.08.25

Python Flask Web框架与API开发
Python Flask Web框架与API开发

本专题系统介绍 Python Flask Web框架的基础与进阶应用,包括Flask路由、请求与响应、模板渲染、表单处理、安全性加固、数据库集成(SQLAlchemy)、以及使用Flask构建 RESTful API 服务。通过多个实战项目,帮助学习者掌握使用 Flask 开发高效、可扩展的 Web 应用与 API。

81

2025.12.15

WEB3.0概念龙头股有哪些?web3.0概念五大龙头股盘点
WEB3.0概念龙头股有哪些?web3.0概念五大龙头股盘点

web3.0 龙头股包括:filecoin (fil):去中心化文件存储网络helium (hnt):去中心化无线网络uniswap (uni):去中心化交易所chainlink (link):去中心化预言机网络the graph (grt):去中心化索引协议。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

438

2024.12.12

Python异步编程与Asyncio高并发应用实践
Python异步编程与Asyncio高并发应用实践

本专题围绕 Python 异步编程模型展开,深入讲解 Asyncio 框架的核心原理与应用实践。内容包括事件循环机制、协程任务调度、异步 IO 处理以及并发任务管理策略。通过构建高并发网络请求与异步数据处理案例,帮助开发者掌握 Python 在高并发场景中的高效开发方法,并提升系统资源利用率与整体运行性能。

37

2026.03.12

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

136

2026.03.11

Go高并发任务调度与Goroutine池化实践
Go高并发任务调度与Goroutine池化实践

本专题围绕 Go 语言在高并发任务处理场景中的实践展开,系统讲解 Goroutine 调度模型、Channel 通信机制以及并发控制策略。内容包括任务队列设计、Goroutine 池化管理、资源限制控制以及并发任务的性能优化方法。通过实际案例演示,帮助开发者构建稳定高效的 Go 并发任务处理系统,提高系统在高负载环境下的处理能力与稳定性。

47

2026.03.10

Kotlin Android模块化架构与组件化开发实践
Kotlin Android模块化架构与组件化开发实践

本专题围绕 Kotlin 在 Android 应用开发中的架构实践展开,重点讲解模块化设计与组件化开发的实现思路。内容包括项目模块拆分策略、公共组件封装、依赖管理优化、路由通信机制以及大型项目的工程化管理方法。通过真实项目案例分析,帮助开发者构建结构清晰、易扩展且维护成本低的 Android 应用架构体系,提升团队协作效率与项目迭代速度。

90

2026.03.09

JavaScript浏览器渲染机制与前端性能优化实践
JavaScript浏览器渲染机制与前端性能优化实践

本专题围绕 JavaScript 在浏览器中的执行与渲染机制展开,系统讲解 DOM 构建、CSSOM 解析、重排与重绘原理,以及关键渲染路径优化方法。内容涵盖事件循环机制、异步任务调度、资源加载优化、代码拆分与懒加载等性能优化策略。通过真实前端项目案例,帮助开发者理解浏览器底层工作原理,并掌握提升网页加载速度与交互体验的实用技巧。

102

2026.03.06

Rust内存安全机制与所有权模型深度实践
Rust内存安全机制与所有权模型深度实践

本专题围绕 Rust 语言核心特性展开,深入讲解所有权机制、借用规则、生命周期管理以及智能指针等关键概念。通过系统级开发案例,分析内存安全保障原理与零成本抽象优势,并结合并发场景讲解 Send 与 Sync 特性实现机制。帮助开发者真正理解 Rust 的设计哲学,掌握在高性能与安全性并重场景中的工程实践能力。

226

2026.03.05

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 22.5万人学习

Django 教程
Django 教程

共28课时 | 5万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号