
Uma Merkle tree é uma estrutura de dados que consolida múltiplas entradas num valor único de topo, chamado Merkle root, através de hashing hierárquico. A sua função central é permitir a verificação eficiente da inclusão de um dado específico num conjunto. Como “impressão digital mestre” dos dados, a Merkle tree possibilita verificações de inclusão com informação mínima, desde que a root seja fidedigna.
Uma função hash atua como um “gerador de impressões digitais de dados”: o mesmo input origina sempre o mesmo output, mas qualquer alteração mínima gera uma impressão digital totalmente diferente. Numa Merkle tree, cada dado é hasheado para formar um nó folha, e estes hashes são combinados recursivamente até criar a root.
As Merkle trees permitem verificar rapidamente se uma transação existe num bloco, sem descarregar todo o bloco. Light nodes, que apenas guardam cabeçalhos de bloco, dependem de provas Merkle para esta verificação — um processo chamado Simplified Payment Verification (SPV).
Em blockchains públicas, a largura de banda e o armazenamento são recursos escassos. Com Merkle trees, os validadores só precisam da Merkle root no cabeçalho do bloco e de um caminho curto de autenticação para confirmar a inclusão, reduzindo custos operacionais. Este mecanismo também suporta provas de reservas em exchanges, listas brancas de airdrop e verificação de integridade de dados em Rollup.
As Merkle trees baseiam-se em três propriedades das funções hash: irreversibilidade, resistência a colisões e sensibilidade a pequenas alterações no input. Os dados são primeiro hasheados em nós folha. Depois, pares de hashes são concatenados e novamente hasheados para formar nós superiores, repetindo-se até restar apenas a Merkle root.
Para verificar a inclusão de um dado, apenas são necessários os “hashes irmãos” ao longo do caminho. O verificador começa no hash do dado alvo, combina-o sequencialmente com cada hash irmão e recalcula até ao topo; se o resultado final corresponder à root publicada, confirma-se a inclusão. Como só se processa um hash irmão por nível, o custo de verificação cresce de forma logarítmica com o volume de dados (O(log n)).
O processo para gerar a Merkle root é direto:
Passo 1: Hashear cada entrada de dados individualmente. Os dados devem ser normalizados (codificação uniforme, remoção de espaços extra) para evitar que diferenças de formato originem hashes distintos para conteúdos idênticos.
Passo 2: Concatenar os hashes adjacentes numa ordem fixa e hasheá-los para criar os nós superiores. A ordem fixa é essencial para que os verificadores possam reproduzir a mesma root.
Passo 3: Repetir o passo 2 até restar apenas um hash — a Merkle root. Se existir número ímpar de folhas em qualquer nível, a implementação pode manter ou duplicar o último hash conforme a especificação.
Passo 4: Registar o percurso dos “hashes irmãos” de cada folha até à root; este percurso constitui a Merkle proof usada em futuras verificações.
No Bitcoin, utiliza-se normalmente duplo SHA-256. No Ethereum, o padrão é Keccak-256. É fundamental escolher uma função hash segura.
Uma Merkle proof é a lista de hashes irmãos do nó folha até à root. Só este percurso e a root são necessários para a verificação — não todos os dados.
Passo 1: O verificador hashea o dado alvo para obter o valor da folha.
Passo 2: Segundo a ordem fornecida, este hash é concatenado com o primeiro hash irmão e hasheado para gerar o nó superior.
Passo 3: Repete-se o processo com cada hash irmão seguinte, recalculando até ao topo da árvore.
Passo 4: O valor final é comparado com a Merkle root pública. Se forem iguais, confirma-se a inclusão; caso contrário, o dado não pertence ao conjunto ou a prova é inválida.
Como só se processa um hash irmão por nível, o tamanho da prova é proporcional à altura da árvore. A verificação mantém-se eficiente mesmo para grandes volumes de dados — adequada para browser, dispositivos móveis ou execução em smart contracts.
No Bitcoin, cada cabeçalho de bloco contém a Merkle root das transações. Os utilizadores podem descarregar só o cabeçalho e o caminho de autenticação relevante para usar SPV e confirmar uma transação — sem aceder ao bloco completo. O Bitcoin utiliza duplo SHA-256 e mantém este design desde o início.
No Ethereum, cada cabeçalho de bloco guarda transactionsRoot, receiptsRoot e stateRoot. Estas utilizam árvores Patricia (dicionários Merkleizados comprimidos por prefixo) para armazenar estado, transações e recibos. Aplicações externas podem usar provas de caminho para confirmar que transações ou eventos de log foram incluídos; estas roots e provas sustentam a mensagem cross-chain, light clients e serviços de indexação.
Para prova de reservas em exchanges, é comum agregar os hashes dos saldos dos utilizadores numa única Merkle root através de uma Merkle tree e fornecer a cada utilizador a respetiva Merkle proof. O utilizador pode descarregar a sua prova e verificar se o “hash da conta e saldo” está incluído na root publicada — sem aceder a dados de outros utilizadores. No sistema da Gate, basta ao utilizador verificar a root e o seu caminho, equilibrando privacidade e verificabilidade.
Para listas brancas de airdrop, as equipas agregam listas de endereços numa Merkle root e implementam este valor num smart contract. Durante o claim, os utilizadores submetem endereço e Merkle proof; o contrato verifica on-chain se o caminho corresponde à root antes de permitir o claim. Este método reduz drasticamente o armazenamento on-chain e as taxas de gas, garantindo que as listas não podem ser alteradas unilateralmente.
Ambas usam hashing para garantir integridade, mas os seus designs e aplicações diferem. Uma Merkle tree funciona como “impressão digital mestre” de um lote de dados — combinando entradas aos pares até uma root única; uma Patricia tree é um “dicionário chave-valor comprimido por prefixo”, permitindo pesquisas e atualizações eficientes por caminho — ideal para manter estados de contas mutáveis.
O Ethereum utiliza Patricia trees porque precisa de pesquisa e atualização eficiente de chaves (endereços ou slots de armazenamento) e roots verificáveis. Já as Merkle trees padrão são ideais para conjuntos estáticos publicados de uma só vez — como todas as transações num bloco, uma whitelist de airdrop ou verificação de fragmentos de ficheiros.
A escolha da função hash é crítica; deve resistir a colisões e ataques de pré-imagem. Algoritmos hash obsoletos ou fracos podem permitir que atacantes forjem conjuntos de dados diferentes com a mesma root, comprometendo a integridade.
A normalização e ordenação dos dados são riscos muitas vezes ignorados. Diferenças de codificação, capitalização ou espaços podem fazer com que conteúdos “iguais” gerem hashes distintos; ordenação inconsistente pode impedir a reconstrução de roots coincidentes e invalidar provas.
Privacidade e fuga de informação devem ser consideradas. Embora as Merkle proofs revelem apenas hashes do percurso, em alguns casos (como provas de saldo), a falta de salting ou anonimização pode expor informação sensível. É prática comum adicionar salt ou hashear apenas digests — não dados brutos — nas folhas.
Quanto à segurança de fundos: estar incluído numa prova de reservas de uma exchange não garante a solvência da plataforma; o utilizador deve considerar passivos, holdings on-chain e relatórios de auditoria antes de tomar decisões financeiras. Avalie sempre riscos da plataforma e on-chain antes de agir.
As Merkle trees usam hashing para agregar grandes volumes de dados num único valor root — permitindo verificação de inclusão eficiente com informação mínima. São infraestrutura fundamental para light nodes de blockchain, mensagens cross-chain, airdrops e sistemas de prova de reservas. Compreender as propriedades das funções hash, regras de construção e percursos de prova é essencial.
Para aprendizagem prática: gere localmente uma Merkle root a partir de um pequeno conjunto de dados e crie/verifique um percurso de autenticação para uma entrada; consulte exploradores de blocos para analisar Merkle roots dos cabeçalhos do Bitcoin ou as transactionsRoot/receiptsRoot do Ethereum; por fim, experimente integrar lógica de verificação em smart contracts ou aplicações front-end. Com esta abordagem progressiva, perceberá porque as Merkle trees são eficientes, fiáveis e ubíquas no Web3.
Uma Merkle tree verifica dados através da agregação hierárquica de hashes. Cada bloco de dados recebe o seu hash; os hashes adjacentes são combinados e novamente hasheados em cada camada, formando uma estrutura em triângulo invertido que origina uma root única. Se algum dado for alterado, toda a root muda — e as discrepâncias são detetadas de imediato.
As light wallets utilizam provas Merkle: só precisam de guardar cabeçalhos de bloco com a Merkle root. Ao pedir transações e respetivos percursos Merkle a full nodes — e ao verificar se o hashing ascendente reproduz a root publicada — a light wallet confirma a autenticidade sem armazenar gigabytes de dados.
Armazenar listas completas em smart contracts consome muito espaço — resultando em custos e ineficiência. Com uma Merkle tree, basta guardar uma root de 32 bytes on-chain; no airdrop, os utilizadores submetem endereço e percurso de autenticação para que o contrato verifique a elegibilidade de forma eficiente, poupando custos e protegendo a privacidade.
Se o hash de um nó intermédio for alterado, todos os hashes superiores são afetados — e a root muda. A adulteração é detetada imediatamente, pois resulta numa root inválida. Esta imutabilidade garante a segurança contra manipulação: até pequenas alterações são expostas de imediato.
As Merkle trees servem para verificar integridade de dados e criar provas concisas — não para gestão direta de endereços. Contudo, algumas wallets multi-assinatura ou designs determinísticos hierárquicos podem usar Merkle trees para organizar ou validar legitimidade de chaves derivadas — garantindo transparência e verificabilidade em todo o processo de derivação de chaves.


