Autor: Vitalik, fundador da Ethereum Tradução: Golden Finance 0xjs;

Desde o início do projeto Ethereum, houve uma forte filosofia de tentar manter o núcleo Ethereum o mais simples possível e realizar o máximo possível construindo protocolos sobre ele. No espaço blockchain, o debate “executar em L1” versus “foco em L2” é muitas vezes considerado como envolvendo principalmente escalonamento, mas na verdade, existem problemas semelhantes no atendimento a muitos tipos de necessidades do usuário Ethereum: números, troca de ativos, privacidade, nomes de usuário, criptografia avançada, segurança de conta, resistência à censura, proteção frontal e muito mais. Recentemente, no entanto, há um interesse crescente de alguns em escrever discretamente e formalmente mais desses recursos no protocolo principal do Ethereum.

Este artigo explorará alguns dos raciocínios filosóficos por trás das primeiras ideias de minimização de protocolo no Ethereum, bem como alguns dos meus pensamentos mais recentes sobre essas ideias. O objetivo é construir gradativamente uma estrutura que identifique melhor os objetivos que podem valer a pena considerar para a formação de determinados recursos do protocolo.

Filosofia de Minimização de Acordo Antecipado

No início da história do "Ethereum 2.0" (como era chamado na época), havia um forte desejo de criar um protocolo limpo, simples e bonito que fizesse o mínimo de trabalho possível por conta própria e deixasse quase tudo para o usuários construam sobre ele. Idealmente, o protocolo seria apenas uma máquina virtual e a validação de um bloco exigiria apenas uma chamada para a máquina virtual.

Uma reconstrução muito aproximada de um diagrama de quadro branco que Gavin Wood e eu fizemos no início de 2015, quando discutimos como seria o Ethereum 2.0.

A “função de transição de estado” (a função que lida com os blocos) será apenas uma chamada de máquina virtual, e todas as outras lógicas serão implementadas através de contratos: alguns contratos em nível de sistema, mas principalmente contratos fornecidos pelo usuário. Uma característica muito interessante deste modelo é que mesmo um hard fork inteiro pode ser descrito como uma única transação para o contrato de processamento de blocos, que será aprovada através de governança off-chain ou on-chain e então executada com permissões atualizadas.

Essas discussões de 2015 se aplicam especificamente a duas áreas que nos interessam: abstração e escalonamento de contas. No caso do escalonamento, a ideia é tentar criar uma forma de escalonamento que seja o mais abstrata possível, para que pareça uma extensão natural do diagrama acima. Um contrato pode chamar determinados dados que não são armazenados pela maioria dos nós Ethereum, e o protocolo detectará isso e resolverá a chamada por meio de alguma funcionalidade de cálculo de escala muito geral. Da perspectiva da máquina virtual, a chamada irá para algum subsistema separado e retornará magicamente algum tempo depois com a resposta correta.

Essa forma de pensar foi brevemente explorada, mas rapidamente abandonada porque estávamos muito focados em verificar se alguma forma de escalonamento de blockchain era possível. No entanto, como veremos mais tarde, a combinação de amostragem de disponibilidade de dados e ZK-EVM significa que um futuro possível para o escalonamento do Ethereum pode realmente parecer surpreendentemente próximo desta visão! Para a abstração de contas, por outro lado, sabíamos desde o início que algum tipo de implementação era possível e imediatamente começamos a trabalhar em como tornar o ponto de partida puro de “transações apenas chamadas” o mais próximo possível da realidade.

Aqui, há muito código que acontece entre e depois do código que trata a transação e faz a chamada EVM subjacente para o endereço de envio. Como reduzimos esse código para o mais próximo possível de zero?

Uma das principais tarefas em um trecho de código é activate_transaction(state, tx), que inclui a verificação de que o nonce e a assinatura da transação estão corretos. O objetivo real da abstração de contas desde o início era permitir que os usuários substituíssem o incremento básico de nonce e a verificação ECDSA por sua própria lógica de verificação, facilitando o uso de coisas como recuperação social e carteiras com múltiplas assinaturas. Portanto, remodelar apply_transaction para ser uma simples chamada EVM não se trata apenas de uma tarefa de "tornar o código limpo", mas sim de mover a lógica para o código da conta do usuário para fornecer a flexibilidade necessária aos usuários.

No entanto, a insistência de que apply_transaction contenha o mínimo de lógica formal possível introduziu, em última análise, uma série de desafios. Para entender o porquê, vamos nos aprofundar em uma das primeiras propostas de abstração de contas, EIP 86:

especificação

Se block.number >= METROPOLIS_FORK_BLKNUM, então: 1. Se a assinatura da transação for (0, 0, 0) (ou seja, v = r = s = 0), então ela será considerada válida e o endereço do remetente será definido como 2 ** 160 - 1. 2. Defina o endereço de qualquer contrato criado criando uma transação como sha3(0 + código de inicialização) % 2 ** 160, onde + representa uma conexão, substituindo a fórmula de endereço anterior sha3(rlp.encode( [remetente, nonce])) 3. Crie um novo código de operação, 0xfb, CREATE_P2SH Este código de operação define o endereço de criação como sha3(remetente + código de inicialização)%2 ** 160. Se já existir um contrato nesse endereço, ele falha e retorna 0, como se o código de inicialização tivesse ficado sem Gás.

