Possíveis futuros do protocolo Ethereum, parte 5: O Purge

Avançado11/5/2024, 12:46:30 PM
Um dos desafios que o Ethereum enfrenta é o crescimento do inchaço de dados históricos e da complexidade do protocolo ao longo do tempo. Os principais objetivos de The Purge são reduzir os requisitos de armazenamento do cliente, minimizando ou eliminando a necessidade de cada nó armazenar permanentemente todos os registros históricos e até o estado final; e reduzir a complexidade do protocolo, removendo recursos desnecessários.

Um dos desafios do Ethereum é que, por padrão, o inchaço e a complexidade do protocolo de qualquer blockchain aumentam ao longo do tempo. Isso acontece em dois lugares:

  • Dados históricos: qualquer transação realizada e qualquer conta criada em qualquer momento da história precisa ser armazenada por todos os clientes para sempre e baixada por quaisquer novos clientes que façam uma sincronização completa com a rede. Isso faz com que a carga do cliente e o tempo de sincronização continuem aumentando ao longo do tempo, mesmo que a capacidade da cadeia permaneça a mesma.
  • Recursos do protocolo: é muito mais fácil adicionar uma nova funcionalidade do que remover uma antiga, causando um aumento na complexidade do código ao longo do tempo.

Para que o Ethereum se sustente a longo prazo, precisamos de uma forte contra-pressão contra essas duas tendências, reduzindo a complexidade e o inchaço ao longo do tempo. Mas, ao mesmo tempo, precisamos preservar uma das principais propriedades que tornam as blockchains excelentes: sua permanência. Você pode colocar um NFT, uma mensagem de amor nos dados de transação ou um contrato inteligente contendo um milhão de dólares na cadeia, entrar em uma caverna por dez anos, sair e encontrá-lo ainda lá, esperando que você leia e interaja com ele. Para que os dapps se sintam confortáveis em se tornar completamente descentralizados e remover suas chaves de atualização, eles precisam ter confiança de que suas dependências não vão ser atualizadas de uma forma que os prejudique - especialmente a L1 em si.

A Purge, roteiro de 2023.

Equilibrar entre essas duas necessidades, e minimizar ou reverter a inflação, complexidade e decadência, enquanto preservamos a continuidade, é absolutamente possível se nos dedicarmos a isso. Os organismos vivos podem fazer isso: enquanto a maioria envelhece com o tempo, alguns sortudos não. Mesmo os sistemas sociais podem tem longevidade extrema. Em algumas ocasiões, o Ethereum já mostrou sucessos: a prova de trabalho se foi, o opcode SELFDESTRUCT está quase extinto, e os nós da cadeia de beacon já armazenam dados antigos por apenas seis meses. Descobrir esse caminho para o Ethereum de forma mais generalizada e avançar em direção a um resultado final estável a longo prazo é o desafio supremo da escalabilidade a longo prazo, sustentabilidade técnica e até segurança do Ethereum.

A Purga: principais objetivos

  • Reduzir os requisitos de armazenamento do cliente, reduzindo ou removendo a necessidade de cada nó armazenar permanentemente todo o histórico, e talvez até mesmo o estado eventualmente
  • Reduzindo a complexidade do protocolo eliminando recursos desnecessários

Neste capítulo

Expiração de histórico

Que problema isso resolve?

No momento da redação deste texto, um nó Ethereum totalmente sincronizado requeraproximadamente 1,1 terabytesde espaço em disco para ocliente de execução, mais algumas centenas de gigabytes para o cliente de consenso. A grande maioria disso é história: dados sobre blocos históricos, transações e recibos, a maior parte dos quais tem muitos anos. Isso significa que o tamanho de um nó continua aumentando em centenas de gigabytes a cada ano, mesmo se o limite de gás não aumentar.

O que é isso e como funciona?

Um recurso de simplificação-chave do problema de armazenamento de histórico é que, como cada bloco aponta para o bloco anterior por meio de um link de hash (eoutro estruturas), ter consenso sobre o presente é suficiente para ter consenso sobre a história. Desde que a rede tenha consenso sobre o último bloco, qualquer bloco histórico, transação ou estado (saldo da conta, nonce, código, armazenamento) pode ser fornecido por qualquer ator único, juntamente com uma prova de Merkle, e a prova permite que qualquer outra pessoa verifique sua correção. Embora o consenso seja um modelo de confiança N/2-de-N, a história é um modelo de confiança 1-de-N.

Isso abre muitas opções para como podemos armazenar o histórico. Uma opção natural é uma rede onde cada nó armazena apenas uma pequena porcentagem dos dados. É assim que as redes de torrent funcionam há décadas: enquanto a rede como um todo armazena e distribui milhões de arquivos, cada participante armazena e distribui apenas alguns deles. Talvez de forma contraintuitiva, essa abordagem não diminui necessariamente a robustez dos dados. Se, tornando a execução do nó mais acessível, pudermos chegar a uma rede com 100.000 nós, onde cada nó armazena aleatoriamente 10% do histórico, então cada parte dos dados seria replicada 10.000 vezes - exatamente o mesmo fator de replicação de uma rede de 10.000 nós onde cada nó armazena tudo.

Hoje, o Ethereum já começou a se afastar do modelo de todos os nós armazenando todo o histórico para sempre. Blocos de consenso (ou seja, as partes relacionadas ao consenso de participação) são armazenados apenas por ~6 meses. Blobs são armazenados apenas por ~18 dias.EIP-4444O objetivo é introduzir um período de armazenamento de um ano para blocos e recibos históricos. Um objetivo a longo prazo é ter um período harmonizado (que poderia ser de cerca de 18 dias) durante o qual cada nó é responsável por armazenar tudo e, em seguida, ter uma rede peer-to-peer composta por nós Ethereum armazenando dados mais antigos de forma distribuída.

Os códigos de apagamento podem ser usados para aumentar a robustez mantendo o mesmo fator de replicação. De fato, os blobs já vêm com códigos de apagamento para suportar a amostragem de disponibilidade de dados. A solução mais simples pode ser reutilizar esse código de apagamento e colocar os dados de bloco de execução e consenso em blobs também.

O que resta fazer e quais são os tradeoffs?

O trabalho principal restante envolve a construção e integração de uma solução distribuída concreta para armazenar o histórico - pelo menos o histórico de execução, mas também eventualmente o consenso e os blobs. As soluções mais simples para isso são (i) simplesmente introduzir uma biblioteca de torrents existente e (ii) uma solução nativa do Ethereum chamada gate.a rede Portal. Uma vez que qualquer um deles seja introduzido, podemos ativar o EIP-4444. O próprio EIP-4444 não requer um hard fork, embora exija uma nova versão de protocolo de rede. Por essa razão, há valor em habilitá-lo para todos os clientes ao mesmo tempo, porque caso contrário há riscos de mau funcionamento dos clientes ao se conectarem a outros nós esperando fazer o download de todo o histórico, mas na verdade não o obtendo.

O principal trade-off envolve o quão duro tentamos tornar os dados históricos 'antigos' disponíveis. A solução mais fácil seria simplesmente parar de armazenar a história antiga amanhã e confiar em nós de arquivo existentes e vários provedores centralizados para replicação. Isso é fácil, mas enfraquece a posição do Ethereum como um lugar para fazer registros permanentes. O caminho mais difícil, mas mais seguro, é primeiro construir e integrar a rede torrent para armazenar a história de maneira distribuída. Aqui, há duas dimensões de 'quão duro tentamos':

  1. Quão difícil nós tentamos garantir que um conjunto maximamente grande de nós realmente esteja armazenando todos os dados?
  2. Até que ponto integramos o armazenamento histórico no protocolo?

Uma abordagem maximamente paranóica para (1) envolveriaprova de custódia: na verdade, exigindo que cada validador de prova de participação armazene uma certa porcentagem de histórico e verifique regularmente criptograficamente se eles o fazem. Uma abordagem mais moderada é estabelecer um padrão voluntário para qual porcentagem de histórico cada cliente armazena.

Para (2), uma implementação básica envolve apenas pegar o trabalho que já é feito hoje: Portal já armazena arquivos ERA contendo todo o histórico do Ethereum. Uma implementação mais completa envolveria realmente conectar isso ao processo de sincronização, para que se alguém quisesse sincronizar um nó de armazenamento de histórico completo ou um nó de arquivo, eles pudessem fazê-lo mesmo se nenhum outro nó de arquivo existisse online, sincronizando diretamente da rede Portal.

Como ele interage com outras partes do roteiro?

Reduzir os requisitos de armazenamento de histórico é possivelmente ainda mais importante do que a ausência de estado, se quisermos tornar extremamente fácil executar ou iniciar um nó: dos 1,1 TB necessários para um nó, cerca de 300 GB são de estado, e os restantes 800 GB são de histórico. A visão de um nó Ethereum funcionando em um relógio inteligente e levando apenas alguns minutos para ser configurado só é possível se a ausência de estado e o EIP-4444 forem implementados.

Limitar o armazenamento de histórico também torna mais viável que novas implementações de nós Ethereum suportem apenas versões recentes do protocolo, o que permite que sejam muito mais simples. Por exemplo, muitas linhas de código podem ser removidas com segurança agora que todos os espaços de armazenamento vazios criados durante os ataques DoS de 2016 foram...removido. Agora que a transição para o proof of stake é história antiga, os clientes podem remover com segurança todo o código relacionado ao proof-of-work.

