Em Ethereum, os recursos eram limitados até recentemente e precificados através de um único recurso chamado “Gás”. O gás é uma unidade de medida que mede o “esforço computacional” necessário para processar uma determinada transação ou bloco. O gás reúne os tipos mais longos de “cálculos”, os mais importantes dos quais incluem:
Computação bruta (por exemplo, ADICIONAR, MULTIPLICAR);
Ler, escrever e escrever em Ethereum armazenamento (como SSTORE, SLOAD, ETH transferência);
Largura de banda de dados;
O custo de gerar provas ZK-SNARK para blocos.
Por exemplo, esta transação que enviei consumiu um total de 47.085 Gás. Estes incluem: (i) um custo base de 21.000 Gás, (ii) 1.556 Gás para os bytes de dados de chamada incluídos como parte da transação, (iii) 16.500 Gás para armazenamento de leitura e gravação, (iv) 2.149 Gás para geração de toros e o restante para execução EVM. O Lavagem de dinheiro que os usuários devem pagar é proporcional ao gás consumido pela transação. Um Bloco pode conter até 30 milhões de gás longo, e o preço do gás é continuamente ajustado através do mecanismo de segmentação EIP-1559 para garantir que cada Bloco contenha uma média de 15 milhões de gás.
Esta abordagem tem uma grande vantagem: como tudo é combinado em um único recurso virtual, o design do mercado é muito simples. É fácil otimizar transações para minimizar custos, é relativamente fácil otimizar blocos para cobrar as taxas mais altas possíveis (excluindo MEV) e não há incentivos estranhos para incentivar algumas transações a agruparem-se com outras transações para economizar taxas.
No entanto, esta abordagem apresenta ineficiências: trata os diferentes recursos como se fossem convertíveis entre si, quando as restrições subjacentes reais não são as mesmas. Para entender isso, você pode primeiro olhar para o seguinte gráfico:
A limite de gás impõe uma restrição:
As restrições de segurança subjacentes reais estão muitas vezes mais próximas de:
Essa diferença faz com que gás limites excluam injustificadamente blocos realmente seguros, aceitem blocos realmente inseguros ou ambos.
Se houver n recursos com limites de segurança diferentes, então gás unidimensionais podem fazer a taxa de transferência até longo Gota n vezes. Como resultado, longo houve interesse no conceito de gás de saudade e, com EIP-4844, agora implementamos de fato gás de saudade em Ethereum. Este artigo explora as vantagens dessa abordagem, bem como as perspetivas de melhorias adicionais.
Blob: gás mais longa em Dencun
No início deste ano, o tamanho médio dos blocos era de 150 kB. Uma grande parte disso são dados de rollup: Camada 2 protocolo armazenam dados na cadeia. Esses dados são muito caros: embora o Custo de transação no Rollup seja apenas 5-10 vezes maior do que o da transação correspondente em Ethereum L1, mesmo esse custo é muito alto para um caso de uso longo.
Então, por que não Gota o custo gás para dados de chamada (atualmente 16 gás para bytes diferentes de zero e 4 gás para zero bytes) para torná-rollups mais barato? Já fizemos isso antes, e podemos fazê-lo novamente agora. Mas a resposta aqui é que o tamanho máximo de um bloco é 30.000.000/16=1.875.000 bytes diferentes de zero, e a rede mal ou mal consegue lidar com um bloco desse tamanho. Reduzir o custo em mais 4x aumenta o máximo para 7,5 MB, o que representa um risco significativo para a segurança.
Este problema é eventualmente resolvido através da introdução de um separado, rollup-friendly dados mais curtos (chamado blob) em cada bloco.
Existem diferentes preços e limites para esses dois recursos: após o Hard Fork de Dencun, um Ethereum Bloco máximo longo pode conter (i) 30 milhões de gás e (ii) 6 blobs, cada um dos quais pode conter cerca de 125 kB de calldata. Ambos os recursos têm preços separados e são ajustados através de um mecanismo de preços separado semelhante ao EIP-1559, com o objetivo de usar uma média de 15 milhões de gás e 3 blobs por bloco.
Como resultado, o custo do Rollup foi reduzido por um fator de 100, o volume no Rollup aumentou em mais de 3 vezes, e o tamanho máximo teórico Bloco aumentou apenas ligeiramente: de cerca de 1,9 MB para cerca de 2,6 MB.
Nota: Rollup Lavagem de dinheiro, fornecido por Growthepie.xyz. A forquilha de Dencun ocorreu em 13 de março de 2024, introduzindo blobs de preços mais longos.
Clientes gás e apátridas mais longos
Em um futuro próximo, um problema semelhante surgirá com provas armazenadas para clientes apátridas. Um cliente sem estado é um novo tipo de cliente que será capaz de validar a cadeia sem ter que armazenar uma grande quantidade ou quaisquer dados localmente. Os clientes sem estado fazem isso aceitando provas de partes específicas do estado de Ethereum que as transações nesse bloco precisam acessar.
O diagrama acima mostra um cliente sem estado recebendo um Bloco e prova do valor atual de uma parte específica do estado (por exemplo, equilíbrio de contas, código, armazenamento) tocado pela execução desse Bloco, o que permite que o Nó valide um Bloco sem qualquer armazenamento.
Uma leitura de armazenamento custa de 2100 a 2600 gás, dependendo do tipo de leitura, e as gravações de armazenamento são mais caras. Em média, um bloco executa cerca de 1.000 leituras e gravações de armazenamento (incluindo verificações de saldo ETH, chamadas SSTORE e SLOAD, leituras de código de contrato e outras operações). No entanto, o máximo teórico é de 30.000.000/2.100=14.285 leituras. A carga de largura de banda de um cliente sem estado é proporcional a esse número.
O plano atual é suporte clientes apátridas, transformando o projeto de árvores do Estado da Ethereum de árvores Merkle Patricia para árvores Verkle. No entanto, as árvores Verkle não são resistentes ao quântico e não são ideais para sistemas de prova STARK mais recentes. Como resultado, as pessoas mais longas estão interessadas em apoiar clientes apátridas com árvores binárias Merkle e STARKs, ignorando completamente o Verkle ou atualizando alguns anos após a transição do Verkle, uma vez que o STARK se torna mais maduro.
As provas STARK baseadas em ramos binários hash de árvores têm longo muitas vantagens, mas sua principal fraqueza é o longo tempo que leva para gerar provas: as árvores Verkle podem provar mais de 100.000 valores por segundo, enquanto as STARKs baseadas em hash normalmente provam apenas algumas k hash por segundo, e cada valor precisa conter um “ramo” longo hash.
Considerando os números previstos hoje a partir de sistemas de prova hiperotimizados como Binius e Plonky3, bem como hashes proprietários como Vision-Mark-32, parece que estaremos em uma faixa prática por algum tempo onde provar 1000 valores por segundo é viável, mas provar 14.285 valores não é. O bloqueio médio seria bom, mas o Bloco potencialmente pior caso (publicado por um invasor) interromperia a rede.
Nossa abordagem padrão para lidar com esses casos é reprecificar: aumentar o custo de armazenamento de leituras para reduzir o máximo por bloco para um nível mais seguro. No entanto, fizemos isso longo vezes e, se o fizermos novamente, isso tornaria muito longo aplicativo muito caro. Uma abordagem melhor é a gás: limitar e cobrar o acesso ao armazenamento separadamente, mantendo o uso médio em 1.000 visitas de armazenamento por bloco, mas estabelecendo um limite máximo por bloco, como 2000.
A ubiquidade dos gás mais longos
Outro recurso que vale a pena considerar é o aumento do tamanho do estado: operações que aumentam o tamanho do estado de Ethereum, que precisam ser salvas por um nó completo. O aumento do tamanho do estado é único na medida em que a lógica para limitá-lo vem apenas do uso sustentado de longo prazo, não de picos.
Portanto, pode ser valioso adicionar uma dimensão gás separada para operações que aumentam o tamanho do estado (por exemplo, SSTORE de zero a não zero, criação de contrato), mas o objetivo é diferente: podemos definir um preço flutuante para vela de pavio longo em um uso médio específico, mas não definir um limite por Bloco.
Isso demonstra uma poderosa propriedade da gás longo-dimensional: ela nos permite vela de pavio longo cada recurso separadamente e perguntar (i) qual é o uso médio ideal longo menos? (ii) Qual é a utilização máxima segura por Bloco longo pequena? Em vez de definir o preço do gás com base no valor máximo de cada bloco e deixar o uso médio seguir, temos 2n graus de liberdade para definir 2n parâmetros, ajustando cada parâmetro de acordo com considerações de segurança de rede.
Casos mais complexos, como quando as considerações de segurança de dois recursos são parcialmente somadas, podem ser tratados fazendo com que um Código de operação ou recurso consuma uma certa quantidade de longo tipo de gás (por exemplo, um SSTORE zero a diferente de zero pode consumir 5.000 atestação gás de clientes sem estado e 20.000 gás de expansão de armazenamento).
Máximo por transação (aquele que consome mais dados ou cálculos)
Que x1 seja o custo gás dos dados e x2 seja o custo gás calculado, para que em um sistema de gás unidimensional possamos escrever o custo gás de uma transação:
Neste cenário, definimos o custo gás da transação como:
Ou seja, uma transação não é cobrada com base em dados mais cálculos, mas em qual dos dois recursos ela consome mais tempo. Isso pode ser facilmente estendido para cobrir dimensões mais longo (e.g. max(…,x3∗storage_access)).
Deve ser fácil ver como isso pode aumentar a taxa de transferência, mantendo a segurança. Teoricamente, a quantidade máxima de dados em um bloco ainda é GasLIMIT/x1, que é exatamente o mesmo que no esquema gás unidimensional. Da mesma forma, a quantidade máxima teórica de cálculo é GasLIMIT/x2, que é exatamente a mesma que em um esquema de gás unidimensional. No entanto, o custo gás de qualquer transação que consuma dados e cálculos cai.
Este é, presumivelmente, o esquema adotado no EIP-7623 proposto para reduzir o tamanho máximo do bloco e, ao mesmo tempo, aumentar ainda mais a contagem de blobs. O mecanismo preciso no EIP-7623 é um pouco mais complicado: mantém o preço atual dos dados de chamada em 16 gás por byte, mas adiciona um preço mínimo de 48 gás por byte; O maior do pagamento da transação (16 * bytes + ution_Gas) e (48 * bytes). Como resultado, o EIP-7623 reduz o máximo teórico de dados de chamada de transação em um bloco de cerca de 1,9 MB para cerca de 0,6 MB, mantendo o custo inalterado para aplicativos mais longos. A vantagem desta abordagem é que muda muito pouco em comparação com o atual esquema de gás unidimensional, tornando-a muito fácil de implementar.
No entanto, esta abordagem apresenta dois inconvenientes:
Mesmo que todas as outras transações no bloco usem apenas uma pequena quantidade desse recurso, as transações que ocupam uma grande quantidade de um recurso ainda cobrarão uma grande taxa desnecessariamente;
Incentiva transações com uso intensivo de dados e computação a se fundirem em um único pacote para economizar custos.
Na minha opinião, uma regra como EIP-7623, seja para negociação de calldata ou outros recursos, pode ser de grande benefício o suficiente para que, mesmo com essas desvantagens, valha a pena.
No entanto, se estivermos dispostos a envidar esforços de desenvolvimento (significativamente mais elevados), surgirá uma abordagem mais desejável.
Longest EIP-1559: Uma estratégia mais difícil, mas desejável
Vamos começar analisando como funciona o EIP-1559 regular. Vamos nos concentrar na versão introduzida pelo vela de pavio longo blob em EIP-4844 porque é matematicamente mais elegante.
Acompanhamos um parâmetro, o excesso_blobs. Durante cada bloco, definimos:
em que TARGET = 3. Ou seja, se o número de blobs em um Bloco for longo do que o alvo, o excesso_blobs aumenta e se o número de blobs em um Bloco for menor que o alvo, o excesso_blobs diminui. Em seguida, definimos blob_basefee = exp(excess_blobs / 25.47), onde exp é uma aproximação da função exponencial exp(x)=2.71828^x.
Ou seja, sempre que o excesso_blobs aumenta em cerca de 25, a carga base do blob aumenta em cerca de 2,7x. Se o blob se tornar muito caro, o uso médio cai e o excesso_blobs começa a diminuir, automaticamente Gota o preço novamente. O preço das bolhas é constantemente ajustado para garantir que, em média, o Bloco esteja meio cheio, ou seja, cada Bloco contém uma média de 3 bolhas.
Se houver um pico de uso de curto prazos, há um limite: cada Bloco só pode conter 6 blobs em uma longo máxima, caso em que as transações podem competir entre si aumentando a taxa de prioridade. No entanto, em circunstâncias normais, cada blob paga apenas blob_basefee mais uma pequena taxa de prioridade adicional como incentivo para ser incluído.
Este gás preços já existe em Ethereum há mais tempo: em 2020, EIP-1559 introduziu um mecanismo muito semelhante. Com EIP-4844, definimos dois preços flutuantes separados para Gás e Blobs.
Nota: A base gás cobrar por uma hora em 8 de maio de 2024, em gwei. Fonte: ultrasound.money
Em princípio, poderíamos adicionar mais longo taxas flutuantes independentes para leituras de armazenamento e outros tipos de operações, mas vou desenvolver uma questão na próxima seção.
Para os usuários, a experiência é muito semelhante à de hoje: em vez de pagar uma taxa básica, você paga duas taxas básicas, mas sua carteira pode abstraí-la de suas mãos, mostrando apenas as taxas esperadas e máximas que você pode esperar pagar.
Bloco construtores, há mais tempo, a melhor estratégia é a mesma de hoje: incluir tudo o que funciona. Blocos mais longos não estão cheios - gás ou bolhas. Uma situação desafiadora é que, quando há gás ou bolhas suficientes para exceder o limite de blocos, os construtores precisam potencialmente resolver o problema da mochila mais longa para maximizar seus lucros. No entanto, mesmo que haja uma aproximação bastante boa Algoritmo, neste caso, o ganho de otimizar os lucros formulando Algoritmo proprietária é longo menor do que o ganho de fazer o mesmo com MEV.
O principal desafio para os desenvolvedores é a necessidade de redesenhar a funcionalidade do EVM e sua infraestrutura associada, que atualmente foram projetados com base em um preço único e um limite único, e agora precisam ser adaptados para acomodar preços mais longos e limitações mais longas.
Um problema que os desenvolvedores de aplicativos enfrentam é que a otimização se torna um pouco mais difícil: em alguns casos, você não pode mais longo dizer explicitamente que A é mais eficiente do que B, porque se A usa um calldata mais longo e B usa uma execução mais longo, então quando calldata é mais barato, é mais caro quando calldata é caro.
Um problema que os desenvolvedores de aplicativos enfrentam é que a otimização se torna um pouco mais difícil: em alguns casos, você não pode dizer definitivamente que A é mais eficiente do que B, porque se A usa um calldata mais longo e B usa uma execução mais longo, então A pode ser mais barato quando calldata é barato, e A pode ser mais caro quando calldata é caro.
No entanto, os desenvolvedores ainda podem obter resultados muito bons otimizando com base em preços médios históricos de longo prazo.
Preços, EVM e subchamadas mais longos
Há um problema que não aparece em blobs, nem aparece no EIP-7623 ou mesmo na implementação completa de preços mais longos de velas de longo pavio para calldata, mas se tentarmos precificar o acesso ao estado ou qualquer outro recurso separadamente, então esse problema surge: o limite de gás em subchamadas.
Os limites de gás em EVM existem em dois lugares. Primeiro, cada transação define um limite de gás, que limita a quantidade total de gás que podem ser usados nessa transação. Em segundo lugar, quando um contrato chama outro, essa chamada pode definir o seu próprio limite de gás. Isso permite que os contratos chamem outros contratos em que não confiam e ainda garante que eles ainda tenham gás residuais para realizar outros cálculos após a chamada.
Nota: Rastreamentos de abstração de contas transações em que uma conta chama outra conta e apenas uma quantidade limitada de gás é fornecida ao destinatário para garantir que a chamada externa continue a ser executada mesmo que o destinatário consuma todos os gás alocados a ele.
O desafio é que obter gás mais longos entre diferentes tipos de execução parece exigir subchamadas para fornecer limites mais longos para cada tipo de gás, o que exigiria mudanças muito profundas no EVM e não seria compatível com os aplicativos existentes.
Esta é uma das razões pelas quais as propostas de gás mais longas normalmente permanecem em duas dimensões: dados e execução. Os dados, sejam dados de chamada transacionais ou blobs, só são distribuídos fora do EVM, portanto, nada precisa mudar dentro do EVM para que os dados de chamada ou blobs sejam precificados separadamente.
Podemos encontrar uma solução “EIP-7623-style” para resolver este problema. Esta é uma implementação simples: durante a execução, a operação de armazenamento é cobrada 4 vezes a taxa; Para simplificar a análise, vamos supor 10.000 gases por operação de armazenamento. No final da transação, o min(7500 * storage_operations, ution_Gas) é reembolsado. Como resultado, após deduzir o reembolso, o usuário é obrigado a pagar as seguintes taxas:
Isso reflete a estrutura do EIP-7623. Outra abordagem é rastrear o armazenamento_operations e ution_Gas em tempo real e cobrar 2500 ou 10000 a menos, dependendo do max(ution_Gas + 2500 * storage_operations, 10000 * storage_operations) no pump longo o momento. O Código de operação é chamado. Deste modo, evita-se a necessidade de as transações afetarem gás em excesso, que são, na sua maioria, recuperadas através de reembolsos.
Não temos um licenciamento refinado para subchamadas: as subchamadas podem consumir todas as permissões da transação para operações de armazenamento baratas.
Mas obtemos algo bom o suficiente para que o contrato que faz a subchamada possa definir um limite e garantir que, uma vez que a subchamada seja executada, a chamada principal ainda tenha gás suficientes para o pós-processamento necessário.
A “solução completa de preços mais longos” mais simples que consigo pensar é a seguinte: tratamos a limite de gás de subchamada como proporcional. Ou seja, suponha que existem k tipos de execução diferentes, e cada transação é definida com um limite mais longo L1… Lc 。 Suponha que, no ponto de execução atual, o gás restante seja g1… Gk. Suponha que você chame o Código de operação CALL e use a subchamada Gas para limitar S. Deixe s1=S, depois s2=s1/g1∗g2, s3=s1/g1∗g3 e assim por diante.
Ou seja, tratamos o primeiro tipo de gás (que na verdade é VM execução) como uma “unidade de conta” especial e, em seguida, alocamos outros tipos de gás para que a subchamada obtenha a mesma porcentagem de gás disponíveis em cada tipo de gás. Esta abordagem é um pouco feia e maximiza compatibilidade com versões anteriores.
Se quisermos tornar o esquema mais “neutro” entre diferentes tipos de gás sem sacrificar compatibilidade com versões anteriores, podemos simplesmente representar o parâmetro limite de gás da chamada de criança como parte do gás restante no contexto atual (por exemplo, [1…63]/64).
Em ambos os casos, no entanto, vale a pena enfatizar que, uma vez que você começa a introduzir gás de execução mais longa, a complexidade inerente (feiura) aumenta, o que parece difícil de evitar.
Portanto, nossa tarefa é fazer um compromisso complexo: aceitamos algum nível de aumento de feiura no nível EVM para desbloquear com segurança ganhos significativos de escalabilidade L1 e, em caso afirmativo, qual proposta específica será mais eficaz para protocolo economia e desenvolvedores de aplicativos? É provável que nenhuma das duas opções que mencionei acima seja a melhor, mas ainda há shorts para encontrar soluções mais elegantes e melhores.
Um agradecimento especial a Ansgar Dietrichs, Barnabe Monnot e Davide Crapis pelo seu feedback e revisão.
Ver original
Esta página pode conter conteúdo de terceiros, que é fornecido apenas para fins informativos (não para representações/garantias) e não deve ser considerada como um endosso de suas opiniões pela Gate nem como aconselhamento financeiro ou profissional. Consulte a Isenção de responsabilidade para obter detalhes.
Novo título da Vitalik: O que é o preço mais longo do gás?
Autor: Vitalik Buterin
Compilador: Karen, Foreisght News
Em Ethereum, os recursos eram limitados até recentemente e precificados através de um único recurso chamado “Gás”. O gás é uma unidade de medida que mede o “esforço computacional” necessário para processar uma determinada transação ou bloco. O gás reúne os tipos mais longos de “cálculos”, os mais importantes dos quais incluem:
Computação bruta (por exemplo, ADICIONAR, MULTIPLICAR);
Ler, escrever e escrever em Ethereum armazenamento (como SSTORE, SLOAD, ETH transferência);
Largura de banda de dados;
O custo de gerar provas ZK-SNARK para blocos.
Por exemplo, esta transação que enviei consumiu um total de 47.085 Gás. Estes incluem: (i) um custo base de 21.000 Gás, (ii) 1.556 Gás para os bytes de dados de chamada incluídos como parte da transação, (iii) 16.500 Gás para armazenamento de leitura e gravação, (iv) 2.149 Gás para geração de toros e o restante para execução EVM. O Lavagem de dinheiro que os usuários devem pagar é proporcional ao gás consumido pela transação. Um Bloco pode conter até 30 milhões de gás longo, e o preço do gás é continuamente ajustado através do mecanismo de segmentação EIP-1559 para garantir que cada Bloco contenha uma média de 15 milhões de gás.
Esta abordagem tem uma grande vantagem: como tudo é combinado em um único recurso virtual, o design do mercado é muito simples. É fácil otimizar transações para minimizar custos, é relativamente fácil otimizar blocos para cobrar as taxas mais altas possíveis (excluindo MEV) e não há incentivos estranhos para incentivar algumas transações a agruparem-se com outras transações para economizar taxas.
No entanto, esta abordagem apresenta ineficiências: trata os diferentes recursos como se fossem convertíveis entre si, quando as restrições subjacentes reais não são as mesmas. Para entender isso, você pode primeiro olhar para o seguinte gráfico:
A limite de gás impõe uma restrição:
As restrições de segurança subjacentes reais estão muitas vezes mais próximas de:
Essa diferença faz com que gás limites excluam injustificadamente blocos realmente seguros, aceitem blocos realmente inseguros ou ambos.
Se houver n recursos com limites de segurança diferentes, então gás unidimensionais podem fazer a taxa de transferência até longo Gota n vezes. Como resultado, longo houve interesse no conceito de gás de saudade e, com EIP-4844, agora implementamos de fato gás de saudade em Ethereum. Este artigo explora as vantagens dessa abordagem, bem como as perspetivas de melhorias adicionais.
Blob: gás mais longa em Dencun
No início deste ano, o tamanho médio dos blocos era de 150 kB. Uma grande parte disso são dados de rollup: Camada 2 protocolo armazenam dados na cadeia. Esses dados são muito caros: embora o Custo de transação no Rollup seja apenas 5-10 vezes maior do que o da transação correspondente em Ethereum L1, mesmo esse custo é muito alto para um caso de uso longo.
Então, por que não Gota o custo gás para dados de chamada (atualmente 16 gás para bytes diferentes de zero e 4 gás para zero bytes) para torná-rollups mais barato? Já fizemos isso antes, e podemos fazê-lo novamente agora. Mas a resposta aqui é que o tamanho máximo de um bloco é 30.000.000/16=1.875.000 bytes diferentes de zero, e a rede mal ou mal consegue lidar com um bloco desse tamanho. Reduzir o custo em mais 4x aumenta o máximo para 7,5 MB, o que representa um risco significativo para a segurança.
Este problema é eventualmente resolvido através da introdução de um separado, rollup-friendly dados mais curtos (chamado blob) em cada bloco.
Existem diferentes preços e limites para esses dois recursos: após o Hard Fork de Dencun, um Ethereum Bloco máximo longo pode conter (i) 30 milhões de gás e (ii) 6 blobs, cada um dos quais pode conter cerca de 125 kB de calldata. Ambos os recursos têm preços separados e são ajustados através de um mecanismo de preços separado semelhante ao EIP-1559, com o objetivo de usar uma média de 15 milhões de gás e 3 blobs por bloco.
Como resultado, o custo do Rollup foi reduzido por um fator de 100, o volume no Rollup aumentou em mais de 3 vezes, e o tamanho máximo teórico Bloco aumentou apenas ligeiramente: de cerca de 1,9 MB para cerca de 2,6 MB.
Nota: Rollup Lavagem de dinheiro, fornecido por Growthepie.xyz. A forquilha de Dencun ocorreu em 13 de março de 2024, introduzindo blobs de preços mais longos.
Clientes gás e apátridas mais longos
Em um futuro próximo, um problema semelhante surgirá com provas armazenadas para clientes apátridas. Um cliente sem estado é um novo tipo de cliente que será capaz de validar a cadeia sem ter que armazenar uma grande quantidade ou quaisquer dados localmente. Os clientes sem estado fazem isso aceitando provas de partes específicas do estado de Ethereum que as transações nesse bloco precisam acessar.
O diagrama acima mostra um cliente sem estado recebendo um Bloco e prova do valor atual de uma parte específica do estado (por exemplo, equilíbrio de contas, código, armazenamento) tocado pela execução desse Bloco, o que permite que o Nó valide um Bloco sem qualquer armazenamento.
Uma leitura de armazenamento custa de 2100 a 2600 gás, dependendo do tipo de leitura, e as gravações de armazenamento são mais caras. Em média, um bloco executa cerca de 1.000 leituras e gravações de armazenamento (incluindo verificações de saldo ETH, chamadas SSTORE e SLOAD, leituras de código de contrato e outras operações). No entanto, o máximo teórico é de 30.000.000/2.100=14.285 leituras. A carga de largura de banda de um cliente sem estado é proporcional a esse número.
O plano atual é suporte clientes apátridas, transformando o projeto de árvores do Estado da Ethereum de árvores Merkle Patricia para árvores Verkle. No entanto, as árvores Verkle não são resistentes ao quântico e não são ideais para sistemas de prova STARK mais recentes. Como resultado, as pessoas mais longas estão interessadas em apoiar clientes apátridas com árvores binárias Merkle e STARKs, ignorando completamente o Verkle ou atualizando alguns anos após a transição do Verkle, uma vez que o STARK se torna mais maduro.
As provas STARK baseadas em ramos binários hash de árvores têm longo muitas vantagens, mas sua principal fraqueza é o longo tempo que leva para gerar provas: as árvores Verkle podem provar mais de 100.000 valores por segundo, enquanto as STARKs baseadas em hash normalmente provam apenas algumas k hash por segundo, e cada valor precisa conter um “ramo” longo hash.
Considerando os números previstos hoje a partir de sistemas de prova hiperotimizados como Binius e Plonky3, bem como hashes proprietários como Vision-Mark-32, parece que estaremos em uma faixa prática por algum tempo onde provar 1000 valores por segundo é viável, mas provar 14.285 valores não é. O bloqueio médio seria bom, mas o Bloco potencialmente pior caso (publicado por um invasor) interromperia a rede.
Nossa abordagem padrão para lidar com esses casos é reprecificar: aumentar o custo de armazenamento de leituras para reduzir o máximo por bloco para um nível mais seguro. No entanto, fizemos isso longo vezes e, se o fizermos novamente, isso tornaria muito longo aplicativo muito caro. Uma abordagem melhor é a gás: limitar e cobrar o acesso ao armazenamento separadamente, mantendo o uso médio em 1.000 visitas de armazenamento por bloco, mas estabelecendo um limite máximo por bloco, como 2000.
A ubiquidade dos gás mais longos
Outro recurso que vale a pena considerar é o aumento do tamanho do estado: operações que aumentam o tamanho do estado de Ethereum, que precisam ser salvas por um nó completo. O aumento do tamanho do estado é único na medida em que a lógica para limitá-lo vem apenas do uso sustentado de longo prazo, não de picos.
Portanto, pode ser valioso adicionar uma dimensão gás separada para operações que aumentam o tamanho do estado (por exemplo, SSTORE de zero a não zero, criação de contrato), mas o objetivo é diferente: podemos definir um preço flutuante para vela de pavio longo em um uso médio específico, mas não definir um limite por Bloco.
Isso demonstra uma poderosa propriedade da gás longo-dimensional: ela nos permite vela de pavio longo cada recurso separadamente e perguntar (i) qual é o uso médio ideal longo menos? (ii) Qual é a utilização máxima segura por Bloco longo pequena? Em vez de definir o preço do gás com base no valor máximo de cada bloco e deixar o uso médio seguir, temos 2n graus de liberdade para definir 2n parâmetros, ajustando cada parâmetro de acordo com considerações de segurança de rede.
Casos mais complexos, como quando as considerações de segurança de dois recursos são parcialmente somadas, podem ser tratados fazendo com que um Código de operação ou recurso consuma uma certa quantidade de longo tipo de gás (por exemplo, um SSTORE zero a diferente de zero pode consumir 5.000 atestação gás de clientes sem estado e 20.000 gás de expansão de armazenamento).
Máximo por transação (aquele que consome mais dados ou cálculos)
Que x1 seja o custo gás dos dados e x2 seja o custo gás calculado, para que em um sistema de gás unidimensional possamos escrever o custo gás de uma transação:
Neste cenário, definimos o custo gás da transação como:
Ou seja, uma transação não é cobrada com base em dados mais cálculos, mas em qual dos dois recursos ela consome mais tempo. Isso pode ser facilmente estendido para cobrir dimensões mais longo (e.g. max(…,x3∗storage_access)).
Deve ser fácil ver como isso pode aumentar a taxa de transferência, mantendo a segurança. Teoricamente, a quantidade máxima de dados em um bloco ainda é GasLIMIT/x1, que é exatamente o mesmo que no esquema gás unidimensional. Da mesma forma, a quantidade máxima teórica de cálculo é GasLIMIT/x2, que é exatamente a mesma que em um esquema de gás unidimensional. No entanto, o custo gás de qualquer transação que consuma dados e cálculos cai.
Este é, presumivelmente, o esquema adotado no EIP-7623 proposto para reduzir o tamanho máximo do bloco e, ao mesmo tempo, aumentar ainda mais a contagem de blobs. O mecanismo preciso no EIP-7623 é um pouco mais complicado: mantém o preço atual dos dados de chamada em 16 gás por byte, mas adiciona um preço mínimo de 48 gás por byte; O maior do pagamento da transação (16 * bytes + ution_Gas) e (48 * bytes). Como resultado, o EIP-7623 reduz o máximo teórico de dados de chamada de transação em um bloco de cerca de 1,9 MB para cerca de 0,6 MB, mantendo o custo inalterado para aplicativos mais longos. A vantagem desta abordagem é que muda muito pouco em comparação com o atual esquema de gás unidimensional, tornando-a muito fácil de implementar.
No entanto, esta abordagem apresenta dois inconvenientes:
Mesmo que todas as outras transações no bloco usem apenas uma pequena quantidade desse recurso, as transações que ocupam uma grande quantidade de um recurso ainda cobrarão uma grande taxa desnecessariamente;
Incentiva transações com uso intensivo de dados e computação a se fundirem em um único pacote para economizar custos.
Na minha opinião, uma regra como EIP-7623, seja para negociação de calldata ou outros recursos, pode ser de grande benefício o suficiente para que, mesmo com essas desvantagens, valha a pena.
No entanto, se estivermos dispostos a envidar esforços de desenvolvimento (significativamente mais elevados), surgirá uma abordagem mais desejável.
Longest EIP-1559: Uma estratégia mais difícil, mas desejável
Vamos começar analisando como funciona o EIP-1559 regular. Vamos nos concentrar na versão introduzida pelo vela de pavio longo blob em EIP-4844 porque é matematicamente mais elegante.
Acompanhamos um parâmetro, o excesso_blobs. Durante cada bloco, definimos:
excesso_blobs <-- max(excesso_blobs + len(block.blobs) - TARGET, 0)
em que TARGET = 3. Ou seja, se o número de blobs em um Bloco for longo do que o alvo, o excesso_blobs aumenta e se o número de blobs em um Bloco for menor que o alvo, o excesso_blobs diminui. Em seguida, definimos blob_basefee = exp(excess_blobs / 25.47), onde exp é uma aproximação da função exponencial exp(x)=2.71828^x.
Ou seja, sempre que o excesso_blobs aumenta em cerca de 25, a carga base do blob aumenta em cerca de 2,7x. Se o blob se tornar muito caro, o uso médio cai e o excesso_blobs começa a diminuir, automaticamente Gota o preço novamente. O preço das bolhas é constantemente ajustado para garantir que, em média, o Bloco esteja meio cheio, ou seja, cada Bloco contém uma média de 3 bolhas.
Se houver um pico de uso de curto prazos, há um limite: cada Bloco só pode conter 6 blobs em uma longo máxima, caso em que as transações podem competir entre si aumentando a taxa de prioridade. No entanto, em circunstâncias normais, cada blob paga apenas blob_basefee mais uma pequena taxa de prioridade adicional como incentivo para ser incluído.
Este gás preços já existe em Ethereum há mais tempo: em 2020, EIP-1559 introduziu um mecanismo muito semelhante. Com EIP-4844, definimos dois preços flutuantes separados para Gás e Blobs.
Nota: A base gás cobrar por uma hora em 8 de maio de 2024, em gwei. Fonte: ultrasound.money
Em princípio, poderíamos adicionar mais longo taxas flutuantes independentes para leituras de armazenamento e outros tipos de operações, mas vou desenvolver uma questão na próxima seção.
Para os usuários, a experiência é muito semelhante à de hoje: em vez de pagar uma taxa básica, você paga duas taxas básicas, mas sua carteira pode abstraí-la de suas mãos, mostrando apenas as taxas esperadas e máximas que você pode esperar pagar.
Bloco construtores, há mais tempo, a melhor estratégia é a mesma de hoje: incluir tudo o que funciona. Blocos mais longos não estão cheios - gás ou bolhas. Uma situação desafiadora é que, quando há gás ou bolhas suficientes para exceder o limite de blocos, os construtores precisam potencialmente resolver o problema da mochila mais longa para maximizar seus lucros. No entanto, mesmo que haja uma aproximação bastante boa Algoritmo, neste caso, o ganho de otimizar os lucros formulando Algoritmo proprietária é longo menor do que o ganho de fazer o mesmo com MEV.
O principal desafio para os desenvolvedores é a necessidade de redesenhar a funcionalidade do EVM e sua infraestrutura associada, que atualmente foram projetados com base em um preço único e um limite único, e agora precisam ser adaptados para acomodar preços mais longos e limitações mais longas.
Um problema que os desenvolvedores de aplicativos enfrentam é que a otimização se torna um pouco mais difícil: em alguns casos, você não pode mais longo dizer explicitamente que A é mais eficiente do que B, porque se A usa um calldata mais longo e B usa uma execução mais longo, então quando calldata é mais barato, é mais caro quando calldata é caro.
Um problema que os desenvolvedores de aplicativos enfrentam é que a otimização se torna um pouco mais difícil: em alguns casos, você não pode dizer definitivamente que A é mais eficiente do que B, porque se A usa um calldata mais longo e B usa uma execução mais longo, então A pode ser mais barato quando calldata é barato, e A pode ser mais caro quando calldata é caro.
No entanto, os desenvolvedores ainda podem obter resultados muito bons otimizando com base em preços médios históricos de longo prazo.
Preços, EVM e subchamadas mais longos
Há um problema que não aparece em blobs, nem aparece no EIP-7623 ou mesmo na implementação completa de preços mais longos de velas de longo pavio para calldata, mas se tentarmos precificar o acesso ao estado ou qualquer outro recurso separadamente, então esse problema surge: o limite de gás em subchamadas.
Os limites de gás em EVM existem em dois lugares. Primeiro, cada transação define um limite de gás, que limita a quantidade total de gás que podem ser usados nessa transação. Em segundo lugar, quando um contrato chama outro, essa chamada pode definir o seu próprio limite de gás. Isso permite que os contratos chamem outros contratos em que não confiam e ainda garante que eles ainda tenham gás residuais para realizar outros cálculos após a chamada.
Nota: Rastreamentos de abstração de contas transações em que uma conta chama outra conta e apenas uma quantidade limitada de gás é fornecida ao destinatário para garantir que a chamada externa continue a ser executada mesmo que o destinatário consuma todos os gás alocados a ele.
O desafio é que obter gás mais longos entre diferentes tipos de execução parece exigir subchamadas para fornecer limites mais longos para cada tipo de gás, o que exigiria mudanças muito profundas no EVM e não seria compatível com os aplicativos existentes.
Esta é uma das razões pelas quais as propostas de gás mais longas normalmente permanecem em duas dimensões: dados e execução. Os dados, sejam dados de chamada transacionais ou blobs, só são distribuídos fora do EVM, portanto, nada precisa mudar dentro do EVM para que os dados de chamada ou blobs sejam precificados separadamente.
Podemos encontrar uma solução “EIP-7623-style” para resolver este problema. Esta é uma implementação simples: durante a execução, a operação de armazenamento é cobrada 4 vezes a taxa; Para simplificar a análise, vamos supor 10.000 gases por operação de armazenamento. No final da transação, o min(7500 * storage_operations, ution_Gas) é reembolsado. Como resultado, após deduzir o reembolso, o usuário é obrigado a pagar as seguintes taxas:
ution_Gas + 10000 * armazenamento_operations - min(7500 * armazenamento_operations, ution_Gas)
Isto é igual:
max(ution_Gas + 2500 * armazenamento_operations, 10000 * armazenamento_operations)
Isso reflete a estrutura do EIP-7623. Outra abordagem é rastrear o armazenamento_operations e ution_Gas em tempo real e cobrar 2500 ou 10000 a menos, dependendo do max(ution_Gas + 2500 * storage_operations, 10000 * storage_operations) no pump longo o momento. O Código de operação é chamado. Deste modo, evita-se a necessidade de as transações afetarem gás em excesso, que são, na sua maioria, recuperadas através de reembolsos.
Não temos um licenciamento refinado para subchamadas: as subchamadas podem consumir todas as permissões da transação para operações de armazenamento baratas.
Mas obtemos algo bom o suficiente para que o contrato que faz a subchamada possa definir um limite e garantir que, uma vez que a subchamada seja executada, a chamada principal ainda tenha gás suficientes para o pós-processamento necessário.
A “solução completa de preços mais longos” mais simples que consigo pensar é a seguinte: tratamos a limite de gás de subchamada como proporcional. Ou seja, suponha que existem k tipos de execução diferentes, e cada transação é definida com um limite mais longo L1… Lc 。 Suponha que, no ponto de execução atual, o gás restante seja g1… Gk. Suponha que você chame o Código de operação CALL e use a subchamada Gas para limitar S. Deixe s1=S, depois s2=s1/g1∗g2, s3=s1/g1∗g3 e assim por diante.
Ou seja, tratamos o primeiro tipo de gás (que na verdade é VM execução) como uma “unidade de conta” especial e, em seguida, alocamos outros tipos de gás para que a subchamada obtenha a mesma porcentagem de gás disponíveis em cada tipo de gás. Esta abordagem é um pouco feia e maximiza compatibilidade com versões anteriores.
Se quisermos tornar o esquema mais “neutro” entre diferentes tipos de gás sem sacrificar compatibilidade com versões anteriores, podemos simplesmente representar o parâmetro limite de gás da chamada de criança como parte do gás restante no contexto atual (por exemplo, [1…63]/64).
Em ambos os casos, no entanto, vale a pena enfatizar que, uma vez que você começa a introduzir gás de execução mais longa, a complexidade inerente (feiura) aumenta, o que parece difícil de evitar.
Portanto, nossa tarefa é fazer um compromisso complexo: aceitamos algum nível de aumento de feiura no nível EVM para desbloquear com segurança ganhos significativos de escalabilidade L1 e, em caso afirmativo, qual proposta específica será mais eficaz para protocolo economia e desenvolvedores de aplicativos? É provável que nenhuma das duas opções que mencionei acima seja a melhor, mas ainda há shorts para encontrar soluções mais elegantes e melhores.
Um agradecimento especial a Ansgar Dietrichs, Barnabe Monnot e Davide Crapis pelo seu feedback e revisão.