Basicamente, se você definir a assinatura como (0, 0, 0), a transação se tornará efetivamente "apenas uma chamada". A própria conta será responsável por ter o código para analisar transações, extrair e verificar assinaturas e nonces e pagar taxas. Clique aqui para ver uma versão anterior deste código. Clique aqui para ver o código de validação_transaction que este código de conta substituirá. A certa altura, apply_transaction foi simplesmente reduzido a É apenas um processo chamado por EVM. Em outras palavras, o protocolo Ethereum realiza a verificação das transações, deixando a lógica específica da transação para o código da conta do próprio usuário para fornecer flexibilidade.

No entanto, tentar fazer com que apply_transaction contenha o mínimo de lógica formal possível acabou introduzindo uma série de desafios. Para entender o porquê, vamos examinar detalhadamente uma das primeiras propostas de abstração de contas, a EIP 86.

Observe que os mineradores precisam desenvolver uma estratégia para aceitar essas transações. Essa estratégia precisa ser muito criteriosa, caso contrário poderão aceitar transações que não pagam nada (para o código de validação_transação que será substituído pelo código pré-conta), ou mesmo transações que não surtem efeito (por exemplo, porque a transação já está incluída , Portanto, o nonce não é mais válido). Uma maneira simples de fazer isso é colocar na lista de permissões o codehash dos códigos de conta para os quais eles aceitam transações para enviar; os códigos aprovados incluirão a lógica para pagar taxas de transação aos mineradores. No entanto, isso pode ser muito restritivo; uma estratégia mais flexível, mas ainda assim eficaz, é aceitar qualquer código que esteja em conformidade com o mesmo formato geral descrito acima, consumir apenas uma quantidade limitada de gás para realizar verificações de nonce e assinatura e garantir que as taxas de transação serão cobradas. ser pago aos mineiros. Outra estratégia é, além de outros métodos, tentar tratar qualquer transação que solicite menos de 250 mil gás e só incluí-la se o saldo do minerador aumentar adequadamente após a execução da transação.

Se o EIP-86 fosse incorporado como está, reduziria a complexidade do EVM, mas com grande custo aumentaria a complexidade de outras partes da pilha Ethereum, exigindo essencialmente que o mesmo código fosse escrito em outro lugar enquanto introduzia possibilidades completamente novas e estranhas. como a mesma transação com o mesmo hash pode aparecer na cadeia várias vezes, sem mencionar o problema de invalidação múltipla.

Vários problemas de expiração na abstração de contas. Uma transação incluída na cadeia poderia invalidar milhares de outras transações no mempool, deixando o mempool vulnerável a ser inundado de forma barata.

A abstração de contas evoluiu gradualmente a partir daí. EIP-86 tornou-se EIP-208, que mais tarde se tornou esta postagem em ethresear.ch sobre "Compensações em propostas de abstração de contas" e, meio ano depois, esta postagem em ethresear.ch. No final das contas, tudo isso resultou no EIP-2938, que é bastante viável.

No entanto, o EIP-2938 não é mínimo. O PEI inclui:

  • um novo tipo de transação

  • Três novas variáveis ​​globais de escopo de transação

  • Dois novos opcodes, incluindo o muito desajeitado opcode PAYGAS, lidam com verificações de preço e limite de gás, atuam como pontos de interrupção de execução de EVM e também armazenam temporariamente ETH para pagamentos de taxas.

  • Uma estratégia complexa de mineração e repetição, incluindo uma série de opcodes proibidos durante a fase de verificação das transações

Para promover a abstração de contas sem envolver os principais desenvolvedores do Ethereum que estavam ocupados otimizando o cliente Ethereum e implementando fusões, o EIP-2938 foi finalmente redesenhado para um ERC-4337 completamente fora do protocolo.

ERC-4337. Depende inteiramente de chamadas EVM para fazer tudo!

Por ser um ERC, não requer hard fork e está tecnicamente “fora do protocolo Ethereum”. Então...problema resolvido? Bem, acontece que ainda não está totalmente resolvido. O atual roteiro de médio prazo para o ERC-4337 envolve, na verdade, a transição de grande parte do ERC-4337 para uma série de recursos de protocolo, o que é um exemplo útil do motivo pelo qual esse caminho está sendo considerado.

Solidificação da camada de protocolo ERC-4337

