Trabalho de Conclusão de Curso · CEFET/RJ

Um leilão onde ninguém vê os lances

Nove cenas para entender como um leilão de segundo preço acontece numa blockchain pública sem expor um único lance.

Thiago Rocha Duarte · também disponível como monografia completa.

00

Quanto isso vale para você

Uma cota de um recebível tokenizado vai a leilão. Só existe uma, e várias pessoas a querem. Antes de qualquer teoria, escolha um número: o máximo que você pagaria por ela sem se arrepender.

Quanto essa cota vale para você

R$ 7.500

o máximo que você pagaria sem se arrepender

Esse número te acompanha até o fim do artigo.

Guarde esse número. Ele é a única informação que de fato importa neste artigo, e é exatamente a informação que um leilão comum obriga você a entregar aos concorrentes.

01

A regra que não premia a mentira

Num leilão comum, quem dá o maior lance paga o próprio lance. Você aprende rápido a não escrever quanto a coisa vale para você: escreve menos, torcendo para ainda assim vencer. Todo mundo faz o mesmo, e o leilão acaba decidido por quem chutou melhor, não por quem mais valoriza a cota.

Em 1961, William Vickrey propôs uma mudança de uma linha: quem dá o maior lance vence, mas paga o segundo maior. Arraste o seu lance abaixo e acompanhe o seu lucro sob as duas regras.

Seu lucro, conforme o lance que você dá

R$ 0maior lance rivalseu valorR$ 0seu lanceR$ 10.000
Resultado
Venceu
Você paga
R$ 6.800
o segundo maior lance
Seu lucro
R$ 700
honesto: R$ 700

Esse é o lance honesto. Nenhum outro lance rende mais que ele.

Rivais deste leilão: Ana R$ 4.200, Bruno R$ 6.800, Carla R$ 3.500. Num leilão selado de verdade você não veria esses números.

No segundo preço, a curva do lucro fica plana assim que você passa o maior rival. Subir o lance não aumenta o que você ganha, porque o preço não é o seu lance. Descer só faz você perder um leilão que valia a pena. E mentir para cima, acima do seu valor, pode fazer você vencer um leilão que dá prejuízo.

Sobra uma estratégia: dizer a verdade. É o que a teoria chama de estratégia dominante, e é o motivo de o mecanismo de Vickrey ser tratado como à prova de manipulação.

Troque para o primeiro preço e a curva vira uma rampa. Existe um lance ótimo, mas ele depende do lance dos outros, que você não conhece. O primeiro preço premia quem adivinha. O segundo preço premia quem é honesto.

No artigo: regras formais de Vickrey e a prova de truthfulness (§2.5.4 e §2.5.5)

02

Só que a blockchain é de vidro

Essa garantia toda depende de uma premissa: a de que o leilão é mesmo selado. Você decide o seu lance sem conhecer o dos outros, e os outros decidem sem conhecer o seu.

Numa blockchain pública, a premissa não sobrevive ao caminho da transação. Antes de ser confirmada, ela passa pelo mempool, a sala de espera das transações pendentes, e qualquer nó da rede pode ler o que está ali. Isso não é uma falha: para a rede concordar sobre o próximo bloco, todos precisam conhecer as transações candidatas antes. A transparência é a contrapartida da descentralização.

A mesma transação, com e sem cifração

Mempool · transações à espera de confirmação

Vazio. Envie o seu lance de R$ 7.500.

O mempool é público por construção: um bloco só se forma depois que a rede inteira conhece as transações candidatas.

O que o bot fez tem nome, front-running, e em Vickrey ele é especialmente perverso: a regra do segundo preço trabalha a favor de quem copia. Basta oferecer um pouco mais que você para vencer pagando exatamente o seu número, sem nunca ter avaliado a cota.

Existe uma indústria inteira nessa janela entre enviar e confirmar, estudada sob o nome de MEV. Bots vigiam o mempool, e quem monta o bloco escolhe a ordem das transações dentro dele. Cada etapa vaza uma coisa diferente: quanto, quando, de quem e em que ordem. E o registro fica para sempre, o que transforma cada leilão em material de estudo para os concorrentes nos próximos.