Expiração do estado

Qual problema ele resolve?

Mesmo que removamos a necessidade de os clientes armazenarem o histórico, o requisito de armazenamento de um cliente continuará a crescer, em cerca de 50 GB por ano, devido ao crescimento contínuo do estado: saldos e nonces de contas, código de contrato e armazenamento de contrato. Os usuários podem pagar um custo único para impor um fardo aos clientes presentes e futuros do Ethereum para sempre.

O estado é muito mais difícil de “expirar” do que o histórico, porque o EVM é fundamentalmente projetado com a suposição de que, uma vez que um objeto de estado é criado, ele estará sempre lá e pode ser lido por qualquer transação a qualquer momento. Se introduzirmos a ausência de estado, há um argumento de que talvez esse problema não seja tão ruim assim: apenas uma classe especializada de construtores de blocos precisaria armazenar o estado de fato, e todos os outros nós (mesmo lista de inclusãoprodução!) pode ser executado sem estado. No entanto, há um argumento de que não queremos depender muito do estado de não ter e, eventualmente, podemos querer expirar o estado para manter o Ethereum descentralizado.

O que é isso e como funciona?

Hoje, quando você cria um novo objeto de estado (o que pode acontecer de três maneiras: (i) enviando ETH para uma nova conta, (ii) criando uma nova conta com código, (iii) definindo um slot de armazenamento previamente não utilizado), esse objeto de estado fica no estado para sempre. O que queremos, em vez disso, é que os objetos expirem automaticamente com o tempo. O desafio chave é fazer isso de uma maneira que alcance três objetivos:

  1. Eficiência: não requer grandes quantidades de cálculos extras para executar o processo de expiração
  2. Facilidade de uso: se alguém entrar em uma caverna por cinco anos e voltar, não deve perder o acesso ao seu ETH, ERC20s, NFTs, posições CDP...
  3. Facilidade para desenvolvedores: os desenvolvedores não devem ter que mudar para um modelo mental completamente desconhecido. Além disso, aplicativos que estão ossificados hoje e não são atualizados devem continuar funcionando razoavelmente bem.

É fácil resolver o problema sem atingir esses objetivos. Por exemplo, você pode fazer com que cada objeto de estado também armazene um contador para sua data de expiração (que pode ser estendida gravando ETH, o que pode acontecer automaticamente sempre que for lido ou gravado) e ter um processo que percorra o estado para remover objetos de estado expirados. No entanto, isso introduz computação extra (e até mesmo requisitos de armazenamento), e definitivamente não satisfaz o requisito de facilidade de uso. Os desenvolvedores também teriam dificuldade em raciocinar sobre casos de borda envolvendo valores de armazenamento, às vezes redefinidos para zero. Se você tornar o contrato de temporizador de expiração amplo, isso torna a vida tecnicamente mais fácil para os desenvolvedores, mas torna a economia mais difícil: os desenvolvedores teriam que pensar em como "repassar" os custos contínuos de armazenamento para seus usuários.

Esses são problemas com os quais a comunidade de desenvolvimento central do Ethereum lutou por muitos anos, incluindo propostas como “aluguel de blockchain“ e “regenesis". Eventualmente, combinamos as melhores partes das propostas e convergimos em duas categorias de "soluções conhecidas menos ruins":

  • Soluções parciais de expiração de estado
  • Propostas de expiração de estado baseadas em períodos de endereço.

Expiração parcial de estado

As propostas de expiração parcial do estado funcionam todos com o mesmo princípio. Dividimos o estado em pedaços. Todos armazenam permanentemente o “mapa de nível superior” de quais pedaços estão vazios ou não vazios. Os dados dentro de cada pedaço são armazenados apenas se esses dados tiverem sido acessados recentemente. Existe um mecanismo de “ressurreição” onde, se um pedaço não estiver mais armazenado, qualquer pessoa pode trazer esses dados de volta fornecendo uma prova do que os dados eram.

As principais distinções entre essas propostas são: (i) como definimos 'recentemente' e (ii) como definimos 'chunk'? Uma proposta concreta é EIP-7736, que se baseia no design “stem-and-leaf”introduzido para árvores Verkle (embora compatível com qualquer forma de estado sem estado, por exemplo, árvores binárias). Nesse design, cabeçalho, código e slots de armazenamento que são adjacentes entre si são armazenados sob o mesmo “ramo”. Os dados armazenados embaixo de um ramo podem ter no máximo 256 * 31 = 7.936 bytes. Em muitos casos, todo o cabeçalho e código, e muitos slots de armazenamento-chave, de uma conta serão armazenados sob o mesmo ramo. Se os dados embaixo de um determinado ramo não forem lidos ou gravados por 6 meses, os dados não são mais armazenados, e apenas um compromisso de 32 bytes (“stub”) para os dados é armazenado. Transações futuras que acessam esses dados precisariam “ressuscitar” os dados, com uma prova que seria verificada em relação ao stub.

Existem outras maneiras de implementar uma ideia semelhante. Por exemplo, se a granularidade ao nível da conta não for suficiente, poderíamos criar um esquema em que cada fração de 1/232 da árvore seja governada por um mecanismo semelhante haste-e-folha.

Isso é mais complicado por causa dos incentivos: um atacante poderia forçar os clientes a armazenar permanentemente uma quantidade muito grande de estado colocando uma quantidade muito grande de dados em uma única subárvore e enviando uma única transação a cada ano para 'renovar a árvore'. Se você fizer com que o custo de renovação seja proporcional (ou a duração de renovação inversamente proporcional) ao tamanho da árvore, então alguém poderia prejudicar outro usuário colocando uma quantidade muito grande de dados na mesma subárvore que eles. Pode-se tentar limitar ambos os problemas tornando a granularidade dinâmica com base no tamanho da subárvore: por exemplo, cada 216 = 65536 objetos de estado consecutivos poderiam ser tratados como um 'grupo'. No entanto, essas ideias são mais complexas; a abordagem baseada em caule é simples e alinha os incentivos, porque geralmente todos os dados sob um caule estão relacionados à mesma aplicação ou usuário.

Propostas de expiração de estado baseadas em períodos de endereço

E se quisermos evitar qualquer crescimento de estado permanente, mesmo com stubs de 32 bytes? Este é um problema difícil por causa de @vbuterin/state_size_management#Conflitos_de_r ressurreição": e se um objeto de estado for removido, a execução do EVM posteriormente coloca outro objeto de estado na mesma posição exata, mas depois disso alguém que se importa com o objeto de estado original volta e tenta recuperá-lo? Com a expiração parcial do estado, o "stub" impede a criação de novos dados. Com a expiração completa do estado, não podemos nos dar ao luxo de armazenar nem mesmo o "stub".

O design baseado em período de endereço é a ideia mais conhecida para resolver isso. Em vez de ter uma árvore de estado armazenando todo o estado, temos uma lista de árvores de estado em constante crescimento, e qualquer estado que é lido ou escrito é salvo na árvore de estado mais recente. Uma nova árvore de estado vazia é adicionada uma vez por período (pense: 1 ano). As árvores de estado mais antigas são sólidas congeladas. Espera-se que os nós completos armazenem apenas as duas árvores mais recentes. Se um objeto de estado não foi tocado por dois períodos e, portanto, cai em uma árvore expirada, ele ainda pode ser lido ou gravado, mas a transação precisaria provar uma prova de Merkle para ele - e uma vez que isso aconteça, uma cópia será salva na árvore mais recente novamente.

Uma ideia-chave para tornar tudo isso amigável para usuários e desenvolvedores é o conceito de períodos de endereço. Um período de endereço é um número que faz parte de um endereço. Uma regra importante é que um endereço com período de endereço N só pode ser lido ou gravado durante ou após o período N (ou seja, quando a lista de árvores de estado atinge o comprimento N). Se você estiver salvando um novo objeto de estado (por exemplo, um novo contrato ou um novo saldo ERC20), se certificar de colocar o objeto de estado em um contrato cujo período de endereço seja N ou N-1, você pode salvá-lo imediatamente, sem precisar fornecer provas de que não havia nada lá antes. No entanto, qualquer adição ou edição de estado em períodos de endereço mais antigos requer uma prova.

Este design preserva a maioria das propriedades atuais do Ethereum, é muito leve em termos de computação extra, permite que as aplicações sejam escritas quase como são hoje (ERC20s precisarão ser reescritas, para garantir que os saldos de endereços com período de endereço N sejam armazenados em um contrato filho que também tem período de endereço N) e resolve o problema de "o usuário entra em uma caverna por cinco anos". No entanto, ele tem um grande problema: os endereços precisam ser expandidos além de 20 bytes para caber nos períodos de endereço.

Extensão do espaço de endereçamento

Uma proposta é introduzir um novo formato de endereço de 32 bytes, que inclui um número de versão, um número de período de endereço e um hash expandido.

0x01000000000157aE408398dF7E5f4552091A69125d5dFcb7B8C2659029395bdF

O vermelho é um número de versão. Os quatro zeros coloridos de laranja aqui são destinados como espaço vazio, que poderia caber um número de shard no futuro. O verde é um número de período de endereço. O azul é um hash de 26 bytes.

