link baixar exe verção completa
📖 Manual Passo a Passo — Copiar e Colar
Este manual te guia para criar 5 arquivos na pasta agora-brn e executar tudo. Cada arquivo tem instruções claras de como salvar sem o Notepad adicionar .txt.
🔧 Passo 0 — Criar a pasta
Abra o CMD (tecla Windows → digite cmd → Enter) e cole:
mkdir "C:UsersadnacDesktopbruno cryptoagora-brn" 2>nul cd /d "C:UsersadnacDesktopbruno cryptoagora-brn" echo Pasta pronta: %CD%
📄 ARQUIVO 1 — brn_discovery.py
Como salvar:
-
Abra o Notepad
-
Cole o conteúdo abaixo
-
Arquivo → Salvar Como
-
Nome do arquivo:
"brn_discovery.py"⚠️ COM ASPAS DUPLAS -
Tipo: Todos os arquivos (
*.*) -
Codificação: UTF-8
-
Pasta:
C:UsersadnacDesktopbruno cryptoagora-brn -
Salvar
Conteúdo para copiar:
""" brn_discovery.py - Descoberta automatica de peers da Moeda Bruno (BRN) Escuta e anuncia na rede local via UDP broadcast (porta 5999). """ import json import socket import threading import time from pathlib import Path DISCOVERY_PORT = 5999 BROADCAST_ADDR = "255.255.255.255" ANNOUNCE_INTERVAL = 5 PEERS_FILE = Path(__file__).parent / "peers_auto.json" def _get_local_ip(): s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) try: s.connect(("8.8.8.8", 80)) return s.getsockname()[0] except Exception: return "127.0.0.1" finally: s.close() def _load_peers(): if PEERS_FILE.exists(): try: return json.loads(PEERS_FILE.read_text(encoding="utf-8")) except Exception: return {} return {} def _save_peers(peers): try: PEERS_FILE.write_text( json.dumps(peers, indent=2, ensure_ascii=False), encoding="utf-8" ) except Exception: pass class PeerDiscovery: def __init__(self, my_port, node_id=None, on_new_peer=None): self.my_port = int(my_port) self.node_id = node_id or f"{_get_local_ip()}:{my_port}" self.on_new_peer = on_new_peer self.peers = _load_peers() self.running = False self._threads = [] def _announce_loop(self): sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) payload = json.dumps({ "brn": True, "node_id": self.node_id, "port": self.my_port, "ts": time.time(), }).encode("utf-8") while self.running: try: sock.sendto(payload, (BROADCAST_ADDR, DISCOVERY_PORT)) except Exception: pass time.sleep(ANNOUNCE_INTERVAL) sock.close() def _listen_loop(self): sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) try: sock.bind(("", DISCOVERY_PORT)) except Exception as e: print(f"[discovery] Falha ao abrir porta UDP {DISCOVERY_PORT}: {e}") return sock.settimeout(1.0) while self.running: try: data, addr = sock.recvfrom(2048) msg = json.loads(data.decode("utf-8")) if not msg.get("brn"): continue peer_id = msg.get("node_id") if peer_id == self.node_id: continue peer_ip = addr[0] peer_port = msg.get("port") key = f"{peer_ip}:{peer_port}" is_new = key not in self.peers self.peers[key] = { "ip": peer_ip, "port": peer_port, "node_id": peer_id, "last_seen": time.time(), } if is_new: print(f"[discovery] Novo peer: {key}") _save_peers(self.peers) if self.on_new_peer: try: self.on_new_peer(peer_ip, peer_port) except Exception as e: print(f"[discovery] Erro no callback: {e}") except socket.timeout: continue except Exception: continue sock.close() def start(self): self.running = True t1 = threading.Thread(target=self._announce_loop, daemon=True) t2 = threading.Thread(target=self._listen_loop, daemon=True) t1.start() t2.start() self._threads = [t1, t2] def stop(self): self.running = False for t in self._threads: t.join(timeout=2) def list_peers(self): now = time.time() return [p for p in self.peers.values() if now - p.get("last_seen", 0) < 30]
📄 ARQUIVO 2 — brn_status.py
Como salvar:
-
Notepad novo
-
Cole o conteúdo
-
Salvar Como → nome:
"brn_status.py"(com aspas) -
Tipo: Todos os arquivos (
*.*) -
Codificação: UTF-8
-
Mesma pasta
Conteúdo para copiar:
""" brn_status.py - Dashboard de status da blockchain BRN Mostra altura, tamanho em disco, mempool e peers em tempo real. """ import os import time from pathlib import Path UPDATE_INTERVAL = 2 BASE = Path(__file__).parent def _find_db(): dbs = sorted(BASE.glob("blockchain_node_*.db")) return dbs[0] if dbs else None def _human_size(num_bytes): for unit in ["B", "KB", "MB", "GB"]: if num_bytes < 1024: return f"{num_bytes:.2f} {unit}" num_bytes /= 1024 return f"{num_bytes:.2f} TB" def get_chain_info(): db = _find_db() if not db: return {"height": 0, "size": 0, "db": None, "error": "banco nao encontrado"} info = {"height": 0, "size": db.stat().st_size, "db": db.name, "error": None} try: import sqlite3 conn = sqlite3.connect(f"file:{db}?mode=ro", uri=True, timeout=2) cur = conn.cursor() cur.execute("SELECT name FROM sqlite_master WHERE type='table'") tables = [r[0] for r in cur.fetchall()] for tbl in ["blocks", "chain", "blockchain"]: if tbl in tables: cur.execute(f"SELECT COUNT(*) FROM {tbl}") info["height"] = cur.fetchone()[0] break conn.close() except Exception as e: info["error"] = str(e) return info def get_mempool_info(): import json files = sorted(BASE.glob("mempool_node_*.json")) if not files: return 0 try: data = json.loads(files[0].read_text(encoding="utf-8")) if isinstance(data, list): return len(data) if isinstance(data, dict): return len(data.get("transactions", data)) except Exception: pass return 0 def get_peers_info(): import json pfile = BASE / "peers_auto.json" if not pfile.exists(): return [] try: data = json.loads(pfile.read_text(encoding="utf-8")) now = time.time() return [k for k, v in data.items() if now - v.get("last_seen", 0) < 30] except Exception: return [] def _clear(): os.system("cls" if os.name == "nt" else "clear") def render(): chain = get_chain_info() mempool = get_mempool_info() peers = get_peers_info() _clear() print("=" * 62) print(" MOEDA BRUNO (BRN) - STATUS DA BLOCKCHAIN") print("=" * 62) print() if chain["error"]: print(f" [AVISO] {chain['error']}") print(f" Banco: {chain['db'] or 'nao encontrado'}") else: print(f" Altura do bloco : {chain['height']:>10,}".replace(",", ".")) print(f" Tamanho em disco : {_human_size(chain['size']):>10}") print(f" Arquivo : {chain['db']}") print() print(f" Transacoes na mempool : {mempool}") print(f" Peers conectados : {len(peers)}") for p in peers[:8]: print(f" - {p}") if len(peers) > 8: print(f" ... e mais {len(peers) - 8}") print() print("-" * 62) print(f" Atualizado: {time.strftime('%H:%M:%S')} (Ctrl+C para sair)") print("=" * 62) def main(): try: while True: render() time.sleep(UPDATE_INTERVAL) except KeyboardInterrupt: print(" Encerrado.") if __name__ == "__main__": main()
📄 ARQUIVO 3 — brn_autostart.py
Salvar igual aos anteriores — nome: "brn_autostart.py"
Conteúdo para copiar:
""" brn_autostart.py - Inicia o no BRN com descoberta automatica de peers e dashboard de status. Uso: python brn_autostart.py 6001 """ import json import sys import threading import time import urllib.request from pathlib import Path from brn_discovery import PeerDiscovery, _load_peers from brn_status import get_chain_info, get_mempool_info, get_peers_info BASE = Path(__file__).parent def notificar_peer(peer_ip, peer_port, my_port): endpoints = [ ("http://127.0.0.1:{port}/add_peer", {"ip": peer_ip, "port": peer_port}), ("http://127.0.0.1:{port}/connect", {"host": peer_ip, "port": peer_port}), ("http://127.0.0.1:{port}/api/peers", {"address": f"{peer_ip}:{peer_port}"}), ] for url_tpl, payload in endpoints: url = url_tpl.format(port=my_port) try: req = urllib.request.Request( url, data=json.dumps(payload).encode("utf-8"), headers={"Content-Type": "application/json"}, method="POST", ) with urllib.request.urlopen(req, timeout=2) as resp: if 200 <= resp.status < 300: print(f"[sync] Peer {peer_ip}:{peer_port} enviado ao app local.") return True except Exception: continue print(f"[sync] Nao consegui avisar o app sobre {peer_ip}:{peer_port}.") return False def loop_sincronizacao(my_port, stop_flag): while not stop_flag.is_set(): peers = _load_peers() now = time.time() for key, p in peers.items(): if now - p.get("last_seen", 0) > 60: continue notificar_peer(p["ip"], p["port"], my_port) time.sleep(15) def loop_dashboard(stop_flag): import os while not stop_flag.is_set(): chain = get_chain_info() mempool = get_mempool_info() peers = get_peers_info() os.system("cls" if os.name == "nt" else "clear") print("=" * 62) print(" MOEDA BRUNO (BRN) - NO ATIVO COM DESCOBERTA AUTOMATICA") print("=" * 62) print() if chain["error"]: print(f" [AVISO] {chain['error']}") else: def human(n): for u in ["B", "KB", "MB", "GB"]: if n < 1024: return f"{n:.2f} {u}" n /= 1024 return f"{n:.2f} TB" print(f" Altura do bloco : {chain['height']:>10,}".replace(",", ".")) print(f" Tamanho em disco : {human(chain['size']):>10}") print(f" Arquivo : {chain['db']}") print() print(f" Transacoes mempool : {mempool}") print(f" Peers online : {len(peers)}") for p in peers[:8]: print(f" - {p}") print() print("-" * 62) print(f" Atualizado: {time.strftime('%H:%M:%S')} (Ctrl+C para sair)") print("=" * 62) time.sleep(2) def main(): if len(sys.argv) < 2: print("Uso: python brn_autostart.py" ) sys.exit(1) my_port = int(sys.argv[1]) print(f"[brn] Iniciando no na porta {my_port}...") discovery = PeerDiscovery( my_port=my_port, on_new_peer=lambda ip, port: notificar_peer(ip, port, my_port), ) discovery.start() print(f"[brn] Descoberta UDP ativa (porta 5999).") stop_flag = threading.Event() t_sync = threading.Thread( target=loop_sincronizacao, args=(my_port, stop_flag), daemon=True ) t_dash = threading.Thread(target=loop_dashboard, args=(stop_flag,), daemon=True) t_sync.start() t_dash.start() try: while True: time.sleep(1) except KeyboardInterrupt: print(" [brn] Encerrando...") stop_flag.set() discovery.stop() if __name__ == "__main__": main()
📄 ARQUIVO 4 — executar_auto.cmd
Salvar — nome: "executar_auto.cmd"
Conteúdo para copiar:
@echo off
chcp 65001 >nul
setlocal
title Moeda Bruno (BRN) - Auto Connect + Status
cd /d "%~dp0"
set "PORTA=6001"
if not "%~1"=="" set "PORTA=%~1"
echo ============================================================
echo MOEDA BRUNO (BRN) - Inicializacao Automatica
echo Porta: %PORTA%
echo ============================================================
echo.
where python >nul 2>nul
if errorlevel 1 (
echo [ERRO] Python nao encontrado no PATH.
echo Instale com: winget install Python.Python.3.12
pause
exit /b 1
)
if exist "envScriptsactivate.bat" (
call "envScriptsactivate.bat"
) else (
echo [AVISO] Ambiente virtual nao existe. Criando...
python -m venv env
call "envScriptsactivate.bat"
python -m pip install --upgrade pip >nul
pip install pywebview flask pyqt6 PyQt6-WebEngine qtpy ecdsa cryptography
)
python -c "import flask, webview" >nul 2>nul
if errorlevel 1 (
echo Instalando dependencias...
pip install pywebview flask pyqt6 PyQt6-WebEngine qtpy ecdsa cryptography
)
echo.
echo Iniciando no principal na porta %PORTA%...
start "BRN Node %PORTA%" cmd /k "call envScriptsactivate.bat && python bruno_blockchain_real.py %PORTA%"
timeout /t 4 /nobreak >nul
echo.
echo Iniciando descoberta automatica de peers + dashboard...
echo.
python brn_autostart.py %PORTA%
pause
📄 ARQUIVO 5 — README.md (documentação)
Salvar — nome: "README.md"
Conteúdo para copiar:
# Moeda Bruno (BRN) - Auto Connect + Dashboard Sistema de conexao automatica P2P com dashboard de status da blockchain. ## Arquivos - `brn_discovery.py` - Descoberta automatica de peers via UDP broadcast - `brn_status.py` - Dashboard de altura e tamanho da blockchain - `brn_autostart.py` - Orquestrador (descoberta + dashboard + sync) - `executar_auto.cmd` - Launcher Windows ## Como usar ### Primeira maquina (PC1) executar_auto.cmd ### Segunda maquina (PC2) executar_auto.cmd 6002 ### Terceira maquina (PC3) executar_auto.cmd 6003 ## O que aparece - Altura do bloco atual - Tamanho em disco do banco - Transacoes na mempool - Peers conectados automaticamente ## Firewall Libere as portas (executar como admin): netsh advfirewall firewall add rule name="BRN TCP 6001" dir=in action=allow protocol=TCP localport=6001 netsh advfirewall firewall add rule name="BRN Discovery UDP" dir=in action=allow protocol=UDP localport=5999 ## Portas usadas - 6001, 6002, 6003... - Nos da blockchain (TCP) - 5999 - Descoberta automatica (UDP)
✅ Passo Final — Verificar tudo
No CMD, cole:
cd /d "C:UsersadnacDesktopbruno cryptoagora-brn" dir
Deve listar 5 arquivos:
brn_discovery.py brn_status.py brn_autostart.py executar_auto.cmd README.md
Se aparecer
.txtem algum, renomeie:ren "brn_discovery.py.txt" "brn_discovery.py"(repita para cada)
🚀 Executar
cd /d "C:UsersadnacDesktopbruno cryptoagora-brn" executar_auto.cmd
🆘 Dicas rápidas
| Problema | Solução |
|---|---|
Arquivo virou .txt |
Renomeie com ren "nome.txt" "nome" |
python não encontrado |
winget install Python.Python.3.12 |
| Dashboard não atualiza | O bruno_blockchain_real.py precisa estar rodando na mesma pasta |
| 0 peers encontrados | Verifique firewall UDP 5999 nas duas máquinas |
⚠️ Regra de ouro do Notepad: sempre coloque o nome do arquivo entre aspas duplas no "Salvar Como". Isso impede o .txt automático
Nerva Network Info
Rede Nerva
Height: Carregando...
Difficulty: Carregando...


Mercado KuCoin
| Par | Preço (USDT) | Variação (24h) |
|---|---|---|
| Carregando dados... | ||