Algumas razões principais foram discutidas para a eventual introdução do ERC-4337 no protocolo:

  • Eficiência de gás: Qualquer operação executada dentro do EVM incorre em algum grau de sobrecarga da máquina virtual, incluindo ineficiências ao usar recursos de gás caros, como slots de armazenamento. Atualmente, essas ineficiências adicionais somam pelo menos cerca de 20.000 gases, e muitas vezes mais. Colocar esses componentes no protocolo é a maneira mais fácil de eliminar esses problemas.

  • Risco de erro de código: se o “contrato de ponto de entrada” do ERC-4337 apresentar erros suficientes, todas as carteiras compatíveis com ERC-4337 poderão ver todos os seus fundos eliminados. Ao substituir contratos por funções de protocolo, você cria uma responsabilidade implícita de corrigir bugs de código e eliminar riscos para os fundos dos usuários.

  • Suporta opcodes EVM como tx.origin. O próprio ERC-4337 faz com que tx.origin retorne o endereço enviado por um “empacotador” que empacota um conjunto de ações do usuário em uma transação. A abstração da conta nativa pode resolver esse problema fazendo com que tx.origin aponte para a conta que realmente envia a transação, fazendo com que funcione da mesma forma que o EOA.

  • Resistência à censura: No caso do PBS, um desafio é facilitar a censura de transações individuais. Num mundo onde todas as transações são visíveis para o protocolo Ethereum, este problema é bastante mitigado pelas listas de inclusão, que permitem ao proponente especificar em quase todos os casos o que deve ser incluído nos próximos dois slots da lista de transações. No entanto, o ERC-4337 fora do protocolo envolve “operações do usuário” em uma única transação, tornando as operações do usuário invisíveis para o protocolo Ethereum, portanto, a lista de inclusão fornecida pelo protocolo Ethereum não fornecerá resistência à censura para operações do usuário ERC-4337; Formalizar o ERC-4337 e tornar as operações do usuário um tipo de transação “oficial” resolveria esse problema.

Vale a pena estudar mais a fundo a questão da eficiência do gás. Em sua forma atual, o ERC-4337 é significativamente mais caro do que as transações “básicas” do Ethereum: uma transação custa 21.000 gás, enquanto o ERC-4337 custa cerca de 42.000 gás. A documentação lista alguns destes motivos:

  • Há uma série de custos separados de leitura/gravação de armazenamento a serem pagos, que para EOA são agrupados em um único pagamento de 21.000 gás:

  • Editar slot de armazenamento contendo pubkey+nonce (~5000)

  • Custo de dados de chamada UserOperation (~4.500, reduzido para ~2.500 com compactação)

  • ECRECOVER(〜3000)

  • Aqueça a própria carteira (~2600)

  • Aquecer contas de destinatários (~2600)

  • Transferir ETH para a conta do destinatário (~9.000)

  • Editar armazenamento para cobrir taxas (~5.000)

  • Acesse o slot de armazenamento que contém o agente (~2100) e depois o próprio agente (~2600)

  • Além dos custos de leitura/gravação de armazenamento mencionados acima, o contrato precisa executar "lógica de negócios" (descompactar UserOperation, hash, embaralhar variáveis, etc.), enquanto as transações EOA são tratadas "de graça" pelo protocolo Ethereum.

  • O gás é necessário para pagar os toros (a EOA não emite toros)

  • Custo único de criação de contrato (custo base ~32.000, o código no proxy adiciona 200 gas por byte, mais 20.000 gas para definir o endereço do proxy)

Em teoria, deveria ser possível manipular o sistema de custo de gás EVM para que o custo dentro do protocolo e o custo extra-protocolo de acesso ao armazenamento correspondam, não há razão para que a transferência de ETH custasse 9.000 gás quando outras operações de edição de armazenamento são muito mais baratas; . Na verdade, dois EIPs relacionados à próxima transição da árvore Verkle tentam fazer exatamente isso. Mas mesmo se fizermos isso, há uma grande razão pela qual os recursos formais do protocolo serão inevitavelmente muito mais baratos que o código EVM, não importa quão eficiente o EVM se torne: o código formalizado não precisa pagar gás para pré-carregamento.

Uma carteira ERC-4337 totalmente funcional é enorme. Esta implementação, compilada e colocada na cadeia, ocupa cerca de 12.800 bytes. Claro, você poderia implantar esse código enorme uma vez e usar DELEGATECALL para permitir que cada carteira individual o chamasse, mas o código ainda precisaria estar acessível em cada bloco que o utiliza. De acordo com o próximo EIP de custo de gás da árvore Verkle, 12.800 bytes ocuparão 413 pedaços, e o acesso a esses pedaços exigirá o pagamento de 2x WITNESS_BRANCH_COST (3.800 gás no total) e 413x WITNESS_CHUNK_COST (82.600 gás no total). Isso sem mencionar o próprio ponto de entrada ERC-4337, que tem 23.689 bytes on-chain na versão 0.6.0 (o carregamento requer ~158.700 gás por regras EIP da árvore Verkle).