O desafio aqui é a compatibilidade retroativa. Contratos existentes são projetados em torno de endereços de 20 bytes e muitas vezes usam técnicas de compactação de byte apertado que assumem explicitamente que os endereços têm exatamente 20 bytes de comprimento.@ipsilon/address-space-extension-exploration">Uma ideia para resolver isso envolve um mapa de tradução, onde contratos no estilo antigo interagindo com endereços no estilo novo veriam um hash de 20 bytes do endereço no estilo novo. No entanto, existem complexidades significativas envolvidas em tornar isso seguro.

Contração do espaço de endereçamento

Outra abordagem segue a direção oposta: imediatamente proibimos uma subfaixa de endereços de tamanho 2128 (por exemplo, todos os endereços que começam com 0xffffffff) e, em seguida, usamos essa faixa para introduzir endereços com períodos de endereço e hashes de 14 bytes.

0xfffffff000169125d5dFcb7B8C2659029395bdF

O sacrifício-chave que esta abordagem faz é queintroduz riscos de segurança para endereços contrafactuais: endereços que possuem ativos ou permissões, mas cujo código ainda não foi publicado na cadeia. O risco envolve alguém criando um endereço que afirma ter um pedaço de código (ainda não publicado), mas também tem outro pedaço válido de código que faz hash para o mesmo endereço. Calcular tal colisão requer 280hashes hoje; a contração do espaço de endereço reduziria esse número para um 2 muito acessível56hashes.

A área de risco chave, endereços contrafactuais que não são carteiras mantidas por um único proprietário, é um caso relativamente raro hoje, mas provavelmente se tornará mais comum à medida que entramos em um mundo multi-L2. A única solução é simplesmente aceitar esse risco, mas identificar todos os casos de uso comuns onde isso pode ser um problema e encontrar soluções eficazes.

O que resta fazer e quais são os tradeoffs?

Vejo quatro caminhos viáveis para o futuro:

  • Fazemos apatridia e nunca introduzimos a caducidade estatal. O estado está em constante crescimento (embora lentamente: podemos não vê-lo ultrapassar 8 TB por décadas), mas só precisa ser mantido por uma classe relativamente especializada de usuários: nem mesmo os validadores de PoS precisariam do estado. \
    \
    A única função que precisa de acesso a partes do estado é a produção da lista de inclusão, mas podemos realizar isso de forma descentralizada: cada usuário é responsável por manter a parte da árvore de estado que contém suas próprias contas. Quando eles transmitem uma transação, eles a transmitem com uma prova dos objetos de estado acessados durante a etapa de verificação (isso funciona tanto para EOAs quanto para contas ERC-4337). Validadores sem estado podem então combinar essas provas em uma prova para toda a lista de inclusão.
  • Fazemos expiração parcial de estado e aceitamos uma taxa muito menor, mas ainda não nula, de crescimento do tamanho permanente do estado. Este resultado é semelhante, argumentavelmente, a como propostas de expiração de histórico envolvendo redes peer-to-peer aceitam uma taxa muito menor, mas ainda não nula, de crescimento do armazenamento permanente de histórico de cada cliente que precisa armazenar uma porcentagem baixa, mas fixa, dos dados históricos.
  • Realizamos a expiração do estado, com expansão do espaço de endereços. Isso envolverá um processo de vários anos para garantir que a abordagem de conversão de formato de endereço funcione e seja segura, inclusive para aplicativos existentes.
  • Fazemos a expiração de estado, com contração do espaço de endereços. Isso envolverá um processo de vários anos para garantir que todos os riscos de segurança envolvendo colisões de endereços, incluindo situações entre cadeias, sejam tratados.

Um ponto importante é que as questões difíceis em torno da expansão e contração do espaço de endereço terão que ser abordadas eventualmente, independentemente de as políticas de expiração de estado que dependem de alterações no formato do endereço serem ou não implementadas. Hoje, leva aproximadamente 280 hashes para gerar uma colisão de endereço, uma carga computacional que já é viável para atores extremamente bem dotados de recursos: uma GPU pode fazer cerca de 227 hashes, então, executando por um ano, ele pode calcular 252, então todos ~2^30 GPUs no mundopoderia calcular uma colisão em ~1/4 de ano, e FPGAs e ASICs poderiam acelerar isso ainda mais. No futuro, tais ataques estarão disponíveis para cada vez mais pessoas. Assim, o custo real de implementar a expiração completa do estado pode não ser tão alto quanto parece, já que temos que resolver esse problema de endereço muito desafiador de qualquer maneira.

Como interage com outras partes do roteiro?

Fazer a expiração de estado potencialmente torna as transições de um formato de árvore de estado para outro mais fácil, porque não haverá necessidade de um procedimento de transição: você pode simplesmente começar a fazer novas árvores usando um novo formato e, mais tarde, fazer um hard fork para converter as árvores mais antigas. Assim, embora a expiração do estado seja complexa, ela tem benefícios na simplificação de outros aspectos do roteiro.

Limpeza de recursos

Quais problemas ele resolve?

Uma das condições prévias fundamentais de segurança, acessibilidade e neutralidade credívelé a simplicidade. Se um protocolo é bonito e simples, reduz a chance de haver bugs. Aumenta a chance de novos desenvolvedores serem capazes de entrar e trabalhar com qualquer parte dele. É mais provável que seja justo e mais fácil de defender contra interesses especiais. Infelizmente, os protocolos, como qualquer sistema social, por padrão tornam-se mais complexos com o tempo. Se não quisermos que o Ethereum entre em um buraco negro de complexidade cada vez maior, precisamos fazer uma das duas coisas: (i) parar de fazer mudanças e ossificar o protocolo, (ii) ser capaz de realmente remover recursos e reduzir a complexidade. Um caminho intermediário, de fazer menos mudanças no protocolo e também remover pelo menos um pouco de complexidade ao longo do tempo, também é possível. Esta seção falará sobre como podemos reduzir ou remover complexidade.

O que é isso e como funciona?

Não há uma grande solução única que possa reduzir a complexidade do protocolo; a natureza inerente do problema é que há muitas pequenas soluções.

Um exemplo que está principalmente concluído e pode servir como um modelo de como lidar com os outros é o @vbuterin/selfdestruct">remoção do opcode SELFDESTRUCT. O opcode SELFDESTRUCT era o único opcode que poderia modificar um número ilimitado de slots de armazenamento dentro de um único bloco, exigindo que os clientes implementassem significativamente mais complexidade para evitar ataques de DoS. O objetivo original do opcode era permitir a limpeza voluntária do estado, permitindo que o tamanho do estado diminuísse ao longo do tempo. Na prática, muito poucos acabaram usando.opcode foi nerfadopara permitir apenas contas auto-destrutivas criadas na mesma transação na atualização Dencun. Isso resolve o problema de DoS e permite uma simplificação significativa no código do cliente. No futuro, provavelmente faz sentido remover eventualmente a opcode completamente.

Alguns exemplos-chave de oportunidades de simplificação de protocolo que foram identificadas até agora incluem o seguinte. Primeiro, alguns exemplos que estão fora do EVM; estes são relativamente não invasivos e, portanto, mais fáceis de obter consenso e implementar em um prazo mais curto.

  • Transição RLP → SSZ: originalmente, objetos Ethereum eram serializados usando uma codificação chamada RLPRLP é não tipado e desnecessariamente complexo. Hoje, a cadeia de beacons usaSSZ, que é significativamente melhor em muitos aspectos, incluindo o suporte não apenas à serialização, mas também ao hashing. Eventualmente, queremos nos livrar completamente do RLP e mover todos os tipos de dados para serem estruturas SSZ, o que por sua vez facilitaria muito a atualização. EIPs atuais para isso incluem [1] [2] [3].
  • Remoção de tipos de transações antigos: hoje existem muitos tipos de transações, muitos deles poderiam ser potencialmente removidos. Uma alternativa mais moderada à remoção completa é um recurso de abstração de conta, pelo qual contas inteligentes poderiam incluir o código para processar e verificar transações no estilo antigo, se assim o desejarem.
  • Reforma de LOG: os logs criam filtros de bloom e outras lógicas que adicionam complexidade ao protocolo, mas não são realmente usados pelos clientes porque são muito lentos. Nós poderíamos remover esses recursose em vez disso, se esforçar em alternativas, como ferramentas de leitura de log descentralizadas fora do protocolo que usam tecnologia moderna como SNARKs.
  • Remoção eventual do mecanismo de comitê de sincronização da corrente de beacon: o mecanismo de comitê de sincronizaçãofoi originalmente introduzido para permitir a verificação de clientes leves do Ethereum. No entanto, isso adiciona uma complexidade significativa ao protocolo. Eventualmente, seremos capazes deverificar a camada de consenso do Ethereum diretamente usando SNARKs, o que eliminaria a necessidade de um protocolo de verificação de cliente leve dedicado. Potencialmente, alterações no consenso poderiam nos permitir remover os comitês de sincronização ainda mais cedo, criando um protocolo de cliente leve mais 'nativo' que envolve a verificação de assinaturas de um subconjunto aleatório dos validadores de consenso do Ethereum.
  • Harmonização do formato de dados: hoje, o estado de execução é armazenado em uma árvore de Patricia Merkle, o estado de consenso é armazenado em um árvore SSZ, e os blobs são comprometidos com @vbuterin#Qual é o formato dos dados de blob e como eles são commitados">Compromissos KZG. No futuro, faz sentido criar um único formato unificado para os dados de bloco e um único formato unificado para o estado. Esses formatos cobririam todas as necessidades importantes: (i) provas fáceis para clientes sem estado, (ii) serialização e codificação por apagamento para dados, (iii) estruturas de dados padronizadas.
  • Remoção dos comitês da cadeia de beacons: esse mecanismo foi originalmente introduzido para suportar umversão particular de shard de execução. Em vez disso, acabamos fazendo shardagem por meio de L2s e blobs. Portanto, comissões são desnecessárias e, portanto, há um em movimento em direção à remoção deles.
  • Remoção de mistura de endianidade: o EVM é big-endian e a camada de consenso é little-endian. Pode fazer sentido re-harmonizar e tornar tudo uma coisa ou outra (provavelmente big-endian, porque o EVM é mais difícil de mudar)