Se o lance aparece em texto claro em algum instante, o leilão deixou de ser selado naquele instante. Escondê-lo depois não recupera nada.

No artigo: vazamento em leilões nativos e as variantes de MEV (§1.2.1 e §1.2.2)

03

O remendo que não fecha

A resposta clássica da engenharia de contratos é o commit-reveal. Primeiro você envia apenas o hash do seu lance, uma impressão digital que prende você ao número sem revelá-lo. Depois que o prazo fecha, você volta e revela o valor; o contrato recalcula o hash e confere se bate.

Isso resolve o mempool: enquanto o leilão corre, ninguém vê nada. Mexa nos participantes abaixo para ver o que ele não resolve.

Duas transações por pessoa, e o que sobra público no fim

Fase 1 · comprometimento
Ana0x2b36127b
Bruno0x6a6cfe21
Você0x64ecc929

O hash prende cada um ao próprio lance sem revelá-lo.

Fase 2 · revelação

Todo lance revelado vira registro permanente.

Transações
6
com FHE seriam 3
Lances expostos
3
para sempre
Apuração
R$ 6.800
Você paga

Funcionou: Você vence e paga R$ 6.800. E agora os 3 números estão públicos para sempre, inclusive os de quem perdeu. O sigilo não foi garantido, só adiado até o fim do leilão.

Clique em qualquer participante para fazê-lo sumir na segunda fase.

São dois furos, e o segundo é mais fundo que o primeiro.

  • Quem some trava a apuração. Um participante que percebe ter perdido não tem motivo nenhum para voltar e revelar. As saídas usuais, caução obrigatória, prazo-limite ou re-leilão, cobram de todo mundo para punir um.
  • Quem revela entrega o número. É por construção: para saber quais são os dois maiores, todos precisam abrir o jogo. No fim, cada participante conhece a avaliação de todos os outros, e leva isso para os leilões seguintes.

Some a isso duas transações por pessoa em vez de uma, com o custo e a chance de esquecimento que vêm junto.

O commit-reveal esconde os lances durante o leilão e os publica no fim. Vickrey precisa exatamente do contrário: revelar o preço e nunca revelar os lances.

No artigo: as quatro limitações estruturais do commit-reveal (§1.2.3)

04

Calcular sem ver

As duas tentativas anteriores falharam pelo mesmo motivo: em algum momento o número precisou existir em texto claro para que alguém pudesse compará-lo. A pergunta que abre a saída é se esse momento precisa mesmo existir.

A criptografia totalmente homomórfica, a FHE, responde que não. Num esquema homomórfico, operações feitas sobre os textos cifrados correspondem a operações sobre os textos claros. Você entrega números cifrados a uma máquina em que não confia, ela devolve o resultado cifrado, e só quem tem a chave decifra. A máquina calculou sem ver.

As duas colunas abaixo fazem a mesma conta, a de descobrir qual dos dois lances é o maior. Mexa nos valores e compare.

A mesma conta, em claro e sobre ciphertexts

seu lance
R$ 7.500
0x03d6b075
lance rival
R$ 6.800
0x545e93b4
o seu é maior?
sim
0x1c1bc382
maior dos dois
R$ 7.500
0xa33ec8ef

A coluna da direita percorreu a conta inteira sem que ninguém soubesse os valores. Nem sequer o resultado da comparação é legível: ele também é um ciphertext. Peça a decifração e compare as duas colunas.

Cifrar de novo troca todos os handles sem mudar nenhum resultado: o mesmo valor cifrado duas vezes não produz o mesmo ciphertext.

Duas coisas ali merecem atenção. A primeira é que até o resultado da comparação sai cifrado: o contrato consegue usar esse resultado, mas não consegue lê-lo. A segunda é que a chave de decifração não pertence a ninguém em particular. Ela é dividida em pedaços entre os participantes de uma rede de threshold, e nada é decifrado sem que um número mínimo deles coopere.

Delegar a conta sem entregar os dados: é isso que a FHE faz. O resto deste artigo é o que acontece quando se tenta usar isso para rodar Vickrey de verdade.