Isso leva a um problema: o custo do gás para realmente acessar esse código deve ser distribuído de alguma forma entre as transações. A abordagem atualmente usada pelo ERC-4337 não é muito boa: a primeira transação do pacote absorve o custo único de armazenamento/leitura de código, tornando-o significativamente mais caro do que o restante das transações. Tornar essas bibliotecas compartilhadas comumente usadas parte do protocolo, acessíveis a todos sem pagar taxa, é uma solução para esse problema.

O que podemos aprender com este exemplo sobre quando solidificar em protocolos de forma mais geral?

Neste exemplo, podemos aprender algumas lições sobre os princípios mais gerais de quando resumir as coisas.

  • É uma boa ideia mover a complexidade para as bordas, especialmente quando há altos custos de cura. Isso se torna aparente no roteiro de “Abstração de Conta Descentralizada”, já que o carregamento do código da carteira padronizada requer 244.100 gás, enquanto a agregação (confira minha palestra neste verão para mais detalhes) pode exigir centenas de milhares de gás para verificação ZK-SNARKs, além do custo na cadeia de verificação de prova. A imposição destes custos aos utilizadores é quase impossível, pois introduziria muitas ineficiências de mercado, que podem ser claramente resolvidas tornando certas funcionalidades acessíveis a todos os utilizadores, sem custos, como funcionalidades de protocolo.

  • A resposta coletiva da comunidade aos erros de codificação. Se um conjunto de trechos de código for usado por todos os usuários ou por uma ampla classe de usuários, muitas vezes é mais razoável que a comunidade blockchain assuma a responsabilidade de corrigir possíveis bugs por meio de um hard fork. O ERC-4337 introduz uma grande quantidade de código compartilhado globalmente e, a longo prazo, a correção de bugs nesse código é melhor feita por meio de um hard fork, em vez de fazer com que os usuários percam grandes quantidades de ETH.

  • Às vezes, formas mais poderosas de funcionalidade podem ser alcançadas aproveitando diretamente o poder de um protocolo. Por exemplo, a censura dentro do protocolo pode garantir melhor a resistência à censura, mas para que as operações em nível de usuário realmente se beneficiem do protocolo, as operações individuais em nível de usuário precisam ser “legíveis” para o protocolo. Outro exemplo menos conhecido é o design de prova de aposta Ethereum de 2017 com abstração autoritativa, e isso foi abandonado em favor do BLS para resumo, porque o BLS suporta mecanismos de "agregação" que devem ser implementados nos níveis de protocolo e rede, que can Torna o processamento de um grande número de assinaturas mais eficiente.

Mas é importante lembrar que mesmo a abstração de contas estabelecida no protocolo ainda é um enorme “contra-estabelecimento” em relação ao status quo. Hoje, as transações de nível superior do Ethereum só podem ser iniciadas por contas de propriedade externa (EOA), que são verificadas usando uma única assinatura de curva elíptica secp256k1. A abstração da conta reflete isso e fornece abertura para os usuários definirem condições de validação. Portanto, nesta história sobre abstração de contas, também vemos o maior argumento contra a naftalina: flexibilidade para atender às diferentes necessidades dos usuários.

Vamos tentar refinar ainda mais esta história examinando algumas das características que foram recentemente consideradas para estabelecimento. Prestaremos atenção especial a: ZK-EVMs, separação proponente-construtor, mempools privados, participações de liquidez e nova pré-compilação.

Cura de ZK-EVMs

Vamos voltar nossa atenção para outro possível alvo estabelecido no protocolo Ethereum: ZK-EVMs. Atualmente, temos um grande número de rollups ZK que precisam escrever códigos bastante semelhantes para verificar blocos semelhantes ao Ethereum na execução do ZK-SNARK. Existe um ecossistema bastante diversificado de implementações independentes: PSE ZK-EVM, Kakarot, Polygon ZK-EVM, Linea, Zeth e muitos mais.

Uma das controvérsias recentes no campo do EVM ZK-rollup envolve como lidar com a possibilidade de bugs no código ZK. Atualmente, todos os sistemas em execução possuem algum tipo de mecanismo de “conselho de segurança” que substitui o sistema de certificação em caso de erro. Num artigo do ano passado, tentei criar um quadro padronizado que encorajasse os projectos a clarificar o seu nível de confiança entre os sistemas de certificação e o Conselho de Segurança, e a avançar no sentido da redução da autoridade sobre o Conselho de Segurança ao longo do tempo.

A médio prazo, os rollups podem contar com múltiplos sistemas de certificação, e o Conselho de Segurança só terá qualquer poder no caso extremo em que dois sistemas de certificação diferentes discordem entre si.

No entanto, existe a sensação de que parte do trabalho é redundante. Já temos a camada base Ethereum, que possui um EVM, e já temos um mecanismo funcional para tratamento de erros na implementação: se houver um erro, o cliente com o erro será atualizado para corrigir o erro, e a cadeia continuará . Do ponto de vista do cliente com o bug, do ponto de vista das múltiplas implementações da comunidade Ethereum e do consenso social fora da cadeia, o bloqueio parece estar finalizado, mas pelo menos não veremos os usuários perdendo fundos. Da mesma forma, se um rollup quiser apenas se tornar e permanecer equivalente ao EVM, então, quando suas regras internas do ZK-EVM precisarem corresponder à atualização da camada base Ethereum, eles não devem implementar sua própria governança, mas devem ser construídos diretamente no Ethereum camada base Além disso, essa camada base sabe quando atualizar e para quais novas regras atualizar.

