Este artigo apresenta principalmente o desenvolvimento e o conteúdo relacionado de contas abstratas (AA, contas abstratas) na solução de Camada 2 do zkSync. O foco estará em três partes:
Contrato de conta: tipo de conta, ponto de entrada importante e pontos-chave relacionados ao contrato de conta
Transação: método de verificação, método de execução e processo de transação AA
Taxa de manuseio: taxa de transação, Paymaster
Índice
prefácio
Breve visão geral do contrato zkSync AA
Modelo de taxas e Paymaster na era do zkSync
Resumo e comparação
Conclusão
fundo
Familiarizado com carteira de contrato inteligente e seus recursos comuns
Obtenha uma visão geral de como funcionam as transações Ethereum
Uma compreensão geral do modo de operação do EIP-4337
Uma compreensão geral do modo de operação do ZK (validade) Rollup
Uma rápida olhada no zkSync
Aqui, para facilitar a leitura, não é necessário entender o zkSync em profundidade, mas revisar brevemente as informações básicas do zkSync. Existem duas versões principais do zkSync, versão 1.0 (zkSync Lite) e versão 2.0 (zkSync Era).
zkSync versão 1.0 suporta apenas EOA (conta externa) e não suporta contratos inteligentes (suporta apenas transferência e troca de token), enquanto zkSync 2.0, ou seja, zkSync Era, pertence a AA nativo (conta abstrata) (todos os tipos de conta são contratos, sem EOA , que é a diferença entre EOA e conta de contrato no Ethereum), e é compatível com EVM (Ethereum Virtual Machine), e suporta o desenvolvimento de contratos inteligentes usando Rust, Yul, Vyper, Solidity, etc.
O zkSync mencionado abaixo refere-se ao zkSync 2.0, ou seja, zkSync Era, salvo especificação em contrário.
Na Era zkSync, existem vários contratos, que podem ser entendidos porque implementam algumas funções importantes do sistema operacional do zkSync em contratos inteligentes. Esses contratos são contratos pré-compilados que nunca foram implantados (executados diretamente no nó), mas todos possuem um endereço formal.
Ao implementar o protocolo AA, o zkSync realizará operações lógicas e julgamentos por meio de alguns contratos. Por exemplo, ao verificar o nonce, ele será julgado pelo NonceHolder, enquanto a implementação do mecanismo de conta abstrata e a cobrança de taxas serão julgadas pelo bootloader. A seguir será apresentado um por um.
Recapitulação da abstração da conta
O conceito central de abstração de conta pode ser resumido em dois pontos-chave: abstração de assinatura e abstração de pagamento.
O objetivo da abstração de assinatura é permitir que vários contratos de contas utilizem diferentes esquemas de verificação. Isso significa que os usuários não estão limitados a um algoritmo de assinatura digital que só pode usar uma curva específica, mas podem escolher qualquer mecanismo de verificação que desejarem.
A abstração de pagamento visa fornecer aos usuários uma variedade de opções de pagamento por transação. Por exemplo, os pagamentos poderiam ser feitos usando tokens ERC-20 em vez de tokens nativos, ou as transações poderiam ser patrocinadas por terceiros, ou mesmo outros modelos de pagamento mais ad hoc.
As contas no zkSync 2.0 podem iniciar transações como EOA, mas também podem usar sua programabilidade para implementar lógica arbitrária, como contas de contrato. Isso é o que chamamos de Abstração de Conta, que combina as vantagens dos dois tipos de contas no Ethereum para flexibilizar a experiência de utilização de contas AA, atingindo assim os dois objetivos acima: abstração de assinatura e abstração de pagamento.
Mecanismo AA na Era zkSync
Na Era zkSync, a função mais importante do zkSync AA é o bootloader, que é um Contrato, usado principalmente para processar transações e executar o mecanismo AA, correspondente ao Contrato EntryPoint do EIP-4337. O bootloader não pode ser chamado pelo usuário (só pode ser acionado pelo Operador), e nunca foi implantado (roda diretamente no nó), mas possui um endereço oficial (pode ser usado para receber pagamentos).
Operador é uma função importante no ZK Rollup. É um servidor off-chain centralizado. Semelhante ao sequenciador que você deve ter visto, ele é responsável por acionar contratos como o bootloader de fora.
Protocolos de abstração de conta nativa (como StarkNet, zkSync) são basicamente projetados com referência ao EIP-4337. Na implementação do zkSync, o usuário enviará a transação para o Operador, e o Operador enviará a transação para o bootloader e iniciará um série de processamento.
Do ponto de vista do bloco:
Quando o bootloader recebe entrada do Operador, o bootloader primeiro definirá algumas variáveis de ambiente para o bloco (como preço do gás, número do bloco, carimbo de data/hora do bloco, etc.). Em seguida, o bootloader lerá sequencialmente a lista de transações, primeiro consultará se o contrato da conta concorda com a transação (ou seja, chamará a função de validação no mecanismo AA) e, em seguida, os colocará no bloco.
Após a verificação de cada transação, o Operador verifica se o bloco é grande o suficiente para ser enviado ao verificador (ou se atinge o tempo limite). Se for grande o suficiente ou expirar, o Operador fecha o bloco, para de adicionar novas transações ao bootloader e conclui a execução da transação.
Do ponto de vista das transações, quando o Operador aciona o bootloader, o bootloader processará cada transação sequencialmente:
Confirme se o nonce correspondente ao endereço do contrato da conta do usuário é legal
Chame a função de validação no contrato da conta do usuário para verificação
Após a verificação ser aprovada, o contrato da conta enviará a taxa do gás para o endereço do bootloader (ou através do Paymaster, que será introduzido posteriormente), e o bootloader verificará se recebeu dinheiro suficiente.
Chame a função ute no contrato da conta do usuário para executar a transação.
As três primeiras etapas acima correspondem ao loop de verificação (Verification Loop) do EIP-4337, e a quarta etapa corresponde ao loop de execução (ution Loop) do EIP-4337.
Aqui está principalmente uma introdução geral, e os detalhes e funções de cada etapa serão elaborados um por um na descrição detalhada a seguir.
Visão geral rápida do contrato de conta abstrata zkSync
Nonce
O nonce da conta zkSync é registrado em um contrato de sistema chamado NonceHolder, que lembra se cada par (account_address, nonce) é usado pelo mapeamento (mapeamento) para julgar se o nonce é legal.
De acordo com o exposto, o primeiro passo após o Operador acionar o bootloader é verificar o nonce. Portanto, antes do início de cada transação, NonceHolder será usado para confirmar se o conjunto de nonces usado atualmente é legal (atualmente apenas verifica se eles foram usados). Se o nonce for legal, entrará na fase de verificação (Fase de Verificação), momento em que o nonce será marcado como utilizado; se não for legal, a transação (verificação) falhará.
Pontos importantes sobre o nonce atual do zkSync:
Embora atualmente os usuários possam enviar várias transações com nonces diferentes para a conta para execução ao mesmo tempo, como o zkSync não suporta processamento paralelo, as transações com nonces diferentes ainda serão processadas sequencialmente.
Em teoria, os usuários podem usar qualquer número inteiro diferente de zero de 256 bits como nonce, mas zkSync ainda recomenda usar incrementNonceIfEquals como uma forma de gerenciar nonce para garantir que ele seja incrementado em ordem (atualmente o mecanismo AA do zkSync apenas confirma nonce não utilizado, mas o oficial documento indica que o incremento sequencial pode ser necessário no futuro).
Contrato de conta
O contrato de conta no zkSync possui os seguintes quatro pontos de entrada necessários (ponto de entrada), que são:
ValidateTransaction: Chamado durante a fase de verificação para confirmar se a operação foi autorizada pelo proprietário da conta, onde os usuários podem personalizar sua própria lógica de verificação (como vários algoritmos de assinatura, assinaturas múltiplas, etc.).
payForTransaction: Quando a taxa de transação for paga por esta conta (em vez de usar paymaster), a operadora chamará esta função para pagar pelo menos tx.gasprice * tx.gaslimit de ETH para o endereço do bootloader.
prepareForPaymaster: Quando a taxa de transação for paga pelo Paymaster, a operadora chamará esta função para concluir o trabalho de preparação antes de interagir com o paymaster. O exemplo fornecido pelo zkSync é um token ERC-20 aprovado pela Paymaster.
uteTransaction: Após a fase de verificação ser aprovada e a taxa de transação cobrada com sucesso, esta função será utilizada para realizar a operação que o usuário deseja realizar (como interagir com o contrato, remessa, etc.).
Sobre o Paymaster, o valor da taxa de manuseio (tx.gasprice * tx.gaslimit), etc. será explicado nos capítulos subsequentes.
Há também uma função de seguro não essencial uteTransactionFromOutside na conta do zkSync. Os fundos podem ser retirados para L1 usando o “mecanismo de escape” quando as operações não podem ser realizadas (como quando o gerador de sequência não responde ou o zkSync é considerado um risco regulatório). Esta parte tem pouco a ver com o protocolo AA, por isso não será descrita em detalhes aqui.Os interessados podem conferir os documentos oficiais e as especificações do zkSync.
Pontos-chave e limitações das funções de validação
Na função ValidTransaction, várias lógicas personalizadas podem ser implementadas. Por exemplo, se a conta implementou o padrão EIP-1271, a lógica de verificação no EIP-1271 pode ser aplicada diretamente ao ValidTransaction ou consultar o contrato da conta com múltiplas assinaturas. implementação no documento oficial zkSync.
Ao mesmo tempo, para evitar ameaças DoS na Fase de Verificação do EIP-4337, existem algumas restrições (não pode envolver opcodes externos e profundidade limitada, etc.), e existem restrições semelhantes no zkSync, por exemplo:
1. A lógica do contrato só pode tocar em seu próprio slot (se o endereço do contrato da conta for A):
slot pertencente ao endereço A
slot A em qualquer outro endereço
O slot keccak256(A||X) de qualquer outro endereço, que pode usar diretamente o endereço como chave do mapeamento (como mapeamento (address=>value)), também é equivalente a permitir acesso ao slot keccak256( A||X), para alcançar a expansão. Por exemplo, saldos de tokens no ERC-20.
2. A lógica do contrato não deve usar variáveis globais, como block.number
Pontos-chave e limitações da execução de funções
O que precisa ser observado na função uteTransaction é que se você deseja realizar uma chamada de sistema (Call), você precisa garantir que ela tenha o sinalizador is. Porque esses contratos do sistema têm um grande impacto no sistema de contas. Por exemplo, a única maneira de aumentar o nonce é interagir com o NonceHolder. Para implantar um contrato, você deve interagir com o ContractDeployer. O uso do sinalizador is pode garantir que os desenvolvedores da conta interajam conscientemente com contratos de sistema.
No entanto, é recomendável usar a biblioteca ContractsCaller fornecida por zkSync para evitar o manuseio do sinalizador is e usar CallWithPropagatedRevert para concluir a chamada do sistema.
O exemplo de código acima envolve a interação com DEPLOYER__CONTRACT. A situação de contrato de sistema mais comum que os desenvolvedores de contas encontram é que queremos usar uma conta para implantar um contrato.Neste momento, devemos interagir com o contrato do sistema ContractDeployer. Nesse caso, o desenvolvedor da conta precisa se comunicar com o contrato ContractDeployer para garantir que o contrato seja implantado com êxito e execute as operações necessárias.
Modelo de taxas e Paymaster na era do zkSync
Taxas e limite de gás
O modelo de taxa do zkSync é muito semelhante ao Ethereum, o token de taxa ainda é ETH. No entanto, como outras soluções da Camada 2 (como Arbitrum, Optimism), o zkSync também precisa considerar o custo adicional de publicação em L1 (taxa de segurança), além do cálculo básico e dos custos de slot de gravação. Como o preço do gás que publica dados em L1 é muito instável, o Operador do zkSync define os seguintes parâmetros dinâmicos quando cada bloco é aberto (começa a registrar transações):
gasPrice: preço do gás em gwei, ou seja, tx.gasprice no objeto de transação mencionado acima
gasPerPubdata: A quantidade de gás necessária para publicar um byte de dados no Ethereum
Além disso, ao contrário do EIP-4337, o zkSync não precisa definir três limites de gás: verifyGas, utionGas e preVerificationGas, mas requer apenas um gasLimit para cobrir todos os custos acima, portanto, os usuários precisam garantir que o gasLimit seja suficiente para cobrir o Fase de verificação, fase de envio e upload de dados Todas as despesas, como taxas de segurança para L1. Este custo de taxa está incluído no tx.gaslimit no objeto de transação mencionado acima.
Multiplique os dois (tx.gasprice * tx.gaslimit) para obter a taxa de transação paga ao bootloader.
Pagador
Paymaster paga principalmente ETH ao bootloader em vez do contrato da conta do usuário na fase de taxa de pagamento da transação do usuário. Os usuários podem escolher diferentes Paymaster e modos de pagamento para pagar a taxa de manuseio, como (mas não limitado a):
Pagamento de tokens ERC-20 ao Paymaster antes do início da transação ou após a execução da transação
Recarregue o contrato Paymaster com cartão de crédito
Paymaster continuará a pagar parte ou todas as taxas para os usuários gratuitamente
A forma como os usuários interagem com o Paymaster depende de diferentes protocolos, pode ser centralizado ou descentralizado; pode ser antes ou depois da transação; pode usar tokens ERC-20 ou moeda legal, ou até mesmo gratuito.
O contrato Paymaster do zkSync consiste principalmente em duas funções, nomeadamente activateAndPayForPaymasterTransaction (obrigatório) e postTransaction (opcional), ambas as quais só podem ser chamadas pelo bootloader:
activateAndPayForPaymasterTransaction é a única função que deve ser implementada em todo o contrato Paymaster. Quando a operadora recebe uma transação com parâmetro Paymaster, significa que a taxa de movimentação não é paga pelo contrato da conta do usuário, mas sim pelo Paymaster. Neste ponto, a operadora chamará activateAndPayForPaymasterTransaction para determinar se o Paymaster está disposto a pagar a taxa de transação. Se o Paymaster concordar, esta função enviará pelo menos tx.gasprice * tx.gaslimit ETH para o bootloader.
postTransaction é uma função opcional, geralmente usada para reembolso (devolver o gás não utilizado ao remetente). No entanto, o zkSync atual ainda não suporta esta operação.
O Paymaster no zkSync executará postTransaction após a implementação do postTransaction, o que é diferente do EIP-4337. O EIP-4337 não chamará postOp quando validPaymasterUserOp não retornar o contexto e vice-versa.
Com base no exposto, por exemplo, o usuário agora deseja enviar uma transação cuja taxa de movimentação é paga pelo Paymaster, o processo é o seguinte:
Use NonceHolder para confirmar se o nonce é legal
Chame validTransaction no contrato de conta do usuário para verificar se a transação foi autorizada pelo proprietário da conta
Chame prepareForPaymaster no Contrato de Conta do usuário, que pode executar, por exemplo, aprovar um determinado número de Tokens ERC-20 para Paymaster ou não fazer nada
Chame validAndPayForPaymasterTransaction no Contrato Paymaster para confirmar que o Paymaster está disposto a pagar e cobrar a taxa de manuseio e, ao mesmo tempo, o Paymaster cobrará do usuário uma certa quantia de ERC-20 (aprovado anteriormente)
Confirme se o bootloader recebe o valor correto (pelo menos tx.gasprice * tx.gaslimit) de taxas ETH
Chame uteTransaction no contrato de conta do usuário para executar a transação que o usuário deseja
Se o Contrato Paymaster implementar postTransaction e o gás ainda for suficiente (sem erro de falta de gás), execute postTransaction
Na última etapa, mesmo que postTransaction não possa ser executado devido a um erro de falta de gás, esta transação AA é considerada bem-sucedida, mas a ação de chamar postTransaction é omitida.
Se você se aprofundar no Paymaster do zkSync, descobrirá que suas regras de verificação são ligeiramente diferentes de 4337 (o zkSync Paymaster pode pisar em qualquer outro slot de contrato), e também existem vários tipos (como com base em aprovação). Esta parte é devida. para a comparação de detalhes. Os interessados podem consultar documentos oficiais ou minha implementação anterior.
Resumo e comparação
Através das explicações anteriores, aprendemos quais são os pontos de entrada importantes do contrato de conta, bem como suas funções e restrições relacionadas. Ao mesmo tempo, também aprendemos sobre as funções do contrato do sistema. A seguir, vamos resumir o processo de transação de operação automatizada (AA) no zkSync desde a construção até a conclusão, e também fornecerei referências mais detalhadas para quem quiser saber mais:
O usuário usa o SDK ou carteira localmente para construir objetos de transação (por exemplo: de, para, dados, valor, etc.).
O usuário assina a transação. A assinatura aqui não é necessariamente o formato tradicional EIP-712 e a assinatura da curva ECDSA. zkSync também oferece suporte a EIP-2718 e EIP-1559. A chave para escolher um método de assinatura e um método de verificação é verificar por meio da função de verificação no contrato da conta.
Envie a transação assinada ao operador através da API RPC. Neste ponto, a transação entra no estado pendente. O operador passa a transação para o bootloader (chama a função processL2Tx no contrato do bootloader) e inicia uma série de processos do protocolo AA.
O Bootloader verificará se o Nonce é legal e usará o NonceHolder para verificar.
O Bootloader chamará a função activateTransaction no contrato da conta do usuário para confirmar que a transação foi autorizada pelo proprietário da conta.
Existem duas maneiras de o Bootloader cobrar taxas, e o método de cobrança específico depende dos parâmetros da transação (se o parâmetro paymaster está anexado ao construir o objeto de transação):
a. Chame a função payForTransaction e o contrato da conta para cobrar a taxa de transação;
b. Chame as funções prepareForPaymaster e activateAndPayForPaymasterTransaction para cobrar a taxa de transação com o contrato Paymaster.
"Ligue para payForTransaction para contratar a taxa com a conta" ou "ligue para prepareForPaymaster e validAndPayForPaymasterTransaction para contratar a taxa com o Paymaster"
Verifique se o bootloader recebeu pelo menos taxas de transação tx.gasprice * tx.gaslimit.
O Bootloader chamará a função uteTransaction no contrato da conta do usuário para executar a transação.
(Opcional) Se estiver usando o Paymaster para pagar a taxa de transação, o bootloader chamará a função postTransaction. Se o Paymaster não implementar postTransaction ou se o gás acabar, esta etapa será ignorada.
As etapas 4 a 7 acima são a fase de verificação (definida no l2TxValidation do bootloader) e a fase de execução das etapas 8 a 9 (definida no l2Txution do bootloader).
Comparação de EIP-4337, StarkNet e zkSync Era
Basicamente, os processos do mecanismo AA dos três são semelhantes, sendo todos fase de verificação→mecanismo de taxa de manuseio (pago por contrato de conta ou Paymaster)→fase de execução.As principais diferenças são:
O papel da implementação do mecanismo AA é: a diferença entre a abertura na era zkSync e os outros dois AA é que o Operador precisa cooperar com o bootloader (contrato do sistema), por exemplo, o bootloader abrirá um novo bloco e definirá os parâmetros relevantes do bloco, e receba a operação O trader enviado pelo membro e verificado. No 4337, essa parte é coordenada pelo Bundler e pelo EntryPoint, enquanto no StarkNet, essa parte fica toda a cargo do Sequencer.
O custo do gás precisa considerar a taxa de segurança L1: L2 AA precisa considerar o custo de upload de dados para L1, não apenas o ZK (validade) Rollups Native AA mencionado no push, mas também precisa ser incluído em L1 quando otimista Rollups implementam taxa de segurança 4337 (calculada em preVerificationGas, consulte documentos relacionados à Alquimia para obter detalhes).
Se é possível enviar transações antes da implantação do contrato da conta: Na era do StarkNet e zkSync, não existe um EntryPoint como 4337 que tenha o campo initCode para permitir ao usuário implantar o contrato da conta, portanto, não envia transações antes que a conta possa ser configurada.
Comparado
Como a StarkNet ainda não realizou o mecanismo Paymaster e o zkSync ainda não concluiu o projeto do mecanismo de reembolso de gás, algumas comparações mais detalhadas não estão listadas aqui.
Além disso, concluímos o mempool P2P para o empacotador 4337 atual, e o sequenciador e o operador de zkRollups também são os únicos servidores oficiais, portanto, existem certos componentes centralizados.
No processo de desenvolvimento, como o zkSync não tem problemas de conexão com vários bundlers (só precisa interagir com a API do Operador), é fácil de usar o 4337, e a experiência de desenvolvimento de contratos de conta (SDK) também é melhor; em ao mesmo tempo, zkSync pode usar Solidity como uma linguagem de desenvolvimento de contrato, portanto, não há necessidade de cruzar o limiar do Cairo no desenvolvimento StarkNet.
Conclusão
Como StarkNet e zkSync pertencem à categoria de AA local (AA nativo), você também pode consultar minha introdução anterior ao StarkNet AA, intitulada "Introdução à abstração de conta StarkNet" (Introdução à abstração de conta StarkNet). Além disso, você pode ler outros artigos relacionados ao EIP-4337 para obter mais informações.
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.
Introdução à abstração de conta nativa no zkSync
Autor: Escrito por ChiHaoLu, imToken Labs
Este artigo apresenta principalmente o desenvolvimento e o conteúdo relacionado de contas abstratas (AA, contas abstratas) na solução de Camada 2 do zkSync. O foco estará em três partes:
Índice
fundo
Aqui, para facilitar a leitura, não é necessário entender o zkSync em profundidade, mas revisar brevemente as informações básicas do zkSync. Existem duas versões principais do zkSync, versão 1.0 (zkSync Lite) e versão 2.0 (zkSync Era).
zkSync versão 1.0 suporta apenas EOA (conta externa) e não suporta contratos inteligentes (suporta apenas transferência e troca de token), enquanto zkSync 2.0, ou seja, zkSync Era, pertence a AA nativo (conta abstrata) (todos os tipos de conta são contratos, sem EOA , que é a diferença entre EOA e conta de contrato no Ethereum), e é compatível com EVM (Ethereum Virtual Machine), e suporta o desenvolvimento de contratos inteligentes usando Rust, Yul, Vyper, Solidity, etc.
O zkSync mencionado abaixo refere-se ao zkSync 2.0, ou seja, zkSync Era, salvo especificação em contrário.
Na Era zkSync, existem vários contratos, que podem ser entendidos porque implementam algumas funções importantes do sistema operacional do zkSync em contratos inteligentes. Esses contratos são contratos pré-compilados que nunca foram implantados (executados diretamente no nó), mas todos possuem um endereço formal.
Ao implementar o protocolo AA, o zkSync realizará operações lógicas e julgamentos por meio de alguns contratos. Por exemplo, ao verificar o nonce, ele será julgado pelo NonceHolder, enquanto a implementação do mecanismo de conta abstrata e a cobrança de taxas serão julgadas pelo bootloader. A seguir será apresentado um por um.
Recapitulação da abstração da conta
O conceito central de abstração de conta pode ser resumido em dois pontos-chave: abstração de assinatura e abstração de pagamento.
O objetivo da abstração de assinatura é permitir que vários contratos de contas utilizem diferentes esquemas de verificação. Isso significa que os usuários não estão limitados a um algoritmo de assinatura digital que só pode usar uma curva específica, mas podem escolher qualquer mecanismo de verificação que desejarem.
A abstração de pagamento visa fornecer aos usuários uma variedade de opções de pagamento por transação. Por exemplo, os pagamentos poderiam ser feitos usando tokens ERC-20 em vez de tokens nativos, ou as transações poderiam ser patrocinadas por terceiros, ou mesmo outros modelos de pagamento mais ad hoc.
As contas no zkSync 2.0 podem iniciar transações como EOA, mas também podem usar sua programabilidade para implementar lógica arbitrária, como contas de contrato. Isso é o que chamamos de Abstração de Conta, que combina as vantagens dos dois tipos de contas no Ethereum para flexibilizar a experiência de utilização de contas AA, atingindo assim os dois objetivos acima: abstração de assinatura e abstração de pagamento.
Mecanismo AA na Era zkSync
Na Era zkSync, a função mais importante do zkSync AA é o bootloader, que é um Contrato, usado principalmente para processar transações e executar o mecanismo AA, correspondente ao Contrato EntryPoint do EIP-4337. O bootloader não pode ser chamado pelo usuário (só pode ser acionado pelo Operador), e nunca foi implantado (roda diretamente no nó), mas possui um endereço oficial (pode ser usado para receber pagamentos).
Operador é uma função importante no ZK Rollup. É um servidor off-chain centralizado. Semelhante ao sequenciador que você deve ter visto, ele é responsável por acionar contratos como o bootloader de fora.
Protocolos de abstração de conta nativa (como StarkNet, zkSync) são basicamente projetados com referência ao EIP-4337. Na implementação do zkSync, o usuário enviará a transação para o Operador, e o Operador enviará a transação para o bootloader e iniciará um série de processamento.
Do ponto de vista do bloco:
Quando o bootloader recebe entrada do Operador, o bootloader primeiro definirá algumas variáveis de ambiente para o bloco (como preço do gás, número do bloco, carimbo de data/hora do bloco, etc.). Em seguida, o bootloader lerá sequencialmente a lista de transações, primeiro consultará se o contrato da conta concorda com a transação (ou seja, chamará a função de validação no mecanismo AA) e, em seguida, os colocará no bloco.
Após a verificação de cada transação, o Operador verifica se o bloco é grande o suficiente para ser enviado ao verificador (ou se atinge o tempo limite). Se for grande o suficiente ou expirar, o Operador fecha o bloco, para de adicionar novas transações ao bootloader e conclui a execução da transação.
Do ponto de vista das transações, quando o Operador aciona o bootloader, o bootloader processará cada transação sequencialmente:
As três primeiras etapas acima correspondem ao loop de verificação (Verification Loop) do EIP-4337, e a quarta etapa corresponde ao loop de execução (ution Loop) do EIP-4337.
Aqui está principalmente uma introdução geral, e os detalhes e funções de cada etapa serão elaborados um por um na descrição detalhada a seguir.
Visão geral rápida do contrato de conta abstrata zkSync
Nonce
O nonce da conta zkSync é registrado em um contrato de sistema chamado NonceHolder, que lembra se cada par (account_address, nonce) é usado pelo mapeamento (mapeamento) para julgar se o nonce é legal.
De acordo com o exposto, o primeiro passo após o Operador acionar o bootloader é verificar o nonce. Portanto, antes do início de cada transação, NonceHolder será usado para confirmar se o conjunto de nonces usado atualmente é legal (atualmente apenas verifica se eles foram usados). Se o nonce for legal, entrará na fase de verificação (Fase de Verificação), momento em que o nonce será marcado como utilizado; se não for legal, a transação (verificação) falhará.
Pontos importantes sobre o nonce atual do zkSync:
Embora atualmente os usuários possam enviar várias transações com nonces diferentes para a conta para execução ao mesmo tempo, como o zkSync não suporta processamento paralelo, as transações com nonces diferentes ainda serão processadas sequencialmente.
Em teoria, os usuários podem usar qualquer número inteiro diferente de zero de 256 bits como nonce, mas zkSync ainda recomenda usar incrementNonceIfEquals como uma forma de gerenciar nonce para garantir que ele seja incrementado em ordem (atualmente o mecanismo AA do zkSync apenas confirma nonce não utilizado, mas o oficial documento indica que o incremento sequencial pode ser necessário no futuro).
Contrato de conta
O contrato de conta no zkSync possui os seguintes quatro pontos de entrada necessários (ponto de entrada), que são:
Sobre o Paymaster, o valor da taxa de manuseio (tx.gasprice * tx.gaslimit), etc. será explicado nos capítulos subsequentes.
Há também uma função de seguro não essencial uteTransactionFromOutside na conta do zkSync. Os fundos podem ser retirados para L1 usando o “mecanismo de escape” quando as operações não podem ser realizadas (como quando o gerador de sequência não responde ou o zkSync é considerado um risco regulatório). Esta parte tem pouco a ver com o protocolo AA, por isso não será descrita em detalhes aqui.Os interessados podem conferir os documentos oficiais e as especificações do zkSync.
Pontos-chave e limitações das funções de validação
Na função ValidTransaction, várias lógicas personalizadas podem ser implementadas. Por exemplo, se a conta implementou o padrão EIP-1271, a lógica de verificação no EIP-1271 pode ser aplicada diretamente ao ValidTransaction ou consultar o contrato da conta com múltiplas assinaturas. implementação no documento oficial zkSync.
Ao mesmo tempo, para evitar ameaças DoS na Fase de Verificação do EIP-4337, existem algumas restrições (não pode envolver opcodes externos e profundidade limitada, etc.), e existem restrições semelhantes no zkSync, por exemplo:
1. A lógica do contrato só pode tocar em seu próprio slot (se o endereço do contrato da conta for A):
slot pertencente ao endereço A
slot A em qualquer outro endereço
O slot keccak256(A||X) de qualquer outro endereço, que pode usar diretamente o endereço como chave do mapeamento (como mapeamento (address=>value)), também é equivalente a permitir acesso ao slot keccak256( A||X), para alcançar a expansão. Por exemplo, saldos de tokens no ERC-20.
2. A lógica do contrato não deve usar variáveis globais, como block.number
Pontos-chave e limitações da execução de funções
O que precisa ser observado na função uteTransaction é que se você deseja realizar uma chamada de sistema (Call), você precisa garantir que ela tenha o sinalizador is. Porque esses contratos do sistema têm um grande impacto no sistema de contas. Por exemplo, a única maneira de aumentar o nonce é interagir com o NonceHolder. Para implantar um contrato, você deve interagir com o ContractDeployer. O uso do sinalizador is pode garantir que os desenvolvedores da conta interajam conscientemente com contratos de sistema.
No entanto, é recomendável usar a biblioteca ContractsCaller fornecida por zkSync para evitar o manuseio do sinalizador is e usar CallWithPropagatedRevert para concluir a chamada do sistema.
O exemplo de código acima envolve a interação com DEPLOYER__CONTRACT. A situação de contrato de sistema mais comum que os desenvolvedores de contas encontram é que queremos usar uma conta para implantar um contrato.Neste momento, devemos interagir com o contrato do sistema ContractDeployer. Nesse caso, o desenvolvedor da conta precisa se comunicar com o contrato ContractDeployer para garantir que o contrato seja implantado com êxito e execute as operações necessárias.
Modelo de taxas e Paymaster na era do zkSync
Taxas e limite de gás
O modelo de taxa do zkSync é muito semelhante ao Ethereum, o token de taxa ainda é ETH. No entanto, como outras soluções da Camada 2 (como Arbitrum, Optimism), o zkSync também precisa considerar o custo adicional de publicação em L1 (taxa de segurança), além do cálculo básico e dos custos de slot de gravação. Como o preço do gás que publica dados em L1 é muito instável, o Operador do zkSync define os seguintes parâmetros dinâmicos quando cada bloco é aberto (começa a registrar transações):
gasPrice: preço do gás em gwei, ou seja, tx.gasprice no objeto de transação mencionado acima
gasPerPubdata: A quantidade de gás necessária para publicar um byte de dados no Ethereum
Além disso, ao contrário do EIP-4337, o zkSync não precisa definir três limites de gás: verifyGas, utionGas e preVerificationGas, mas requer apenas um gasLimit para cobrir todos os custos acima, portanto, os usuários precisam garantir que o gasLimit seja suficiente para cobrir o Fase de verificação, fase de envio e upload de dados Todas as despesas, como taxas de segurança para L1. Este custo de taxa está incluído no tx.gaslimit no objeto de transação mencionado acima.
Multiplique os dois (tx.gasprice * tx.gaslimit) para obter a taxa de transação paga ao bootloader.
Pagador
Paymaster paga principalmente ETH ao bootloader em vez do contrato da conta do usuário na fase de taxa de pagamento da transação do usuário. Os usuários podem escolher diferentes Paymaster e modos de pagamento para pagar a taxa de manuseio, como (mas não limitado a):
Pagamento de tokens ERC-20 ao Paymaster antes do início da transação ou após a execução da transação
Recarregue o contrato Paymaster com cartão de crédito
Paymaster continuará a pagar parte ou todas as taxas para os usuários gratuitamente
A forma como os usuários interagem com o Paymaster depende de diferentes protocolos, pode ser centralizado ou descentralizado; pode ser antes ou depois da transação; pode usar tokens ERC-20 ou moeda legal, ou até mesmo gratuito.
O contrato Paymaster do zkSync consiste principalmente em duas funções, nomeadamente activateAndPayForPaymasterTransaction (obrigatório) e postTransaction (opcional), ambas as quais só podem ser chamadas pelo bootloader:
activateAndPayForPaymasterTransaction é a única função que deve ser implementada em todo o contrato Paymaster. Quando a operadora recebe uma transação com parâmetro Paymaster, significa que a taxa de movimentação não é paga pelo contrato da conta do usuário, mas sim pelo Paymaster. Neste ponto, a operadora chamará activateAndPayForPaymasterTransaction para determinar se o Paymaster está disposto a pagar a taxa de transação. Se o Paymaster concordar, esta função enviará pelo menos tx.gasprice * tx.gaslimit ETH para o bootloader.
postTransaction é uma função opcional, geralmente usada para reembolso (devolver o gás não utilizado ao remetente). No entanto, o zkSync atual ainda não suporta esta operação.
O Paymaster no zkSync executará postTransaction após a implementação do postTransaction, o que é diferente do EIP-4337. O EIP-4337 não chamará postOp quando validPaymasterUserOp não retornar o contexto e vice-versa.
Com base no exposto, por exemplo, o usuário agora deseja enviar uma transação cuja taxa de movimentação é paga pelo Paymaster, o processo é o seguinte:
Na última etapa, mesmo que postTransaction não possa ser executado devido a um erro de falta de gás, esta transação AA é considerada bem-sucedida, mas a ação de chamar postTransaction é omitida.
Se você se aprofundar no Paymaster do zkSync, descobrirá que suas regras de verificação são ligeiramente diferentes de 4337 (o zkSync Paymaster pode pisar em qualquer outro slot de contrato), e também existem vários tipos (como com base em aprovação). Esta parte é devida. para a comparação de detalhes. Os interessados podem consultar documentos oficiais ou minha implementação anterior.
Resumo e comparação
Através das explicações anteriores, aprendemos quais são os pontos de entrada importantes do contrato de conta, bem como suas funções e restrições relacionadas. Ao mesmo tempo, também aprendemos sobre as funções do contrato do sistema. A seguir, vamos resumir o processo de transação de operação automatizada (AA) no zkSync desde a construção até a conclusão, e também fornecerei referências mais detalhadas para quem quiser saber mais:
O usuário usa o SDK ou carteira localmente para construir objetos de transação (por exemplo: de, para, dados, valor, etc.).
O usuário assina a transação. A assinatura aqui não é necessariamente o formato tradicional EIP-712 e a assinatura da curva ECDSA. zkSync também oferece suporte a EIP-2718 e EIP-1559. A chave para escolher um método de assinatura e um método de verificação é verificar por meio da função de verificação no contrato da conta.
Envie a transação assinada ao operador através da API RPC. Neste ponto, a transação entra no estado pendente. O operador passa a transação para o bootloader (chama a função processL2Tx no contrato do bootloader) e inicia uma série de processos do protocolo AA.
O Bootloader verificará se o Nonce é legal e usará o NonceHolder para verificar.
O Bootloader chamará a função activateTransaction no contrato da conta do usuário para confirmar que a transação foi autorizada pelo proprietário da conta.
Existem duas maneiras de o Bootloader cobrar taxas, e o método de cobrança específico depende dos parâmetros da transação (se o parâmetro paymaster está anexado ao construir o objeto de transação):
a. Chame a função payForTransaction e o contrato da conta para cobrar a taxa de transação;
b. Chame as funções prepareForPaymaster e activateAndPayForPaymasterTransaction para cobrar a taxa de transação com o contrato Paymaster.
"Ligue para payForTransaction para contratar a taxa com a conta" ou "ligue para prepareForPaymaster e validAndPayForPaymasterTransaction para contratar a taxa com o Paymaster"
Verifique se o bootloader recebeu pelo menos taxas de transação tx.gasprice * tx.gaslimit.
O Bootloader chamará a função uteTransaction no contrato da conta do usuário para executar a transação.
(Opcional) Se estiver usando o Paymaster para pagar a taxa de transação, o bootloader chamará a função postTransaction. Se o Paymaster não implementar postTransaction ou se o gás acabar, esta etapa será ignorada.
As etapas 4 a 7 acima são a fase de verificação (definida no l2TxValidation do bootloader) e a fase de execução das etapas 8 a 9 (definida no l2Txution do bootloader).
Comparação de EIP-4337, StarkNet e zkSync Era
Basicamente, os processos do mecanismo AA dos três são semelhantes, sendo todos fase de verificação→mecanismo de taxa de manuseio (pago por contrato de conta ou Paymaster)→fase de execução.As principais diferenças são:
Comparado
Além disso, concluímos o mempool P2P para o empacotador 4337 atual, e o sequenciador e o operador de zkRollups também são os únicos servidores oficiais, portanto, existem certos componentes centralizados.
No processo de desenvolvimento, como o zkSync não tem problemas de conexão com vários bundlers (só precisa interagir com a API do Operador), é fácil de usar o 4337, e a experiência de desenvolvimento de contratos de conta (SDK) também é melhor; em ao mesmo tempo, zkSync pode usar Solidity como uma linguagem de desenvolvimento de contrato, portanto, não há necessidade de cruzar o limiar do Cairo no desenvolvimento StarkNet.
Conclusão
Como StarkNet e zkSync pertencem à categoria de AA local (AA nativo), você também pode consultar minha introdução anterior ao StarkNet AA, intitulada "Introdução à abstração de conta StarkNet" (Introdução à abstração de conta StarkNet). Além disso, você pode ler outros artigos relacionados ao EIP-4337 para obter mais informações.