Este artículo presenta principalmente el desarrollo y el contenido relacionado de cuentas abstractas (AA, cuentas abstractas) en la solución de Capa 2 de zkSync. La atención se centrará en tres partes:
Contrato de cuenta: tipo de cuenta, punto de entrada importante y puntos clave relacionados del contrato de cuenta
Transacción: método de verificación, método de ejecución y proceso de transacción AA
Tarifa de gestión: tarifa de transacción, Paymaster
Tabla de contenido
prefacio
Breve descripción general del contrato zkSync AA
Modelo de tarifas y Paymaster en la era de zkSync
Resumen y comparación
Conclusión
fondo
Familiarizado con la billetera de contrato inteligente y sus características comunes.
Obtenga una descripción general de cómo funcionan las transacciones de Ethereum
Una comprensión general del modo de funcionamiento de EIP-4337.
Una comprensión general del modo de operación de ZK (validez) Rollup
Vista rápida a zkSync
Aquí, para facilitar la lectura, no es necesario comprender zkSync en profundidad, sino revisar brevemente la información básica de zkSync. Hay dos versiones principales de zkSync, la versión 1.0 (zkSync Lite) y la versión 2.0 (zkSync Era).
La versión 1.0 de zkSync solo admite EOA (cuenta externa) y no admite contratos inteligentes (solo admite transferencia e intercambio de tokens), mientras que zkSync 2.0, es decir, zkSync Era, pertenece a AA nativa (cuenta abstracta) (todos los tipos de cuentas son contratos, no EOA , que es la diferencia entre EOA y cuenta de contrato en Ethereum), es compatible con EVM (Ethereum Virtual Machine) y admite el desarrollo de contratos inteligentes utilizando Rust, Yul, Vyper, Solidity, etc.
El zkSync mencionado a continuación se refiere a zkSync 2.0, es decir, zkSync Era, a menos que se especifique lo contrario.
En zkSync Era, existen múltiples contratos, que pueden entenderse porque implementan algunas funciones importantes del sistema operativo de zkSync en contratos inteligentes. Estos contratos son contratos precompilados que nunca se han implementado (se ejecutan directamente en el nodo), pero todos tienen una dirección formal.
Al implementar el protocolo AA, zkSync realizará operaciones lógicas y juicios a través de algunos contratos. Por ejemplo, al verificar nonce, es juzgado por NonceHolder, mientras que la implementación del mecanismo de cuenta abstracta y el cobro de tarifas son juzgados por el gestor de arranque. A continuación se presentará ellos uno por uno.
Resumen de la abstracción de la cuenta
El concepto central de abstracción de cuentas se puede resumir en dos puntos clave: abstracción de firmas y abstracción de pagos.
El objetivo de la abstracción de firma es permitir que varios contratos de cuentas utilicen diferentes esquemas de verificación. Esto significa que los usuarios no están limitados a un algoritmo de firma digital que sólo puede utilizar una curva específica, sino que pueden elegir cualquier mecanismo de verificación que deseen.
La abstracción de pago tiene como objetivo proporcionar a los usuarios una variedad de opciones de pago de transacciones. Por ejemplo, los pagos podrían realizarse utilizando tokens ERC-20 en lugar de tokens nativos, o las transacciones podrían ser patrocinadas por un tercero, o incluso otros modelos de pago más ad hoc.
Las cuentas en zkSync 2.0 pueden iniciar transacciones como EOA, pero también pueden usar su programabilidad para implementar lógica arbitraria, como cuentas de contrato. Esto es lo que llamamos Account Abstraction, que combina las ventajas de los dos tipos de cuentas en Ethereum para flexibilizar la experiencia de uso de cuentas AA, logrando así los dos objetivos anteriores: abstracción de firmas y abstracción de pagos.
Mecanismo AA en la era zkSync
En zkSync Era, la función más importante de zkSync AA es el gestor de arranque, que es un contrato, utilizado principalmente para procesar transacciones y ejecutar el mecanismo AA, correspondiente al contrato de punto de entrada de EIP-4337. El usuario no puede llamar al gestor de arranque (solo puede activarlo el Operador) y nunca se ha implementado (se ejecuta directamente en el nodo), pero tiene una dirección oficial (se puede usar para recibir pagos).
El operador es un rol importante en ZK Rollup. Es un servidor centralizado fuera de la cadena. Similar al secuenciador que habrás visto, es responsable de activar contratos como el gestor de arranque desde el exterior.
Los protocolos de abstracción de cuentas nativas (como StarkNet, zkSync) están diseñados básicamente con referencia a EIP-4337. En la implementación de zkSync, el usuario enviará la transacción al Operador, y el Operador enviará la transacción al gestor de arranque e iniciará una serie de procesamiento.
Desde el punto de vista del bloque:
Cuando el gestor de arranque recibe información del Operador, primero definirá algunas variables de entorno para el bloque (como el precio del gas, el número de bloque, la marca de tiempo del bloque, etc.). Luego, el gestor de arranque leerá secuencialmente la lista de transacciones, primero consultará si el contrato de la cuenta coincide con la transacción (es decir, llamará a la función de validación en el mecanismo AA) y luego las colocará en el bloque.
Después de verificar cada transacción, el operador verifica si el bloque es lo suficientemente grande como para enviarlo al verificador (o si se agota el tiempo de espera). Si es lo suficientemente grande o se agota el tiempo de espera, el operador cierra el bloque, deja de agregar nuevas transacciones al gestor de arranque y completa la ejecución de la transacción.
Desde la perspectiva de las transacciones, cuando el Operador activa el gestor de arranque, el gestor de arranque procesará cada transacción secuencialmente:
Confirmar si el nonce correspondiente a la dirección del contrato de la cuenta de usuario es legal
Llame a la función de validación en el contrato de la cuenta de usuario para su verificación.
Una vez aprobada la verificación, el contrato de la cuenta enviará la tarifa del gas a la dirección del gestor de arranque (o a través de Paymaster, que se presentará más adelante), y el gestor de arranque comprobará si ha recibido suficiente dinero.
Llame a la función ute en el contrato de la cuenta de usuario para ejecutar la transacción.
Los primeros tres pasos anteriores corresponden al bucle de verificación (Verification Loop) de EIP-4337, y el cuarto paso corresponde al bucle de ejecución (ution Loop) de EIP-4337.
Aquí se ofrece principalmente una introducción general, y los detalles y funciones de cada paso se detallarán uno por uno en la siguiente descripción detallada.
Resumen rápido del contrato de cuenta abstracta de zkSync
Mientras tanto
El nonce de cuenta de zkSync se registra en un contrato del sistema llamado NonceHolder, que recuerda si cada par (cuenta _dirección, nonce) se utiliza mediante mapeo (mapping) para juzgar si el nonce es legal.
De acuerdo con lo anterior, el primer paso después de que el Operador activa el gestor de arranque es verificar el nonce. Por lo tanto, antes de que comience cada transacción, se utilizará NonceHolder para confirmar si el conjunto de nonces actualmente utilizado es legal (actualmente solo verifica si se han utilizado). Si el nonce es legal entrará en la fase de verificación (Verification Phase), momento en el cual el nonce se marcará como usado; si no es legal la transacción (verificación) fallará.
Puntos importantes sobre el nonce actual de zkSync:
Aunque actualmente los usuarios pueden enviar múltiples transacciones con diferentes nonces a la cuenta para su ejecución al mismo tiempo, dado que zkSync no admite el procesamiento paralelo, las transacciones con diferentes nonces aún se procesarán secuencialmente.
En teoría, los usuarios pueden usar cualquier entero distinto de cero de 256 bits como nonce, pero zkSync aún recomienda usar incrementNonceIfEquals como una forma de administrar el nonce para garantizar que se incremente en orden (actualmente, el mecanismo AA de zkSync solo confirma el nonce no utilizado, pero el oficial documento indica que el incremento secuencial puede ser necesario en el futuro).
Contrato de cuenta
El contrato de cuenta en zkSync tiene los siguientes cuatro puntos de entrada necesarios (Entry Point), que son:
validarTransacción: se llama durante la fase de verificación para confirmar si la operación está autorizada por el propietario de la cuenta, donde los usuarios pueden personalizar su propia lógica de verificación (como varios algoritmos de firma, firma múltiple, etc.).
payForTransaction: cuando esta cuenta paga la tarifa de transacción (en lugar de usar paymaster), el operador llamará a esta función para pagar al menos tx.gasprice * tx.gaslimit de ETH a la dirección del gestor de arranque.
prepareForPaymaster: cuando Paymaster pagará la tarifa de transacción, el operador llamará a esta función para completar el trabajo preparatorio antes de interactuar con Paymaster. El ejemplo proporcionado por zkSync es un token ERC-20 aprobado por Paymaster.
uteTransaction: una vez superada con éxito la fase de verificación y cobrada correctamente la tarifa de transacción, esta función se utilizará para realizar la operación que el usuario desea lograr (como interactuar con el contrato, remesa, etc.).
Acerca de Paymaster, el monto de la tarifa de manejo (tx.gasprice * tx.gaslimit), etc., se explicará en capítulos posteriores.
También hay una función de seguro no esencial uteTransactionFromOutside en la cuenta de zkSync. Los fondos se pueden retirar a L1 utilizando el "mecanismo de escape" cuando no se pueden realizar operaciones (como cuando el generador de secuencia no responde o se considera que zkSync es un riesgo regulatorio). Esta parte tiene poco que ver con el protocolo AA, por lo que no se describirá en detalle aquí, los interesados pueden consultar los documentos oficiales y las especificaciones de zkSync.
Puntos clave y limitaciones de las funciones de validación
En la función validarTransacción, se pueden implementar varias lógicas personalizadas. Por ejemplo, si la cuenta ha implementado el estándar EIP-1271, la lógica de verificación en EIP-1271 se puede aplicar directamente a validarTransacción o consultar el contrato de cuenta de firma múltiple. Implementación en el documento oficial de zkSync.
Al mismo tiempo, para evitar amenazas DoS en la fase de verificación de EIP-4337, existen algunas restricciones (no pueden involucrar códigos de operación externos y profundidad limitada, etc.), y existen restricciones similares en zkSync, por ejemplo:
1. La lógica del contrato solo puede tocar su propia ranura (si la dirección del contrato de la cuenta es A):
ranura perteneciente a la dirección A
ranura A en cualquier otra dirección
La ranura keccak256(A||X) de cualquier otra dirección, que puede usar directamente la dirección como clave de mapeo (como mapeo (dirección=>valor)), también equivale a permitir el acceso a la ranura keccak256( A||X), para lograr la expansión. Por ejemplo, saldos de tokens en ERC-20.
2. La lógica del contrato no debe utilizar variables globales, como block.number
Puntos clave y limitaciones de la ejecución de funciones
Lo que hay que tener en cuenta en la función uteTransaction es que si desea realizar una llamada al sistema (Llamada), debe asegurarse de que tenga el indicador is. Debido a que estos contratos del sistema tienen un gran impacto en el sistema de cuentas. Por ejemplo, la única forma de aumentar el nonce es interactuar con NonceHolder. Para implementar un contrato, debe interactuar con ContractDeployer. El uso del indicador is puede garantizar que los desarrolladores de cuentas interactúen conscientemente con contratos sistema.
Sin embargo, se recomienda utilizar la biblioteca ContractsCaller proporcionada por zkSync para evitar manejar el indicador is usted mismo y utilizar CallWithPropagatedRevert para completar la llamada al sistema.
El ejemplo de código anterior implica interactuar con DEPLOYER__CONTRACT. La situación de contrato del sistema más común que encuentran los desarrolladores de cuentas es que queremos usar una cuenta para implementar un contrato, en este momento debemos interactuar con el contrato del sistema ContractDeployer. En este caso, el desarrollador de la cuenta debe comunicarse con el contrato ContractDeployer para garantizar que el contrato se implemente correctamente y realice las operaciones requeridas.
Modelo de tarifas y Paymaster en la era de zkSync
Tarifas y límite de gasolina
El modelo de tarifa de zkSync es muy similar al de Ethereum, el token de tarifa sigue siendo ETH. Sin embargo, al igual que otras soluciones de Capa 2 (como Arbitrum, Optimism), zkSync también debe considerar el costo adicional de publicación en L1 (tarifa de seguridad) además del cálculo básico y los costos de ranura de escritura. Dado que el precio del gas que publica datos en L1 es muy inestable, el Operador de zkSync define los siguientes parámetros dinámicos cuando se abre cada bloque (comienza a registrar transacciones):
gasPrice: precio del gas en gwei, es decir, tx.gasprice en el objeto de transacción mencionado anteriormente
gasPerPubdata: La cantidad de gas necesaria para publicar un byte de datos en Ethereum
Además, a diferencia de EIP-4337, zkSync no necesita definir tres límites de gas: verificarGas, utionGas y preVerificationGas, sino que solo requiere un gasLimit para cubrir todos los costos anteriores, por lo que los usuarios deben asegurarse de que gasLimit sea suficiente para cubrir el Etapa de verificación, etapa de verificación y carga de datos. Todos los gastos, como tarifas de seguridad a L1. Este costo de tarifa está incluido en el límite de tx.gas en el objeto de transacción mencionado anteriormente.
Multiplique los dos (tx.gasprice * tx.gaslimit) para que la tarifa de transacción se pague al gestor de arranque.
Pagador
Paymaster paga principalmente ETH al gestor de arranque en lugar del contrato de cuenta del usuario en la etapa de pago de la tarifa de transacción del usuario. Los usuarios pueden elegir diferentes Paymaster y modos de pago para pagar la tarifa de manejo, tales como (pero no limitados a):
Pago de tokens ERC-20 a Paymaster antes de que se inicie la transacción o después de que se ejecute la transacción
Recargar el contrato Paymaster con tarjeta de crédito
Paymaster seguirá pagando parte o la totalidad de las tarifas de los usuarios de forma gratuita
La forma en que los usuarios interactúan con Paymaster depende de diferentes protocolos, puede ser centralizado o descentralizado; puede ser antes o después de la transacción; puede usar tokens ERC-20 o moneda de curso legal, o incluso gratis.
El contrato Paymaster de zkSync consta principalmente de dos funciones, a saber, validarAndPayForPaymasterTransaction (obligatorio) y postTransaction (opcional), las cuales solo pueden ser invocadas por el gestor de arranque:
ValidarAndPayForPaymasterTransaction es la única función que debe implementarse en todo el contrato Paymaster. Cuando el operador recibe una transacción con un parámetro Paymaster, significa que la tarifa de manejo no la paga el contrato de cuenta del usuario, sino Paymaster. En este punto, el operador llamará a validarAndPayForPaymasterTransaction para determinar si el Paymaster está dispuesto a pagar la tarifa de transacción. Si Paymaster está de acuerdo, esta función enviará al menos tx.gasprice * tx.gaslimit ETH al gestor de arranque.
postTransaction es una función opcional, generalmente utilizada para reembolso (devolver el gas no utilizado al remitente). Sin embargo, el zkSync actual aún no admite esta operación.
Paymaster en zkSync ejecutará postTransaction después de implementar postTransaction, que es diferente de EIP-4337. EIP-4337 no llamará a postOp cuando validarPaymasterUserOp no devuelve el contexto, y viceversa.
Con base en lo anterior, por ejemplo, el usuario ahora desea enviar una transacción cuya tarifa de manejo la paga Paymaster, el proceso es el siguiente:
Utilice NonceHolder para confirmar si el nonce es legal
Llame a validarTransacción en el Contrato de cuenta del usuario para verificar que la transacción esté autorizada por el propietario de la cuenta.
Llame a prepareForPaymaster en el contrato de cuenta del usuario, que puede ejecutar, por ejemplo, aprobar una cierta cantidad de tokens ERC-20 para Paymaster o no hacer nada.
Llame a validarAndPayForPaymasterTransaction en el Contrato Paymaster para confirmar que Paymaster está dispuesto a pagar y cobrar la tarifa de manejo y, al mismo tiempo, Paymaster le cobrará al usuario una cierta cantidad de ERC-20 (aprobado anteriormente).
Confirme que el gestor de arranque reciba la cantidad correcta (al menos tx.gasprice * tx.gaslimit) de tarifas ETH
Llame a uteTransaction en el contrato de cuenta del usuario para ejecutar la transacción que el usuario desea.
Si el Contrato Pagador implementa la postTransacción y el gas aún es suficiente (sin error de falta de gas), entonces ejecute la postTransacción.
En el último paso, incluso si postTransaction no se puede ejecutar debido a un error de falta de gas, esta transacción AA se considera exitosa, pero se omite la acción de llamar a postTransaction.
Si profundiza en el Paymaster de zkSync, encontrará que sus Reglas de verificación son ligeramente diferentes de las 4337 (zkSync Paymaster puede ocupar cualquier otro espacio de contrato), y también hay varios tipos (como los basados en aprobación). A la comparación de detalles, aquellos que estén interesados pueden consultar los documentos oficiales o mi implementación anterior.
Resumen y comparación
A través de las explicaciones anteriores, hemos aprendido qué puntos de entrada importantes tiene el contrato de cuenta, así como sus funciones y restricciones relacionadas. Al mismo tiempo, también aprendimos sobre las funciones del contrato sistema. A continuación, resumamos el proceso de una transacción de operación automatizada (AA) en zkSync desde su construcción hasta su finalización, y también proporcionaré referencias más detalladas para aquellos que quieran obtener más información:
El usuario utiliza el SDK o la billetera localmente para construir objetos de transacción (por ejemplo: desde, hacia, datos, valor, etc.).
El usuario firma la transacción. La firma aquí no es necesariamente el formato tradicional EIP-712 y la firma curva ECDSA. zkSync también es compatible con EIP-2718 y EIP-1559. La clave para elegir un método de firma y un método de verificación es verificar a través de la función de verificación en el contrato de la cuenta.
Envíe la transacción firmada al operador a través de la API RPC. En este punto la transacción entra en estado pendiente. El operador pasa la transacción al gestor de arranque (llama a la función ProcessL2Tx en el contrato del gestor de arranque) e inicia una serie de procesos del protocolo AA.
El gestor de arranque comprobará si Nonce es legal y utilizará NonceHolder para comprobarlo.
El gestor de arranque llamará a la función validarTransacción en el contrato de la cuenta del usuario para confirmar que la transacción ha sido autorizada por el propietario de la cuenta.
Hay dos formas en que Bootloader cobra tarifas, y el método de cobro específico depende de los parámetros de la transacción (si el parámetro pagador está adjunto al construir el objeto de transacción):
a. Llame a la función payForTransaction y al contrato de cuenta para cobrar la tarifa de transacción;
b. Llame a las funciones prepareForPaymaster y validarAndPayForPaymasterTransaction para cobrar la tarifa de transacción con el contrato Paymaster.
"Llame a payForTransaction para contratar la tarifa con la Cuenta" o "llame a prepareForPaymaster y valideAndPayForPaymasterTransaction para contratar la tarifa con Paymaster"
Verifique si el gestor de arranque ha recibido al menos tx.gasprice * tx.gaslimit tarifas de transacción.
El gestor de arranque llamará a la función uteTransaction en el contrato de la cuenta del usuario para ejecutar la transacción.
(Opcional) Si usa Paymaster para pagar la tarifa de transacción, el gestor de arranque llamará a la función postTransaction. Si Paymaster no implementa postTransaction o se agota el gas, se omitirá este paso.
Los pasos 4.~7. anteriores son la fase de verificación (definida en l2TxValidation del gestor de arranque) y la fase de ejecución de los pasos 8.~9 (definida en l2Txution del gestor de arranque).
Comparación de EIP-4337, StarkNet y zkSync Era
Básicamente, los procesos del mecanismo AA de los tres son similares, todos los cuales son etapa de verificación → mecanismo de tarifa de manejo (pagado por contrato de cuenta o pagador) → etapa de ejecución. Las principales diferencias son:
La función de implementar el mecanismo AA es: la diferencia entre abrir en la era zkSync y los otros dos AA es que el Operador necesita cooperar con el gestor de arranque (contrato del sistema), por ejemplo, el gestor de arranque abrirá un nuevo bloque y definirá los parámetros relevantes del bloque y recibir la operación El comerciante enviado por el miembro y verificado. En 4337, esta parte está coordinada por Bundler y EntryPoint, mientras que en StarkNet, esta parte está a cargo de Sequencer.
¿El costo del gas debe considerar la tarifa de seguridad L1?: L2 AA debe considerar el costo de cargar datos en L1, no solo los ZK (Validez) Rollups Native AA mencionados en el envío, sino que también debe incluirse en L1 cuando es optimista. Los paquetes acumulativos implementan la tarifa de seguridad 4337 (calculada en preVerificationGas, consulte los documentos relacionados con Alchemy para obtener más detalles).
Si es posible enviar transacciones antes de que se implemente el contrato de cuenta: en la era de StarkNet y zkSync, no existe un EntryPoint como 4337 que tenga el campo initCode para permitir al usuario implementar el contrato de cuenta, por lo que no envía transacciones. antes de poder configurar la cuenta.
Comparado
Dado que StarkNet aún no ha implementado el mecanismo Paymaster y zkSync aún no ha completado el diseño del mecanismo de reembolso de gas, aquí no se enumeran algunas comparaciones más detalladas.
Además, hemos completado el mempool P2P para el paquete 4337 actual, y el secuenciador y operador de zkRollups también son los únicos servidores oficiales, por lo que hay ciertos componentes centralizados.
En el proceso de desarrollo, dado que zkSync no tiene el problema de conectarse con varios paquetes (solo necesita interactuar con la API del Operador), es fácil de usar 4337 y la experiencia de desarrollar contratos de cuenta (SDK) también es mejor; en Al mismo tiempo, zkSync puede utilizar Solidity como lenguaje de desarrollo por contrato, por lo que no es necesario cruzar el umbral de El Cairo en el desarrollo de StarkNet.
Conclusión
Dado que tanto StarkNet como zkSync pertenecen a la categoría de AA local (AA nativo), también puede consultar mi introducción anterior a StarkNet AA, titulada "Introducción a la abstracción de cuentas StarkNet" (Introducción a la abstracción de cuentas StarkNet). Además, puede leer otros artículos relacionados con EIP-4337 para obtener más información.
Ver originales
Esta página puede contener contenido de terceros, que se proporciona únicamente con fines informativos (sin garantías ni declaraciones) y no debe considerarse como un respaldo por parte de Gate a las opiniones expresadas ni como asesoramiento financiero o profesional. Consulte el Descargo de responsabilidad para obtener más detalles.
Introducción a la abstracción de cuentas nativa en zkSync
Autor: Escrito por ChiHaoLu, imToken Labs
Este artículo presenta principalmente el desarrollo y el contenido relacionado de cuentas abstractas (AA, cuentas abstractas) en la solución de Capa 2 de zkSync. La atención se centrará en tres partes:
Tabla de contenido
fondo
Aquí, para facilitar la lectura, no es necesario comprender zkSync en profundidad, sino revisar brevemente la información básica de zkSync. Hay dos versiones principales de zkSync, la versión 1.0 (zkSync Lite) y la versión 2.0 (zkSync Era).
La versión 1.0 de zkSync solo admite EOA (cuenta externa) y no admite contratos inteligentes (solo admite transferencia e intercambio de tokens), mientras que zkSync 2.0, es decir, zkSync Era, pertenece a AA nativa (cuenta abstracta) (todos los tipos de cuentas son contratos, no EOA , que es la diferencia entre EOA y cuenta de contrato en Ethereum), es compatible con EVM (Ethereum Virtual Machine) y admite el desarrollo de contratos inteligentes utilizando Rust, Yul, Vyper, Solidity, etc.
El zkSync mencionado a continuación se refiere a zkSync 2.0, es decir, zkSync Era, a menos que se especifique lo contrario.
En zkSync Era, existen múltiples contratos, que pueden entenderse porque implementan algunas funciones importantes del sistema operativo de zkSync en contratos inteligentes. Estos contratos son contratos precompilados que nunca se han implementado (se ejecutan directamente en el nodo), pero todos tienen una dirección formal.
Al implementar el protocolo AA, zkSync realizará operaciones lógicas y juicios a través de algunos contratos. Por ejemplo, al verificar nonce, es juzgado por NonceHolder, mientras que la implementación del mecanismo de cuenta abstracta y el cobro de tarifas son juzgados por el gestor de arranque. A continuación se presentará ellos uno por uno.
Resumen de la abstracción de la cuenta
El concepto central de abstracción de cuentas se puede resumir en dos puntos clave: abstracción de firmas y abstracción de pagos.
El objetivo de la abstracción de firma es permitir que varios contratos de cuentas utilicen diferentes esquemas de verificación. Esto significa que los usuarios no están limitados a un algoritmo de firma digital que sólo puede utilizar una curva específica, sino que pueden elegir cualquier mecanismo de verificación que deseen.
La abstracción de pago tiene como objetivo proporcionar a los usuarios una variedad de opciones de pago de transacciones. Por ejemplo, los pagos podrían realizarse utilizando tokens ERC-20 en lugar de tokens nativos, o las transacciones podrían ser patrocinadas por un tercero, o incluso otros modelos de pago más ad hoc.
Las cuentas en zkSync 2.0 pueden iniciar transacciones como EOA, pero también pueden usar su programabilidad para implementar lógica arbitraria, como cuentas de contrato. Esto es lo que llamamos Account Abstraction, que combina las ventajas de los dos tipos de cuentas en Ethereum para flexibilizar la experiencia de uso de cuentas AA, logrando así los dos objetivos anteriores: abstracción de firmas y abstracción de pagos.
Mecanismo AA en la era zkSync
En zkSync Era, la función más importante de zkSync AA es el gestor de arranque, que es un contrato, utilizado principalmente para procesar transacciones y ejecutar el mecanismo AA, correspondiente al contrato de punto de entrada de EIP-4337. El usuario no puede llamar al gestor de arranque (solo puede activarlo el Operador) y nunca se ha implementado (se ejecuta directamente en el nodo), pero tiene una dirección oficial (se puede usar para recibir pagos).
El operador es un rol importante en ZK Rollup. Es un servidor centralizado fuera de la cadena. Similar al secuenciador que habrás visto, es responsable de activar contratos como el gestor de arranque desde el exterior.
Los protocolos de abstracción de cuentas nativas (como StarkNet, zkSync) están diseñados básicamente con referencia a EIP-4337. En la implementación de zkSync, el usuario enviará la transacción al Operador, y el Operador enviará la transacción al gestor de arranque e iniciará una serie de procesamiento.
Desde el punto de vista del bloque:
Cuando el gestor de arranque recibe información del Operador, primero definirá algunas variables de entorno para el bloque (como el precio del gas, el número de bloque, la marca de tiempo del bloque, etc.). Luego, el gestor de arranque leerá secuencialmente la lista de transacciones, primero consultará si el contrato de la cuenta coincide con la transacción (es decir, llamará a la función de validación en el mecanismo AA) y luego las colocará en el bloque.
Después de verificar cada transacción, el operador verifica si el bloque es lo suficientemente grande como para enviarlo al verificador (o si se agota el tiempo de espera). Si es lo suficientemente grande o se agota el tiempo de espera, el operador cierra el bloque, deja de agregar nuevas transacciones al gestor de arranque y completa la ejecución de la transacción.
Desde la perspectiva de las transacciones, cuando el Operador activa el gestor de arranque, el gestor de arranque procesará cada transacción secuencialmente:
Los primeros tres pasos anteriores corresponden al bucle de verificación (Verification Loop) de EIP-4337, y el cuarto paso corresponde al bucle de ejecución (ution Loop) de EIP-4337.
Aquí se ofrece principalmente una introducción general, y los detalles y funciones de cada paso se detallarán uno por uno en la siguiente descripción detallada.
Resumen rápido del contrato de cuenta abstracta de zkSync
Mientras tanto
El nonce de cuenta de zkSync se registra en un contrato del sistema llamado NonceHolder, que recuerda si cada par (cuenta _dirección, nonce) se utiliza mediante mapeo (mapping) para juzgar si el nonce es legal.
De acuerdo con lo anterior, el primer paso después de que el Operador activa el gestor de arranque es verificar el nonce. Por lo tanto, antes de que comience cada transacción, se utilizará NonceHolder para confirmar si el conjunto de nonces actualmente utilizado es legal (actualmente solo verifica si se han utilizado). Si el nonce es legal entrará en la fase de verificación (Verification Phase), momento en el cual el nonce se marcará como usado; si no es legal la transacción (verificación) fallará.
Puntos importantes sobre el nonce actual de zkSync:
Aunque actualmente los usuarios pueden enviar múltiples transacciones con diferentes nonces a la cuenta para su ejecución al mismo tiempo, dado que zkSync no admite el procesamiento paralelo, las transacciones con diferentes nonces aún se procesarán secuencialmente.
En teoría, los usuarios pueden usar cualquier entero distinto de cero de 256 bits como nonce, pero zkSync aún recomienda usar incrementNonceIfEquals como una forma de administrar el nonce para garantizar que se incremente en orden (actualmente, el mecanismo AA de zkSync solo confirma el nonce no utilizado, pero el oficial documento indica que el incremento secuencial puede ser necesario en el futuro).
Contrato de cuenta
El contrato de cuenta en zkSync tiene los siguientes cuatro puntos de entrada necesarios (Entry Point), que son:
Acerca de Paymaster, el monto de la tarifa de manejo (tx.gasprice * tx.gaslimit), etc., se explicará en capítulos posteriores.
También hay una función de seguro no esencial uteTransactionFromOutside en la cuenta de zkSync. Los fondos se pueden retirar a L1 utilizando el "mecanismo de escape" cuando no se pueden realizar operaciones (como cuando el generador de secuencia no responde o se considera que zkSync es un riesgo regulatorio). Esta parte tiene poco que ver con el protocolo AA, por lo que no se describirá en detalle aquí, los interesados pueden consultar los documentos oficiales y las especificaciones de zkSync.
Puntos clave y limitaciones de las funciones de validación
En la función validarTransacción, se pueden implementar varias lógicas personalizadas. Por ejemplo, si la cuenta ha implementado el estándar EIP-1271, la lógica de verificación en EIP-1271 se puede aplicar directamente a validarTransacción o consultar el contrato de cuenta de firma múltiple. Implementación en el documento oficial de zkSync.
Al mismo tiempo, para evitar amenazas DoS en la fase de verificación de EIP-4337, existen algunas restricciones (no pueden involucrar códigos de operación externos y profundidad limitada, etc.), y existen restricciones similares en zkSync, por ejemplo:
1. La lógica del contrato solo puede tocar su propia ranura (si la dirección del contrato de la cuenta es A):
ranura perteneciente a la dirección A
ranura A en cualquier otra dirección
La ranura keccak256(A||X) de cualquier otra dirección, que puede usar directamente la dirección como clave de mapeo (como mapeo (dirección=>valor)), también equivale a permitir el acceso a la ranura keccak256( A||X), para lograr la expansión. Por ejemplo, saldos de tokens en ERC-20.
2. La lógica del contrato no debe utilizar variables globales, como block.number
Puntos clave y limitaciones de la ejecución de funciones
Lo que hay que tener en cuenta en la función uteTransaction es que si desea realizar una llamada al sistema (Llamada), debe asegurarse de que tenga el indicador is. Debido a que estos contratos del sistema tienen un gran impacto en el sistema de cuentas. Por ejemplo, la única forma de aumentar el nonce es interactuar con NonceHolder. Para implementar un contrato, debe interactuar con ContractDeployer. El uso del indicador is puede garantizar que los desarrolladores de cuentas interactúen conscientemente con contratos sistema.
Sin embargo, se recomienda utilizar la biblioteca ContractsCaller proporcionada por zkSync para evitar manejar el indicador is usted mismo y utilizar CallWithPropagatedRevert para completar la llamada al sistema.
El ejemplo de código anterior implica interactuar con DEPLOYER__CONTRACT. La situación de contrato del sistema más común que encuentran los desarrolladores de cuentas es que queremos usar una cuenta para implementar un contrato, en este momento debemos interactuar con el contrato del sistema ContractDeployer. En este caso, el desarrollador de la cuenta debe comunicarse con el contrato ContractDeployer para garantizar que el contrato se implemente correctamente y realice las operaciones requeridas.
Modelo de tarifas y Paymaster en la era de zkSync
Tarifas y límite de gasolina
El modelo de tarifa de zkSync es muy similar al de Ethereum, el token de tarifa sigue siendo ETH. Sin embargo, al igual que otras soluciones de Capa 2 (como Arbitrum, Optimism), zkSync también debe considerar el costo adicional de publicación en L1 (tarifa de seguridad) además del cálculo básico y los costos de ranura de escritura. Dado que el precio del gas que publica datos en L1 es muy inestable, el Operador de zkSync define los siguientes parámetros dinámicos cuando se abre cada bloque (comienza a registrar transacciones):
gasPrice: precio del gas en gwei, es decir, tx.gasprice en el objeto de transacción mencionado anteriormente
gasPerPubdata: La cantidad de gas necesaria para publicar un byte de datos en Ethereum
Además, a diferencia de EIP-4337, zkSync no necesita definir tres límites de gas: verificarGas, utionGas y preVerificationGas, sino que solo requiere un gasLimit para cubrir todos los costos anteriores, por lo que los usuarios deben asegurarse de que gasLimit sea suficiente para cubrir el Etapa de verificación, etapa de verificación y carga de datos. Todos los gastos, como tarifas de seguridad a L1. Este costo de tarifa está incluido en el límite de tx.gas en el objeto de transacción mencionado anteriormente.
Multiplique los dos (tx.gasprice * tx.gaslimit) para que la tarifa de transacción se pague al gestor de arranque.
Pagador
Paymaster paga principalmente ETH al gestor de arranque en lugar del contrato de cuenta del usuario en la etapa de pago de la tarifa de transacción del usuario. Los usuarios pueden elegir diferentes Paymaster y modos de pago para pagar la tarifa de manejo, tales como (pero no limitados a):
Pago de tokens ERC-20 a Paymaster antes de que se inicie la transacción o después de que se ejecute la transacción
Recargar el contrato Paymaster con tarjeta de crédito
Paymaster seguirá pagando parte o la totalidad de las tarifas de los usuarios de forma gratuita
La forma en que los usuarios interactúan con Paymaster depende de diferentes protocolos, puede ser centralizado o descentralizado; puede ser antes o después de la transacción; puede usar tokens ERC-20 o moneda de curso legal, o incluso gratis.
El contrato Paymaster de zkSync consta principalmente de dos funciones, a saber, validarAndPayForPaymasterTransaction (obligatorio) y postTransaction (opcional), las cuales solo pueden ser invocadas por el gestor de arranque:
ValidarAndPayForPaymasterTransaction es la única función que debe implementarse en todo el contrato Paymaster. Cuando el operador recibe una transacción con un parámetro Paymaster, significa que la tarifa de manejo no la paga el contrato de cuenta del usuario, sino Paymaster. En este punto, el operador llamará a validarAndPayForPaymasterTransaction para determinar si el Paymaster está dispuesto a pagar la tarifa de transacción. Si Paymaster está de acuerdo, esta función enviará al menos tx.gasprice * tx.gaslimit ETH al gestor de arranque.
postTransaction es una función opcional, generalmente utilizada para reembolso (devolver el gas no utilizado al remitente). Sin embargo, el zkSync actual aún no admite esta operación.
Paymaster en zkSync ejecutará postTransaction después de implementar postTransaction, que es diferente de EIP-4337. EIP-4337 no llamará a postOp cuando validarPaymasterUserOp no devuelve el contexto, y viceversa.
Con base en lo anterior, por ejemplo, el usuario ahora desea enviar una transacción cuya tarifa de manejo la paga Paymaster, el proceso es el siguiente:
En el último paso, incluso si postTransaction no se puede ejecutar debido a un error de falta de gas, esta transacción AA se considera exitosa, pero se omite la acción de llamar a postTransaction.
Si profundiza en el Paymaster de zkSync, encontrará que sus Reglas de verificación son ligeramente diferentes de las 4337 (zkSync Paymaster puede ocupar cualquier otro espacio de contrato), y también hay varios tipos (como los basados en aprobación). A la comparación de detalles, aquellos que estén interesados pueden consultar los documentos oficiales o mi implementación anterior.
Resumen y comparación
A través de las explicaciones anteriores, hemos aprendido qué puntos de entrada importantes tiene el contrato de cuenta, así como sus funciones y restricciones relacionadas. Al mismo tiempo, también aprendimos sobre las funciones del contrato sistema. A continuación, resumamos el proceso de una transacción de operación automatizada (AA) en zkSync desde su construcción hasta su finalización, y también proporcionaré referencias más detalladas para aquellos que quieran obtener más información:
El usuario utiliza el SDK o la billetera localmente para construir objetos de transacción (por ejemplo: desde, hacia, datos, valor, etc.).
El usuario firma la transacción. La firma aquí no es necesariamente el formato tradicional EIP-712 y la firma curva ECDSA. zkSync también es compatible con EIP-2718 y EIP-1559. La clave para elegir un método de firma y un método de verificación es verificar a través de la función de verificación en el contrato de la cuenta.
Envíe la transacción firmada al operador a través de la API RPC. En este punto la transacción entra en estado pendiente. El operador pasa la transacción al gestor de arranque (llama a la función ProcessL2Tx en el contrato del gestor de arranque) e inicia una serie de procesos del protocolo AA.
El gestor de arranque comprobará si Nonce es legal y utilizará NonceHolder para comprobarlo.
El gestor de arranque llamará a la función validarTransacción en el contrato de la cuenta del usuario para confirmar que la transacción ha sido autorizada por el propietario de la cuenta.
Hay dos formas en que Bootloader cobra tarifas, y el método de cobro específico depende de los parámetros de la transacción (si el parámetro pagador está adjunto al construir el objeto de transacción):
a. Llame a la función payForTransaction y al contrato de cuenta para cobrar la tarifa de transacción;
b. Llame a las funciones prepareForPaymaster y validarAndPayForPaymasterTransaction para cobrar la tarifa de transacción con el contrato Paymaster.
"Llame a payForTransaction para contratar la tarifa con la Cuenta" o "llame a prepareForPaymaster y valideAndPayForPaymasterTransaction para contratar la tarifa con Paymaster"
Verifique si el gestor de arranque ha recibido al menos tx.gasprice * tx.gaslimit tarifas de transacción.
El gestor de arranque llamará a la función uteTransaction en el contrato de la cuenta del usuario para ejecutar la transacción.
(Opcional) Si usa Paymaster para pagar la tarifa de transacción, el gestor de arranque llamará a la función postTransaction. Si Paymaster no implementa postTransaction o se agota el gas, se omitirá este paso.
Los pasos 4.~7. anteriores son la fase de verificación (definida en l2TxValidation del gestor de arranque) y la fase de ejecución de los pasos 8.~9 (definida en l2Txution del gestor de arranque).
Comparación de EIP-4337, StarkNet y zkSync Era
Básicamente, los procesos del mecanismo AA de los tres son similares, todos los cuales son etapa de verificación → mecanismo de tarifa de manejo (pagado por contrato de cuenta o pagador) → etapa de ejecución. Las principales diferencias son:
Comparado
Además, hemos completado el mempool P2P para el paquete 4337 actual, y el secuenciador y operador de zkRollups también son los únicos servidores oficiales, por lo que hay ciertos componentes centralizados.
En el proceso de desarrollo, dado que zkSync no tiene el problema de conectarse con varios paquetes (solo necesita interactuar con la API del Operador), es fácil de usar 4337 y la experiencia de desarrollar contratos de cuenta (SDK) también es mejor; en Al mismo tiempo, zkSync puede utilizar Solidity como lenguaje de desarrollo por contrato, por lo que no es necesario cruzar el umbral de El Cairo en el desarrollo de StarkNet.
Conclusión
Dado que tanto StarkNet como zkSync pertenecen a la categoría de AA local (AA nativo), también puede consultar mi introducción anterior a StarkNet AA, titulada "Introducción a la abstracción de cuentas StarkNet" (Introducción a la abstracción de cuentas StarkNet). Además, puede leer otros artículos relacionados con EIP-4337 para obtener más información.