No artigo: homomorfismo, TFHE e a rede de decifração por threshold (§2.2.3 e §2.3)

05

O problema da exclusão

Com comparação cifrada em mãos, parece que acabou: é só achar o maior e o segundo maior. Mas Vickrey esconde uma armadilha justamente aí.

Para achar o segundo, você precisa tirar o primeiro do meio. E para tirar o primeiro, você precisaria saber quem é o primeiro. Sob cifração, você não sabe, e perguntar quebraria todo o sigilo que se acabou de construir. Esse é o problema da exclusão, e é o nó que este trabalho desata.

A saída adotada aqui é não guardar os lances. O contrato mantém apenas dois números cifrados, o maior e o segundo maior, mais a identidade cifrada de quem lidera, e atualiza os três a cada lance que chega. Avance os lances abaixo, e ligue o raio-X para ver o que existe atrás de cada cadeado.

O contrato processando os lances

Ana0x57701713
Bruno0x56701580
Você0x59701a39
highestBid
0x0535cd7c
secondHighestBid
0x97ee7943
highestBidder
0xb192520c
Estado inicial: os três agregados começam zerados e autorizados para o próprio contrato.
O raio-X existe só para você. A blockchain enxerga sempre a coluna da esquerda.

Três coisas acontecem aí, e nenhuma delas é evidente.

  • O custo não cresce. São sempre duas comparações e quatro seleções, tenha o leilão três ou trezentos participantes, porque nenhum lance antigo precisa ser revisitado.
  • O armazenamento não cresce. São sempre três valores cifrados guardados, e não um por participante.
  • Não existe nenhum se. As seis operações rodam sempre, inclusive quando o lance não muda nada. Um desvio condicional exigiria alguém ter lido o resultado da comparação, e ninguém leu.

O empate ainda sai de graça. Como a comparação é estritamente maior, um lance igual ao do líder não o substitui: vence quem chegou primeiro, que é a regra clássica de desempate em leilões. Os três cenários de empate do simulador são os mesmos que a suíte de testes do contrato verifica.

A alternativa conhecida na literatura é guardar todos os lances e, no fechamento, zerar o vencedor com uma máscara cifrada para então procurar o novo máximo. Funciona, mas cobra por participante: guarda N lances, gasta N comparações no fechamento e ainda precisa de lógica extra para não zerar dois lances empatados de uma vez.

No artigo: o problema da exclusão, o padrão top-2 incremental e o tratamento de empates (§4.2.2 a §4.2.4)

06

O que sobra para quem está olhando

Quando o leilão fecha, duas coisas viram públicas por necessidade: quem venceu, porque alguém precisa receber a cota, e o segundo maior lance, porque é o preço a pagar. Todo o resto continua cifrado para sempre.

Continua cifrado é fácil de dizer. Também dá para medir. Como o teto de lance é público e o segundo preço foi revelado, um observador consegue estreitar cada lance a uma faixa: o do vencedor está entre o preço pago e o teto, e cada perdedor está entre zero e o preço pago. O tamanho dessas faixas é o tamanho da dúvida que sobrou.

O que um observador ainda não sabe, depois do leilão fechado

Lance do vencedorentre 0,0002 e 0,01 ETH · 98% do domínio
53,1 bits de incerteza · 9,8×10¹⁵ valores possíveis
Segundo maior lanceexatamente 0,0002 ETH · revelado
0,0 bits de incerteza · 1 valor possível
Demais perdedores (1 lance)entre 0 e 0,0002 ETH · 2% do domínio
47,5 bits cada · 2,0×10¹⁴ valores possíveis
Incerteza que sobrou
100,6 bits
sobre 2 lances não revelados
Incerteza original
106,3 bits
antes do leilão fechar
Preservado
95%
num leilão público: 0%

Repare que a faixa dos perdedores ocupa só 2% do domínio e mesmo assim guarda 2,0×10¹⁴ valores possíveis. Proporção pequena não significa incerteza pequena.

