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:

cmd
mkdir "C:UsersadnacDesktopbruno cryptoagora-brn" 2>nul
cd /d "C:UsersadnacDesktopbruno cryptoagora-brn"
echo Pasta pronta: %CD%

📄 ARQUIVO 1 — brn_discovery.py

Como salvar:

  1. Abra o Notepad

  2. Cole o conteúdo abaixo

  3. Arquivo → Salvar Como

  4. Nome do arquivo: "brn_discovery.py" ⚠️ COM ASPAS DUPLAS

  5. Tipo: Todos os arquivos (*.*)

  6. Codificação: UTF-8

  7. Pasta: C:UsersadnacDesktopbruno cryptoagora-brn

  8. Salvar

Conteúdo para copiar:

python
"""
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:

  1. Notepad novo

  2. Cole o conteúdo

  3. Salvar Como → nome: "brn_status.py" (com aspas)

  4. Tipo: Todos os arquivos (*.*)

  5. Codificação: UTF-8

  6. Mesma pasta

Conteúdo para copiar:

python
"""
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:

python
"""
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:

cmd
@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:

markdown
# 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:

cmd
cd /d "C:UsersadnacDesktopbruno cryptoagora-brn"
dir

Deve listar 5 arquivos:

text
brn_discovery.py
brn_status.py
brn_autostart.py
executar_auto.cmd
README.md

Se aparecer .txt em algum, renomeie:

cmd
ren "brn_discovery.py.txt" "brn_discovery.py"

(repita para cada)


🚀 Executar

cmd
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 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...
Atualizando...