Como esses ZK-EVMs L2 usam basicamente o mesmo EVM do Ethereum, não podemos de alguma forma transformar “verificar a execução do EVM no ZK” em um recurso de protocolo? No caso de bugs e atualizações, podemos lidar com isso aplicando o consenso social do Ethereum, da mesma forma que já fazemos para a própria execução do EVM da camada base?

Este é um tema importante e desafiador. Existem algumas sutilezas:

1. Esperamos permanecer compatíveis com a filosofia multicliente da Ethereum. Isso significa que queremos permitir que diferentes clientes usem diferentes sistemas de prova. Isto, por sua vez, significa que para qualquer execução EVM que utilize um sistema ZK-SNARK para provas, queremos garantir que os dados subjacentes estejam disponíveis para que as provas possam ser geradas para outros sistemas ZK-SNARK.

2. Embora a tecnologia ainda não esteja madura, podemos desejar realizar uma auditoria. Na prática, isso significa exatamente a mesma coisa: se alguma execução for comprovada, queremos que os dados subjacentes estejam disponíveis para que usuários e desenvolvedores possam inspecioná-los caso algo dê errado.

3. Precisamos de tempos de prova mais rápidos para que, se um tipo de prova for gerado, outros tipos de provas possam ser gerados rapidamente para que outros clientes possam verificá-los. Este problema poderia ser resolvido criando uma pré-compilação que tivesse uma resposta assíncrona após um determinado intervalo de tempo (por exemplo, 3 horas), mas isso adiciona complexidade.

4. Esperamos apoiar não apenas cópias de EVMs, mas também “quase-EVMs”. Inovar no nível de execução e ampliar o EVM faz parte do apelo do L2. Se a VM para um determinado L2 for apenas ligeiramente diferente do EVM, seria bom se a VM do L2 usasse o protocolo nativo ZK-EVM para as mesmas partes do EVM e confiasse apenas em seu próprio código para lidar com as diferentes partes do EVM. . Isso pode ser conseguido projetando a pré-compilação ZK-EVM de modo que permita ao chamador especificar um conjunto de opcodes ou campos de bits ou listas de endereços que são manipulados por uma tabela fornecida externamente, em vez do próprio EVM. Também podemos tornar o custo do gás personalizável até certo ponto.

Um possível tópico de discórdia com a disponibilidade de dados ao usar ZK-EVM nativo é a monitoração de estado. ZK-EVMs serão mais eficientes em termos de dados se não precisarem transportar dados de “testemunha”. Ou seja, se dados específicos foram lidos ou escritos em algum bloco anterior, podemos simplesmente assumir que o provador tem acesso a eles e não precisamos distribuí-los novamente. Isso vai além de não recarregar o armazenamento e o código; acontece que se um rollup compactar os dados corretamente para que a compactação seja com estado, isso economizará até 3x os dados em comparação com a compactação sem estado.

Isso significa que para a pré-compilação ZK-EVM, temos duas opções:

1. A pré-compilação requer que todos os dados estejam disponíveis no mesmo bloco. Isso significa que o provador pode ser sem estado, mas também significa que usar esse rollup ZK pré-compilado é mais caro do que usar um rollup de código personalizado.

2. A pré-compilação permite ponteiros para dados usados ​​ou gerados em execuções anteriores. Isso permite que o rollup ZK seja quase ideal, mas é mais complexo e introduz novos tipos de estado que devem ser armazenados pelo provador.

Que lições podemos tirar disso? Há um bom argumento de que a verificação ZK-EVM poderia ser estabelecida de alguma forma: o rollup já está construindo sua própria versão personalizada, e o que parece errado é a disposição da Ethereum de colocar o peso de suas múltiplas implementações e consenso social fora da cadeia após o EVM. L1 é executado, L2 que faz exatamente o mesmo trabalho tem que implementar um dispositivo complexo envolvendo o conselho de segurança. Mas, por outro lado, há uma grande desvantagem nos detalhes: existem diferentes versões do ZK-EVM estabelecido, com diferentes custos e benefícios. Stateful versus stateless é apenas a ponta do iceberg; tentar oferecer suporte a "quase EVMs" com código personalizado comprovado por outros sistemas pode revelar um espaço de design maior. Portanto, estabelecer ZK-EVMs traz promessas e desafios.

Separação solidificada entre proponente e construtor (ePBS)