Barras: os valores ainda compatíveis com o que ficou público. Bits: o tamanho dessa dúvida.

Nos valores do leilão de demonstração, cerca de 95% da incerteza original sobrevive ao fechamento. Num leilão público ela seria zero: cada lance ficaria escrito, com nome e valor, para sempre. No commit-reveal da cena 03, também: todos os números revelados são públicos.

A regra de Vickrey exige revelar exatamente um número. A medida mostra que ela cobra exatamente isso, e não um centavo de informação a mais.

A conta é generosa com o observador de propósito. Ela assume que ele não tem nenhuma pista além do que está na blockchain, o que produz o maior valor possível de incerteza. Quem chegar sabendo mais, termina sabendo mais.

No artigo: a derivação da entropia residual e o modelo de adversário (§5.4)

07

Quanto isso custa

Privacidade não sai de graça. Cada comparação cifrada é uma operação pesada, e alguém paga a conta. Os números abaixo vêm de leilões completos rodados numa rede pública de testes, com três, cinco e dez participantes e cinco repetições cada.

Gás por operação

createAuction364.585
bid583.309
requestSettlement187.218
finalizeSettlement129.454
withdraw (participante)79.600
withdraw (vendedor)75.989
Ciclo completo
2.745.979
gás, com 3 participantes
Um lance custa
US$ 0,02
R$ 0,11
O leilão inteiro
US$ 0,10
R$ 0,52

O lance concentra toda a aritmética homomórfica e é, de longe, a operação mais cara: consome cerca de 28 vezes o piso de uma transferência simples de ETH, que são 21.000 de gás. As demais só mexem em autorizações, provas ou saldos. Conversão pelo preço de gás e pela cotação do ETH de 18 de julho de 2026.

Medições na Arbitrum Sepolia, cinco repetições por configuração.

Troque o número de participantes no mock e repare que as barras quase não se mexem. É a promessa do padrão top-2 aparecendo na medida: o custo por operação não depende de quantas pessoas já lançaram. Na rede de testes existe alguma variação, mas ela vem da taxa de dados da rede, e não do algoritmo.

Em dinheiro, um lance cifrado custa centavos de dólar e um leilão inteiro não passa de alguns reais. Para ativos de alto valor unitário, que é o caso de recebíveis e imóveis tokenizados, o custo da confidencialidade é ruído.

Onde o tempo é gasto

Cifração no cliente6,8 s
createAuction2,6 s
bid2,6 s
requestSettlement2,6 s
Decifração via TSN2,9 s
finalizeSettlement2,5 s
withdraw2,4 s
Para dar um lance
9,4 s
cifrar mais confirmar
Para fechar o leilão
5,4 s
consultar a rede mais publicar

A maior espera não é da blockchain: é a cifração no seu próprio dispositivo, 6,8 s em média, mais que qualquer transação. Cifrar um valor e gerar a prova de que ele é bem formado é pesado, e é o primeiro lugar para onde olhar em otimizações futuras.

Em destaque, as etapas que rodam fora da blockchain, orquestradas pelo cliente.

Quem dá um lance espera cerca de nove segundos, e a maior parte disso não é a rede: é o próprio navegador cifrando o valor e gerando a prova de que ele é bem formado. As confirmações na blockchain ficam todas perto de dois segundos e meio, e a consulta à rede de decifração, perto de três.

O gargalo não está onde se imagina. Não é a blockchain nem a rede de decifração: é o seu dispositivo cifrando o lance.

No artigo: custo computacional e latência, com as tabelas completas (§5.2 e §5.3)

08

Ver funcionando

O caminho inteiro em uma frase: Vickrey premia a honestidade, mas exige sigilo; a blockchain pública não guarda sigilo; o commit-reveal adia o sigilo em vez de garanti-lo; a FHE calcula sem ver; o padrão top-2 entrega o segundo preço sem precisar excluir ninguém explicitamente; e ao final sobra quase toda a incerteza sobre os lances, por centavos de dólar por participante.

Nada disso é hipotético. O contrato está implantado numa rede pública, com o código verificado, e você pode rodar um leilão do começo ao fim.