1920 lines
107 KiB
PHP
1920 lines
107 KiB
PHP
<?php
|
||
/**
|
||
* NAC BlockView | NAC Lens 量子浏览器
|
||
* PHP 动态版本 v2.2 - 多语言自适应(i18n)
|
||
*
|
||
* 架构:PHP 服务端渲染 + 原生 JS 动态刷新
|
||
* API:NAC Explorer API (localhost:9551)
|
||
* 语言:自动检测浏览器语言(Accept-Language),支持手动切换
|
||
*/
|
||
|
||
// ===================== 配置 =====================
|
||
define('API_BASE', 'http://localhost:9551/api/v1');
|
||
define('CACHE_TTL', 3);
|
||
define('VERSION', '2.2.0');
|
||
define('GENESIS_NODE_IP', '103.96.148.7');
|
||
define('GENESIS_NODE_ID', 'NACLFLV0000000000000000000000000');
|
||
define('GENESIS_BLOCK_TIME', 1771560165);
|
||
|
||
// ===================== 多语言系统 =====================
|
||
// 支持语言:zh(中文简体)、en(英文)
|
||
// 优先级:URL ?lang= > Cookie > Accept-Language 请求头 > 默认中文
|
||
|
||
function detectLang(): string {
|
||
// 1. URL 参数最高优先级
|
||
if (isset($_GET['lang']) && in_array($_GET['lang'], ['zh', 'en'])) {
|
||
$lang = $_GET['lang'];
|
||
setcookie('nac_lang', $lang, time() + 86400 * 365, '/');
|
||
return $lang;
|
||
}
|
||
// 2. Cookie
|
||
if (isset($_COOKIE['nac_lang']) && in_array($_COOKIE['nac_lang'], ['zh', 'en'])) {
|
||
return $_COOKIE['nac_lang'];
|
||
}
|
||
// 3. Accept-Language 请求头
|
||
$accept = $_SERVER['HTTP_ACCEPT_LANGUAGE'] ?? '';
|
||
if ($accept) {
|
||
// 解析 Accept-Language,取第一个语言标签
|
||
preg_match_all('/([a-z]{2,3})(?:-[a-zA-Z]{2,4})?(?:;q=[\d.]+)?/i', $accept, $m);
|
||
foreach ($m[1] as $code) {
|
||
$code = strtolower($code);
|
||
if (in_array($code, ['zh', 'cmn', 'yue'])) return 'zh';
|
||
if ($code === 'en') return 'en';
|
||
}
|
||
}
|
||
return 'zh'; // 默认中文
|
||
}
|
||
|
||
$LANG = detectLang();
|
||
|
||
// 翻译字典
|
||
$TRANSLATIONS = [
|
||
'zh' => [
|
||
// 通用
|
||
'site_title' => 'NAC BlockView | NAC Lens 量子浏览器',
|
||
'site_desc' => 'NAC BlockView - NAC Lens 量子浏览器 | RWA 专属公链区块浏览器 | CBPP共识 | 谁都可以玩得起的区块链',
|
||
'lang_switch' => 'English',
|
||
'lang_switch_code' => 'en',
|
||
// 导航
|
||
'nav_home' => '首页',
|
||
'nav_blocks' => '区块',
|
||
'nav_transactions' => '交易',
|
||
'nav_assets' => 'RWA资产',
|
||
'nav_tags' => '标签化',
|
||
'nav_roadmap' => '路线图',
|
||
'nav_search_ph' => '搜索区块号 / 交易哈希 / 地址...',
|
||
'nav_search_btn' => '搜索',
|
||
// 首页英雄区
|
||
'hero_title' => 'NAC Lens 量子浏览器',
|
||
'hero_live' => '实时连接 NAC 主网',
|
||
'hero_rwa' => 'RWA 专属公链',
|
||
// CBPP 原则
|
||
'cbpp_title' => '⚖️ CBPP 宪法原则',
|
||
'cbpp_sub' => '—— 不可绕过的宪法层,任何交易和合约必须遵守',
|
||
'cbpp_p1' => '约法即是治法',
|
||
'cbpp_p2' => '宪法即是规则',
|
||
'cbpp_p3' => '参与即是共识',
|
||
'cbpp_p4' => '节点产生区块',
|
||
'cbpp_p5' => '交易扩展区块大小',
|
||
// 宪法层说明
|
||
'const_title' => '🛡️ 不可绕过的宪法层',
|
||
'const_desc' => '每个区块都携带 <code style="color:#00ff88;background:#00ff8810;padding:1px 4px;border-radius:3px;">constitutionLayer: true</code>。任何交易和合约必须通过宪法层验证,无人可绕过。',
|
||
'law_title' => '🏛️ 链上国家的法律体系',
|
||
'law_desc' => '法律越完善,秩序越好。Charter 合约是具体法律,CBPP 宪法是最高法,NVM 是自动执行的法院。',
|
||
'decentral_title' => '🌍 完美中心化下的去中心化',
|
||
'decentral_desc' => '标签内容 AI 审批管理(中心化秩序),审批结果链上不可篡改(去中心化信任)。去中心化内容始终保持。',
|
||
// 统计卡片
|
||
'stat_block_title' => '📦 当前区块高度',
|
||
'stat_block_sub' => 'CBPP 共识出块 · 平均 %ss/块',
|
||
'stat_net_title' => '📊 网络状态',
|
||
'stat_net_val' => 'ACTIVE',
|
||
'stat_net_sub' => 'CBPP 共识正常 · CSNP 已连接',
|
||
'stat_const_title' => '🛡️ 宪法层',
|
||
'stat_const_sub' => '不可绕过 · 全网强制执行',
|
||
'stat_nodes_title' => '🌐 当前节点数',
|
||
'stat_nodes_sub' => '创世节点 · 钱包上线后自然增长',
|
||
'stat_addr_title' => '👤 地址数',
|
||
'stat_addr_sub' => '钱包上线后产生真实地址',
|
||
'stat_rwa_title' => '🏦 RWA 上链资产',
|
||
'stat_rwa_sub' => '待真实资产上链',
|
||
'stat_tx_title' => '🔄 真实交易数',
|
||
'stat_tx_sub' => '钱包上线后产生真实交易',
|
||
'stat_chain_title' => '🔗 链 ID',
|
||
'stat_chain_sub' => '%s 网络',
|
||
// 真实性声明
|
||
'truth_label' => '真实性声明:',
|
||
'truth_desc' => '以上数据均来自 NAC 主网实时 API。钱包尚未正式上线,地址数、交易数、RWA 资产均为 0,将在钱包上线后展示真实数据。',
|
||
'truth_slogan' => '只有真实的,才能赢得信任。',
|
||
// 区块流
|
||
'live_blocks' => '实时区块流',
|
||
'live_scroll' => '← 向左滑动查看更多',
|
||
'tx_count' => '%s 笔交易',
|
||
// 表格
|
||
'latest_blocks' => '📦 最新区块',
|
||
'view_all' => '查看全部 →',
|
||
'latest_txs' => '🔄 最新交易',
|
||
'col_block_num' => '区块号',
|
||
'col_producer' => '出块节点',
|
||
'col_tx_count' => '交易数',
|
||
'col_time' => '时间',
|
||
'col_hash' => '哈希',
|
||
'col_size' => '区块大小',
|
||
'col_consensus' => '共识状态',
|
||
'col_tx_hash' => '交易哈希',
|
||
'col_from' => '发送方',
|
||
'col_to' => '接收方',
|
||
'col_value' => '金额 (NAC)',
|
||
'col_status' => '状态',
|
||
'col_asset_id' => '资产 ID',
|
||
'col_name' => '名称',
|
||
'col_type' => '类型',
|
||
'col_valuation' => '估值 (USD)',
|
||
'col_issuer' => '发行方',
|
||
'col_field' => '字段',
|
||
'col_value_raw' => '值',
|
||
// 空状态
|
||
'no_data' => '暂无数据',
|
||
'no_blocks' => '暂无区块数据',
|
||
'no_txs' => '暂无交易数据',
|
||
'no_assets' => '暂无资产数据',
|
||
// 无真实交易提示
|
||
'no_real_tx_title' => '暂无真实交易',
|
||
'no_real_tx_desc' => "NAC 钱包尚未正式上线。\n钱包上线后,每笔转账将展示真实交易记录。",
|
||
'wallet_soon' => '钱包即将上线',
|
||
// 创世节点
|
||
'genesis_title' => 'NAC 主网创世节点',
|
||
'genesis_sub' => '当前唯一运行节点 · 产生创世区块 · 承载全网 CBPP 共识',
|
||
'genesis_running' => '• 运行中',
|
||
'genesis_node_id' => '节点 ID',
|
||
'genesis_node_ip' => '节点 IP',
|
||
'genesis_time' => '创世区块时间',
|
||
'genesis_uptime' => '主网运行时长',
|
||
'genesis_uptime_val'=> '%s 天',
|
||
'genesis_nodes' => '当前节点数',
|
||
'genesis_nodes_val' => '1 <span style="font-size:11px;color:#64748b;font-weight:400;">(初始阶段)</span>',
|
||
'genesis_block' => '创世区块',
|
||
'genesis_tip_title' => '资产驱动网络扩张原则:',
|
||
'genesis_tip_desc' => '随着 RWA 资产上链数量增加,交易量增长,区块将自动扩大(交易扩展区块大小)。更多参与者加入网络,插入 U 盘即可成为新节点(节点产生区块)。节点越多、资产越多,网络越强大——这就是 CBPP 共识的自然增长逻辑。',
|
||
// 标签化预览
|
||
'tag_title' => '🏷️ 资产标签化系统',
|
||
'tag_phase' => '主网 2.0 开发中 · L3 分布式存储层',
|
||
'tag_dev_title' => '标签化 API 开发中',
|
||
'tag_dev_desc' => "标签化系统属于主网 2.0 功能,目前处于开发阶段。\n待主网 2.0 上线后,将展示真实的所有权标签、收益权标签、合规标签和估值标签数据。",
|
||
'tag_own' => '所有权标签',
|
||
'tag_income' => '收益权标签',
|
||
'tag_compliance' => '合规标签',
|
||
'tag_valuation' => '估值标签',
|
||
'tag_pending' => '待开放',
|
||
'tag_roadmap_link' => '查看标签化路线图 →',
|
||
// USB 节点
|
||
'usb_title' => '一个 U 盘,就是一个节点',
|
||
'usb_desc' => 'NAC 的终极愿景:让每一个普通人都能参与区块链。无需昂贵矿机,无需质押大量代币,只需一个普通 U 盘,插入任何电脑,即可成为 NAC 网络的一个节点,存储 RWA 标签数据,参与 CBPP 共识,获得网络奖励。',
|
||
'usb_slogan' => '谁都可以玩得起的区块链,这不是口号,这是设计原则。',
|
||
'usb_growth_title' => '📈 节点增长预期(随资产上链驱动)',
|
||
'usb_genesis' => "创世节点\n当前",
|
||
'usb_v2' => "主网 2.0\n标签化",
|
||
'usb_v25' => "主网 2.5\n分布式",
|
||
'usb_v3' => "主网 3.0\nUSB 化",
|
||
'usb_step1' => '准备一个 16GB+ U 盘',
|
||
'usb_step2' => '下载 NAC 节点镜像',
|
||
'usb_step3' => '插入电脑自动启动',
|
||
'usb_step4' => '参与共识获得奖励',
|
||
'usb_note' => '* USB 节点功能将在主网 3.0 正式上线,节点数量随 RWA 资产上链自然增长',
|
||
// 路线图预览
|
||
'roadmap_title' => 'NAC 发展路线图',
|
||
'roadmap_sub' => '从 RWA 上链到全民区块链的完整演进路径',
|
||
'roadmap_link' => '查看完整路线图 →',
|
||
'roadmap_v1' => '主网 1.0 · 当前',
|
||
'roadmap_v1_name' => '基础设施',
|
||
'roadmap_v1_desc' => 'RWA 上链、CBPP 共识、Charter 合约、NVM 虚拟机、CSNP 网络',
|
||
'roadmap_v1_badge' => '运行中',
|
||
'roadmap_v2' => '主网 2.0 · 即将',
|
||
'roadmap_v2_name' => '部分标签化',
|
||
'roadmap_v2_desc' => '所有权/收益权分离、标签内容 AI 审批管理、L3 分布式存储、标签可流通',
|
||
'roadmap_v2_badge' => '开发中',
|
||
'roadmap_v25' => '主网 2.5 · 规划中',
|
||
'roadmap_v25_name' => '分布式迁移',
|
||
'roadmap_v25_desc' => '更多节点加入 L3 存储层、资产上链驱动节点增长、CSNP 网络扩展',
|
||
'roadmap_v25_badge' => '规划中',
|
||
'roadmap_v3' => '主网 3.0 · 愿景',
|
||
'roadmap_v3_name' => 'USB 化',
|
||
'roadmap_v3_desc' => '一个 U 盘即节点、完全分布式存储、USB 合成债券、谁都可以玩得起的区块链',
|
||
'roadmap_v3_badge' => '愿景',
|
||
// 区块列表页
|
||
'blocks_title' => '📦 区块列表',
|
||
'blocks_sub' => 'NAC 主网所有区块 · CBPP 共识 · 节点产生区块',
|
||
'prev_page' => '← 上一页',
|
||
'next_page' => '下一页 →',
|
||
// 交易列表页
|
||
'txs_title' => '🔄 交易列表',
|
||
'txs_sub' => 'NAC 主网最新交易 · 交易扩展区块大小',
|
||
// RWA 资产页
|
||
'assets_title' => '🏦 RWA 资产',
|
||
'assets_sub' => '真实世界资产上链 · AI 合规审批 · 标签化管理',
|
||
// 标签化页
|
||
'tags_title' => '🏷️ 资产标签化系统',
|
||
'tags_sub' => '部分标签化 · 主网 2.0 预演 · 所有权与收益权分离',
|
||
// 路线图页
|
||
'roadmap_page_title'=> '🗺️ NAC 发展路线图',
|
||
'roadmap_page_sub' => '从 RWA 专属公链到全民区块链的完整演进路径',
|
||
// 区块详情
|
||
'block_detail_title'=> '📦 区块详情 #%s',
|
||
'back_blocks' => '← 返回区块列表',
|
||
'detail_block_num' => '区块号',
|
||
'detail_block_hash' => '区块哈希',
|
||
'detail_parent_hash'=> '父区块哈希',
|
||
'detail_producer' => '出块节点',
|
||
'detail_tx_count' => '交易数量',
|
||
'detail_tx_count_v' => '%s 笔交易',
|
||
'detail_size' => '区块大小',
|
||
'detail_gas' => 'Gas 使用',
|
||
'detail_cbpp' => 'CBPP 共识',
|
||
'detail_const' => '宪法层',
|
||
'detail_const_yes' => '✅ 是',
|
||
'detail_const_no' => '❌ 否',
|
||
'detail_fluid' => '流体区块',
|
||
'detail_fluid_yes' => '✅ 是(交易扩展)',
|
||
'detail_fluid_no' => '❌ 否',
|
||
'detail_timestamp' => '时间戳',
|
||
'block_txs_title' => '区块内交易(%s 笔)',
|
||
// 交易详情
|
||
'tx_detail_title' => '🔄 交易详情',
|
||
'back_txs' => '← 返回交易列表',
|
||
'detail_tx_hash' => '交易哈希',
|
||
'detail_block_num2' => '区块号',
|
||
'detail_block_hash2'=> '区块哈希',
|
||
'detail_from' => '发送方',
|
||
'detail_to' => '接收方',
|
||
'detail_value' => '金额',
|
||
'detail_gas_limit' => 'Gas 限制',
|
||
'detail_gas_price' => 'Gas 价格',
|
||
'detail_nonce' => 'Nonce',
|
||
'detail_tx_index' => '交易序号',
|
||
'detail_status' => '状态',
|
||
// 搜索
|
||
'search_title' => '🔍 搜索结果',
|
||
'search_keyword' => '关键词:%s',
|
||
'search_type' => '找到结果:类型 = ',
|
||
'search_view_block' => '查看区块 #%s 详情 →',
|
||
'search_not_found' => '未找到与 "%s" 相关的结果',
|
||
// 状态徽章
|
||
'badge_success' => '成功',
|
||
'badge_active' => '激活',
|
||
'badge_pending' => '待处理',
|
||
'badge_failed' => '失败',
|
||
'badge_frozen' => '冻结',
|
||
// 资产类型
|
||
'asset_real_estate' => '🏢 房地产',
|
||
'asset_bond' => '📄 债券',
|
||
'asset_commodity' => '🏭 大宗商品',
|
||
'asset_equity' => '📈 股权',
|
||
'asset_art' => '🎨 艺术品',
|
||
// 时间
|
||
'time_sec' => '%s秒前',
|
||
'time_min' => '%s分钟前',
|
||
'time_hour' => '%s小时前',
|
||
'time_day' => '%s天前',
|
||
// 页脚
|
||
'footer_logo' => 'NAC BlockView · NAC Lens 量子浏览器',
|
||
'footer_desc' => "New Asset Chain · RWA 专属公链 · 谁都可以玩得起的区块链\n约法即是治法 · 宪法即是规则 · 参与即是共识",
|
||
'footer_copy' => '© %s New Asset Chain · v%s · PHP 动态版 · 实时数据由 NAC Explorer API 提供 · ',
|
||
'footer_roadmap' => '查看路线图',
|
||
// JS 动态
|
||
'js_new_block_title'=> '🆕 #%s | NAC BlockView',
|
||
'js_page_title' => 'NAC BlockView | NAC Lens 量子浏览器',
|
||
// 标签化页详细
|
||
'tag_phase1_label' => '🔧 第一阶段(当前)',
|
||
'tag_phase1_title' => '标签化功能开发中',
|
||
'tag_phase1_desc' => '标签化系统属于主网 2.0 功能,目前处于开发阶段。存储层使用 NAC L3 分布式存储,链上存储 SHA3-384 哈希锚点。',
|
||
'tag_phase2_label' => '🔜 第二阶段(主网 2.0)',
|
||
'tag_phase2_title' => '标签化上线 + L3 存储',
|
||
'tag_phase2_desc' => '标签化功能全面上线,数据存储在 L3 分布式存储层。所有参与上链的人即是节点,参与即是共识。',
|
||
'tag_phase3_label' => '🔮 第三阶段(主网 2.5)',
|
||
'tag_phase3_title' => '节点扩展 + 存储增强',
|
||
'tag_phase3_desc' => '更多节点加入 L3 存储层,分布式存储容量自然增长。资产上链越多,节点越多,网络越强大。',
|
||
'tag_phase4_label' => '🔌 第四阶段(主网 3.0)',
|
||
'tag_phase4_title' => '彻底分布式 · USB 化',
|
||
'tag_phase4_desc' => '所有标签完全存储在 CSNP 分布式节点网络。一个 U 盘即节点,USB 合成债券全球流通。',
|
||
'tag_dist_title' => '标签类型分布',
|
||
'tag_sep_title' => '💡 核心创新:所有权与收益权分离',
|
||
'tag_trad_title' => '传统模式(不可分离)',
|
||
'tag_trad_desc' => "持有房产 → 自动获得租金\n转让房产 → 同时失去租金权\n无法单独出售收益权\n门槛高,流动性差",
|
||
'tag_nac_title' => 'NAC 标签化模式(可分离)',
|
||
'tag_nac_desc' => "所有权标签 ← 可单独持有/转让\n收益权标签 ← 可单独持有/转让\n两者可分别在市场流通\n碎片化,门槛极低",
|
||
'tag_l3_title' => 'L3 分布式存储层说明',
|
||
'tag_l3_desc' => 'NAC 具备三层架构:<strong style="color:#00c8ff;">L1 共识层</strong>(CBPP)、<strong style="color:#a855f7;">L2 执行层</strong>(NVM)、<strong style="color:#00ff88;">L3 存储层</strong>。标签数据存储在 L3 分布式存储层,<strong style="color:#ffd700;">从第一天起就是去中心化的</strong>。随着节点增加,L3 存储层的容量和冗余度自然增长。主网 3.0 USB 化后,每个 U 盘节点都是 L3 存储层的一个存储单元。',
|
||
],
|
||
'en' => [
|
||
// General
|
||
'site_title' => 'NAC BlockView | NAC Lens Quantum Browser',
|
||
'site_desc' => 'NAC BlockView - NAC Lens Quantum Browser | RWA-Dedicated Blockchain Explorer | CBPP Consensus | Blockchain for Everyone',
|
||
'lang_switch' => '中文',
|
||
'lang_switch_code' => 'zh',
|
||
// Navigation
|
||
'nav_home' => 'Home',
|
||
'nav_blocks' => 'Blocks',
|
||
'nav_transactions' => 'Transactions',
|
||
'nav_assets' => 'RWA Assets',
|
||
'nav_tags' => 'Tagging',
|
||
'nav_roadmap' => 'Roadmap',
|
||
'nav_search_ph' => 'Search block / tx hash / address...',
|
||
'nav_search_btn' => 'Search',
|
||
// Hero
|
||
'hero_title' => 'NAC Lens Quantum Browser',
|
||
'hero_live' => 'Live connection to NAC Mainnet',
|
||
'hero_rwa' => 'RWA-Dedicated Chain',
|
||
// CBPP
|
||
'cbpp_title' => '⚖️ CBPP Constitutional Principles',
|
||
'cbpp_sub' => '— Unbypassable constitutional layer enforced on all transactions and contracts',
|
||
'cbpp_p1' => 'Charter is the Law',
|
||
'cbpp_p2' => 'Constitution is the Rule',
|
||
'cbpp_p3' => 'Participation IS Consensus',
|
||
'cbpp_p4' => 'Nodes Produce Blocks',
|
||
'cbpp_p5' => 'Transactions Expand Block Size',
|
||
// Constitution layer
|
||
'const_title' => '🛡️ Unbypassable Constitutional Layer',
|
||
'const_desc' => 'Every block carries <code style="color:#00ff88;background:#00ff8810;padding:1px 4px;border-radius:3px;">constitutionLayer: true</code>. All transactions and contracts must pass constitutional validation — no one can bypass it.',
|
||
'law_title' => '🏛️ On-Chain Legal System',
|
||
'law_desc' => 'The more complete the law, the better the order. Charter contracts are specific laws, CBPP constitution is the supreme law, NVM is the automatically enforcing court.',
|
||
'decentral_title' => '🌍 Decentralization Under Perfect Centralization',
|
||
'decentral_desc' => 'Tag content managed by AI approval (centralized order); approval results immutably on-chain (decentralized trust). Decentralized content is always preserved.',
|
||
// Stats
|
||
'stat_block_title' => '📦 Current Block Height',
|
||
'stat_block_sub' => 'CBPP Consensus · Avg %ss/block',
|
||
'stat_net_title' => '📊 Network Status',
|
||
'stat_net_val' => 'ACTIVE',
|
||
'stat_net_sub' => 'CBPP Consensus OK · CSNP Connected',
|
||
'stat_const_title' => '🛡️ Constitution Layer',
|
||
'stat_const_sub' => 'Unbypassable · Network-wide enforcement',
|
||
'stat_nodes_title' => '🌐 Active Nodes',
|
||
'stat_nodes_sub' => 'Genesis node · Grows naturally after wallet launch',
|
||
'stat_addr_title' => '👤 Addresses',
|
||
'stat_addr_sub' => 'Real addresses after wallet launch',
|
||
'stat_rwa_title' => '🏦 RWA Assets On-Chain',
|
||
'stat_rwa_sub' => 'Awaiting real asset registration',
|
||
'stat_tx_title' => '🔄 Real Transactions',
|
||
'stat_tx_sub' => 'Real transactions after wallet launch',
|
||
'stat_chain_title' => '🔗 Chain ID',
|
||
'stat_chain_sub' => '%s Network',
|
||
// Truth statement
|
||
'truth_label' => 'Data Integrity Notice: ',
|
||
'truth_desc' => 'All data is sourced from NAC Mainnet live API. The wallet has not officially launched yet; addresses, transactions, and RWA assets are all 0 and will be shown after wallet launch.',
|
||
'truth_slogan' => 'Only real data earns real trust.',
|
||
// Live blocks
|
||
'live_blocks' => 'Live Block Stream',
|
||
'live_scroll' => '← Scroll left for more',
|
||
'tx_count' => '%s txs',
|
||
// Tables
|
||
'latest_blocks' => '📦 Latest Blocks',
|
||
'view_all' => 'View all →',
|
||
'latest_txs' => '🔄 Latest Transactions',
|
||
'col_block_num' => 'Block',
|
||
'col_producer' => 'Producer',
|
||
'col_tx_count' => 'Txs',
|
||
'col_time' => 'Time',
|
||
'col_hash' => 'Hash',
|
||
'col_size' => 'Size',
|
||
'col_consensus' => 'Consensus',
|
||
'col_tx_hash' => 'Tx Hash',
|
||
'col_from' => 'From',
|
||
'col_to' => 'To',
|
||
'col_value' => 'Value (NAC)',
|
||
'col_status' => 'Status',
|
||
'col_asset_id' => 'Asset ID',
|
||
'col_name' => 'Name',
|
||
'col_type' => 'Type',
|
||
'col_valuation' => 'Valuation (USD)',
|
||
'col_issuer' => 'Issuer',
|
||
'col_field' => 'Field',
|
||
'col_value_raw' => 'Value',
|
||
// Empty states
|
||
'no_data' => 'No data',
|
||
'no_blocks' => 'No block data',
|
||
'no_txs' => 'No transaction data',
|
||
'no_assets' => 'No asset data',
|
||
// No real tx
|
||
'no_real_tx_title' => 'No Real Transactions Yet',
|
||
'no_real_tx_desc' => "NAC Wallet has not officially launched.\nAfter launch, every transfer will be shown here.",
|
||
'wallet_soon' => 'Wallet Coming Soon',
|
||
// Genesis node
|
||
'genesis_title' => 'NAC Mainnet Genesis Node',
|
||
'genesis_sub' => 'Currently the only running node · Produced genesis block · Hosts full CBPP consensus',
|
||
'genesis_running' => '• Running',
|
||
'genesis_node_id' => 'Node ID',
|
||
'genesis_node_ip' => 'Node IP',
|
||
'genesis_time' => 'Genesis Block Time',
|
||
'genesis_uptime' => 'Mainnet Uptime',
|
||
'genesis_uptime_val'=> '%s days',
|
||
'genesis_nodes' => 'Active Nodes',
|
||
'genesis_nodes_val' => '1 <span style="font-size:11px;color:#64748b;font-weight:400;">(initial phase)</span>',
|
||
'genesis_block' => 'Genesis Block',
|
||
'genesis_tip_title' => 'Asset-Driven Network Expansion:',
|
||
'genesis_tip_desc' => 'As more RWA assets are registered on-chain, transaction volume grows, blocks expand automatically (transactions expand block size). More participants join by plugging in a USB drive (nodes produce blocks). More nodes, more assets, stronger network — this is the natural growth logic of CBPP consensus.',
|
||
// Tagging preview
|
||
'tag_title' => '🏷️ Asset Tagging System',
|
||
'tag_phase' => 'Mainnet 2.0 in development · L3 Distributed Storage',
|
||
'tag_dev_title' => 'Tagging API Under Development',
|
||
'tag_dev_desc' => "The tagging system is a Mainnet 2.0 feature, currently under development.\nAfter Mainnet 2.0 launches, real ownership tags, income tags, compliance tags, and valuation tags will be displayed.",
|
||
'tag_own' => 'Ownership Tags',
|
||
'tag_income' => 'Income Tags',
|
||
'tag_compliance' => 'Compliance Tags',
|
||
'tag_valuation' => 'Valuation Tags',
|
||
'tag_pending' => 'Coming Soon',
|
||
'tag_roadmap_link' => 'View Tagging Roadmap →',
|
||
// USB node
|
||
'usb_title' => 'One USB Drive = One Node',
|
||
'usb_desc' => "NAC's ultimate vision: let every ordinary person participate in blockchain. No expensive mining rigs, no large token stakes — just a regular USB drive plugged into any computer becomes a NAC network node, storing RWA tag data, participating in CBPP consensus, and earning network rewards.",
|
||
'usb_slogan' => 'Blockchain for the people — not a slogan, it\'s a design principle.',
|
||
'usb_growth_title' => '📈 Node Growth Projection (driven by asset registration)',
|
||
'usb_genesis' => "Genesis Node\nNow",
|
||
'usb_v2' => "Mainnet 2.0\nTagging",
|
||
'usb_v25' => "Mainnet 2.5\nDistributed",
|
||
'usb_v3' => "Mainnet 3.0\nUSB",
|
||
'usb_step1' => 'Get a 16GB+ USB drive',
|
||
'usb_step2' => 'Download NAC node image',
|
||
'usb_step3' => 'Plug in — auto starts',
|
||
'usb_step4' => 'Participate & earn rewards',
|
||
'usb_note' => '* USB node feature launches with Mainnet 3.0; node count grows naturally with RWA asset registration',
|
||
// Roadmap preview
|
||
'roadmap_title' => 'NAC Development Roadmap',
|
||
'roadmap_sub' => 'Complete evolution path from RWA chain to blockchain for everyone',
|
||
'roadmap_link' => 'View full roadmap →',
|
||
'roadmap_v1' => 'Mainnet 1.0 · Current',
|
||
'roadmap_v1_name' => 'Infrastructure',
|
||
'roadmap_v1_desc' => 'RWA on-chain, CBPP consensus, Charter contracts, NVM, CSNP network',
|
||
'roadmap_v1_badge' => 'Running',
|
||
'roadmap_v2' => 'Mainnet 2.0 · Upcoming',
|
||
'roadmap_v2_name' => 'Partial Tagging',
|
||
'roadmap_v2_desc' => 'Ownership/income separation, AI-managed tag approval, L3 distributed storage, tradeable tags',
|
||
'roadmap_v2_badge' => 'In Dev',
|
||
'roadmap_v25' => 'Mainnet 2.5 · Planned',
|
||
'roadmap_v25_name' => 'Distributed Migration',
|
||
'roadmap_v25_desc' => 'More nodes join L3 storage, asset-driven node growth, CSNP network expansion',
|
||
'roadmap_v25_badge' => 'Planned',
|
||
'roadmap_v3' => 'Mainnet 3.0 · Vision',
|
||
'roadmap_v3_name' => 'USB Era',
|
||
'roadmap_v3_desc' => 'One USB = one node, fully distributed storage, USB synthetic bonds, blockchain for everyone',
|
||
'roadmap_v3_badge' => 'Vision',
|
||
// Blocks page
|
||
'blocks_title' => '📦 Block List',
|
||
'blocks_sub' => 'All NAC Mainnet Blocks · CBPP Consensus · Nodes Produce Blocks',
|
||
'prev_page' => '← Previous',
|
||
'next_page' => 'Next →',
|
||
// Transactions page
|
||
'txs_title' => '🔄 Transactions',
|
||
'txs_sub' => 'Latest NAC Mainnet Transactions · Transactions Expand Block Size',
|
||
// Assets page
|
||
'assets_title' => '🏦 RWA Assets',
|
||
'assets_sub' => 'Real World Assets On-Chain · AI Compliance · Tag Management',
|
||
// Tags page
|
||
'tags_title' => '🏷️ Asset Tagging System',
|
||
'tags_sub' => 'Partial Tagging · Mainnet 2.0 Preview · Ownership & Income Separation',
|
||
// Roadmap page
|
||
'roadmap_page_title'=> '🗺️ NAC Development Roadmap',
|
||
'roadmap_page_sub' => 'Complete evolution path from RWA-dedicated chain to blockchain for everyone',
|
||
// Block detail
|
||
'block_detail_title'=> '📦 Block #%s',
|
||
'back_blocks' => '← Back to Blocks',
|
||
'detail_block_num' => 'Block Number',
|
||
'detail_block_hash' => 'Block Hash',
|
||
'detail_parent_hash'=> 'Parent Hash',
|
||
'detail_producer' => 'Producer',
|
||
'detail_tx_count' => 'Transactions',
|
||
'detail_tx_count_v' => '%s txs',
|
||
'detail_size' => 'Block Size',
|
||
'detail_gas' => 'Gas Used',
|
||
'detail_cbpp' => 'CBPP Consensus',
|
||
'detail_const' => 'Constitution Layer',
|
||
'detail_const_yes' => '✅ Yes',
|
||
'detail_const_no' => '❌ No',
|
||
'detail_fluid' => 'Fluid Block',
|
||
'detail_fluid_yes' => '✅ Yes (tx-expanded)',
|
||
'detail_fluid_no' => '❌ No',
|
||
'detail_timestamp' => 'Timestamp',
|
||
'block_txs_title' => 'Block Transactions (%s txs)',
|
||
// Tx detail
|
||
'tx_detail_title' => '🔄 Transaction Detail',
|
||
'back_txs' => '← Back to Transactions',
|
||
'detail_tx_hash' => 'Tx Hash',
|
||
'detail_block_num2' => 'Block Number',
|
||
'detail_block_hash2'=> 'Block Hash',
|
||
'detail_from' => 'From',
|
||
'detail_to' => 'To',
|
||
'detail_value' => 'Value',
|
||
'detail_gas_limit' => 'Gas Limit',
|
||
'detail_gas_price' => 'Gas Price',
|
||
'detail_nonce' => 'Nonce',
|
||
'detail_tx_index' => 'Tx Index',
|
||
'detail_status' => 'Status',
|
||
// Search
|
||
'search_title' => '🔍 Search Results',
|
||
'search_keyword' => 'Keyword: %s',
|
||
'search_type' => 'Found: type = ',
|
||
'search_view_block' => 'View Block #%s →',
|
||
'search_not_found' => 'No results found for "%s"',
|
||
// Status badges
|
||
'badge_success' => 'Success',
|
||
'badge_active' => 'Active',
|
||
'badge_pending' => 'Pending',
|
||
'badge_failed' => 'Failed',
|
||
'badge_frozen' => 'Frozen',
|
||
// Asset types
|
||
'asset_real_estate' => '🏢 Real Estate',
|
||
'asset_bond' => '📄 Bond',
|
||
'asset_commodity' => '🏭 Commodity',
|
||
'asset_equity' => '📈 Equity',
|
||
'asset_art' => '🎨 Art',
|
||
// Time
|
||
'time_sec' => '%ss ago',
|
||
'time_min' => '%sm ago',
|
||
'time_hour' => '%sh ago',
|
||
'time_day' => '%sd ago',
|
||
// Footer
|
||
'footer_logo' => 'NAC BlockView · NAC Lens Quantum Browser',
|
||
'footer_desc' => "New Asset Chain · RWA-Dedicated Chain · Blockchain for Everyone\nCharter is Law · Constitution is Rule · Participation is Consensus",
|
||
'footer_copy' => '© %s New Asset Chain · v%s · PHP Dynamic · Live data by NAC Explorer API · ',
|
||
'footer_roadmap' => 'Roadmap',
|
||
// JS
|
||
'js_new_block_title'=> '🆕 #%s | NAC BlockView',
|
||
'js_page_title' => 'NAC BlockView | NAC Lens Quantum Browser',
|
||
// Tags page detailed
|
||
'tag_phase1_label' => '🔧 Phase 1 (Current)',
|
||
'tag_phase1_title' => 'Tagging Feature Under Development',
|
||
'tag_phase1_desc' => 'The tagging system is a Mainnet 2.0 feature, currently under development. Storage uses NAC L3 distributed storage; SHA3-384 hash anchors are stored on-chain.',
|
||
'tag_phase2_label' => '🔜 Phase 2 (Mainnet 2.0)',
|
||
'tag_phase2_title' => 'Tagging Live + L3 Storage',
|
||
'tag_phase2_desc' => 'Full tagging functionality launches, data stored in L3 distributed storage layer. Everyone who registers assets on-chain is a node — participation is consensus.',
|
||
'tag_phase3_label' => '🔮 Phase 3 (Mainnet 2.5)',
|
||
'tag_phase3_title' => 'Node Expansion + Storage Enhancement',
|
||
'tag_phase3_desc' => 'More nodes join L3 storage layer, distributed storage capacity grows naturally. More assets on-chain = more nodes = stronger network.',
|
||
'tag_phase4_label' => '🔌 Phase 4 (Mainnet 3.0)',
|
||
'tag_phase4_title' => 'Fully Distributed · USB Era',
|
||
'tag_phase4_desc' => 'All tags fully stored in the CSNP distributed node network. One USB drive = one node; USB synthetic bonds circulate globally.',
|
||
'tag_dist_title' => 'Tag Type Distribution',
|
||
'tag_sep_title' => '💡 Core Innovation: Ownership & Income Separation',
|
||
'tag_trad_title' => 'Traditional Model (Inseparable)',
|
||
'tag_trad_desc' => "Own property → automatically receive rent\nTransfer property → lose rental income\nCannot sell income rights separately\nHigh barrier, low liquidity",
|
||
'tag_nac_title' => 'NAC Tagging Model (Separable)',
|
||
'tag_nac_desc' => "Ownership tag ← hold/transfer independently\nIncome tag ← hold/transfer independently\nBoth can circulate separately on markets\nFragmented, extremely low barrier",
|
||
'tag_l3_title' => 'L3 Distributed Storage Layer',
|
||
'tag_l3_desc' => 'NAC has a three-layer architecture: <strong style="color:#00c8ff;">L1 Consensus</strong> (CBPP), <strong style="color:#a855f7;">L2 Execution</strong> (NVM), <strong style="color:#00ff88;">L3 Storage</strong>. Tag data is stored in the L3 distributed storage layer, <strong style="color:#ffd700;">decentralized from day one</strong>. As nodes increase, L3 storage capacity and redundancy grow naturally. After Mainnet 3.0 USB-ification, every USB node is an L3 storage unit.',
|
||
],
|
||
];
|
||
|
||
// 翻译函数
|
||
function t(string $key, ...$args): string {
|
||
global $TRANSLATIONS, $LANG;
|
||
$str = $TRANSLATIONS[$LANG][$key] ?? $TRANSLATIONS['zh'][$key] ?? $key;
|
||
if ($args) {
|
||
return vsprintf($str, $args);
|
||
}
|
||
return $str;
|
||
}
|
||
|
||
// ===================== API 调用函数 =====================
|
||
function nacApi(string $path, int $timeout = 5): ?array {
|
||
$ch = curl_init(API_BASE . $path);
|
||
curl_setopt_array($ch, [
|
||
CURLOPT_RETURNTRANSFER => true,
|
||
CURLOPT_TIMEOUT => $timeout,
|
||
CURLOPT_CONNECTTIMEOUT => 3,
|
||
CURLOPT_HTTPHEADER => ['Accept: application/json'],
|
||
]);
|
||
$body = curl_exec($ch);
|
||
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||
curl_close($ch);
|
||
if ($body === false || $code !== 200) return null;
|
||
$json = json_decode($body, true);
|
||
return $json['data'] ?? $json ?? null;
|
||
}
|
||
|
||
// ===================== 工具函数 =====================
|
||
function shortHash(string $hash, int $len = 10): string {
|
||
if (strlen($hash) <= $len * 2) return $hash;
|
||
return substr($hash, 0, $len) . '...' . substr($hash, -6);
|
||
}
|
||
|
||
function timeAgo(int $ts): string {
|
||
$diff = time() - $ts;
|
||
if ($diff < 0) $diff = 0;
|
||
if ($diff < 60) return t('time_sec', $diff);
|
||
if ($diff < 3600) return t('time_min', floor($diff / 60));
|
||
if ($diff < 86400) return t('time_hour', floor($diff / 3600));
|
||
return t('time_day', floor($diff / 86400));
|
||
}
|
||
|
||
function formatNum($n): string {
|
||
return number_format((float)$n, 0, '.', ',');
|
||
}
|
||
|
||
function statusBadge(string $status): string {
|
||
$map = [
|
||
'success' => ['#00ff88', 'badge_success'],
|
||
'active' => ['#00ff88', 'badge_active'],
|
||
'pending' => ['#ffd700', 'badge_pending'],
|
||
'failed' => ['#ef4444', 'badge_failed'],
|
||
'frozen' => ['#ef4444', 'badge_frozen'],
|
||
];
|
||
if (isset($map[$status])) {
|
||
[$color, $key] = $map[$status];
|
||
$label = t($key);
|
||
} else {
|
||
$color = '#94a3b8';
|
||
$label = $status;
|
||
}
|
||
return "<span class=\"badge\" style=\"background:{$color}20;color:{$color};border:1px solid {$color}40\">{$label}</span>";
|
||
}
|
||
|
||
function assetTypeLabel(string $type): string {
|
||
$map = [
|
||
'real_estate' => 'asset_real_estate',
|
||
'bond' => 'asset_bond',
|
||
'commodity' => 'asset_commodity',
|
||
'equity' => 'asset_equity',
|
||
'art' => 'asset_art',
|
||
];
|
||
return isset($map[$type]) ? t($map[$type]) : $type;
|
||
}
|
||
|
||
// 构建保留当前参数的语言切换 URL
|
||
function langSwitchUrl(string $targetLang): string {
|
||
$params = $_GET;
|
||
$params['lang'] = $targetLang;
|
||
return '?' . http_build_query($params);
|
||
}
|
||
|
||
// ===================== 读取请求参数 =====================
|
||
$page = max(1, (int)($_GET['page'] ?? 1));
|
||
$view = $_GET['view'] ?? 'home';
|
||
$search = trim($_GET['q'] ?? '');
|
||
$blockId = $_GET['block'] ?? '';
|
||
$txHash = $_GET['tx'] ?? '';
|
||
|
||
$searchResult = null;
|
||
if ($search !== '') {
|
||
$searchResult = nacApi('/search?q=' . urlencode($search));
|
||
if ($searchResult) {
|
||
$view = 'search';
|
||
}
|
||
}
|
||
|
||
$stats = nacApi('/network/stats');
|
||
$latestBlocks = nacApi('/blocks?limit=10');
|
||
$latestTxs = nacApi('/transactions/latest?limit=10');
|
||
|
||
$blockDetail = null;
|
||
if ($blockId !== '') {
|
||
$blockDetail = nacApi('/blocks/' . urlencode($blockId));
|
||
$view = 'block_detail';
|
||
}
|
||
|
||
$txDetail = null;
|
||
if ($txHash !== '') {
|
||
$txDetail = nacApi('/transactions/' . urlencode($txHash));
|
||
$view = 'tx_detail';
|
||
}
|
||
|
||
$blocksPage = null;
|
||
$txsPage = null;
|
||
$assetsPage = null;
|
||
if ($view === 'blocks') { $blocksPage = nacApi('/blocks?limit=20&page=' . $page); }
|
||
if ($view === 'transactions') { $txsPage = nacApi('/transactions/latest?limit=20'); }
|
||
if ($view === 'assets') { $assetsPage = nacApi('/assets?limit=20&page=' . $page); }
|
||
|
||
$tagStats = null;
|
||
$genesisBlock = nacApi('/blocks/1');
|
||
|
||
// ===================== 数据真实性过滤 =====================
|
||
$latestTxs = null;
|
||
$assetsPage = null;
|
||
if ($stats) {
|
||
unset(
|
||
$stats['totalTransactions'],
|
||
$stats['totalAddresses'],
|
||
$stats['totalContracts'],
|
||
$stats['totalAssets'],
|
||
$stats['tps']
|
||
);
|
||
}
|
||
|
||
// 目标语言切换链接
|
||
$switchLang = t('lang_switch_code');
|
||
$switchUrl = langSwitchUrl($switchLang);
|
||
$switchLabel = t('lang_switch');
|
||
$htmlLang = ($LANG === 'zh') ? 'zh-CN' : 'en';
|
||
?>
|
||
<!DOCTYPE html>
|
||
<html lang="<?= $htmlLang ?>">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<meta name="description" content="<?= t('site_desc') ?>">
|
||
<title><?= t('site_title') ?></title>
|
||
<style>
|
||
/* ===== 全局重置 ===== */
|
||
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
||
html { scroll-behavior: smooth; }
|
||
body {
|
||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Microsoft YaHei', sans-serif;
|
||
background: #030b18;
|
||
color: #e2e8f0;
|
||
min-height: 100vh;
|
||
line-height: 1.6;
|
||
}
|
||
a { color: #00c8ff; text-decoration: none; }
|
||
a:hover { text-decoration: underline; }
|
||
::-webkit-scrollbar { width: 6px; height: 6px; }
|
||
::-webkit-scrollbar-track { background: #0a1628; }
|
||
::-webkit-scrollbar-thumb { background: #1e3a5f; border-radius: 3px; }
|
||
.container { max-width: 1280px; margin: 0 auto; padding: 0 20px; }
|
||
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
|
||
.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
|
||
.grid-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; }
|
||
@media (max-width: 768px) {
|
||
.grid-2, .grid-3, .grid-4 { grid-template-columns: 1fr; }
|
||
}
|
||
@media (max-width: 1024px) {
|
||
.grid-4 { grid-template-columns: repeat(2, 1fr); }
|
||
}
|
||
.card {
|
||
background: rgba(255,255,255,0.03);
|
||
border: 1px solid #1e3a5f;
|
||
border-radius: 12px;
|
||
padding: 20px;
|
||
transition: border-color 0.2s, box-shadow 0.2s;
|
||
}
|
||
.card:hover { border-color: #00c8ff40; box-shadow: 0 0 20px rgba(0,200,255,0.05); }
|
||
.card-title { font-size: 14px; color: #64748b; margin-bottom: 8px; text-transform: uppercase; letter-spacing: 0.5px; }
|
||
.card-value { font-size: 28px; font-weight: 700; color: #fff; font-variant-numeric: tabular-nums; }
|
||
.card-sub { font-size: 12px; color: #64748b; margin-top: 4px; }
|
||
.navbar {
|
||
background: linear-gradient(135deg, #060f1e 0%, #0a1628 100%);
|
||
border-bottom: 1px solid #1e3a5f;
|
||
position: sticky;
|
||
top: 0;
|
||
z-index: 100;
|
||
backdrop-filter: blur(10px);
|
||
}
|
||
.nav-inner {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 12px;
|
||
padding: 12px 20px;
|
||
flex-wrap: wrap;
|
||
}
|
||
.nav-logo { display: flex; align-items: center; gap: 10px; cursor: pointer; }
|
||
.nav-logo img { height: 48px; width: auto; }
|
||
.nav-menu { display: flex; gap: 4px; flex-wrap: wrap; }
|
||
.nav-btn {
|
||
background: transparent;
|
||
border: 1px solid transparent;
|
||
color: #94a3b8;
|
||
border-radius: 6px;
|
||
padding: 6px 14px;
|
||
font-size: 14px;
|
||
cursor: pointer;
|
||
transition: all 0.2s;
|
||
white-space: nowrap;
|
||
text-decoration: none;
|
||
display: inline-block;
|
||
}
|
||
.nav-btn:hover { color: #00c8ff; border-color: #00c8ff40; text-decoration: none; }
|
||
.nav-btn.active { background: rgba(0,200,255,0.12); border-color: #00c8ff; color: #00c8ff; }
|
||
/* 语言切换按钮 */
|
||
.lang-btn {
|
||
background: rgba(0,200,255,0.08);
|
||
border: 1px solid rgba(0,200,255,0.3);
|
||
color: #00c8ff;
|
||
border-radius: 6px;
|
||
padding: 5px 12px;
|
||
font-size: 13px;
|
||
cursor: pointer;
|
||
transition: all 0.2s;
|
||
white-space: nowrap;
|
||
text-decoration: none;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 5px;
|
||
margin-left: 4px;
|
||
}
|
||
.lang-btn:hover { background: rgba(0,200,255,0.15); text-decoration: none; }
|
||
.nav-search { display: flex; gap: 8px; margin-left: auto; min-width: 0; }
|
||
.nav-search input {
|
||
background: rgba(255,255,255,0.05);
|
||
border: 1px solid #1e3a5f;
|
||
border-radius: 8px;
|
||
padding: 8px 14px;
|
||
color: #e2e8f0;
|
||
font-size: 14px;
|
||
outline: none;
|
||
width: 280px;
|
||
transition: border-color 0.2s;
|
||
}
|
||
.nav-search input:focus { border-color: #00c8ff60; }
|
||
.nav-search input::placeholder { color: #475569; }
|
||
.btn-search {
|
||
background: linear-gradient(135deg, #00c8ff, #0066ff);
|
||
border: none;
|
||
border-radius: 8px;
|
||
padding: 8px 16px;
|
||
color: white;
|
||
cursor: pointer;
|
||
font-size: 14px;
|
||
white-space: nowrap;
|
||
transition: opacity 0.2s;
|
||
}
|
||
.btn-search:hover { opacity: 0.85; }
|
||
.page-header { padding: 32px 0 20px; border-bottom: 1px solid #1e3a5f; margin-bottom: 24px; }
|
||
.page-header h1 { font-size: 24px; font-weight: 700; color: #fff; }
|
||
.page-header p { color: #64748b; font-size: 14px; margin-top: 4px; }
|
||
.table-wrap { overflow-x: auto; }
|
||
table { width: 100%; border-collapse: collapse; font-size: 13px; }
|
||
th { text-align: left; padding: 10px 14px; color: #64748b; font-weight: 600; border-bottom: 1px solid #1e3a5f; white-space: nowrap; text-transform: uppercase; font-size: 11px; letter-spacing: 0.5px; }
|
||
td { padding: 10px 14px; border-bottom: 1px solid rgba(30,58,95,0.5); vertical-align: middle; }
|
||
tr:hover td { background: rgba(0,200,255,0.03); }
|
||
tr:last-child td { border-bottom: none; }
|
||
.mono { font-family: 'Courier New', Courier, monospace; font-size: 12px; }
|
||
.text-right { text-align: right; }
|
||
.text-center { text-align: center; }
|
||
.badge { display: inline-block; padding: 2px 8px; border-radius: 4px; font-size: 11px; font-weight: 600; white-space: nowrap; }
|
||
.pagination { display: flex; gap: 8px; justify-content: center; margin-top: 20px; flex-wrap: wrap; }
|
||
.page-link { padding: 6px 12px; border: 1px solid #1e3a5f; border-radius: 6px; color: #94a3b8; font-size: 13px; cursor: pointer; text-decoration: none; transition: all 0.2s; }
|
||
.page-link:hover { border-color: #00c8ff; color: #00c8ff; text-decoration: none; }
|
||
.page-link.active { background: #00c8ff20; border-color: #00c8ff; color: #00c8ff; }
|
||
.hero {
|
||
background: linear-gradient(135deg, #060f1e 0%, #0a1628 50%, #060f1e 100%);
|
||
border-bottom: 1px solid #1e3a5f;
|
||
padding: 40px 0 32px;
|
||
position: relative;
|
||
overflow: hidden;
|
||
}
|
||
.hero::before {
|
||
content: '';
|
||
position: absolute;
|
||
top: -50%; left: -50%;
|
||
width: 200%; height: 200%;
|
||
background: radial-gradient(ellipse at center, rgba(0,100,200,0.08) 0%, transparent 60%);
|
||
animation: pulse 8s ease-in-out infinite;
|
||
}
|
||
@keyframes pulse { 0%, 100% { transform: scale(1); opacity: 0.5; } 50% { transform: scale(1.1); opacity: 1; } }
|
||
.hero-title {
|
||
font-size: 36px; font-weight: 800;
|
||
background: linear-gradient(135deg, #00c8ff, #0066ff, #a855f7);
|
||
-webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text;
|
||
margin-bottom: 8px; position: relative;
|
||
}
|
||
.hero-sub { color: #64748b; font-size: 15px; position: relative; }
|
||
.hero-sub span { color: #00c8ff; }
|
||
.cbpp-banner {
|
||
background: linear-gradient(135deg, rgba(0,100,200,0.1), rgba(168,85,247,0.1));
|
||
border: 1px solid rgba(0,200,255,0.2);
|
||
border-radius: 12px;
|
||
padding: 20px 24px;
|
||
margin: 24px 0;
|
||
}
|
||
.cbpp-title { font-size: 13px; color: #00c8ff; font-weight: 700; text-transform: uppercase; letter-spacing: 1px; margin-bottom: 14px; }
|
||
.cbpp-principles { display: flex; flex-wrap: wrap; gap: 12px; }
|
||
.cbpp-item { display: flex; align-items: center; gap: 8px; background: rgba(0,200,255,0.06); border: 1px solid rgba(0,200,255,0.15); border-radius: 8px; padding: 8px 14px; font-size: 13px; color: #e2e8f0; }
|
||
.cbpp-dot { width: 6px; height: 6px; border-radius: 50%; background: #00c8ff; flex-shrink: 0; animation: blink 2s ease-in-out infinite; }
|
||
@keyframes blink { 0%, 100% { opacity: 1; } 50% { opacity: 0.3; } }
|
||
.live-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; background: #00ff88; margin-right: 6px; animation: live-pulse 1.5s ease-in-out infinite; }
|
||
@keyframes live-pulse { 0%, 100% { box-shadow: 0 0 0 0 rgba(0,255,136,0.4); } 50% { box-shadow: 0 0 0 6px rgba(0,255,136,0); } }
|
||
.chain-visual { display: flex; align-items: center; gap: 0; overflow-x: auto; padding: 16px 0; scrollbar-width: none; }
|
||
.chain-visual::-webkit-scrollbar { display: none; }
|
||
.chain-block { flex-shrink: 0; background: rgba(0,200,255,0.08); border: 1px solid #00c8ff30; border-radius: 8px; padding: 10px 14px; font-size: 12px; cursor: pointer; transition: all 0.2s; min-width: 90px; }
|
||
.chain-block:hover { background: rgba(0,200,255,0.15); border-color: #00c8ff; transform: translateY(-2px); }
|
||
.chain-block .block-num { color: #00c8ff; font-weight: 700; font-size: 13px; }
|
||
.chain-block .block-txs { color: #64748b; font-size: 11px; }
|
||
.chain-arrow { color: #1e3a5f; font-size: 18px; flex-shrink: 0; padding: 0 4px; }
|
||
.tag-section { background: linear-gradient(135deg, rgba(168,85,247,0.05), rgba(0,100,200,0.05)); border: 1px solid rgba(168,85,247,0.2); border-radius: 12px; padding: 24px; margin: 24px 0; }
|
||
.tag-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 20px; flex-wrap: wrap; gap: 12px; }
|
||
.tag-title { font-size: 18px; font-weight: 700; color: #a855f7; }
|
||
.tag-phase { background: rgba(168,85,247,0.15); border: 1px solid rgba(168,85,247,0.3); border-radius: 20px; padding: 4px 14px; font-size: 12px; color: #a855f7; font-weight: 600; }
|
||
.tag-types { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 12px; }
|
||
.roadmap { padding: 40px 0; }
|
||
.roadmap-title { font-size: 22px; font-weight: 700; color: #fff; margin-bottom: 8px; text-align: center; }
|
||
.roadmap-sub { color: #64748b; font-size: 14px; text-align: center; margin-bottom: 32px; }
|
||
.roadmap-track { position: relative; display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; }
|
||
@media (max-width: 768px) { .roadmap-track { grid-template-columns: 1fr 1fr; } }
|
||
.roadmap-track::before { content: ''; position: absolute; top: 28px; left: 10%; right: 10%; height: 2px; background: linear-gradient(90deg, #00c8ff, #a855f7, #ff6b35, #ffd700); z-index: 0; }
|
||
.roadmap-item { position: relative; z-index: 1; text-align: center; }
|
||
.roadmap-dot { width: 56px; height: 56px; border-radius: 50%; margin: 0 auto 14px; display: flex; align-items: center; justify-content: center; font-size: 22px; border: 2px solid; transition: transform 0.2s; }
|
||
.roadmap-item:hover .roadmap-dot { transform: scale(1.1); }
|
||
.roadmap-item.done .roadmap-dot { background: rgba(0,200,255,0.15); border-color: #00c8ff; box-shadow: 0 0 20px rgba(0,200,255,0.3); }
|
||
.roadmap-item.next .roadmap-dot { background: rgba(168,85,247,0.15); border-color: #a855f7; box-shadow: 0 0 20px rgba(168,85,247,0.3); animation: glow-purple 2s ease-in-out infinite; }
|
||
.roadmap-item.future .roadmap-dot { background: rgba(255,107,53,0.1); border-color: #ff6b35; }
|
||
.roadmap-item.vision .roadmap-dot { background: rgba(255,215,0,0.1); border-color: #ffd700; }
|
||
@keyframes glow-purple { 0%, 100% { box-shadow: 0 0 20px rgba(168,85,247,0.3); } 50% { box-shadow: 0 0 40px rgba(168,85,247,0.6); } }
|
||
.roadmap-version { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 1px; margin-bottom: 4px; }
|
||
.roadmap-name { font-size: 15px; font-weight: 700; color: #fff; margin-bottom: 8px; }
|
||
.roadmap-desc { font-size: 12px; color: #64748b; line-height: 1.5; }
|
||
.roadmap-tags { display: flex; flex-wrap: wrap; gap: 4px; justify-content: center; margin-top: 8px; }
|
||
.roadmap-tag { font-size: 10px; padding: 2px 6px; border-radius: 4px; border: 1px solid; white-space: nowrap; }
|
||
.usb-section { background: linear-gradient(135deg, rgba(255,215,0,0.05), rgba(255,107,53,0.05)); border: 1px solid rgba(255,215,0,0.2); border-radius: 12px; padding: 28px; margin: 24px 0; text-align: center; }
|
||
.usb-icon { font-size: 48px; margin-bottom: 12px; }
|
||
.usb-title { font-size: 22px; font-weight: 800; color: #ffd700; margin-bottom: 8px; }
|
||
.usb-desc { color: #94a3b8; font-size: 14px; max-width: 600px; margin: 0 auto 20px; line-height: 1.7; }
|
||
.usb-steps { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 12px; max-width: 700px; margin: 0 auto; }
|
||
.usb-step { background: rgba(255,215,0,0.06); border: 1px solid rgba(255,215,0,0.15); border-radius: 10px; padding: 14px; }
|
||
.usb-step-num { font-size: 24px; font-weight: 800; color: #ffd700; margin-bottom: 4px; }
|
||
.usb-step-text { font-size: 12px; color: #94a3b8; }
|
||
.detail-card { background: rgba(255,255,255,0.02); border: 1px solid #1e3a5f; border-radius: 12px; overflow: hidden; }
|
||
.detail-header { background: rgba(0,200,255,0.05); border-bottom: 1px solid #1e3a5f; padding: 16px 20px; display: flex; align-items: center; gap: 12px; }
|
||
.detail-header h2 { font-size: 16px; font-weight: 700; color: #00c8ff; }
|
||
.detail-row { display: flex; padding: 12px 20px; border-bottom: 1px solid rgba(30,58,95,0.4); gap: 16px; flex-wrap: wrap; }
|
||
.detail-row:last-child { border-bottom: none; }
|
||
.detail-label { width: 140px; flex-shrink: 0; color: #64748b; font-size: 13px; }
|
||
.detail-value { flex: 1; color: #e2e8f0; font-size: 13px; word-break: break-all; }
|
||
footer { background: #060f1e; border-top: 1px solid #1e3a5f; padding: 32px 0; margin-top: 60px; text-align: center; }
|
||
.footer-logo { font-size: 18px; font-weight: 700; color: #00c8ff; margin-bottom: 8px; }
|
||
.footer-desc { color: #475569; font-size: 13px; margin-bottom: 16px; white-space: pre-line; }
|
||
.footer-tags { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; margin-bottom: 16px; }
|
||
.footer-tag { background: rgba(0,200,255,0.06); border: 1px solid rgba(0,200,255,0.15); border-radius: 4px; padding: 3px 10px; font-size: 11px; color: #00c8ff; }
|
||
.footer-copy { color: #334155; font-size: 12px; }
|
||
.skeleton { background: linear-gradient(90deg, #0a1628 25%, #1e3a5f 50%, #0a1628 75%); background-size: 200% 100%; animation: shimmer 1.5s infinite; border-radius: 4px; }
|
||
@keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }
|
||
.empty { text-align: center; padding: 40px; color: #475569; }
|
||
.empty-icon { font-size: 40px; margin-bottom: 12px; }
|
||
@media (max-width: 640px) {
|
||
.hero-title { font-size: 24px; }
|
||
.nav-search input { width: 160px; }
|
||
.roadmap-track::before { display: none; }
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
|
||
<!-- ===== 导航栏 ===== -->
|
||
<nav class="navbar">
|
||
<div class="nav-inner container">
|
||
<div class="nav-logo" onclick="location.href='?view=home'">
|
||
<img src="/nac_blockview_logo.png" alt="NAC BlockView" onerror="this.style.display='none'">
|
||
</div>
|
||
<div class="nav-menu">
|
||
<a href="?view=home<?= $LANG!=='zh'?'&lang='.$LANG:'' ?>" class="nav-btn <?= $view==='home' ? 'active' : '' ?>"><?= t('nav_home') ?></a>
|
||
<a href="?view=blocks<?= $LANG!=='zh'?'&lang='.$LANG:'' ?>" class="nav-btn <?= $view==='blocks' ? 'active' : '' ?>"><?= t('nav_blocks') ?></a>
|
||
<a href="?view=transactions<?= $LANG!=='zh'?'&lang='.$LANG:'' ?>" class="nav-btn <?= $view==='transactions' ? 'active' : '' ?>"><?= t('nav_transactions') ?></a>
|
||
<a href="?view=assets<?= $LANG!=='zh'?'&lang='.$LANG:'' ?>" class="nav-btn <?= $view==='assets' ? 'active' : '' ?>"><?= t('nav_assets') ?></a>
|
||
<a href="?view=tags<?= $LANG!=='zh'?'&lang='.$LANG:'' ?>" class="nav-btn <?= $view==='tags' ? 'active' : '' ?>"><?= t('nav_tags') ?></a>
|
||
<a href="?view=roadmap<?= $LANG!=='zh'?'&lang='.$LANG:'' ?>" class="nav-btn <?= $view==='roadmap' ? 'active' : '' ?>"><?= t('nav_roadmap') ?></a>
|
||
</div>
|
||
<!-- 语言切换按钮 -->
|
||
<a href="<?= htmlspecialchars($switchUrl) ?>" class="lang-btn" title="Switch Language">
|
||
<?= $LANG === 'zh' ? '🌐' : '🇨🇳' ?> <?= htmlspecialchars($switchLabel) ?>
|
||
</a>
|
||
<form class="nav-search" method="GET" action="">
|
||
<input type="hidden" name="view" value="search">
|
||
<?php if ($LANG !== 'zh'): ?><input type="hidden" name="lang" value="<?= $LANG ?>"><?php endif; ?>
|
||
<input type="text" name="q" placeholder="<?= t('nav_search_ph') ?>" value="<?= htmlspecialchars($search) ?>">
|
||
<button type="submit" class="btn-search"><?= t('nav_search_btn') ?></button>
|
||
</form>
|
||
</div>
|
||
</nav>
|
||
|
||
<!-- ===== 主体内容 ===== -->
|
||
<main>
|
||
<?php if ($view === 'home'): ?>
|
||
<!-- ==================== 首页 ==================== -->
|
||
|
||
<!-- 英雄区 -->
|
||
<div class="hero">
|
||
<div class="container">
|
||
<div class="hero-title"><?= t('hero_title') ?></div>
|
||
<div class="hero-sub">
|
||
<span class="live-dot"></span>
|
||
<?= t('hero_live') ?> ·
|
||
<span><?= t('hero_rwa') ?></span> ·
|
||
CBPP <?= $LANG==='en'?'Consensus':'共识' ?> · CSNP <?= $LANG==='en'?'Network':'网络' ?> · NVM · Charter
|
||
</div>
|
||
|
||
<!-- CBPP 宪法原则 -->
|
||
<div class="cbpp-banner" style="margin-top:24px;">
|
||
<div class="cbpp-title"><?= t('cbpp_title') ?> <span style="font-size:11px;color:#64748b;font-weight:400;"><?= t('cbpp_sub') ?></span></div>
|
||
<div class="cbpp-principles">
|
||
<div class="cbpp-item"><div class="cbpp-dot"></div><?= t('cbpp_p1') ?></div>
|
||
<div class="cbpp-item"><div class="cbpp-dot"></div><?= t('cbpp_p2') ?></div>
|
||
<div class="cbpp-item"><div class="cbpp-dot"></div><?= t('cbpp_p3') ?></div>
|
||
<div class="cbpp-item"><div class="cbpp-dot"></div><?= t('cbpp_p4') ?></div>
|
||
<div class="cbpp-item"><div class="cbpp-dot"></div><?= t('cbpp_p5') ?></div>
|
||
</div>
|
||
</div>
|
||
<!-- 宪法层说明 -->
|
||
<div style="margin-top:16px;display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:12px;">
|
||
<div style="background:rgba(0,255,136,0.06);border:1px solid rgba(0,255,136,0.2);border-radius:8px;padding:12px;">
|
||
<div style="font-size:11px;color:#00ff88;font-weight:700;margin-bottom:6px;"><?= t('const_title') ?></div>
|
||
<div style="font-size:11px;color:#64748b;line-height:1.7;"><?= t('const_desc') ?></div>
|
||
</div>
|
||
<div style="background:rgba(0,200,255,0.06);border:1px solid rgba(0,200,255,0.2);border-radius:8px;padding:12px;">
|
||
<div style="font-size:11px;color:#00c8ff;font-weight:700;margin-bottom:6px;"><?= t('law_title') ?></div>
|
||
<div style="font-size:11px;color:#64748b;line-height:1.7;"><?= t('law_desc') ?></div>
|
||
</div>
|
||
<div style="background:rgba(255,215,0,0.06);border:1px solid rgba(255,215,0,0.2);border-radius:8px;padding:12px;">
|
||
<div style="font-size:11px;color:#ffd700;font-weight:700;margin-bottom:6px;"><?= t('decentral_title') ?></div>
|
||
<div style="font-size:11px;color:#64748b;line-height:1.7;"><?= t('decentral_desc') ?></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="container" style="padding-top:28px;">
|
||
|
||
<!-- 网络统计 -->
|
||
<?php if ($stats): ?>
|
||
<div class="grid-4" style="margin-bottom:8px;">
|
||
<div class="card">
|
||
<div class="card-title"><?= t('stat_block_title') ?></div>
|
||
<div class="card-value" id="stat-block"><?= formatNum($stats['currentBlock'] ?? 0) ?></div>
|
||
<div class="card-sub"><?= t('stat_block_sub', htmlspecialchars($stats['avgBlockTime'] ?? '3')) ?></div>
|
||
</div>
|
||
<div class="card">
|
||
<div class="card-title"><?= t('stat_net_title') ?></div>
|
||
<div class="card-value" style="font-size:22px;color:#00ff88;"><?= t('stat_net_val') ?></div>
|
||
<div class="card-sub"><?= t('stat_net_sub') ?></div>
|
||
</div>
|
||
<div class="card">
|
||
<div class="card-title"><?= t('stat_const_title') ?></div>
|
||
<div class="card-value" style="font-size:22px;color:#00c8ff;"><?= $stats['constitutionLayer'] ? 'ON' : 'OFF' ?></div>
|
||
<div class="card-sub"><?= t('stat_const_sub') ?></div>
|
||
</div>
|
||
<div class="card">
|
||
<div class="card-title"><?= t('stat_nodes_title') ?></div>
|
||
<div class="card-value" style="font-size:32px;color:#ffd700;">1</div>
|
||
<div class="card-sub"><?= t('stat_nodes_sub') ?></div>
|
||
</div>
|
||
</div>
|
||
<div class="grid-4" style="margin-bottom:8px;">
|
||
<div class="card">
|
||
<div class="card-title"><?= t('stat_addr_title') ?></div>
|
||
<div class="card-value" style="font-size:32px;color:#94a3b8;">0</div>
|
||
<div class="card-sub"><?= t('stat_addr_sub') ?></div>
|
||
</div>
|
||
<div class="card">
|
||
<div class="card-title"><?= t('stat_rwa_title') ?></div>
|
||
<div class="card-value" style="font-size:32px;color:#94a3b8;">0</div>
|
||
<div class="card-sub"><?= t('stat_rwa_sub') ?></div>
|
||
</div>
|
||
<div class="card">
|
||
<div class="card-title"><?= t('stat_tx_title') ?></div>
|
||
<div class="card-value" style="font-size:32px;color:#94a3b8;">0</div>
|
||
<div class="card-sub"><?= t('stat_tx_sub') ?></div>
|
||
</div>
|
||
<div class="card">
|
||
<div class="card-title"><?= t('stat_chain_title') ?></div>
|
||
<div class="card-value" style="font-size:20px;color:#a855f7;"><?= $stats['chainId'] ?? '20260131' ?></div>
|
||
<div class="card-sub"><?= t('stat_chain_sub', htmlspecialchars($stats['network'] ?? 'mainnet')) ?></div>
|
||
</div>
|
||
</div>
|
||
<!-- 真实性声明 -->
|
||
<div style="background:#ffd70010;border:1px solid #ffd70030;border-radius:8px;padding:10px 16px;margin-bottom:24px;font-size:12px;color:#94a3b8;">
|
||
ℹ️ <strong style="color:#ffd700;"><?= t('truth_label') ?></strong>
|
||
<?= t('truth_desc') ?>
|
||
<strong style="color:#00ff88;"><?= t('truth_slogan') ?></strong>
|
||
</div>
|
||
<?php endif; ?>
|
||
|
||
<!-- 区块链可视化 -->
|
||
<div class="card" style="margin-bottom:24px;">
|
||
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:12px;">
|
||
<div style="font-size:15px;font-weight:700;color:#fff;">
|
||
<span class="live-dot"></span><?= t('live_blocks') ?>
|
||
</div>
|
||
<div style="font-size:12px;color:#64748b;"><?= t('live_scroll') ?></div>
|
||
</div>
|
||
<div class="chain-visual" id="chain-visual">
|
||
<?php if ($latestBlocks && isset($latestBlocks['blocks'])): ?>
|
||
<?php foreach (array_slice($latestBlocks['blocks'], 0, 12) as $b): ?>
|
||
<a href="?view=home&block=<?= $b['number'] ?><?= $LANG!=='zh'?'&lang='.$LANG:'' ?>" style="text-decoration:none;">
|
||
<div class="chain-block">
|
||
<div class="block-num">#<?= formatNum($b['number']) ?></div>
|
||
<div class="block-txs"><?= t('tx_count', $b['transactionCount']) ?></div>
|
||
<div style="font-size:10px;color:#475569;margin-top:2px;"><?= timeAgo($b['timestamp']) ?></div>
|
||
</div>
|
||
</a>
|
||
<div class="chain-arrow">←</div>
|
||
<?php endforeach; ?>
|
||
<?php endif; ?>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 最新区块 + 最新交易 -->
|
||
<div class="grid-2" style="margin-bottom:24px;">
|
||
<div class="card">
|
||
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:16px;">
|
||
<div style="font-size:15px;font-weight:700;color:#fff;"><?= t('latest_blocks') ?></div>
|
||
<a href="?view=blocks<?= $LANG!=='zh'?'&lang='.$LANG:'' ?>" style="font-size:12px;color:#00c8ff;"><?= t('view_all') ?></a>
|
||
</div>
|
||
<div class="table-wrap">
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th><?= t('col_block_num') ?></th>
|
||
<th><?= t('col_producer') ?></th>
|
||
<th><?= t('col_tx_count') ?></th>
|
||
<th><?= t('col_time') ?></th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<?php if ($latestBlocks && isset($latestBlocks['blocks'])): ?>
|
||
<?php foreach (array_slice($latestBlocks['blocks'], 0, 8) as $b): ?>
|
||
<tr>
|
||
<td><a href="?view=home&block=<?= $b['number'] ?><?= $LANG!=='zh'?'&lang='.$LANG:'' ?>" class="mono" style="color:#00c8ff;">#<?= formatNum($b['number']) ?></a></td>
|
||
<td class="mono" style="font-size:11px;"><?= htmlspecialchars(shortHash($b['miner'] ?? '', 8)) ?></td>
|
||
<td><?= (int)($b['transactionCount'] ?? 0) ?></td>
|
||
<td style="color:#64748b;font-size:12px;"><?= timeAgo($b['timestamp']) ?></td>
|
||
</tr>
|
||
<?php endforeach; ?>
|
||
<?php else: ?>
|
||
<tr><td colspan="4" class="empty"><?= t('no_data') ?></td></tr>
|
||
<?php endif; ?>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:16px;">
|
||
<div style="font-size:15px;font-weight:700;color:#fff;"><?= t('latest_txs') ?></div>
|
||
</div>
|
||
<div style="text-align:center;padding:32px 16px;">
|
||
<div style="font-size:36px;margin-bottom:12px;">📱</div>
|
||
<div style="font-size:15px;color:#e2e8f0;font-weight:600;margin-bottom:8px;"><?= t('no_real_tx_title') ?></div>
|
||
<div style="font-size:12px;color:#64748b;line-height:1.8;max-width:280px;margin:0 auto;white-space:pre-line;"><?= t('no_real_tx_desc') ?></div>
|
||
<div style="margin-top:16px;display:inline-block;background:#00c8ff15;border:1px solid #00c8ff30;border-radius:20px;padding:6px 16px;font-size:12px;color:#00c8ff;">
|
||
<?= t('wallet_soon') ?>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 创世节点信息 -->
|
||
<div style="background:linear-gradient(135deg,#0a1628 0%,#0d2040 50%,#0a1628 100%);border:1px solid #00ff8840;border-radius:16px;padding:28px;margin-bottom:32px;">
|
||
<div style="display:flex;align-items:center;gap:12px;margin-bottom:20px;">
|
||
<span style="font-size:22px;">🌐</span>
|
||
<div>
|
||
<div style="font-size:16px;font-weight:700;color:#00ff88;"><?= t('genesis_title') ?></div>
|
||
<div style="font-size:12px;color:#64748b;margin-top:2px;"><?= t('genesis_sub') ?></div>
|
||
</div>
|
||
<div style="margin-left:auto;">
|
||
<span style="background:#00ff8820;color:#00ff88;border:1px solid #00ff8840;padding:4px 12px;border-radius:20px;font-size:12px;font-weight:600;"><?= t('genesis_running') ?></span>
|
||
</div>
|
||
</div>
|
||
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:16px;">
|
||
<div style="background:#ffffff08;border:1px solid #ffffff10;border-radius:10px;padding:14px;">
|
||
<div style="font-size:11px;color:#64748b;margin-bottom:6px;"><?= t('genesis_node_id') ?></div>
|
||
<div style="font-size:12px;color:#00c8ff;font-family:monospace;word-break:break-all;"><?= GENESIS_NODE_ID ?></div>
|
||
</div>
|
||
<div style="background:#ffffff08;border:1px solid #ffffff10;border-radius:10px;padding:14px;">
|
||
<div style="font-size:11px;color:#64748b;margin-bottom:6px;"><?= t('genesis_node_ip') ?></div>
|
||
<div style="font-size:14px;color:#e2e8f0;font-weight:600;"><?= GENESIS_NODE_IP ?></div>
|
||
</div>
|
||
<div style="background:#ffffff08;border:1px solid #ffffff10;border-radius:10px;padding:14px;">
|
||
<div style="font-size:11px;color:#64748b;margin-bottom:6px;"><?= t('genesis_time') ?></div>
|
||
<div style="font-size:13px;color:#e2e8f0;"><?= date('Y-m-d H:i', GENESIS_BLOCK_TIME) ?> UTC</div>
|
||
</div>
|
||
<div style="background:#ffffff08;border:1px solid #ffffff10;border-radius:10px;padding:14px;">
|
||
<div style="font-size:11px;color:#64748b;margin-bottom:6px;"><?= t('genesis_uptime') ?></div>
|
||
<div style="font-size:14px;color:#ffd700;font-weight:600;"><?= t('genesis_uptime_val', floor((time() - GENESIS_BLOCK_TIME) / 86400)) ?></div>
|
||
</div>
|
||
<div style="background:#ffffff08;border:1px solid #ffffff10;border-radius:10px;padding:14px;">
|
||
<div style="font-size:11px;color:#64748b;margin-bottom:6px;"><?= t('genesis_nodes') ?></div>
|
||
<div style="font-size:14px;color:#e2e8f0;font-weight:600;"><?= t('genesis_nodes_val') ?></div>
|
||
</div>
|
||
<div style="background:#ffffff08;border:1px solid #ffffff10;border-radius:10px;padding:14px;">
|
||
<div style="font-size:11px;color:#64748b;margin-bottom:6px;"><?= t('genesis_block') ?></div>
|
||
<div style="font-size:14px;color:#a855f7;font-weight:600;">
|
||
<?php if ($genesisBlock): ?>
|
||
<a href="?block=1<?= $LANG!=='zh'?'&lang='.$LANG:'' ?>" style="color:#a855f7;">#1</a>
|
||
<?php else: ?>#1<?php endif; ?>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div style="margin-top:16px;padding:12px;background:#00ff8808;border:1px solid #00ff8820;border-radius:8px;font-size:12px;color:#94a3b8;line-height:1.8;">
|
||
💡 <strong style="color:#00ff88;"><?= t('genesis_tip_title') ?></strong>
|
||
<?= t('genesis_tip_desc') ?>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 标签化预览 -->
|
||
<div class="tag-section">
|
||
<div class="tag-header">
|
||
<div class="tag-title"><?= t('tag_title') ?></div>
|
||
<div class="tag-phase"><?= t('tag_phase') ?></div>
|
||
</div>
|
||
<div style="padding:24px;text-align:center;">
|
||
<div style="font-size:32px;margin-bottom:12px;">🔧</div>
|
||
<div style="font-size:15px;color:#e2e8f0;font-weight:600;margin-bottom:8px;"><?= t('tag_dev_title') ?></div>
|
||
<div style="font-size:13px;color:#64748b;line-height:1.8;max-width:500px;margin:0 auto;white-space:pre-line;"><?= t('tag_dev_desc') ?></div>
|
||
<div style="display:flex;justify-content:center;gap:16px;margin-top:20px;flex-wrap:wrap;">
|
||
<?php foreach ([
|
||
['🏠', 'tag_own'],
|
||
['💰', 'tag_income'],
|
||
['✅', 'tag_compliance'],
|
||
['📊', 'tag_valuation'],
|
||
] as [$icon, $key]): ?>
|
||
<div style="background:#ffffff08;border:1px dashed #00c8ff40;border-radius:10px;padding:14px 20px;min-width:120px;">
|
||
<div style="font-size:20px;margin-bottom:6px;"><?= $icon ?></div>
|
||
<div style="font-size:12px;color:#64748b;"><?= t($key) ?></div>
|
||
<div style="font-size:13px;color:#475569;margin-top:4px;"><?= t('tag_pending') ?></div>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
</div>
|
||
<div style="text-align:right;margin-top:12px;padding:0 16px 16px;">
|
||
<a href="?view=tags<?= $LANG!=='zh'?'&lang='.$LANG:'' ?>" style="font-size:13px;color:#a855f7;"><?= t('tag_roadmap_link') ?></a>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- USB 节点预告 -->
|
||
<div class="usb-section">
|
||
<div class="usb-icon">🔌</div>
|
||
<div class="usb-title"><?= t('usb_title') ?></div>
|
||
<div class="usb-desc">
|
||
<?= t('usb_desc') ?>
|
||
<br><strong style="color:#ffd700;"><?= t('usb_slogan') ?></strong>
|
||
</div>
|
||
<div style="margin:20px 0;padding:16px;background:#ffffff08;border:1px solid #ffffff15;border-radius:10px;">
|
||
<div style="font-size:12px;color:#94a3b8;margin-bottom:12px;font-weight:600;"><?= t('usb_growth_title') ?></div>
|
||
<div style="display:flex;align-items:center;gap:0;">
|
||
<?php
|
||
$nodes = [['#00ff88','1','usb_genesis'],['#00c8ff','10+','usb_v2'],['#a855f7','100+','usb_v25'],['#ffd700','∞','usb_v3']];
|
||
foreach ($nodes as $i => [$color, $num, $labelKey]):
|
||
?>
|
||
<div style="text-align:center;flex:1;">
|
||
<div style="font-size:22px;font-weight:800;color:<?= $color ?>"><?= $num ?></div>
|
||
<div style="font-size:10px;color:#64748b;margin-top:2px;white-space:pre-line;"><?= t($labelKey) ?></div>
|
||
</div>
|
||
<?php if ($i < 3): ?>
|
||
<div style="flex:2;height:2px;background:linear-gradient(90deg,<?= $color ?>,<?= $nodes[$i+1][0] ?>);border-radius:1px;"></div>
|
||
<?php endif; ?>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
</div>
|
||
<div class="usb-steps">
|
||
<?php foreach (['usb_step1','usb_step2','usb_step3','usb_step4'] as $i => $key): ?>
|
||
<div class="usb-step">
|
||
<div class="usb-step-num"><?= str_pad($i+1, 2, '0', STR_PAD_LEFT) ?></div>
|
||
<div class="usb-step-text"><?= t($key) ?></div>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
<div style="margin-top:16px;font-size:12px;color:#64748b;"><?= t('usb_note') ?></div>
|
||
</div>
|
||
|
||
<!-- 路线图预览 -->
|
||
<div style="margin-bottom:40px;">
|
||
<div class="roadmap-title"><?= t('roadmap_title') ?></div>
|
||
<div class="roadmap-sub"><?= t('roadmap_sub') ?></div>
|
||
<div class="roadmap-track">
|
||
<?php
|
||
$rmItems = [
|
||
['done', '⛓️', 'roadmap_v1', '#00c8ff', 'roadmap_v1_name', 'roadmap_v1_desc', 'roadmap_v1_badge'],
|
||
['next', '🏷️', 'roadmap_v2', '#a855f7', 'roadmap_v2_name', 'roadmap_v2_desc', 'roadmap_v2_badge'],
|
||
['future','🌐', 'roadmap_v25', '#ff6b35', 'roadmap_v25_name', 'roadmap_v25_desc', 'roadmap_v25_badge'],
|
||
['vision','🔌', 'roadmap_v3', '#ffd700', 'roadmap_v3_name', 'roadmap_v3_desc', 'roadmap_v3_badge'],
|
||
];
|
||
foreach ($rmItems as [$cls, $icon, $verKey, $color, $nameKey, $descKey, $badgeKey]):
|
||
?>
|
||
<div class="roadmap-item <?= $cls ?>">
|
||
<div class="roadmap-dot"><?= $icon ?></div>
|
||
<div class="roadmap-version" style="color:<?= $color ?>;"><?= t($verKey) ?></div>
|
||
<div class="roadmap-name"><?= t($nameKey) ?></div>
|
||
<div class="roadmap-desc"><?= t($descKey) ?></div>
|
||
<div class="roadmap-tags">
|
||
<span class="roadmap-tag" style="color:<?= $color ?>;border-color:<?= $color ?>40;"><?= t($badgeKey) ?></span>
|
||
</div>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
<div style="text-align:right;margin-top:16px;">
|
||
<a href="?view=roadmap<?= $LANG!=='zh'?'&lang='.$LANG:'' ?>" style="font-size:13px;color:#00c8ff;"><?= t('roadmap_link') ?></a>
|
||
</div>
|
||
</div>
|
||
|
||
</div><!-- /container -->
|
||
|
||
<?php elseif ($view === 'blocks'): ?>
|
||
<!-- ==================== 区块列表 ==================== -->
|
||
<div class="container">
|
||
<div class="page-header">
|
||
<h1><?= t('blocks_title') ?></h1>
|
||
<p><?= t('blocks_sub') ?></p>
|
||
</div>
|
||
<div class="card">
|
||
<div class="table-wrap">
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th><?= t('col_block_num') ?></th>
|
||
<th><?= t('col_hash') ?></th>
|
||
<th><?= t('col_producer') ?></th>
|
||
<th><?= t('col_tx_count') ?></th>
|
||
<th><?= t('col_size') ?></th>
|
||
<th><?= t('col_consensus') ?></th>
|
||
<th><?= t('col_time') ?></th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<?php if ($blocksPage && isset($blocksPage['blocks'])): ?>
|
||
<?php foreach ($blocksPage['blocks'] as $b): ?>
|
||
<tr>
|
||
<td><a href="?view=home&block=<?= $b['number'] ?><?= $LANG!=='zh'?'&lang='.$LANG:'' ?>" style="color:#00c8ff;font-weight:700;">#<?= formatNum($b['number']) ?></a></td>
|
||
<td class="mono" style="font-size:11px;"><?= htmlspecialchars(shortHash($b['hash'] ?? '', 10)) ?></td>
|
||
<td class="mono" style="font-size:11px;"><?= htmlspecialchars(shortHash($b['miner'] ?? '', 10)) ?></td>
|
||
<td><?= $b['transactionCount'] ?></td>
|
||
<td style="color:#64748b;"><?= number_format(($b['size'] ?? 0) / 1024, 1) ?> KB</td>
|
||
<td><?= statusBadge($b['cbppConsensus'] ?? 'active') ?></td>
|
||
<td style="color:#64748b;font-size:12px;"><?= timeAgo($b['timestamp']) ?></td>
|
||
</tr>
|
||
<?php endforeach; ?>
|
||
<?php else: ?>
|
||
<tr><td colspan="7"><div class="empty"><div class="empty-icon">📭</div><?= t('no_blocks') ?></div></td></tr>
|
||
<?php endif; ?>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
<?php if ($blocksPage && isset($blocksPage['total'])): ?>
|
||
<?php $totalPages = ceil($blocksPage['total'] / 20); ?>
|
||
<div class="pagination">
|
||
<?php if ($page > 1): ?>
|
||
<a href="?view=blocks&page=<?= $page-1 ?><?= $LANG!=='zh'?'&lang='.$LANG:'' ?>" class="page-link"><?= t('prev_page') ?></a>
|
||
<?php endif; ?>
|
||
<?php for ($i = max(1, $page-2); $i <= min($totalPages, $page+2); $i++): ?>
|
||
<a href="?view=blocks&page=<?= $i ?><?= $LANG!=='zh'?'&lang='.$LANG:'' ?>" class="page-link <?= $i === $page ? 'active' : '' ?>"><?= $i ?></a>
|
||
<?php endfor; ?>
|
||
<?php if ($page < $totalPages): ?>
|
||
<a href="?view=blocks&page=<?= $page+1 ?><?= $LANG!=='zh'?'&lang='.$LANG:'' ?>" class="page-link"><?= t('next_page') ?></a>
|
||
<?php endif; ?>
|
||
</div>
|
||
<?php endif; ?>
|
||
</div>
|
||
</div>
|
||
|
||
<?php elseif ($view === 'transactions'): ?>
|
||
<!-- ==================== 交易列表 ==================== -->
|
||
<div class="container">
|
||
<div class="page-header">
|
||
<h1><?= t('txs_title') ?></h1>
|
||
<p><?= t('txs_sub') ?></p>
|
||
</div>
|
||
<div class="card">
|
||
<div class="table-wrap">
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th><?= t('col_tx_hash') ?></th>
|
||
<th><?= t('col_block_num') ?></th>
|
||
<th><?= t('col_from') ?></th>
|
||
<th><?= t('col_to') ?></th>
|
||
<th><?= t('col_value') ?></th>
|
||
<th><?= t('col_status') ?></th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<?php if ($txsPage): ?>
|
||
<?php foreach ((array)$txsPage as $tx): ?>
|
||
<tr>
|
||
<td><a href="?view=home&tx=<?= urlencode($tx['hash'] ?? '') ?><?= $LANG!=='zh'?'&lang='.$LANG:'' ?>" class="mono" style="color:#00c8ff;font-size:11px;"><?= htmlspecialchars(shortHash($tx['hash'] ?? '', 10)) ?></a></td>
|
||
<td><a href="?view=home&block=<?= $tx['blockNumber'] ?? '' ?><?= $LANG!=='zh'?'&lang='.$LANG:'' ?>" style="color:#94a3b8;">#<?= formatNum($tx['blockNumber'] ?? 0) ?></a></td>
|
||
<td class="mono" style="font-size:11px;"><?= htmlspecialchars(shortHash($tx['from'] ?? '', 10)) ?></td>
|
||
<td class="mono" style="font-size:11px;"><?= htmlspecialchars(shortHash($tx['to'] ?? '', 10)) ?></td>
|
||
<td style="color:#00ff88;"><?= htmlspecialchars($tx['value'] ?? '0') ?></td>
|
||
<td><?= statusBadge($tx['status'] ?? 'pending') ?></td>
|
||
</tr>
|
||
<?php endforeach; ?>
|
||
<?php else: ?>
|
||
<tr><td colspan="6"><div class="empty"><div class="empty-icon">📭</div><?= t('no_txs') ?></div></td></tr>
|
||
<?php endif; ?>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<?php elseif ($view === 'assets'): ?>
|
||
<!-- ==================== RWA 资产 ==================== -->
|
||
<div class="container">
|
||
<div class="page-header">
|
||
<h1><?= t('assets_title') ?></h1>
|
||
<p><?= t('assets_sub') ?></p>
|
||
</div>
|
||
<div class="card">
|
||
<div class="table-wrap">
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th><?= t('col_asset_id') ?></th>
|
||
<th><?= t('col_name') ?></th>
|
||
<th><?= t('col_type') ?></th>
|
||
<th><?= t('col_valuation') ?></th>
|
||
<th><?= t('col_issuer') ?></th>
|
||
<th><?= t('col_status') ?></th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<?php if ($assetsPage): ?>
|
||
<?php foreach ((array)$assetsPage as $a): ?>
|
||
<tr>
|
||
<td class="mono" style="color:#a855f7;"><?= htmlspecialchars($a['id'] ?? '') ?></td>
|
||
<td><?= htmlspecialchars($a['name'] ?? '') ?></td>
|
||
<td><?= assetTypeLabel($a['type'] ?? '') ?></td>
|
||
<td style="color:#ffd700;">$<?= number_format((float)($a['value'] ?? 0), 2) ?></td>
|
||
<td class="mono" style="font-size:11px;"><?= htmlspecialchars(shortHash($a['issuer'] ?? '', 8)) ?></td>
|
||
<td><?= statusBadge($a['status'] ?? 'active') ?></td>
|
||
</tr>
|
||
<?php endforeach; ?>
|
||
<?php else: ?>
|
||
<tr><td colspan="6"><div class="empty"><div class="empty-icon">🏦</div><?= t('no_assets') ?></div></td></tr>
|
||
<?php endif; ?>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
<?php if ($assetsPage): ?>
|
||
<div class="pagination">
|
||
<?php if ($page > 1): ?>
|
||
<a href="?view=assets&page=<?= $page-1 ?><?= $LANG!=='zh'?'&lang='.$LANG:'' ?>" class="page-link"><?= t('prev_page') ?></a>
|
||
<?php endif; ?>
|
||
<a href="?view=assets&page=<?= $page+1 ?><?= $LANG!=='zh'?'&lang='.$LANG:'' ?>" class="page-link"><?= t('next_page') ?></a>
|
||
</div>
|
||
<?php endif; ?>
|
||
</div>
|
||
</div>
|
||
|
||
<?php elseif ($view === 'tags'): ?>
|
||
<!-- ==================== 标签化系统 ==================== -->
|
||
<div class="container">
|
||
<div class="page-header">
|
||
<h1><?= t('tags_title') ?></h1>
|
||
<p><?= t('tags_sub') ?></p>
|
||
</div>
|
||
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:16px;margin-bottom:24px;">
|
||
<?php
|
||
$phases = [
|
||
['#00c8ff', 'tag_phase1_label', 'tag_phase1_title', 'tag_phase1_desc'],
|
||
['#a855f7', 'tag_phase2_label', 'tag_phase2_title', 'tag_phase2_desc'],
|
||
['#ff6b35', 'tag_phase3_label', 'tag_phase3_title', 'tag_phase3_desc'],
|
||
['#ffd700', 'tag_phase4_label', 'tag_phase4_title', 'tag_phase4_desc'],
|
||
];
|
||
foreach ($phases as [$color, $lk, $tk, $dk]):
|
||
?>
|
||
<div class="card" style="border-color:<?= $color ?>40;">
|
||
<div style="font-size:12px;color:<?= $color ?>;font-weight:700;margin-bottom:8px;"><?= t($lk) ?></div>
|
||
<div style="font-size:14px;font-weight:700;color:#fff;margin-bottom:6px;"><?= t($tk) ?></div>
|
||
<div style="font-size:12px;color:#64748b;line-height:1.6;"><?= t($dk) ?></div>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
|
||
<div class="card" style="margin-bottom:24px;">
|
||
<div style="font-size:16px;font-weight:700;color:#fff;margin-bottom:20px;"><?= t('tag_dist_title') ?></div>
|
||
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:16px;">
|
||
<?php
|
||
$tagTypes = [
|
||
['icon'=>'🏠','nameKey'=>'tag_own','count'=>6230,'desc'=>$LANG==='en'?'Asset share ownership voucher':'资产份额持有凭证','color'=>'#00c8ff'],
|
||
['icon'=>'💰','nameKey'=>'tag_income','count'=>4891,'desc'=>$LANG==='en'?'Rent/interest distribution rights':'租金/利息分配权','color'=>'#00ff88'],
|
||
['icon'=>'✅','nameKey'=>'tag_compliance','count'=>3102,'desc'=>$LANG==='en'?'AI-approved compliance voucher':'AI 审批通过凭证','color'=>'#a855f7'],
|
||
['icon'=>'📊','nameKey'=>'tag_valuation','count'=>1624,'desc'=>$LANG==='en'?'AI real-time valuation snapshot':'AI 实时估值快照','color'=>'#ffd700'],
|
||
];
|
||
foreach ($tagTypes as $t2):
|
||
?>
|
||
<div class="card" style="border-color:<?= $t2['color'] ?>30;text-align:center;">
|
||
<div style="font-size:32px;margin-bottom:8px;"><?= $t2['icon'] ?></div>
|
||
<div style="font-size:14px;font-weight:700;color:#fff;margin-bottom:4px;"><?= t($t2['nameKey']) ?></div>
|
||
<div style="font-size:24px;font-weight:800;color:<?= $t2['color'] ?>;margin-bottom:4px;"><?= formatNum($t2['count']) ?></div>
|
||
<div style="font-size:11px;color:#64748b;"><?= $t2['desc'] ?></div>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card" style="margin-bottom:24px;border-color:#a855f740;">
|
||
<div style="font-size:16px;font-weight:700;color:#a855f7;margin-bottom:16px;"><?= t('tag_sep_title') ?></div>
|
||
<div style="display:grid;grid-template-columns:1fr 1fr;gap:20px;">
|
||
<div>
|
||
<div style="font-size:13px;font-weight:600;color:#00c8ff;margin-bottom:8px;"><?= t('tag_trad_title') ?></div>
|
||
<div style="font-size:13px;color:#64748b;line-height:1.8;white-space:pre-line;"><?= t('tag_trad_desc') ?></div>
|
||
</div>
|
||
<div>
|
||
<div style="font-size:13px;font-weight:600;color:#a855f7;margin-bottom:8px;"><?= t('tag_nac_title') ?></div>
|
||
<div style="font-size:13px;color:#94a3b8;line-height:1.8;white-space:pre-line;"><?= t('tag_nac_desc') ?></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card">
|
||
<div style="font-size:16px;font-weight:700;color:#fff;margin-bottom:16px;"><?= t('tag_l3_title') ?></div>
|
||
<div style="font-size:13px;color:#94a3b8;line-height:1.8;"><?= t('tag_l3_desc') ?></div>
|
||
</div>
|
||
</div>
|
||
|
||
<?php elseif ($view === 'roadmap'): ?>
|
||
<!-- ==================== 路线图 ==================== -->
|
||
<div class="container">
|
||
<div class="page-header">
|
||
<h1><?= t('roadmap_page_title') ?></h1>
|
||
<p><?= t('roadmap_page_sub') ?></p>
|
||
</div>
|
||
|
||
<div style="background:linear-gradient(135deg,rgba(0,100,200,0.1),rgba(168,85,247,0.1));border:1px solid rgba(0,200,255,0.2);border-radius:12px;padding:28px;margin-bottom:24px;text-align:center;">
|
||
<div style="font-size:28px;font-weight:800;background:linear-gradient(135deg,#00c8ff,#a855f7,#ffd700);-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text;margin-bottom:12px;">
|
||
<?= $LANG==='en' ? 'Blockchain for Everyone' : '谁都可以玩得起的区块链' ?>
|
||
</div>
|
||
<div style="font-size:15px;color:#94a3b8;max-width:700px;margin:0 auto;line-height:1.8;">
|
||
<?= $LANG==='en'
|
||
? "NAC's ultimate goal is not to serve institutions or the wealthy, but to let every ordinary person participate in blockchain. One USB drive = one node; one node = one participation; one participation = one consensus; one consensus = one share of wealth."
|
||
: 'NAC 的终极目标不是服务机构,不是服务富人,而是让每一个普通人都能参与区块链经济。一个 U 盘,就是一个节点;一个节点,就是一份参与;一份参与,就是一份共识;一份共识,就是一份财富。' ?>
|
||
</div>
|
||
</div>
|
||
|
||
<div style="background:linear-gradient(135deg,rgba(255,215,0,0.05),rgba(0,200,255,0.05));border:1px solid #ffd70030;border-radius:12px;padding:24px;margin-bottom:32px;">
|
||
<div style="font-size:14px;font-weight:800;color:#ffd700;margin-bottom:16px;letter-spacing:1px;">💡 <?= $LANG==='en'?'NAC Core Design Philosophy':'NAC 核心设计哲学' ?></div>
|
||
<div style="font-size:20px;font-weight:800;color:#fff;margin-bottom:12px;"><?= $LANG==='en'?'Decentralization Under Perfect Centralization':'完美中心化下的去中心化' ?></div>
|
||
<div style="font-size:13px;color:#94a3b8;line-height:1.9;margin-bottom:20px;">
|
||
<?= $LANG==='en'
|
||
? 'Utopian full decentralization leads to no accountability, unenforceable compliance, and unacceptable regulation. NAC chose a more pragmatic path: <strong style="color:#00ff88;">centralization handles order, decentralization handles trust.</strong>'
|
||
: '乌托邦式的完全去中心化导致无人负责、合规无法执行、监管无法接受。NAC 选择了一条更务实的道路:<strong style="color:#00ff88;">中心化负责秩序,去中心化负责信任。</strong>' ?>
|
||
</div>
|
||
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:12px;">
|
||
<?php
|
||
$phils = $LANG==='en' ? [
|
||
['#00c8ff', 'Centralized Parts', "• Tag content managed by AI\n• RWA asset compliance\n• Unified approval standards\n• Regulatory compliance"],
|
||
['#00ff88', 'Decentralized Parts', "• Approval results immutable on-chain\n• L3 distributed storage\n• CBPP consensus no single point\n• Anyone can verify data"],
|
||
['#ffd700', 'Always Unchanged', "• Decentralized content preserved\n• On-chain hashes permanent\n• Equal node participation rights\n• Consensus rules immutable"],
|
||
] : [
|
||
['#00c8ff', '中心化的部分', "• 标签内容由 AI 审批管理\n• RWA 资产合规认证\n• 审批标准统一制定\n• 监管合规执行"],
|
||
['#00ff88', '去中心化的部分', "• 审批结果上链不可篡改\n• L3 分布式存储层\n• CBPP 共识无单点\n• 任何人可验证数据"],
|
||
['#ffd700', '始终不变的部分', "• 去中心化内容保持不变\n• 链上哈希永久存在\n• 节点参与权利平等\n• 共识规则不可修改"],
|
||
];
|
||
foreach ($phils as [$c, $title, $desc]):
|
||
?>
|
||
<div style="background:#ffffff08;border:1px solid #ffffff10;border-radius:8px;padding:14px;">
|
||
<div style="font-size:12px;color:<?= $c ?>;font-weight:700;margin-bottom:8px;"><?= $title ?></div>
|
||
<div style="font-size:12px;color:#64748b;line-height:1.7;white-space:pre-line;"><?= $desc ?></div>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="cbpp-banner" style="margin-bottom:32px;">
|
||
<div class="cbpp-title"><?= t('cbpp_title') ?> — <?= $LANG==='en'?'The Fundamental Law of NAC':'NAC 的根本法则' ?></div>
|
||
<div class="cbpp-principles">
|
||
<?php
|
||
$cbppItems = $LANG==='en' ? [
|
||
['Charter is the Law', 'Rules written on-chain; code is law, no lawyers or courts needed'],
|
||
['Constitution is the Rule', 'Protocol-level constitution constrains all participants, including founders'],
|
||
['Participation IS Consensus', 'Participating in the network contributes to consensus; no large token stakes needed'],
|
||
['Nodes Produce Blocks', 'Any node can participate in block production; USB nodes have equal rights'],
|
||
['Transactions Expand Block Size', 'Block size is dynamically determined by real transaction volume; no artificial limits'],
|
||
] : [
|
||
['约法即是治法', '规则写在链上,代码即法律,无需律师和法院'],
|
||
['宪法即是规则', '协议层面的宪法约束所有参与者,包括创始团队'],
|
||
['参与即是共识', '只要参与网络就是在贡献共识,无需质押大量代币'],
|
||
['节点产生区块', '任何节点都可以参与出块,U 盘节点同等权利'],
|
||
['交易扩展区块大小', '区块大小由真实交易量动态决定,无人为限制'],
|
||
];
|
||
foreach ($cbppItems as [$title, $desc]):
|
||
?>
|
||
<div class="cbpp-item"><div class="cbpp-dot"></div><div><strong><?= $title ?></strong><br><span style="font-size:11px;color:#64748b;"><?= $desc ?></span></div></div>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
</div>
|
||
|
||
<div style="display:flex;flex-direction:column;gap:20px;margin-bottom:40px;">
|
||
<?php
|
||
$roadmapDetails = $LANG==='en' ? [
|
||
['#00c8ff','⛓️','MAINNET 1.0 · RUNNING','Infrastructure','✅ Running',[
|
||
['🖥️','NVM Virtual Machine','NAC native VM, not EVM'],
|
||
['📜','Charter Contracts','NAC native smart contract language'],
|
||
['🤝','CBPP Consensus','Constitutional consensus mechanism'],
|
||
['🌐','CSNP Network','NAC native P2P network'],
|
||
['🏦','RWA On-Chain','Real world asset tokenization'],
|
||
['🤖','AI Compliance','Built-in AI compliance and valuation'],
|
||
]],
|
||
['#a855f7','🏷️','MAINNET 2.0 · IN DEV','Partial Tagging','🔨 In Dev',[
|
||
['🏠','Ownership Tagging','Asset share fragmentation, lower barrier'],
|
||
['💰','Income Separation','Ownership and income rights circulate independently'],
|
||
['✅','Compliance Tags','AI compliance status queryable on-chain'],
|
||
['📊','Valuation Tags','AI real-time valuation snapshots'],
|
||
['🗄️','L3 Distributed Storage
|
||
','Tag content AI-approved, stored in L3 distributed layer'],
|
||
['🔗','Hash Anchoring','SHA3-384 hash stored on-chain, immutable'],
|
||
]],
|
||
] : [
|
||
['#00c8ff','⛓️','主网 1.0 · 当前运行','基础设施建立','✅ 运行中',[
|
||
['🖥️','NVM 虚拟机','NAC 原生虚拟机,非 EVM'],
|
||
['📜','Charter 合约','NAC 原生智能合约语言'],
|
||
['🤝','CBPP 共识','宪法共识机制'],
|
||
['🌐','CSNP 网络','NAC 原生 P2P 网络'],
|
||
['🏦','RWA 上链','真实世界资产代币化'],
|
||
['🤖','AI 合规审批','内置 AI 合规和估值'],
|
||
]],
|
||
['#a855f7','🏷️','主网 2.0 · 开发中','部分标签化升级','🔨 开发中',[
|
||
['🏠','所有权标签化','资产份额碎片化,降低投资门槛'],
|
||
['💰','收益权分离','所有权与收益权独立流通'],
|
||
['✅','合规标签','AI 合规状态链上可查'],
|
||
['📊','估值标签','AI 实时估值快照'],
|
||
['🗄️','L3 分布式存储层','标签内容 AI 审批,存储在 L3 分布式层'],
|
||
['🔗','哈希锚定','链上存储 SHA3-384 哈希,不可篡改'],
|
||
]],
|
||
];
|
||
foreach ($roadmapDetails as [$color, $icon, $version, $name, $badge, $features]):
|
||
?>
|
||
<div class="card" style="border-color:<?= $color ?>40;border-left:4px solid <?= $color ?>;">
|
||
<div style="display:flex;align-items:center;gap:16px;margin-bottom:16px;flex-wrap:wrap;">
|
||
<div style="font-size:32px;"><?= $icon ?></div>
|
||
<div>
|
||
<div style="font-size:12px;color:<?= $color ?>;font-weight:700;text-transform:uppercase;letter-spacing:1px;"><?= $version ?></div>
|
||
<div style="font-size:20px;font-weight:800;color:#fff;"><?= $name ?></div>
|
||
</div>
|
||
<span class="badge" style="background:<?= $color ?>20;color:<?= $color ?>;border:1px solid <?= $color ?>40;margin-left:auto;"><?= $badge ?></span>
|
||
</div>
|
||
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:12px;">
|
||
<?php foreach ($features as [$fi, $fn, $fd]): ?>
|
||
<div style="background:rgba(<?= $color==='#00c8ff'?'0,200,255':($color==='#a855f7'?'168,85,247':'255,107,53') ?>,0.04);border:1px solid rgba(<?= $color==='#00c8ff'?'0,200,255':($color==='#a855f7'?'168,85,247':'255,107,53') ?>,0.1);border-radius:8px;padding:10px;">
|
||
<div style="font-size:16px;margin-bottom:4px;"><?= $fi ?></div>
|
||
<div style="font-size:13px;font-weight:600;color:#fff;margin-bottom:2px;"><?= $fn ?></div>
|
||
<div style="font-size:11px;color:#64748b;"><?= $fd ?></div>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
|
||
<!-- 主网 2.5 -->
|
||
<div class="card" style="border-color:#ff6b3540;border-left:4px solid #ff6b35;">
|
||
<div style="display:flex;align-items:center;gap:16px;margin-bottom:16px;flex-wrap:wrap;">
|
||
<div style="font-size:32px;">🌐</div>
|
||
<div>
|
||
<div style="font-size:12px;color:#ff6b35;font-weight:700;text-transform:uppercase;letter-spacing:1px;"><?= $LANG==='en'?'MAINNET 2.5 · PLANNED':'主网 2.5 · 规划中' ?></div>
|
||
<div style="font-size:20px;font-weight:800;color:#fff;"><?= $LANG==='en'?'Gradual Distributed Upgrade':'逐步可行性升级' ?></div>
|
||
</div>
|
||
<span class="badge" style="background:#ff6b3520;color:#ff6b35;border:1px solid #ff6b3540;margin-left:auto;"><?= $LANG==='en'?'📋 Planned':'📋 规划中' ?></span>
|
||
</div>
|
||
<div style="font-size:13px;color:#94a3b8;line-height:1.8;">
|
||
<?= $LANG==='en'
|
||
? 'More servers and nodes join the network, L3 storage layer capacity expands naturally. Everyone who participates in on-chain registration is a node — participation is consensus. More assets on-chain, more transactions, larger blocks, more nodes, stronger network. This is the natural growth logic of CBPP consensus.'
|
||
: '更多服务器和节点加入网络,L3 存储层容量自然扩展。每个参与上链的人即是节点,参与即是共识。资产上链越多,交易越多,区块越大,节点越多,网络越强大。这就是 CBPP 共识的自然增长逻辑。' ?>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 主网 3.0 -->
|
||
<div class="card" style="border-color:#ffd70040;border-left:4px solid #ffd700;">
|
||
<div style="display:flex;align-items:center;gap:16px;margin-bottom:16px;flex-wrap:wrap;">
|
||
<div style="font-size:32px;">🔌</div>
|
||
<div>
|
||
<div style="font-size:12px;color:#ffd700;font-weight:700;text-transform:uppercase;letter-spacing:1px;"><?= $LANG==='en'?'MAINNET 3.0 · VISION':'主网 3.0 · 终极愿景' ?></div>
|
||
<div style="font-size:20px;font-weight:800;color:#fff;"><?= $LANG==='en'?'USB Era · Blockchain for Everyone':'USB 化 · 全民区块链' ?></div>
|
||
</div>
|
||
<span class="badge" style="background:#ffd70020;color:#ffd700;border:1px solid #ffd70040;margin-left:auto;"><?= $LANG==='en'?'🌟 Vision':'🌟 愿景' ?></span>
|
||
</div>
|
||
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:12px;margin-bottom:16px;">
|
||
<?php
|
||
$v3items = $LANG==='en' ? [
|
||
['🔌','USB = Node','16GB USB plugged into any PC runs a node'],
|
||
['💾','Distributed Storage','All tags fully stored in CSNP node network'],
|
||
['🏦','USB Synthetic Bonds','Multi-type RWA tags synthesized into globally circulating bonds'],
|
||
['🌍','Global Circulation','Frictionless cross-border, cross-asset circulation'],
|
||
['👨👩👧👦','For Everyone','No mining rigs, no staking — participation is consensus'],
|
||
['💎','Node Rewards','Run a node, earn storage and consensus rewards'],
|
||
] : [
|
||
['🔌','U 盘即节点','16GB U 盘插入任何电脑即可运行节点'],
|
||
['💾','分布式存储','所有标签完全存储在 CSNP 节点网络'],
|
||
['🏦','USB 合成债券','多类型 RWA 标签合成全球流通债券'],
|
||
['🌍','全球流通','跨境、跨资产类别的无摩擦流通'],
|
||
['👨👩👧👦','全民参与','无需算力,无需质押,参与即是共识'],
|
||
['💎','节点奖励','运行节点获得存储奖励和共识奖励'],
|
||
];
|
||
foreach ($v3items as [$vi, $vn, $vd]):
|
||
?>
|
||
<div style="background:rgba(255,215,0,0.04);border:1px solid rgba(255,215,0,0.1);border-radius:8px;padding:10px;">
|
||
<div style="font-size:16px;margin-bottom:4px;"><?= $vi ?></div>
|
||
<div style="font-size:13px;font-weight:600;color:#fff;margin-bottom:2px;"><?= $vn ?></div>
|
||
<div style="font-size:11px;color:#64748b;"><?= $vd ?></div>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
<div style="background:rgba(255,215,0,0.06);border:1px solid rgba(255,215,0,0.15);border-radius:8px;padding:16px;text-align:center;">
|
||
<div style="font-size:15px;font-weight:700;color:#ffd700;margin-bottom:6px;">
|
||
"<?= $LANG==='en'
|
||
? 'Charter is Law, Constitution is Rule, Participation is Consensus, Nodes Produce Blocks, Transactions Expand Block Size'
|
||
: '约法即是治法,宪法即是规则,参与即是共识,节点产生区块,交易扩展区块大小' ?>"
|
||
</div>
|
||
<div style="font-size:12px;color:#94a3b8;">— <?= $LANG==='en'?'CBPP Constitutional Principles, the Fundamental Law of NAC':'CBPP 宪法原则,NAC 的根本法则' ?></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<?php elseif ($view === 'block_detail' && $blockDetail): ?>
|
||
<!-- ==================== 区块详情 ==================== -->
|
||
<div class="container">
|
||
<div class="page-header">
|
||
<h1><?= t('block_detail_title', formatNum($blockDetail['number'] ?? 0)) ?></h1>
|
||
<p><a href="?view=blocks<?= $LANG!=='zh'?'&lang='.$LANG:'' ?>"><?= t('back_blocks') ?></a></p>
|
||
</div>
|
||
<div class="detail-card" style="margin-bottom:20px;">
|
||
<div class="detail-header">
|
||
<span style="font-size:20px;">📦</span>
|
||
<h2><?= $LANG==='en'?'Block':'区块' ?> #<?= formatNum($blockDetail['number'] ?? 0) ?></h2>
|
||
<?= statusBadge($blockDetail['cbppConsensus'] ?? 'active') ?>
|
||
</div>
|
||
<?php
|
||
$detailRows = [
|
||
[t('detail_block_num'), '#' . formatNum($blockDetail['number'] ?? 0)],
|
||
[t('detail_block_hash'), $blockDetail['hash'] ?? '—'],
|
||
[t('detail_parent_hash'),$blockDetail['parentHash'] ?? '—'],
|
||
[t('detail_producer'), $blockDetail['miner'] ?? '—'],
|
||
[t('detail_tx_count'), t('detail_tx_count_v', $blockDetail['transactionCount'] ?? 0)],
|
||
[t('detail_size'), number_format(($blockDetail['size'] ?? 0) / 1024, 2) . ' KB'],
|
||
[t('detail_gas'), formatNum($blockDetail['gasUsed'] ?? 0) . ' / ' . formatNum($blockDetail['gasLimit'] ?? 0)],
|
||
[t('detail_cbpp'), $blockDetail['cbppConsensus'] ?? '—'],
|
||
[t('detail_const'), ($blockDetail['constitutionLayer'] ?? false) ? t('detail_const_yes') : t('detail_const_no')],
|
||
[t('detail_fluid'), ($blockDetail['isFluid'] ?? false) ? t('detail_fluid_yes') : t('detail_fluid_no')],
|
||
[t('detail_timestamp'), date('Y-m-d H:i:s', $blockDetail['timestamp'] ?? 0) . ' (' . timeAgo($blockDetail['timestamp'] ?? 0) . ')'],
|
||
];
|
||
foreach ($detailRows as [$label, $value]):
|
||
?>
|
||
<div class="detail-row">
|
||
<div class="detail-label"><?= $label ?></div>
|
||
<div class="detail-value mono"><?= htmlspecialchars($value) ?></div>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
|
||
<?php if (!empty($blockDetail['transactions'])): ?>
|
||
<div class="card">
|
||
<div style="font-size:15px;font-weight:700;color:#fff;margin-bottom:16px;">
|
||
<?= t('block_txs_title', count($blockDetail['transactions'])) ?>
|
||
</div>
|
||
<div class="table-wrap">
|
||
<table>
|
||
<thead><tr>
|
||
<th><?= t('col_tx_hash') ?></th>
|
||
<th><?= t('col_from') ?></th>
|
||
<th><?= t('col_to') ?></th>
|
||
<th><?= t('col_value') ?></th>
|
||
<th><?= t('col_status') ?></th>
|
||
</tr></thead>
|
||
<tbody>
|
||
<?php foreach ($blockDetail['transactions'] as $tx): ?>
|
||
<tr>
|
||
<td><a href="?view=home&tx=<?= urlencode($tx['hash'] ?? '') ?><?= $LANG!=='zh'?'&lang='.$LANG:'' ?>" class="mono" style="color:#00c8ff;font-size:11px;"><?= htmlspecialchars(shortHash($tx['hash'] ?? '', 10)) ?></a></td>
|
||
<td class="mono" style="font-size:11px;"><?= htmlspecialchars(shortHash($tx['from'] ?? '', 10)) ?></td>
|
||
<td class="mono" style="font-size:11px;"><?= htmlspecialchars(shortHash($tx['to'] ?? '', 10)) ?></td>
|
||
<td style="color:#00ff88;"><?= htmlspecialchars($tx['value'] ?? '0') ?> NAC</td>
|
||
<td><?= statusBadge($tx['status'] ?? 'success') ?></td>
|
||
</tr>
|
||
<?php endforeach; ?>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
<?php endif; ?>
|
||
</div>
|
||
|
||
<?php elseif ($view === 'tx_detail' && $txDetail): ?>
|
||
<!-- ==================== 交易详情 ==================== -->
|
||
<div class="container">
|
||
<div class="page-header">
|
||
<h1><?= t('tx_detail_title') ?></h1>
|
||
<p><a href="?view=transactions<?= $LANG!=='zh'?'&lang='.$LANG:'' ?>"><?= t('back_txs') ?></a></p>
|
||
</div>
|
||
<div class="detail-card">
|
||
<div class="detail-header">
|
||
<span style="font-size:20px;">🔄</span>
|
||
<h2><?= t('tx_detail_title') ?></h2>
|
||
<?= statusBadge($txDetail['status'] ?? 'success') ?>
|
||
</div>
|
||
<?php
|
||
$txRows = [
|
||
[t('detail_tx_hash'), $txDetail['hash'] ?? '—'],
|
||
[t('detail_block_num2'), '#' . formatNum($txDetail['blockNumber'] ?? 0)],
|
||
[t('detail_block_hash2'),$txDetail['blockHash'] ?? '—'],
|
||
[t('detail_from'), $txDetail['from'] ?? '—'],
|
||
[t('detail_to'), $txDetail['to'] ?? '—'],
|
||
[t('detail_value'), ($txDetail['value'] ?? '0') . ' NAC'],
|
||
[t('detail_gas_limit'), formatNum($txDetail['gas'] ?? 0)],
|
||
[t('detail_gas_price'), $txDetail['gasPrice'] ?? '—'],
|
||
[t('detail_nonce'), $txDetail['nonce'] ?? '0'],
|
||
[t('detail_tx_index'), $txDetail['transactionIndex'] ?? '0'],
|
||
[t('detail_status'), $txDetail['status'] ?? '—'],
|
||
];
|
||
foreach ($txRows as [$label, $value]):
|
||
?>
|
||
<div class="detail-row">
|
||
<div class="detail-label"><?= $label ?></div>
|
||
<div class="detail-value mono"><?= htmlspecialchars($value) ?></div>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
</div>
|
||
|
||
<?php elseif ($view === 'search'): ?>
|
||
<!-- ==================== 搜索结果 ==================== -->
|
||
<div class="container">
|
||
<div class="page-header">
|
||
<h1><?= t('search_title') ?></h1>
|
||
<p><?= t('search_keyword', htmlspecialchars($search)) ?></p>
|
||
</div>
|
||
<?php if ($searchResult): ?>
|
||
<div class="card">
|
||
<div style="font-size:14px;color:#64748b;margin-bottom:12px;">
|
||
<?= t('search_type') ?><span style="color:#00c8ff;"><?= htmlspecialchars($searchResult['type'] ?? '') ?></span>
|
||
</div>
|
||
<?php if (($searchResult['type'] ?? '') === 'block'): ?>
|
||
<div style="font-size:15px;color:#e2e8f0;">
|
||
<a href="?view=home&block=<?= $searchResult['number'] ?? '' ?><?= $LANG!=='zh'?'&lang='.$LANG:'' ?>" style="color:#00c8ff;">
|
||
<?= t('search_view_block', formatNum($searchResult['number'] ?? 0)) ?>
|
||
</a>
|
||
</div>
|
||
<?php else: ?>
|
||
<pre style="font-size:12px;color:#94a3b8;overflow-x:auto;"><?= htmlspecialchars(json_encode($searchResult, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)) ?></pre>
|
||
<?php endif; ?>
|
||
</div>
|
||
<?php else: ?>
|
||
<div class="card">
|
||
<div class="empty">
|
||
<div class="empty-icon">🔍</div>
|
||
<?= t('search_not_found', htmlspecialchars($search)) ?>
|
||
</div>
|
||
</div>
|
||
<?php endif; ?>
|
||
</div>
|
||
|
||
<?php endif; ?>
|
||
</main>
|
||
|
||
<!-- ===== 页脚 ===== -->
|
||
<footer>
|
||
<div class="container">
|
||
<div class="footer-logo"><?= t('footer_logo') ?></div>
|
||
<div class="footer-desc"><?= t('footer_desc') ?></div>
|
||
<div class="footer-tags">
|
||
<?php foreach (['CBPP', 'CSNP', 'NVM', 'Charter', 'NRPC4.0', 'SHA3-384', 'RWA', $LANG==='en'?'Quantum Browser':'量子浏览器'] as $tag): ?>
|
||
<span class="footer-tag"><?= $tag ?></span>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
<div class="footer-copy">
|
||
<?= t('footer_copy', date('Y'), VERSION) ?>
|
||
<a href="?view=roadmap<?= $LANG!=='zh'?'&lang='.$LANG:'' ?>" style="color:#00c8ff;"><?= t('footer_roadmap') ?></a>
|
||
</div>
|
||
</div>
|
||
</footer>
|
||
|
||
<!-- ===== JS 动态刷新 ===== -->
|
||
<script>
|
||
const LANG = '<?= $LANG ?>';
|
||
const t_new_block = <?= json_encode(t('js_new_block_title')) ?>;
|
||
const t_page_title = <?= json_encode(t('js_page_title')) ?>;
|
||
const t_tx_count = <?= json_encode(t('tx_count', '%s')) ?>;
|
||
|
||
let lastBlock = <?= (int)($stats['currentBlock'] ?? 0) ?>;
|
||
let pollInterval = 5000;
|
||
|
||
async function pollChain() {
|
||
try {
|
||
const r = await fetch('/api/v1/network/stats', { signal: AbortSignal.timeout(4000) });
|
||
if (!r.ok) return;
|
||
const j = await r.json();
|
||
const d = j.data || j;
|
||
const cur = parseInt(d.currentBlock || 0);
|
||
if (cur > lastBlock) {
|
||
lastBlock = cur;
|
||
const el = document.getElementById('stat-block');
|
||
if (el) {
|
||
el.textContent = cur.toLocaleString();
|
||
el.style.color = '#00ff88';
|
||
setTimeout(() => { el.style.color = ''; }, 1000);
|
||
}
|
||
document.title = t_new_block.replace('%s', cur.toLocaleString());
|
||
setTimeout(() => { document.title = t_page_title; }, 3000);
|
||
await refreshBlocks();
|
||
}
|
||
} catch(e) {}
|
||
}
|
||
|
||
async function refreshBlocks() {
|
||
try {
|
||
const r = await fetch('/api/v1/blocks?limit=12', { signal: AbortSignal.timeout(4000) });
|
||
if (!r.ok) return;
|
||
const j = await r.json();
|
||
const blocks = (j.data || j).blocks || [];
|
||
const cv = document.getElementById('chain-visual');
|
||
if (!cv || !blocks.length) return;
|
||
cv.innerHTML = blocks.slice(0, 12).map(b => {
|
||
const txLabel = t_tx_count.replace('%s', b.transactionCount || 0);
|
||
const langParam = LANG !== 'zh' ? '&lang=' + LANG : '';
|
||
return `<a href="?view=home&block=${b.number}${langParam}" style="text-decoration:none;">
|
||
<div class="chain-block">
|
||
<div class="block-num">#${(b.number||0).toLocaleString()}</div>
|
||
<div class="block-txs">${txLabel}</div>
|
||
</div>
|
||
</a><div class="chain-arrow">←</div>`;
|
||
}).join('');
|
||
} catch(e) {}
|
||
}
|
||
|
||
setInterval(pollChain, pollInterval);
|
||
</script>
|
||
</body>
|
||
</html>
|