Arquitetura Mesh Offline
Visão geral da solução
-
Rede offline: dispositivos formam uma mesh P2P via BLE/libp2p (até ~50 nodes em área).
-
Transações: criações P2P entre sender→receiver via BLE.
-
Validação local: um subset dinâmica de dispositivos na mesh (eleitos automaticamente) assina a tx. Requer k assinaturas (p.ex. k=5).
-
Agregação + bloco local: validadores agregam txs num Local Block (LB) e produzem um agg_sig (BLS threshold).
-
Sync para online: assim que qualquer nó da mesh encontra internet, submete o LB (merkle_root + agg_sig) à blockchain global.
-
Blockchain global: recomenda-se PoS (menos custo energético, finalidades rápidas) ou usar uma L1 compatível/EVM/Substrate para facilidade.
Componentes e tecnologias recomendadas
-
BLE + libp2p (mesh).
-
Chaves efêmeras + ED25519 (assinatura local) + BLS threshold para agregação on-chain.
-
Wallet local com
local_noncee cache de locks. -
Mini-node (VL) leve em Rust/Go para validar e submeter LBs.
-
Chain de destino: PoS L1 ou L2 (submeter merkle_root/agg_sig).
Fluxo (alto nível — 7 passos)
-
Sender gera TX (tx_hash = H(sender_pub || nonce || amount || ts || meta)) e envia ao Receiver via BLE.
-
Receiver broadcast na mesh um sign request com
tx_hash+local_nonce. -
N dispositivos automáticos checam regras (saldo provisório, rate-limit, prova proximidade) e, se OK, assinam com chave efêmera e respondem com
sig_meta(device_hash, rssi, ts, sig). -
Quando Receiver coleta ≥k sig_meta válidas e distintas, forma LB (insere TX) e cria
agg_sig(threshold BLS) — LB tem merkle_root. Geratemporary_lock. -
LB fica salvo localmente; todos os nodes da mesh sincronizam LB entre si (gossip).
-
Quando um node obtém internet, ele pega LBs não-sincronizados e submete (merkle_root + agg_sig + validator_commitments) à blockchain global via API.
-
Rede global verifica agg_sig, valida nonces contra ledger e abre challenge window. Se tudo ok, grava hash do LB e confirma txs globalmente.
Como eleger validadores entre 50 usuários (permissionless, justo)
-
Eleição automática por VRF (verifiable random function) + peso por
Trust Score:-
Cada nó gera uma saída VRF em cada epoch; se VRF < threshold(node_TS, epoch), o nó é candidato validador.
-
Isso distribui validação ao acaso, mas favorece quem provou honestidade.
-
-
Alternativa simples: seleção randômica por shuffle determinístico da lista de peers + pick first k.
Mitigações essenciais (Sybil, replay, colusão)
-
Nonce monotônico na wallet + checagem local.
-
k assinaturas distintas + device_id_hash diversity check (não aceitar múltiplos sigs do mesmo device).
-
Rate-limits por device e limitação de recompensa.
-
Locks temporários (TTL curto) publicados em batch para chain (reduz double-spend).
-
Janela de challenge (p.ex. 48 h) e slashing/reputational penalty se prova.
-
Heurísticas anti-bot (assinaturas em massa do mesmo coordenador/geo-hash).
-
BLS threshold para reduzir footprint on-chain.
Recomendação sobre PoW vs PoS
-
PoS é melhor aqui: menor custo, confirmações mais rápidas e mais fácil integrar slashing/reputação.
-
PoW adiciona barreira energética e latência — não ajuda o offline use-case.
-
Ideal: submeter LBs a uma PoS L1 (ou L2 rollup) que aceite provas compactas (merkle_root + agg_sig).
Pseudocódigo compacto (mensagens BLE, assinatura, criação de LB e sync)
// --- on Sender ---
tx = {sender_pub, receiver_pub, amount, local_nonce, ts}
tx_hash = H(tx)
send_ble(receiver_id, {type: "TX_OFFER", tx, tx_hash})
// --- on Receiver ---
on_receive(TX_OFFER):
if wallet.provisional_balance >= amount and nonce_ok:
broadcast_mesh({type:"SIGN_REQUEST", tx_hash, nonce})
sigs = []
while sigs.count < k and timeout not reached:
wait incoming SIGN_RESPONSE
if valid_sig(response): sigs.append(response)
if sigs.count >= k:
agg_sig = BLS_aggregate(sigs)
LB = create_local_block([tx], merkle_root(...), agg_sig, validators_meta)
store_local(LB)
create_temporary_lock(tx.sender, tx.amount, TTL)
gossip_mesh({type:"NEW_LB", LB})
// --- on any Node with Internet ---
periodic_sync():
for each LB in local_storage not yet submitted:
payload = {merkle_root: LB.merkle_root, agg_sig: LB.agg_sig, meta: LB.validators_meta}
resp = submit_to_chain(payload)
if resp.accepted:
mark_confirmed(LB)
else if resp.dispute:
open_challenge_procedure(LB)
// --- Validator auto-signing (BLE listener) ---
on_receive(SIGN_REQUEST):
if passes_checks(nonce, rate_limit, proximity, local_cache):
sig = sign_with_ephemeral_key(tx_hash)
send_ble(originator, {type:"SIGN_RESPONSE", device_hash, rssi, ts, sig})
Parâmetros práticos sugeridos (iniciar)
-
network size target: 50 nodes (ok).
-
k (assinaturas) padrão urbano = 5.
-
rate-limit por device = 20 assinaturas recompensadas/dia.
-
temporary_lock TTL = 30–90 minutos.
-
challenge window = 48 horas.
-
stake opcional para acelerar reputação; mas permissionless por padrão.
Próximos passos práticos se queres protótipo
-
Prototipar wallet mobile (React Native) que cria txs e faz BLE gossip.
-
Implementar listener simples (NodeJS/Go) que age como validator e testa coleta de k sigs.
-
Testnet local: montar uma L1 Substrate/PoS local para submeter merkle_roots.
-
Simular ataques Sybil/colusão para ajustar parâmetros.