A ascensão do MEV tornou a produção de blocos um exercício de economia de escala, com jogadores experientes capazes de gerar blocos que geram mais receita do que algoritmos padrão que simplesmente monitoram as transações no mempool e as incluem. A comunidade Ethereum até agora tentou lidar com este problema usando um esquema de separação proponente-construtor fora do protocolo como MEV-Boost, que permite que validadores regulares ("proponentes") terceirizem a construção de blocos para atores dedicados ("Construtor").

No entanto, o MEV-Boost impõe suposições de confiança a uma nova classe de participantes, chamada de retransmissores. Nos últimos dois anos, surgiram muitas propostas para criar um “PBS solidificado”. Quais são os benefícios de fazer isso? Neste caso, a resposta é muito simples: um PBS construído utilizando diretamente os poderes do protocolo é mais forte em termos de pressupostos de confiança (no sentido de que os pressupostos de confiança são mais fracos) do que um PBS construído sem eles. Isto é semelhante ao caso de estabelecer um oráculo de preços num protocolo, embora nesse caso haja um contra-argumento poderoso.

Estabeleça um pool de memória privado

Quando um usuário envia uma transação, a transação torna-se imediatamente pública e visível para todos, mesmo antes de ser incluída na rede. Isto deixa os utilizadores de muitas aplicações vulneráveis ​​a ataques económicos, como o front-running: se um utilizador fizer uma grande transação no Uniswap, um atacante poderá colocar uma transação diante dele, aumentando o preço da sua compra e recolhendo o lucro da arbitragem.

Recentemente, tem havido uma série de projetos dedicados à criação de “mempools privados” (ou “mempools criptográficos”) que permitem que as transações dos usuários permaneçam criptografadas até que sejam irreversivelmente aceitas em um bloco.

No entanto, este esquema requer um tipo específico de criptografia: para evitar que os usuários inundem o sistema e executem o próprio processo de descriptografia antes que a transação seja realmente aceita de forma irreversível, a criptografia deve ser habilitada para descriptografar automaticamente quando a transação for realmente aceita de forma irreversível. .

Para implementar esta forma de criptografia, existem várias técnicas diferentes, com diferentes compensações, bem descritas por Jon Charbonneau em um artigo (e neste vídeo e apresentação de slides):

  • Criptografe para um operador centralizado como Flashbots Protect.

  • Criptografia de bloqueio de tempo, uma forma de criptografia que pode ser descriptografada por qualquer pessoa após um certo número de etapas computacionais sequenciais, que não podem ser paralelizadas.

  • Criptografia de limite, confia em um comitê majoritário para descriptografar os dados. Veja o conceito de cadeia de farol veneziana para uma proposta concreta.

  • Hardware confiável, como SGX.

Infelizmente, todos estes têm vários pontos fracos. Por razões óbvias, isto não é aceitável para o operador do centro para inclusão no acordo. A criptografia tradicional de timelock é muito cara para executar milhares de transações em um mempool público. Uma primitiva mais poderosa chamada criptografia atrasada permite a descriptografia eficiente de um certo número de mensagens, mas é difícil de construir na prática, e às vezes ainda são descobertos ataques a compilações existentes. Tal como acontece com as funções hash, poderemos precisar de muitos mais anos de pesquisa e análise antes que a criptografia atrasada esteja suficientemente madura. A criptografia de limite exige que se confie em um comitê majoritário para não conspirar, o que é inaceitável em um ambiente onde o conluio pode ser indetectável (ao contrário de um ataque de 51% em que se sabe imediatamente quem participou). SGX introduz uma dependência para um único fabricante confiável.

Embora para cada solução exista um subconjunto de usuários dispostos a confiar nela, nenhuma solução é atualmente confiável o suficiente para ser realmente aceita no Nível 1. Portanto, até pelo menos até/a menos que a criptografia atrasada melhore ou haja outros avanços tecnológicos, incorporar o front-running no Nível 1 parece uma proposta difícil, mesmo que seja um recurso muito valioso para o qual surgiram muitas soluções de aplicativos.

Hipoteca líquida solidificada

Uma necessidade comum entre os usuários do Ethereum DeFi é poder usar seu ETH tanto para piquetagem quanto como garantia em outras aplicações. Outra solicitação comum é apenas por conveniência: os usuários desejam poder fazer staking sem a complexidade de executar um nó e estar sempre online (além de proteger suas chaves de staking que agora estão online).

De longe, a “interface” de piquetagem mais simples que atende a essas duas necessidades é um token ERC20: converta seu ETH em “piquetagem ETH”, segure-o e depois converta-o novamente. Na verdade, provedores de liquidez como Lido e Rocketpool surgiram para fazer exatamente isso. No entanto, existem alguns mecanismos naturais de centralização em jogo com o staking de liquidez: as pessoas naturalmente apostam na versão maior do ETH porque é a mais familiar e líquida (e melhor suportada por aplicativos, e aplicativos que, por sua vez, o favorecem porque é mais familiar, já que é aquele de que a maioria dos usuários já ouviu falar).