Agora, alguns exemplos que estão dentro do EVM:

  • Simplificação da mecânica de gás: as regras atuais de gás não são bem otimizadas para dar limites claros à quantidade de recursos necessários para verificar um bloco. Exemplos-chave incluem (i) custos de leitura/gravação de armazenamento, que pretendem limitar o número de leituras/escritas em um bloco, mas atualmente são bastante caóticos, e (ii) regras de preenchimento de memória, onde atualmente é difícil estimar o consumo máximo de memória do EVM. As correções propostas incluem mudanças de custo de gás de estado sem estado, que harmonizam todos os custos relacionados ao armazenamento em uma fórmula simples e,esta proposta para precificação de memória.
  • Remoção de pré-compilações: muitas das pré-compilações que o Ethereum possui hoje são desnecessariamente complexas e relativamente não utilizadas, e compõem uma grande porcentagem de falhas quase-misses de consenso, sem serem de fato utilizadas por quaisquer aplicativos. Duas maneiras de lidar com isso são (i) simplesmente remover a pré-compilação e (ii) substituí-la por um pedaço (inevitavelmente mais caro) de código EVM que implementa a mesma lógica.Este rascunho EIP propõepara fazer isso para o precompilado de identidade como primeiro passo; mais tarde, RIPEMD160, MODEXP e BLAKE podem ser candidatos para remoção.
  • Remoção da observabilidade do gás: fazer com que a execução do EVM não consiga mais ver quanto gás resta. Isso quebraria algumas aplicações (principalmente transações patrocinadas), mas permitiria atualizações muito mais fáceis no futuro (por exemplo, para versões mais avançadas degás multidimensional. AEspecificação de EOFjá torna o gás não observável, embora para ser útil para simplificação do protocolo EOF precisaria se tornar obrigatório.
  • Melhorias na análise estática: hoje, o código EVM é difícil de analisar estaticamente, especialmente porque os saltos podem ser dinâmicos. Isso também torna mais difícil fazer implementações EVM otimizadas que pré-compilam o código EVM em alguma outra linguagem. Potencialmente, podemos corrigir isso porremovendo saltos dinâmicos(ou tornando-os muito mais caros, por exemplo, custo de gás linear no número total de JUMPDESTs em um contrato). EOF faz isso, embora obter ganhos de simplificação do protocolo a partir disso exigiria tornar o EOF obrigatório.

O que resta fazer e quais são os compromissos?

O principal tradeoff ao fazer esse tipo de simplificação de recurso é (i) o quanto simplificamos e o quão rápido vs (ii) compatibilidade com versões anteriores. O valor do Ethereum como uma cadeia vem do fato de ser uma plataforma onde você pode implantar um aplicativo e ter a confiança de que ele ainda funcionará por muitos anos. Ao mesmo tempo, é possível levar esse ideal longe demais e,parafrasear William Jennings Bryan"crucificar o Ethereum em uma cruz de compatibilidade reversa". Se houver apenas duas aplicações em todo o Ethereum que utilizam um determinado recurso, e uma delas não tem usuários há anos e a outra é quase completamente não utilizada e assegura um total de $57 de valor, então devemos simplesmente remover o recurso e, se necessário, pagar às vítimas $57 do próprio bolso.

O problema social mais amplo está em criar um pipeline padronizado para fazer alterações que quebram a compatibilidade reversa, mas não são de emergência. Uma maneira de abordar isso é examinar e estender precedentes existentes, como o processo SELFDESTRUCT. O pipeline parece algo como o seguinte:

  • Passo 1: comece a falar sobre a remoção do recurso X
  • Passo 2: fazer uma análise para identificar o quanto a remoção de X prejudica as aplicações, dependendo dos resultados, (i) abandonar a ideia, (ii) prosseguir como planejado ou (iii) identificar uma maneira modificada e menos disruptiva de remover X e prosseguir com isso.
  • Passo 3: fazer um EIP formal para descontinuar X. Certifique-se de que a infraestrutura popular de nível mais alto (por exemplo, linguagens de programação, carteiras) respeite isso e pare de usar esse recurso.
  • Passo 4: finalmente, remover X realmente

Deve haver um pipeline de vários anos entre a etapa 1 e a etapa 4, com informações claras sobre quais itens estão em qual etapa. Nesse ponto, há um equilíbrio entre o quão vigoroso e rápido é o pipeline de remoção de recursos, em comparação com ser mais conservador e investir mais recursos em outras áreas de desenvolvimento do protocolo, mas ainda estamos longe da fronteira de Pareto.

EOF

Um conjunto importante de alterações que foi proposto para o EVM é oFormato do Objeto EVM (EOF). EOF introduz um grande número de mudanças, como proibir a observabilidade de gás, observabilidade de código (ou seja, sem CODECOPY), permitindo apenas saltos estáticos. O objetivo é permitir que a EVM seja atualizada de forma mais forte, preservando a compatibilidade com versões anteriores (pois a EVM pré-EOF ainda existirá).

Isso tem a vantagem de criar um caminho natural para adicionar novas funcionalidades do EVM e incentivar a migração para um EVM mais restritivo com garantias mais fortes. Tem a desvantagem de aumentar significativamente a complexidade do protocolo, a menos que possamos encontrar uma maneira de eventualmente descontinuar e remover o antigo EVM. Uma grande questão é: qual papel o EOF desempenha nas propostas de simplificação do EVM, especialmente se o objetivo é reduzir a complexidade do EVM como um todo?

Como interage com outras partes do roteiro?

Muitas das propostas de “melhoria” no resto do roteiro também são oportunidades para simplificar recursos antigos. Para repetir alguns exemplos acima:

  • Ao mudar para uma finalidade de slot único, temos a oportunidade de remover comitês, reformular a economia e realizar outras simplificações relacionadas ao proof-of-stake.
  • A implementação total da abstração de contas nos permite remover muita lógica de manipulação de transações existente, movendo-a para um pedaço de 'código EVM de conta padrão' que poderia substituir todas as EOAs.
  • Se movermos o estado do Ethereum para árvores de hash binárias, isso poderia ser harmonizado com uma nova versão de SSZ, de modo que todas as estruturas de dados do Ethereum pudessem ser hashadas da mesma maneira.

Uma abordagem mais radical: transformar grandes partes do protocolo em código de contrato

Uma estratégia de simplificação mais radical do Ethereum é manter o protocolo como está, mas mover grandes partes dele de serem recursos do protocolo para ser código de contrato.

A versão mais extrema disso seria fazer com que o Ethereum L1 fosse "tecnicamente" apenas a cadeia de beacons e introduzir uma VM mínima (por exemplo.RISC-V, Cairo, ou algo ainda mais minimalista especializado em provar sistemas) que permite a qualquer outra pessoa criar seu próprio rollup. A EVM então se tornaria o primeiro desses rollups. Ironicamente, esse é exatamente o mesmo resultado que o propostas de ambiente de execução de 2019-20, embora SNARKs tornem significativamente mais viável a implementação real.

Uma abordagem mais moderada seria manter a relação entre a cadeia de faróis e o ambiente de execução atual do Ethereum como está, mas fazer uma troca no local da EVM. Poderíamos escolher RISC-V, Cairo ou outra VM para ser a nova 'VM oficial do Ethereum' e, em seguida, converter forçadamente todos os contratos EVM em código da nova VM que interpreta a lógica do código original (compilando ou interpretando-o). Teoricamente, isso poderia até ser feito com a 'VM de destino' sendo uma versão do EOF.

Aviso Legal:

  1. Este artigo é reproduzido a partir de [Vitalik Buterin], Todos os direitos autorais pertencem ao autor original [Vitalik Buterin]. Se houver objeções a esta reprodução, por favor, entre em contato com o Aprenda Gateequipe, e eles cuidarão disso prontamente.
  2. Isenção de responsabilidade: As opiniões expressas neste artigo são exclusivamente do autor e não constituem qualquer conselho de investimento.
  3. As traduções do artigo para outros idiomas são feitas pela equipe de aprendizado do gate. A menos que mencionado, copiar, distribuir ou plagiar os artigos traduzidos é proibido.

Possíveis futuros do protocolo Ethereum, parte 5: O Purge

Avançado11/5/2024, 12:46:30 PM
Um dos desafios que o Ethereum enfrenta é o crescimento do inchaço de dados históricos e da complexidade do protocolo ao longo do tempo. Os principais objetivos de The Purge são reduzir os requisitos de armazenamento do cliente, minimizando ou eliminando a necessidade de cada nó armazenar permanentemente todos os registros históricos e até o estado final; e reduzir a complexidade do protocolo, removendo recursos desnecessários.

Um dos desafios do Ethereum é que, por padrão, o inchaço e a complexidade do protocolo de qualquer blockchain aumentam ao longo do tempo. Isso acontece em dois lugares:

  • Dados históricos: qualquer transação realizada e qualquer conta criada em qualquer momento da história precisa ser armazenada por todos os clientes para sempre e baixada por quaisquer novos clientes que façam uma sincronização completa com a rede. Isso faz com que a carga do cliente e o tempo de sincronização continuem aumentando ao longo do tempo, mesmo que a capacidade da cadeia permaneça a mesma.
  • Recursos do protocolo: é muito mais fácil adicionar uma nova funcionalidade do que remover uma antiga, causando um aumento na complexidade do código ao longo do tempo.

Para que o Ethereum se sustente a longo prazo, precisamos de uma forte contra-pressão contra essas duas tendências, reduzindo a complexidade e o inchaço ao longo do tempo. Mas, ao mesmo tempo, precisamos preservar uma das principais propriedades que tornam as blockchains excelentes: sua permanência. Você pode colocar um NFT, uma mensagem de amor nos dados de transação ou um contrato inteligente contendo um milhão de dólares na cadeia, entrar em uma caverna por dez anos, sair e encontrá-lo ainda lá, esperando que você leia e interaja com ele. Para que os dapps se sintam confortáveis em se tornar completamente descentralizados e remover suas chaves de atualização, eles precisam ter confiança de que suas dependências não vão ser atualizadas de uma forma que os prejudique - especialmente a L1 em si.

A Purge, roteiro de 2023.

Equilibrar entre essas duas necessidades, e minimizar ou reverter a inflação, complexidade e decadência, enquanto preservamos a continuidade, é absolutamente possível se nos dedicarmos a isso. Os organismos vivos podem fazer isso: enquanto a maioria envelhece com o tempo, alguns sortudos não. Mesmo os sistemas sociais podem tem longevidade extrema. Em algumas ocasiões, o Ethereum já mostrou sucessos: a prova de trabalho se foi, o opcode SELFDESTRUCT está quase extinto, e os nós da cadeia de beacon já armazenam dados antigos por apenas seis meses. Descobrir esse caminho para o Ethereum de forma mais generalizada e avançar em direção a um resultado final estável a longo prazo é o desafio supremo da escalabilidade a longo prazo, sustentabilidade técnica e até segurança do Ethereum.

A Purga: principais objetivos

  • Reduzir os requisitos de armazenamento do cliente, reduzindo ou removendo a necessidade de cada nó armazenar permanentemente todo o histórico, e talvez até mesmo o estado eventualmente
  • Reduzindo a complexidade do protocolo eliminando recursos desnecessários

Neste capítulo

Expiração de histórico

Que problema isso resolve?

No momento da redação deste texto, um nó Ethereum totalmente sincronizado requeraproximadamente 1,1 terabytesde espaço em disco para ocliente de execução, mais algumas centenas de gigabytes para o cliente de consenso. A grande maioria disso é história: dados sobre blocos históricos, transações e recibos, a maior parte dos quais tem muitos anos. Isso significa que o tamanho de um nó continua aumentando em centenas de gigabytes a cada ano, mesmo se o limite de gás não aumentar.

O que é isso e como funciona?

Um recurso de simplificação-chave do problema de armazenamento de histórico é que, como cada bloco aponta para o bloco anterior por meio de um link de hash (eoutro estruturas), ter consenso sobre o presente é suficiente para ter consenso sobre a história. Desde que a rede tenha consenso sobre o último bloco, qualquer bloco histórico, transação ou estado (saldo da conta, nonce, código, armazenamento) pode ser fornecido por qualquer ator único, juntamente com uma prova de Merkle, e a prova permite que qualquer outra pessoa verifique sua correção. Embora o consenso seja um modelo de confiança N/2-de-N, a história é um modelo de confiança 1-de-N.

Isso abre muitas opções para como podemos armazenar o histórico. Uma opção natural é uma rede onde cada nó armazena apenas uma pequena porcentagem dos dados. É assim que as redes de torrent funcionam há décadas: enquanto a rede como um todo armazena e distribui milhões de arquivos, cada participante armazena e distribui apenas alguns deles. Talvez de forma contraintuitiva, essa abordagem não diminui necessariamente a robustez dos dados. Se, tornando a execução do nó mais acessível, pudermos chegar a uma rede com 100.000 nós, onde cada nó armazena aleatoriamente 10% do histórico, então cada parte dos dados seria replicada 10.000 vezes - exatamente o mesmo fator de replicação de uma rede de 10.000 nós onde cada nó armazena tudo.

Hoje, o Ethereum já começou a se afastar do modelo de todos os nós armazenando todo o histórico para sempre. Blocos de consenso (ou seja, as partes relacionadas ao consenso de participação) são armazenados apenas por ~6 meses. Blobs são armazenados apenas por ~18 dias.EIP-4444O objetivo é introduzir um período de armazenamento de um ano para blocos e recibos históricos. Um objetivo a longo prazo é ter um período harmonizado (que poderia ser de cerca de 18 dias) durante o qual cada nó é responsável por armazenar tudo e, em seguida, ter uma rede peer-to-peer composta por nós Ethereum armazenando dados mais antigos de forma distribuída.

Os códigos de apagamento podem ser usados para aumentar a robustez mantendo o mesmo fator de replicação. De fato, os blobs já vêm com códigos de apagamento para suportar a amostragem de disponibilidade de dados. A solução mais simples pode ser reutilizar esse código de apagamento e colocar os dados de bloco de execução e consenso em blobs também.

O que resta fazer e quais são os tradeoffs?

O trabalho principal restante envolve a construção e integração de uma solução distribuída concreta para armazenar o histórico - pelo menos o histórico de execução, mas também eventualmente o consenso e os blobs. As soluções mais simples para isso são (i) simplesmente introduzir uma biblioteca de torrents existente e (ii) uma solução nativa do Ethereum chamada gate.a rede Portal. Uma vez que qualquer um deles seja introduzido, podemos ativar o EIP-4444. O próprio EIP-4444 não requer um hard fork, embora exija uma nova versão de protocolo de rede. Por essa razão, há valor em habilitá-lo para todos os clientes ao mesmo tempo, porque caso contrário há riscos de mau funcionamento dos clientes ao se conectarem a outros nós esperando fazer o download de todo o histórico, mas na verdade não o obtendo.

O principal trade-off envolve o quão duro tentamos tornar os dados históricos 'antigos' disponíveis. A solução mais fácil seria simplesmente parar de armazenar a história antiga amanhã e confiar em nós de arquivo existentes e vários provedores centralizados para replicação. Isso é fácil, mas enfraquece a posição do Ethereum como um lugar para fazer registros permanentes. O caminho mais difícil, mas mais seguro, é primeiro construir e integrar a rede torrent para armazenar a história de maneira distribuída. Aqui, há duas dimensões de 'quão duro tentamos':

  1. Quão difícil nós tentamos garantir que um conjunto maximamente grande de nós realmente esteja armazenando todos os dados?
  2. Até que ponto integramos o armazenamento histórico no protocolo?

Uma abordagem maximamente paranóica para (1) envolveriaprova de custódia: na verdade, exigindo que cada validador de prova de participação armazene uma certa porcentagem de histórico e verifique regularmente criptograficamente se eles o fazem. Uma abordagem mais moderada é estabelecer um padrão voluntário para qual porcentagem de histórico cada cliente armazena.

Para (2), uma implementação básica envolve apenas pegar o trabalho que já é feito hoje: Portal já armazena arquivos ERA contendo todo o histórico do Ethereum. Uma implementação mais completa envolveria realmente conectar isso ao processo de sincronização, para que se alguém quisesse sincronizar um nó de armazenamento de histórico completo ou um nó de arquivo, eles pudessem fazê-lo mesmo se nenhum outro nó de arquivo existisse online, sincronizando diretamente da rede Portal.

Como ele interage com outras partes do roteiro?

Reduzir os requisitos de armazenamento de histórico é possivelmente ainda mais importante do que a ausência de estado, se quisermos tornar extremamente fácil executar ou iniciar um nó: dos 1,1 TB necessários para um nó, cerca de 300 GB são de estado, e os restantes 800 GB são de histórico. A visão de um nó Ethereum funcionando em um relógio inteligente e levando apenas alguns minutos para ser configurado só é possível se a ausência de estado e o EIP-4444 forem implementados.

Limitar o armazenamento de histórico também torna mais viável que novas implementações de nós Ethereum suportem apenas versões recentes do protocolo, o que permite que sejam muito mais simples. Por exemplo, muitas linhas de código podem ser removidas com segurança agora que todos os espaços de armazenamento vazios criados durante os ataques DoS de 2016 foram...removido. Agora que a transição para o proof of stake é história antiga, os clientes podem remover com segurança todo o código relacionado ao proof-of-work.

Expiração do estado

Qual problema ele resolve?

Mesmo que removamos a necessidade de os clientes armazenarem o histórico, o requisito de armazenamento de um cliente continuará a crescer, em cerca de 50 GB por ano, devido ao crescimento contínuo do estado: saldos e nonces de contas, código de contrato e armazenamento de contrato. Os usuários podem pagar um custo único para impor um fardo aos clientes presentes e futuros do Ethereum para sempre.

O estado é muito mais difícil de “expirar” do que o histórico, porque o EVM é fundamentalmente projetado com a suposição de que, uma vez que um objeto de estado é criado, ele estará sempre lá e pode ser lido por qualquer transação a qualquer momento. Se introduzirmos a ausência de estado, há um argumento de que talvez esse problema não seja tão ruim assim: apenas uma classe especializada de construtores de blocos precisaria armazenar o estado de fato, e todos os outros nós (mesmo lista de inclusãoprodução!) pode ser executado sem estado. No entanto, há um argumento de que não queremos depender muito do estado de não ter e, eventualmente, podemos querer expirar o estado para manter o Ethereum descentralizado.

O que é isso e como funciona?

Hoje, quando você cria um novo objeto de estado (o que pode acontecer de três maneiras: (i) enviando ETH para uma nova conta, (ii) criando uma nova conta com código, (iii) definindo um slot de armazenamento previamente não utilizado), esse objeto de estado fica no estado para sempre. O que queremos, em vez disso, é que os objetos expirem automaticamente com o tempo. O desafio chave é fazer isso de uma maneira que alcance três objetivos:

  1. Eficiência: não requer grandes quantidades de cálculos extras para executar o processo de expiração
  2. Facilidade de uso: se alguém entrar em uma caverna por cinco anos e voltar, não deve perder o acesso ao seu ETH, ERC20s, NFTs, posições CDP...
  3. Facilidade para desenvolvedores: os desenvolvedores não devem ter que mudar para um modelo mental completamente desconhecido. Além disso, aplicativos que estão ossificados hoje e não são atualizados devem continuar funcionando razoavelmente bem.

É fácil resolver o problema sem atingir esses objetivos. Por exemplo, você pode fazer com que cada objeto de estado também armazene um contador para sua data de expiração (que pode ser estendida gravando ETH, o que pode acontecer automaticamente sempre que for lido ou gravado) e ter um processo que percorra o estado para remover objetos de estado expirados. No entanto, isso introduz computação extra (e até mesmo requisitos de armazenamento), e definitivamente não satisfaz o requisito de facilidade de uso. Os desenvolvedores também teriam dificuldade em raciocinar sobre casos de borda envolvendo valores de armazenamento, às vezes redefinidos para zero. Se você tornar o contrato de temporizador de expiração amplo, isso torna a vida tecnicamente mais fácil para os desenvolvedores, mas torna a economia mais difícil: os desenvolvedores teriam que pensar em como "repassar" os custos contínuos de armazenamento para seus usuários.

Esses são problemas com os quais a comunidade de desenvolvimento central do Ethereum lutou por muitos anos, incluindo propostas como “aluguel de blockchain“ e “regenesis". Eventualmente, combinamos as melhores partes das propostas e convergimos em duas categorias de "soluções conhecidas menos ruins":

  • Soluções parciais de expiração de estado
  • Propostas de expiração de estado baseadas em períodos de endereço.

Expiração parcial de estado

As propostas de expiração parcial do estado funcionam todos com o mesmo princípio. Dividimos o estado em pedaços. Todos armazenam permanentemente o “mapa de nível superior” de quais pedaços estão vazios ou não vazios. Os dados dentro de cada pedaço são armazenados apenas se esses dados tiverem sido acessados recentemente. Existe um mecanismo de “ressurreição” onde, se um pedaço não estiver mais armazenado, qualquer pessoa pode trazer esses dados de volta fornecendo uma prova do que os dados eram.

As principais distinções entre essas propostas são: (i) como definimos 'recentemente' e (ii) como definimos 'chunk'? Uma proposta concreta é EIP-7736, que se baseia no design “stem-and-leaf”introduzido para árvores Verkle (embora compatível com qualquer forma de estado sem estado, por exemplo, árvores binárias). Nesse design, cabeçalho, código e slots de armazenamento que são adjacentes entre si são armazenados sob o mesmo “ramo”. Os dados armazenados embaixo de um ramo podem ter no máximo 256 * 31 = 7.936 bytes. Em muitos casos, todo o cabeçalho e código, e muitos slots de armazenamento-chave, de uma conta serão armazenados sob o mesmo ramo. Se os dados embaixo de um determinado ramo não forem lidos ou gravados por 6 meses, os dados não são mais armazenados, e apenas um compromisso de 32 bytes (“stub”) para os dados é armazenado. Transações futuras que acessam esses dados precisariam “ressuscitar” os dados, com uma prova que seria verificada em relação ao stub.

Existem outras maneiras de implementar uma ideia semelhante. Por exemplo, se a granularidade ao nível da conta não for suficiente, poderíamos criar um esquema em que cada fração de 1/232 da árvore seja governada por um mecanismo semelhante haste-e-folha.

Isso é mais complicado por causa dos incentivos: um atacante poderia forçar os clientes a armazenar permanentemente uma quantidade muito grande de estado colocando uma quantidade muito grande de dados em uma única subárvore e enviando uma única transação a cada ano para 'renovar a árvore'. Se você fizer com que o custo de renovação seja proporcional (ou a duração de renovação inversamente proporcional) ao tamanho da árvore, então alguém poderia prejudicar outro usuário colocando uma quantidade muito grande de dados na mesma subárvore que eles. Pode-se tentar limitar ambos os problemas tornando a granularidade dinâmica com base no tamanho da subárvore: por exemplo, cada 216 = 65536 objetos de estado consecutivos poderiam ser tratados como um 'grupo'. No entanto, essas ideias são mais complexas; a abordagem baseada em caule é simples e alinha os incentivos, porque geralmente todos os dados sob um caule estão relacionados à mesma aplicação ou usuário.

Propostas de expiração de estado baseadas em períodos de endereço

E se quisermos evitar qualquer crescimento de estado permanente, mesmo com stubs de 32 bytes? Este é um problema difícil por causa de @vbuterin/state_size_management#Conflitos_de_r ressurreição": e se um objeto de estado for removido, a execução do EVM posteriormente coloca outro objeto de estado na mesma posição exata, mas depois disso alguém que se importa com o objeto de estado original volta e tenta recuperá-lo? Com a expiração parcial do estado, o "stub" impede a criação de novos dados. Com a expiração completa do estado, não podemos nos dar ao luxo de armazenar nem mesmo o "stub".

O design baseado em período de endereço é a ideia mais conhecida para resolver isso. Em vez de ter uma árvore de estado armazenando todo o estado, temos uma lista de árvores de estado em constante crescimento, e qualquer estado que é lido ou escrito é salvo na árvore de estado mais recente. Uma nova árvore de estado vazia é adicionada uma vez por período (pense: 1 ano). As árvores de estado mais antigas são sólidas congeladas. Espera-se que os nós completos armazenem apenas as duas árvores mais recentes. Se um objeto de estado não foi tocado por dois períodos e, portanto, cai em uma árvore expirada, ele ainda pode ser lido ou gravado, mas a transação precisaria provar uma prova de Merkle para ele - e uma vez que isso aconteça, uma cópia será salva na árvore mais recente novamente.

Uma ideia-chave para tornar tudo isso amigável para usuários e desenvolvedores é o conceito de períodos de endereço. Um período de endereço é um número que faz parte de um endereço. Uma regra importante é que um endereço com período de endereço N só pode ser lido ou gravado durante ou após o período N (ou seja, quando a lista de árvores de estado atinge o comprimento N). Se você estiver salvando um novo objeto de estado (por exemplo, um novo contrato ou um novo saldo ERC20), se certificar de colocar o objeto de estado em um contrato cujo período de endereço seja N ou N-1, você pode salvá-lo imediatamente, sem precisar fornecer provas de que não havia nada lá antes. No entanto, qualquer adição ou edição de estado em períodos de endereço mais antigos requer uma prova.

Este design preserva a maioria das propriedades atuais do Ethereum, é muito leve em termos de computação extra, permite que as aplicações sejam escritas quase como são hoje (ERC20s precisarão ser reescritas, para garantir que os saldos de endereços com período de endereço N sejam armazenados em um contrato filho que também tem período de endereço N) e resolve o problema de "o usuário entra em uma caverna por cinco anos". No entanto, ele tem um grande problema: os endereços precisam ser expandidos além de 20 bytes para caber nos períodos de endereço.

Extensão do espaço de endereçamento

Uma proposta é introduzir um novo formato de endereço de 32 bytes, que inclui um número de versão, um número de período de endereço e um hash expandido.

0x01000000000157aE408398dF7E5f4552091A69125d5dFcb7B8C2659029395bdF

O vermelho é um número de versão. Os quatro zeros coloridos de laranja aqui são destinados como espaço vazio, que poderia caber um número de shard no futuro. O verde é um número de período de endereço. O azul é um hash de 26 bytes.

O desafio aqui é a compatibilidade retroativa. Contratos existentes são projetados em torno de endereços de 20 bytes e muitas vezes usam técnicas de compactação de byte apertado que assumem explicitamente que os endereços têm exatamente 20 bytes de comprimento.@ipsilon/address-space-extension-exploration">Uma ideia para resolver isso envolve um mapa de tradução, onde contratos no estilo antigo interagindo com endereços no estilo novo veriam um hash de 20 bytes do endereço no estilo novo. No entanto, existem complexidades significativas envolvidas em tornar isso seguro.

Contração do espaço de endereçamento

Outra abordagem segue a direção oposta: imediatamente proibimos uma subfaixa de endereços de tamanho 2128 (por exemplo, todos os endereços que começam com 0xffffffff) e, em seguida, usamos essa faixa para introduzir endereços com períodos de endereço e hashes de 14 bytes.

0xfffffff000169125d5dFcb7B8C2659029395bdF

O sacrifício-chave que esta abordagem faz é queintroduz riscos de segurança para endereços contrafactuais: endereços que possuem ativos ou permissões, mas cujo código ainda não foi publicado na cadeia. O risco envolve alguém criando um endereço que afirma ter um pedaço de código (ainda não publicado), mas também tem outro pedaço válido de código que faz hash para o mesmo endereço. Calcular tal colisão requer 280hashes hoje; a contração do espaço de endereço reduziria esse número para um 2 muito acessível56hashes.

A área de risco chave, endereços contrafactuais que não são carteiras mantidas por um único proprietário, é um caso relativamente raro hoje, mas provavelmente se tornará mais comum à medida que entramos em um mundo multi-L2. A única solução é simplesmente aceitar esse risco, mas identificar todos os casos de uso comuns onde isso pode ser um problema e encontrar soluções eficazes.

O que resta fazer e quais são os tradeoffs?

Vejo quatro caminhos viáveis para o futuro:

  • Fazemos apatridia e nunca introduzimos a caducidade estatal. O estado está em constante crescimento (embora lentamente: podemos não vê-lo ultrapassar 8 TB por décadas), mas só precisa ser mantido por uma classe relativamente especializada de usuários: nem mesmo os validadores de PoS precisariam do estado. \
    \
    A única função que precisa de acesso a partes do estado é a produção da lista de inclusão, mas podemos realizar isso de forma descentralizada: cada usuário é responsável por manter a parte da árvore de estado que contém suas próprias contas. Quando eles transmitem uma transação, eles a transmitem com uma prova dos objetos de estado acessados durante a etapa de verificação (isso funciona tanto para EOAs quanto para contas ERC-4337). Validadores sem estado podem então combinar essas provas em uma prova para toda a lista de inclusão.
  • Fazemos expiração parcial de estado e aceitamos uma taxa muito menor, mas ainda não nula, de crescimento do tamanho permanente do estado. Este resultado é semelhante, argumentavelmente, a como propostas de expiração de histórico envolvendo redes peer-to-peer aceitam uma taxa muito menor, mas ainda não nula, de crescimento do armazenamento permanente de histórico de cada cliente que precisa armazenar uma porcentagem baixa, mas fixa, dos dados históricos.
  • Realizamos a expiração do estado, com expansão do espaço de endereços. Isso envolverá um processo de vários anos para garantir que a abordagem de conversão de formato de endereço funcione e seja segura, inclusive para aplicativos existentes.
  • Fazemos a expiração de estado, com contração do espaço de endereços. Isso envolverá um processo de vários anos para garantir que todos os riscos de segurança envolvendo colisões de endereços, incluindo situações entre cadeias, sejam tratados.

Um ponto importante é que as questões difíceis em torno da expansão e contração do espaço de endereço terão que ser abordadas eventualmente, independentemente de as políticas de expiração de estado que dependem de alterações no formato do endereço serem ou não implementadas. Hoje, leva aproximadamente 280 hashes para gerar uma colisão de endereço, uma carga computacional que já é viável para atores extremamente bem dotados de recursos: uma GPU pode fazer cerca de 227 hashes, então, executando por um ano, ele pode calcular 252, então todos ~2^30 GPUs no mundopoderia calcular uma colisão em ~1/4 de ano, e FPGAs e ASICs poderiam acelerar isso ainda mais. No futuro, tais ataques estarão disponíveis para cada vez mais pessoas. Assim, o custo real de implementar a expiração completa do estado pode não ser tão alto quanto parece, já que temos que resolver esse problema de endereço muito desafiador de qualquer maneira.

Como interage com outras partes do roteiro?

Fazer a expiração de estado potencialmente torna as transições de um formato de árvore de estado para outro mais fácil, porque não haverá necessidade de um procedimento de transição: você pode simplesmente começar a fazer novas árvores usando um novo formato e, mais tarde, fazer um hard fork para converter as árvores mais antigas. Assim, embora a expiração do estado seja complexa, ela tem benefícios na simplificação de outros aspectos do roteiro.

Limpeza de recursos

Quais problemas ele resolve?

Uma das condições prévias fundamentais de segurança, acessibilidade e neutralidade credívelé a simplicidade. Se um protocolo é bonito e simples, reduz a chance de haver bugs. Aumenta a chance de novos desenvolvedores serem capazes de entrar e trabalhar com qualquer parte dele. É mais provável que seja justo e mais fácil de defender contra interesses especiais. Infelizmente, os protocolos, como qualquer sistema social, por padrão tornam-se mais complexos com o tempo. Se não quisermos que o Ethereum entre em um buraco negro de complexidade cada vez maior, precisamos fazer uma das duas coisas: (i) parar de fazer mudanças e ossificar o protocolo, (ii) ser capaz de realmente remover recursos e reduzir a complexidade. Um caminho intermediário, de fazer menos mudanças no protocolo e também remover pelo menos um pouco de complexidade ao longo do tempo, também é possível. Esta seção falará sobre como podemos reduzir ou remover complexidade.

O que é isso e como funciona?

Não há uma grande solução única que possa reduzir a complexidade do protocolo; a natureza inerente do problema é que há muitas pequenas soluções.

Um exemplo que está principalmente concluído e pode servir como um modelo de como lidar com os outros é o @vbuterin/selfdestruct">remoção do opcode SELFDESTRUCT. O opcode SELFDESTRUCT era o único opcode que poderia modificar um número ilimitado de slots de armazenamento dentro de um único bloco, exigindo que os clientes implementassem significativamente mais complexidade para evitar ataques de DoS. O objetivo original do opcode era permitir a limpeza voluntária do estado, permitindo que o tamanho do estado diminuísse ao longo do tempo. Na prática, muito poucos acabaram usando.opcode foi nerfadopara permitir apenas contas auto-destrutivas criadas na mesma transação na atualização Dencun. Isso resolve o problema de DoS e permite uma simplificação significativa no código do cliente. No futuro, provavelmente faz sentido remover eventualmente a opcode completamente.

Alguns exemplos-chave de oportunidades de simplificação de protocolo que foram identificadas até agora incluem o seguinte. Primeiro, alguns exemplos que estão fora do EVM; estes são relativamente não invasivos e, portanto, mais fáceis de obter consenso e implementar em um prazo mais curto.

  • Transição RLP → SSZ: originalmente, objetos Ethereum eram serializados usando uma codificação chamada RLPRLP é não tipado e desnecessariamente complexo. Hoje, a cadeia de beacons usaSSZ, que é significativamente melhor em muitos aspectos, incluindo o suporte não apenas à serialização, mas também ao hashing. Eventualmente, queremos nos livrar completamente do RLP e mover todos os tipos de dados para serem estruturas SSZ, o que por sua vez facilitaria muito a atualização. EIPs atuais para isso incluem [1] [2] [3].
  • Remoção de tipos de transações antigos: hoje existem muitos tipos de transações, muitos deles poderiam ser potencialmente removidos. Uma alternativa mais moderada à remoção completa é um recurso de abstração de conta, pelo qual contas inteligentes poderiam incluir o código para processar e verificar transações no estilo antigo, se assim o desejarem.
  • Reforma de LOG: os logs criam filtros de bloom e outras lógicas que adicionam complexidade ao protocolo, mas não são realmente usados pelos clientes porque são muito lentos. Nós poderíamos remover esses recursose em vez disso, se esforçar em alternativas, como ferramentas de leitura de log descentralizadas fora do protocolo que usam tecnologia moderna como SNARKs.
  • Remoção eventual do mecanismo de comitê de sincronização da corrente de beacon: o mecanismo de comitê de sincronizaçãofoi originalmente introduzido para permitir a verificação de clientes leves do Ethereum. No entanto, isso adiciona uma complexidade significativa ao protocolo. Eventualmente, seremos capazes deverificar a camada de consenso do Ethereum diretamente usando SNARKs, o que eliminaria a necessidade de um protocolo de verificação de cliente leve dedicado. Potencialmente, alterações no consenso poderiam nos permitir remover os comitês de sincronização ainda mais cedo, criando um protocolo de cliente leve mais 'nativo' que envolve a verificação de assinaturas de um subconjunto aleatório dos validadores de consenso do Ethereum.
  • Harmonização do formato de dados: hoje, o estado de execução é armazenado em uma árvore de Patricia Merkle, o estado de consenso é armazenado em um árvore SSZ, e os blobs são comprometidos com @vbuterin#Qual é o formato dos dados de blob e como eles são commitados">Compromissos KZG. No futuro, faz sentido criar um único formato unificado para os dados de bloco e um único formato unificado para o estado. Esses formatos cobririam todas as necessidades importantes: (i) provas fáceis para clientes sem estado, (ii) serialização e codificação por apagamento para dados, (iii) estruturas de dados padronizadas.
  • Remoção dos comitês da cadeia de beacons: esse mecanismo foi originalmente introduzido para suportar umversão particular de shard de execução. Em vez disso, acabamos fazendo shardagem por meio de L2s e blobs. Portanto, comissões são desnecessárias e, portanto, há um em movimento em direção à remoção deles.
  • Remoção de mistura de endianidade: o EVM é big-endian e a camada de consenso é little-endian. Pode fazer sentido re-harmonizar e tornar tudo uma coisa ou outra (provavelmente big-endian, porque o EVM é mais difícil de mudar)

Agora, alguns exemplos que estão dentro do EVM:

  • Simplificação da mecânica de gás: as regras atuais de gás não são bem otimizadas para dar limites claros à quantidade de recursos necessários para verificar um bloco. Exemplos-chave incluem (i) custos de leitura/gravação de armazenamento, que pretendem limitar o número de leituras/escritas em um bloco, mas atualmente são bastante caóticos, e (ii) regras de preenchimento de memória, onde atualmente é difícil estimar o consumo máximo de memória do EVM. As correções propostas incluem mudanças de custo de gás de estado sem estado, que harmonizam todos os custos relacionados ao armazenamento em uma fórmula simples e,esta proposta para precificação de memória.
  • Remoção de pré-compilações: muitas das pré-compilações que o Ethereum possui hoje são desnecessariamente complexas e relativamente não utilizadas, e compõem uma grande porcentagem de falhas quase-misses de consenso, sem serem de fato utilizadas por quaisquer aplicativos. Duas maneiras de lidar com isso são (i) simplesmente remover a pré-compilação e (ii) substituí-la por um pedaço (inevitavelmente mais caro) de código EVM que implementa a mesma lógica.Este rascunho EIP propõepara fazer isso para o precompilado de identidade como primeiro passo; mais tarde, RIPEMD160, MODEXP e BLAKE podem ser candidatos para remoção.
  • Remoção da observabilidade do gás: fazer com que a execução do EVM não consiga mais ver quanto gás resta. Isso quebraria algumas aplicações (principalmente transações patrocinadas), mas permitiria atualizações muito mais fáceis no futuro (por exemplo, para versões mais avançadas degás multidimensional. AEspecificação de EOFjá torna o gás não observável, embora para ser útil para simplificação do protocolo EOF precisaria se tornar obrigatório.
  • Melhorias na análise estática: hoje, o código EVM é difícil de analisar estaticamente, especialmente porque os saltos podem ser dinâmicos. Isso também torna mais difícil fazer implementações EVM otimizadas que pré-compilam o código EVM em alguma outra linguagem. Potencialmente, podemos corrigir isso porremovendo saltos dinâmicos(ou tornando-os muito mais caros, por exemplo, custo de gás linear no número total de JUMPDESTs em um contrato). EOF faz isso, embora obter ganhos de simplificação do protocolo a partir disso exigiria tornar o EOF obrigatório.

O que resta fazer e quais são os compromissos?

O principal tradeoff ao fazer esse tipo de simplificação de recurso é (i) o quanto simplificamos e o quão rápido vs (ii) compatibilidade com versões anteriores. O valor do Ethereum como uma cadeia vem do fato de ser uma plataforma onde você pode implantar um aplicativo e ter a confiança de que ele ainda funcionará por muitos anos. Ao mesmo tempo, é possível levar esse ideal longe demais e,parafrasear William Jennings Bryan"crucificar o Ethereum em uma cruz de compatibilidade reversa". Se houver apenas duas aplicações em todo o Ethereum que utilizam um determinado recurso, e uma delas não tem usuários há anos e a outra é quase completamente não utilizada e assegura um total de $57 de valor, então devemos simplesmente remover o recurso e, se necessário, pagar às vítimas $57 do próprio bolso.

O problema social mais amplo está em criar um pipeline padronizado para fazer alterações que quebram a compatibilidade reversa, mas não são de emergência. Uma maneira de abordar isso é examinar e estender precedentes existentes, como o processo SELFDESTRUCT. O pipeline parece algo como o seguinte:

  • Passo 1: comece a falar sobre a remoção do recurso X
  • Passo 2: fazer uma análise para identificar o quanto a remoção de X prejudica as aplicações, dependendo dos resultados, (i) abandonar a ideia, (ii) prosseguir como planejado ou (iii) identificar uma maneira modificada e menos disruptiva de remover X e prosseguir com isso.
  • Passo 3: fazer um EIP formal para descontinuar X. Certifique-se de que a infraestrutura popular de nível mais alto (por exemplo, linguagens de programação, carteiras) respeite isso e pare de usar esse recurso.
  • Passo 4: finalmente, remover X realmente

Deve haver um pipeline de vários anos entre a etapa 1 e a etapa 4, com informações claras sobre quais itens estão em qual etapa. Nesse ponto, há um equilíbrio entre o quão vigoroso e rápido é o pipeline de remoção de recursos, em comparação com ser mais conservador e investir mais recursos em outras áreas de desenvolvimento do protocolo, mas ainda estamos longe da fronteira de Pareto.

EOF

Um conjunto importante de alterações que foi proposto para o EVM é oFormato do Objeto EVM (EOF). EOF introduz um grande número de mudanças, como proibir a observabilidade de gás, observabilidade de código (ou seja, sem CODECOPY), permitindo apenas saltos estáticos. O objetivo é permitir que a EVM seja atualizada de forma mais forte, preservando a compatibilidade com versões anteriores (pois a EVM pré-EOF ainda existirá).

Isso tem a vantagem de criar um caminho natural para adicionar novas funcionalidades do EVM e incentivar a migração para um EVM mais restritivo com garantias mais fortes. Tem a desvantagem de aumentar significativamente a complexidade do protocolo, a menos que possamos encontrar uma maneira de eventualmente descontinuar e remover o antigo EVM. Uma grande questão é: qual papel o EOF desempenha nas propostas de simplificação do EVM, especialmente se o objetivo é reduzir a complexidade do EVM como um todo?

Como interage com outras partes do roteiro?

Muitas das propostas de “melhoria” no resto do roteiro também são oportunidades para simplificar recursos antigos. Para repetir alguns exemplos acima:

  • Ao mudar para uma finalidade de slot único, temos a oportunidade de remover comitês, reformular a economia e realizar outras simplificações relacionadas ao proof-of-stake.
  • A implementação total da abstração de contas nos permite remover muita lógica de manipulação de transações existente, movendo-a para um pedaço de 'código EVM de conta padrão' que poderia substituir todas as EOAs.
  • Se movermos o estado do Ethereum para árvores de hash binárias, isso poderia ser harmonizado com uma nova versão de SSZ, de modo que todas as estruturas de dados do Ethereum pudessem ser hashadas da mesma maneira.

Uma abordagem mais radical: transformar grandes partes do protocolo em código de contrato

Uma estratégia de simplificação mais radical do Ethereum é manter o protocolo como está, mas mover grandes partes dele de serem recursos do protocolo para ser código de contrato.

A versão mais extrema disso seria fazer com que o Ethereum L1 fosse "tecnicamente" apenas a cadeia de beacons e introduzir uma VM mínima (por exemplo.RISC-V, Cairo, ou algo ainda mais minimalista especializado em provar sistemas) que permite a qualquer outra pessoa criar seu próprio rollup. A EVM então se tornaria o primeiro desses rollups. Ironicamente, esse é exatamente o mesmo resultado que o propostas de ambiente de execução de 2019-20, embora SNARKs tornem significativamente mais viável a implementação real.

Uma abordagem mais moderada seria manter a relação entre a cadeia de faróis e o ambiente de execução atual do Ethereum como está, mas fazer uma troca no local da EVM. Poderíamos escolher RISC-V, Cairo ou outra VM para ser a nova 'VM oficial do Ethereum' e, em seguida, converter forçadamente todos os contratos EVM em código da nova VM que interpreta a lógica do código original (compilando ou interpretando-o). Teoricamente, isso poderia até ser feito com a 'VM de destino' sendo uma versão do EOF.

Aviso Legal:

  1. Este artigo é reproduzido a partir de [Vitalik Buterin], Todos os direitos autorais pertencem ao autor original [Vitalik Buterin]. Se houver objeções a esta reprodução, por favor, entre em contato com o Aprenda Gateequipe, e eles cuidarão disso prontamente.
  2. Isenção de responsabilidade: As opiniões expressas neste artigo são exclusivamente do autor e não constituem qualquer conselho de investimento.
  3. As traduções do artigo para outros idiomas são feitas pela equipe de aprendizado do gate. A menos que mencionado, copiar, distribuir ou plagiar os artigos traduzidos é proibido.
Comece agora
Inscreva-se e ganhe um cupom de
$100
!