Cada versão do ETH apostado precisa ter um mecanismo para determinar quem pode se tornar o operador do nó base. Não pode ser irrestrito porque os invasores participarão e usarão os fundos dos usuários para amplificar seus ataques. Atualmente, os dois primeiros são Lido, que tem um operador de nó DAO na lista de permissões, e Rocket Pool, que permite que qualquer pessoa execute um nó colocando 8 ETH (ou seja, 1/4 do capital) como depósito. Ambos os métodos apresentam riscos diferentes: o método Rocket Pool permite que um invasor lance um ataque de 51% na rede e force os usuários a pagar a maior parte do custo. Com a abordagem DAO, se um único token apostado se tornasse dominante, isso resultaria em um único dispositivo de governança potencialmente atacável controlando uma grande parte de todos os validadores Ethereum. Para protocolos como o Lido, implementaram salvaguardas, mas uma camada de defesa pode não ser suficiente.

No curto prazo, uma opção é encorajar socialmente os participantes do ecossistema a utilizarem um conjunto diversificado de fornecedores de garantias líquidas para reduzir a possibilidade de qualquer um deles se tornar demasiado grande para se tornar um risco sistémico. A longo prazo, porém, este é um equilíbrio precário e há perigos em confiar demasiado na pressão moral para resolver problemas. Surge uma questão natural: faz sentido solidificar alguma funcionalidade no protocolo para reduzir a concentração de garantias líquidas?

Aqui, a questão chave é: Qual função do protocolo está solidificada? O problema de apenas criar um token fungível “ETH garantido” dentro de um protocolo é que ele precisa ter uma governança global solidificada do Ethereum para escolher quem administra os nós, ou estar aberto a isso, transformando-o em uma ferramenta para invasores.

Um pensamento interessante é o artigo de Dankrad Feist sobre Extremismo Colateral de Liquidez. Em primeiro lugar, temos que aceitar o fato de que se o Ethereum for atacado por 51%, apenas 5% do ETH atacante poderá ser punido. Esta é uma compensação razoável; com mais de 26 milhões de ETH apostados, 1/3 do custo de um ataque (~8 milhões de ETH) é completamente excessivo, especialmente considerando quantos ataques “fora do modelo” podem ocorrer. implementado com muito menos custo. Na verdade, compromissos semelhantes já foram explorados na proposta do “Super Comité” para implementar a finalidade de faixa única.

Se aceitarmos que apenas 5% do ETH de ataque será cortado, então mais de 90% do ETH apostado estará isento de corte, então 90% do ETH apostado pode ser colocado em um token de piquetagem líquido fungível no protocolo, que pode então ser usado por outros aplicativos.

Este caminho é interessante. Mas ainda deixa uma questão: o que exatamente será solidificado? O Rocket Pool funciona de maneira muito semelhante: cada operador de nó investe algum capital e os stakers líquidos colocam o restante. Podemos simplesmente ajustar algumas constantes para limitar a penalidade máxima a 2 ETH, e o rETH existente do Rocket Pool se tornará livre de riscos.

Com ajustes simples de protocolo, podemos fazer algumas coisas inteligentes. Por exemplo, imagine que queremos um sistema onde existem dois “níveis” de staking: operadores de nós (elevados requisitos de garantia) e depositantes (sem requisitos mínimos, podem aderir e sair a qualquer momento), mas ainda queremos dar depósitos por A um comitê de pessoas amostrado aleatoriamente concede poderes como recomendar uma lista de transações que devem ser incluídas (por motivos anticensura), controlar a seleção de garfos durante vazamentos de inatividade ou exigir a assinatura de blocos. Isto pode ser conseguido adaptando o mecanismo no protocolo pelo qual cada validador deve fornecer (i) uma chave de piquetagem regular e (ii) um endereço ETH que cada slot pode chamar para gerar a chave de piquetagem secundária. O protocolo concederá energia a ambas as chaves, mas o mecanismo para selecionar a segunda chave em cada slot pode ser deixado para o protocolo do pool de piquetagem. Ainda pode ser melhor solidificar algo diretamente, mas é importante notar que esse espaço de design “solidificar algumas coisas e deixar outras para o usuário” existe.

Solidificar mais pré-compilação

Contratos pré-compilados (ou "contratos pré-compilados") são contratos Ethereum que implementam operações criptográficas complexas nativamente no código do cliente, em vez de no código do contrato inteligente EVM. A pré-compilação é um compromisso adotado nos primórdios do Ethereum: como o overhead da VM é muito grande para certos tipos de código muito complexo e altamente especializado, podemos implementar no código nativo alguns recursos que são úteis para tipos importantes de aplicações de valor. operações principais para torná-las mais rápidas. Hoje, isso inclui basicamente algumas funções hash específicas e operações de curva elíptica.

Atualmente, há um esforço para adicionar a pré-compilação do secp256r1, uma curva elíptica ligeiramente diferente da secp256k1 usada para contas Ethereum básicas, pois é amplamente suportada por módulos de hardware confiáveis, portanto, seu uso generalizado pode melhorar a segurança da carteira. Nos últimos anos, tem havido esforços para promover a pré-compilação de funções como BLS-12-377, BW6-761 e emparelhamento generalizado.

O contra-argumento a essas solicitações para adicionar mais pré-compiladores é que muitos pré-compiladores adicionados anteriormente (como RIPEMD e BLAKE) acabaram sendo usados ​​menos do que o pretendido, e devemos aprender com isso. Em vez de adicionar mais pré-compilação para operações específicas, provavelmente deveríamos nos concentrar em uma abordagem mais suave baseada em ideias como EVM-MAX e a proposta SIMD sleep-but-always-wakeable, que permitiria que implementações EVM fossem executadas de forma mais barata e ampla. . Pode até ser possível remover e substituir a pré-compilação existente, mas raramente usada, por uma implementação de código EVM da mesma funcionalidade. Dito isto, ainda pode haver algumas operações criptográficas específicas que são valiosas para acelerar, justificando adicioná-las como pré-compiladas.

O que podemos aprender com tudo isso?

O desejo de ter o mínimo de solidificação possível é compreensível e bom; decorre da tradição filosófica do Unix de criar software mínimo que possa ser facilmente adaptado às diferentes necessidades de seus usuários, evitando a maldição do inchaço do software. No entanto, blockchains não são sistemas operacionais de computação pessoal; são sistemas sociais. Isso significa que há razões para incluir certos recursos no protocolo que vão além das considerações puramente pessoais mencionadas acima.

Em muitos casos, estes outros exemplos reintroduzem lições semelhantes observadas na abstração de contas. Mas também há algumas novas lições aprendidas:

  • Ajude a evitar riscos de centralização em outras áreas da pilha. Freqüentemente, manter o protocolo básico simples e simples empurra a complexidade para o ecossistema fora do protocolo. Do ponto de vista da filosofia Unix, tudo bem. Às vezes, porém, o risco de um ecossistema fora de um protocolo é que ele possa se tornar centralizado, muitas vezes (mas não apenas) devido aos altos custos fixos. A solidificação pode, por vezes, reduzir a centralização real.

  • Demasiada solidificação aumentará excessivamente a confiança e a carga de governação do protocolo. Este é o tema de um artigo anterior sobre "Não sobrecarregue o consenso Ethereum" (ver artigo de tradução anterior da Golden Finance): se uma característica específica for solidificada, enfraquecerá o modelo de confiança e tornará o Ethereum como um todo mais "subjetivo" , portanto, isso enfraquece a neutralidade confiável do Ethereum. Nestes casos, é melhor manter essa funcionalidade específica como um mecanismo no topo do Ethereum, em vez de tentar trazê-la para o próprio Ethereum. Aqui, pools de memória criptografada são o melhor exemplo de algo que pode ser muito difícil de solidificar, pelo menos até/a menos que a tecnologia de criptografia melhore.

  • Muita cura pode complicar demais o protocolo. A complexidade do protocolo é um risco sistêmico, e adicionar muitos recursos a um protocolo aumenta esse risco. A pré-compilação é o melhor exemplo disso.

  • A solidificação pode ser contraproducente a longo prazo porque as necessidades dos utilizadores são imprevisíveis. Um recurso que muitas pessoas consideram importante e que será usado por muitos usuários pode, na verdade, não ser muito usado na prática.

Além disso, as garantias de liquidez, ZK-EVM e casos pré-compilados mostram uma possibilidade intermediária: solidificação mínima viável. Em vez de solidificar um recurso inteiro, solidifique partes específicas que abordam os principais desafios da implementação desse recurso sem ser muito subjetivo ou tacanho. Isso inclui:

  • Em vez de solidificar todo o sistema de apostas de liquidez, as regras de penalização deveriam ser alteradas para tornar mais viável a aposta de liquidez sem confiança.

  • Em vez de fortalecer mais a pré-compilação, fortaleça o EVM-MAX e/ou SIMD para tornar uma classe mais ampla de operações mais simples de implementar com eficiência.

  • Em vez de solidificar todo o conceito de Rollups, podemos simplesmente solidificar a verificação EVM.

Podemos expandir o diagrama anterior neste artigo da seguinte maneira:

Às vezes pode até fazer sentido remover a solidificação de alguma coisa. A remoção de pré-compiladores raramente usados ​​é um exemplo. Como suporte compatível com versões futuras para usuários existentes, este mecanismo pode na verdade ser surpreendentemente semelhante àquele que remove a pré-compilação: um deles é o EIP-5003, que permitirá que os EOAs convertam suas contas no local para terem o mesmo (ou melhor). ) contrato de função.

Quais recursos devem ser trazidos para o protocolo e quais recursos devem ser deixados para outras camadas do ecossistema é uma troca complexa, e devemos esperar que continue a melhorar à medida que nossa compreensão das necessidades do usuário e nosso conjunto disponível de ideias e tecnologias e evoluir com o tempo.