Revertir transacciones utilizando assembly en línea (inline assembly) puede ser más eficiente en cuanto a gas que utilizar las declaraciones de alto nivel revert o require de Solidity. En esta guía, exploraremos cómo funcionan internamente los diferentes tipos de reverts en Solidity simulando sus implementaciones en assembly.
El siguiente ejemplo muestra que la declaración revert en la versión de assembly reduce el costo de gas de 157 a 126 gas, ahorrando 31 de gas:

Como requisito previo, asumimos que has leído el artículo Try Catch and All the Ways Solidity Reverts así como nuestro artículo sobre la codificación ABI.
En la EVM, la memoria es un array largo de bytes que están indexados por bytes. Es decir, podemos leer y escribir bytes basándonos en su índice. Aunque la memoria está indexada por bytes, normalmente leemos y escribimos 32 bytes a la vez.
mstore en assembly y cómo funciona
Revertir con assembly depende en gran medida del código de operación (opcode) mstore de Yul para almacenar datos en la memoria, así que primero exploremos a fondo este opcode.
El opcode mstore toma dos argumentos:
- Memory location (Ubicación en memoria): La dirección del byte donde se almacenarán los datos.
- Data (Datos): Los datos de 32 bytes que se almacenarán.
El siguiente es un ejemplo de cómo usar mstore:
assembly {
mstore(memoryLocation, dataToStore)
}
Si deseas almacenar 32 bytes de 0xFF en la ubicación de memoria 0x00, escribirías:
assembly {
mstore(
0x00,
0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
)
}
Esto almacena el valor completo de 32 bytes comenzando en el índice 0x00. Si, en cambio, deseas almacenar el valor en la ubicación de memoria 0x01, escribirías:
assembly {
mstore(
0x01,
0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
)
}
Esto desplaza el inicio de los datos un byte, y el primer byte en 0x00 permanecerá inalterado. El diagrama a continuación muestra cómo mstore almacena los datos en la memoria:

Ten en cuenta que aunque especificamos escribir en el índice de byte 0 con mstore(0, ...), escribimos en el 0 —y también en los siguientes 31 bytes— mstore escribe 32 bytes a la vez.
Relleno de datos implícito (padding) en mstore
Si especificamos menos de 32 bytes (64 caracteres hexadecimales) en el segundo argumento, el compilador de Solidity lo rellenará a la izquierda con ceros (los bytes más significativos) hasta que el valor tenga 32 bytes de longitud, luego escribirá esos 32 bytes comenzando en el índice de byte especificado en el primer argumento de mstore.
Considera el siguiente ejemplo:
assembly {
mstore(0x00, 0xff)
}
El código anterior almacena los datos como 0x00000000000000000000000000000000000000000000000000000000000000ff en memoria, con 0xff ocupando el último byte y el resto de los 31 bytes precedentes llenos de ceros.
En otras palabras, mstore(0x00, 0xff) se convierte implícitamente en mstore(0x00, 0x00000000000000000000000000000000000000000000000000000000000000ff)
El resultado del valor en memoria se muestra aquí:

Recuerda que mstore escribe 32 bytes, pero en este caso, 31 de esos bytes son ceros, abarcando desde el byte 0 hasta el byte 30 inclusive. Esto significa que cualquier dato dentro del rango de bytes 0-31 será sobrescrito con ceros.
Podemos ver cómo se ve en la memoria si devolvemos los datos almacenados como se muestra en la captura de pantalla a continuación:

El siguiente diagrama muestra cómo mstore rellena implícitamente a la izquierda varios valores hexadecimales, siendo la primera fila el ejemplo que acabamos de ver.

Usar mstore8 para almacenar datos en memoria
Alternativamente, podemos usar el opcode mstore8, que es similar a mstore pero almacena solo un byte de datos en una ubicación de memoria específica.
assembly {
mstore8(memoryLocation, exactlyOneByteOfData)
}
Por ejemplo, si queremos almacenar un solo byte de datos (0xff) en el byte 31, podemos almacenarlo directamente usando mstore8 de esta manera:
assembly {
mstore8(31, 0xff)
}
Y la salida será la misma que usar mstore, con 0xff ocupando el último byte.


La diferencia clave entre mstore8 y mstore es que mstore8 no añade 31 ceros adicionales que sobrescribirían los datos almacenados previamente que abarcan desde el byte 0 hasta el byte 31, a diferencia de mstore.
Escribir 0xff con ceros a la derecha usando mstore
Si deseas escribir 0xff en el byte 0 usando mstore en lugar de mstore8, puedes almacenar 0xff como el primer byte y rellenar los 31 bytes restantes con ceros, como se muestra a continuación:
assembly {
mstore(
0x00, 0xff00000000000000000000000000000000000000000000000000000000000000
)
}
Esto almacenará el valor exactamente como lo especificaste, con 0xff al principio y los bytes restantes como ceros:

Aquí hay una prueba de ejecución del código en Remix:

¿Eso parece un montón de ceros, verdad? Alternativamente, podemos usar mstore8 para almacenar un byte de datos en una ubicación de memoria específica. En el ejemplo a continuación, utilizamos mstore8 para almacenar 0xff en el byte 0:

Este es un código mucho más compacto que hace lo mismo que el de la captura de pantalla anterior, excepto que no escribe ceros en los bytes del 1 al 31.
Ten en cuenta que:
mstorealmacena un total de 32 bytes de datos, mientras quemstore8solo almacena un único byte en la ubicación de memoria especificada.- Cuando usas
mstore, si tus datos tienen menos de 32 bytes, se rellenarán automáticamente con bytes en cero a la izquierda (la ubicación de memoria con índice más bajo) para completar los 32 bytes. Estos ceros sobrescribirán cualquier otro contenido de memoria que estuviera previamente allí.
Puedes sobrescribir datos en la memoria si escribes en la misma ubicación múltiples veces
¿Recuerdas cuando mencionamos que los ceros adicionales con los que mstore rellena a la izquierda sobrescribirán cualquier contenido existente dentro del rango del byte 0 al 30? Exploremos cómo ocurre esa sobrescritura.
Si escribimos 0xCC en el byte 0 usando mstore8:
assembly {
mstore8(0, 0xCC)
}
ahora tendremos 0xCC en la posición 0, mientras que el resto de la memoria permanecerá sin cambios, como se ilustra en el diagrama a continuación.

Posteriormente, si almacenamos 0xFF usando mstore(0, 0xFF) de esta manera:
assembly {
mstore8(0, 0xCC)
mstore(0, 0xFF)
}
0xFF sobrescribirá el 0xCC almacenado previamente en el byte 0 y llenará toda la ranura (slot) de 32 bytes (desde el byte 0 hasta el 31) con 0xFF.
Recuerda que mstore escribirá datos en toda la ranura de 32 bytes y si tenemos menos de 32 bytes, rellenará los bytes restantes con ceros de esta manera:
0x00000000000000000000000000000000000000000000000000000000000000**FF**
La animación a continuación muestra cómo ocurre esta sobrescritura:
Esto demuestra que los 31 ceros de relleno de mstore realmente alteran el contenido de la memoria.
Cómo recordar el relleno de mstore
En lugar de memorizar que mstore rellena con ceros a la izquierda los valores hexadecimales, podemos considerar que mstore(0, 0xff) es completamente equivalente a mstore(0, 255).
En otras palabras, mstore(0, 255) está diciendo “almacena el número 255 en los 32 bytes comenzando en el byte 0, con el byte 0 conteniendo los bytes más significativos”.
Dado que 255 es un “número pequeño” en comparación con lo que puede contener un número de 32 bytes (el valor máximo de uint256), solo se usarán los bits menos significativos. Los bits menos significativos están a la derecha, pero los bits significativos a la izquierda se establecen en cero.
De manera similar, el número 0xff00000000000000000000000000000000000000000000000000000000000000 es bastante grande.
En decimal, es 115339776388732929035197660848497720713218148788040405586178452820382218977280. Por lo tanto, agota los bits más significativos, que están a la izquierda.
Usar los datos almacenados para el revert
Hemos visto cómo almacenar datos en la memoria con mstore. Durante un revert, necesitamos almacenar los datos del error en memoria y devolverlos como el mensaje de error de revert.
El opcode revert toma dos argumentos: la ranura (slot) de memoria de inicio y el tamaño total de los datos que pretendemos devolver.
revert(startingMemorySlot, totalMemorySize)
De aquí en adelante, mostraremos cómo imitar el comportamiento del revert de Solidity en las siguientes situaciones:
- Revertir sin una cadena de texto de razón (reason string)
- Revertir con un error personalizado (custom error)
- Revertir con un error personalizado y una cadena de texto de razón
1. Revert sin una razón (mensaje)
Para un revert simple sin mensaje, el código en assembly revert(0,0) es equivalente a revert() en Solidity tanto en comportamiento como en costo de gas. No devuelve ningún dato a quien realiza la llamada.
Internamente, usar revert(0,0) significa “no usar datos” porque la longitud de los datos a los que se hace referencia es cero. Es convencional usar la ubicación de memoria 0 como punto de partida, pero dado que no estamos devolviendo nada, podríamos hacer revert(1,0) y lograr lo mismo.
Aquí hay un ejemplo simple de un revert sin razón utilizando assembly:
contract ContractA {
function zero() external {
assembly {
revert(0,0) //<--- simple revert without reason
}
}
}
La captura de pantalla a continuación muestra un low-level call (llamada de bajo nivel) de ContractA a ContractB y cómo la llamada de bajo nivel devolvió false porque ContractB revirtió, y no se devuelve ningún dato ya que estamos usando revert(0,0)

2a. Revert personalizado en assembly sin parámetros
Para ilustrar cómo simular un custom error sin parámetros utilizando assembly, usemos revert Unauthorized() como ejemplo.
Almacenaremos el function selector del error del revert personalizado en una ubicación específica en la memoria (0x00 por convención) y el revert apuntará a esa ubicación en la memoria.
Aquí está el código en Solidity que usaremos como ejemplo:
contract CustomError {
error Unauthorized();
function revertCustomError() {
revert Unauthorized();
}
}
Seguiremos los pasos a continuación para lograr un revert personalizado en assembly:
- Almacenar el function selector en memoria
- Activar el revert pasando la ubicación de memoria del selector y el tamaño del selector (4 bytes) como argumentos para
revert
assembly {
mstore(memoryLocation, selector)
revert(memoryLocation, sizeOfSelector)
}
1. Almacenar el function selector
Cuando Solidity activa un custom error, el valor de retorno es la codificación ABI del custom error en sí, que incluye el function selector (los primeros cuatro bytes del hash keccak256 de la firma del custom error).
Dado que estamos utilizando el custom error Unauthorized() como ejemplo, primero almacenaremos el function selector (los primeros cuatro bytes del keccak256 de Unauthorized()) que será 0x82b42900 rellenado con ceros adicionales para alargar el valor a 32 bytes para asegurar que los cuatro bytes reales del function selector se escriban desde el byte 0 hasta el byte 3 inclusive. Sin este relleno, el selector no comenzaría en el índice de memoria 0.
bytes32 selector = bytes32(abi.encodeWithSignature("Unauthorized()")); // 0x82b42900
assembly {
mstore(0x00, 0x82b4290000000000000000000000000000000000000000000000000000000000)
}
2. Activar el revert
Ahora activaremos el custom error con la declaración revert a continuación. Recuerda que la plantilla para el revert es revert(startingMemorySlot, totalMemorySize).
revert(0x00, 0x04)
0x00 es la ubicación de memoria donde almacenamos los datos del error, mientras que 0x04 (en hexadecimal) es el tamaño del error, que es solo de 4 bytes. Todo el código del revert debería verse ahora como el código a continuación:
pragma solidity 0.8.27;
contract RevertErrorExample {
function revertWithAssembly() public pure {
assembly {
mstore(
0x00,
0x82b4290000000000000000000000000000000000000000000000000000000000
)
revert(0x0, 0x04)
}
}
}
Aquí está el código que usaremos para comparar nuestra implementación en assembly con la implementación de Solidity:
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.27;
contract RevertErrorExample {
error Unauthorized();
// assembly version
function revertWithAssembly() public pure {
assembly {
mstore(
0x00,
0x82b4290000000000000000000000000000000000000000000000000000000000
)
revert(0x0, 0x04)
}
}
// solidity version
function revertWithoutAssembly() public pure {
revert Unauthorized();
}
}
El resultado se muestra en la captura de pantalla a continuación. La única diferencia está en el costo de gas. La captura de pantalla muestra que ahorramos 54 unidades de gas al activar el revert mediante assembly en lugar de Solidity.

Además, en el código a continuación, callContractB utiliza de forma separada try/catch en customRevertWithAssembly y customRevertWithoutAssembly para analizar el error, demostrando que su comportamiento es el mismo.

Un método alternativo para almacenar el selector cuando un custom error no tiene parámetros y activar el revert
Cuando un custom error no tiene parámetros, el function selector es el único dato relevante a devolver. En ese caso, podemos almacenar el function selector sin añadir manualmente los ceros adicionales y revertirlo desde la región de memoria específica que almacenamos.
Por ejemplo, en lugar de rellenar con ceros de esta manera:
assembly{
mstore(
0x00,
0x82b4290000000000000000000000000000000000000000000000000000000000
)
}
Podemos escribirlo sin rellenarlo manualmente con ceros:
assembly{
mstore(0x00,0x82b42900)
}
En memoria, los ceros se añadirán a la izquierda del function selector desde el byte 0 hasta el byte 27, mientras que el selector real se almacenará desde el byte 28 hasta el 31.
En otras palabras, 0x82b42900 se expande a 0000000000000000000000000000000000000000000000000000000082b42900 y se almacena en los bytes 0 al 31 como se muestra a continuación:

Como el function selector está ahora en el byte 28 (0x1c en hexadecimal), puedes hacer el revert desde esta ubicación en lugar de 0x00, como se muestra a continuación:
assembly {
mstore(0x00,0x82b42900)
revert(0x1c, 0x04)
}
2b. Revert personalizado en assembly con parámetros
Si el custom error tiene parámetros, también necesitaremos aplicar la codificación ABI (ABI encode) a los argumentos, ya que formarán parte de los datos de retorno del revert. Suponiendo que tiene un address como argumento, almacenaremos el argumento en memoria y apuntaremos los argumentos del revert tanto al selector como al address en la memoria.
Como ejemplo, repliquemos el revert personalizado Unauthorized(address) en assembly.
contract CustomError {
error Unauthorized(address caller);
function revertCustomError() {
revert Unauthorized(msg.sender);
}
}
Los pasos para replicar un revert personalizado con argumentos en assembly son similares a los de sin argumentos, la única diferencia es que necesitaremos almacenar los argumentos (en este caso, el address) como parte de los datos de retorno. Seguiremos los pasos a continuación:
- Almacenar el function selector en la memoria para el custom error
- Almacenar el argumento en la memoria después del selector
- Activar el revert pasando la ubicación de memoria de inicio y el tamaño total (4 bytes para el selector + el tamaño del argumento) a la función
revert
1. Almacenar el function selector en la memoria para el custom error
Al igual que en el custom error sin parámetros, primero necesitaremos derivar el function selector de esta manera:
bytes4 selector = bytes4(abi.encodeWithSignature("Unauthorized(address)")
);
Y el selector será 0x8e4a23d6. Ahora procederemos a almacenar el selector comenzando en la ubicación de memoria 0x00 con mstore como se muestra a continuación:
assembly{
// Store the function selector at the memoryy location `0x00`
mstore(0x00, 0x8e4a23d600000000000000000000000000000000000000000000000000000000)
}
2. Almacenar el argumento en la memoria después del selector
Después de escribir el function selector en la memoria comenzando desde el byte 0, ahora almacenaremos el address desde el byte 4 como se muestra a continuación:
assembly{
//...
// Store the address
// *Note that `caller()` in assembly is the same as `msg.sender` in Solidity.*
mstore(0x04, caller())
}
La función caller() devolverá el address promovido (upcasted) a 32 bytes. Por lo tanto, si el address original era 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4, caller() devolverá 0x00000000000000000000000005B38Da6a701c568545dCfcB03FcB875f56beddC4 y este es el valor de 32 bytes que mstore colocará en memoria comenzando en el byte 4.
3. Activar el revert
Y finalmente, ahora podemos activar el revert con la ubicación de memoria de inicio y el tamaño total de los datos que hemos almacenado hasta ahora (4 bytes para el selector + 32 bytes para el address) ocupa 36 bytes (hex 0x24) como argumentos, como se muestra a continuación:
function customRevertWithAssembly() public pure {
assembly {
//...
// 4 bytes for selector + 32 bytes for the address
revert(0x00, 0x24)
}
}
Y así es como se verá el código completo para el revert personalizado con parámetros en assembly:
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.27;
contract A {
function customRevertWithAssembly() public view {
assembly {
// Store the function selector at the memory location `0x00`
mstore(0x00, 0x8e4a23d600000000000000000000000000000000000000000000000000000000)
// Store the address
// N*ote that `caller()` in assembly is the same as `msg.sender` in Solidity.*
mstore(0x04, caller())
// 4 bytes for selector + 32 bytes for the address
revert(0x00, 0x24)
}
}
}
Así es como Solidity almacenará los datos de revert en la memoria y el resultado de los datos de revert se devolverá eventualmente.
3. Revert con una razón en assembly
Cuando se activa un revert con una cadena de texto de razón (reason string) como revert("reason"), el contrato que revierte devuelve la codificación ABI de Error(string), junto con el argumento de cadena. Esto es igual a cómo funciona require con una razón en Solidity.
Para simular el revert con una cadena de texto de razón en assembly, necesitamos aplicar la codificación ABI a la misma función y al argumento de cadena en memoria.
Usemos revert("Unauthorized") como ejemplo:
contract A {
function revertWithAString() external pure {
revert("Unauthorized");
}
}
Si activamos la función revert("Unauthorized"); en el contrato anterior, el resultado se verá como el ejemplo a continuación.

En esta sección, replicaremos el comportamiento del revert con un string en Solidity usando assembly siguiendo los pasos a continuación:
- Almacenar el function selector de
Error(string)en memoria - Almacenar el desplazamiento (offset) hacia la cadena de texto del mensaje de error
- Almacenar la longitud de la cadena de texto del mensaje de error
- Almacenar el mensaje de error real
- Activar el revert
A continuación se muestra una representación rápida de los pasos anteriores en código assembly:
contract RevertErrorExample {
function revertWithAssembly() public pure {
assembly {
// store the selector
mstore(
0x00,
0x08c379a000000000000000000000000000000000000000000000000000000000
)
mstore(0x04, 0x20) // store the offset
mstore(0x24, 0xc) // store the length of the string
mstore(
0x44,
0x556E617574686F72697A65640000000000000000000000000000000000000000
) // store the actual data
revert(0x00, 0x64) // trigger a revert
}
}
}
Examinemos el bloque de assembly línea por línea.
1. Almacenar el function selector de Error(string)
Primero almacenamos el function selector en la ubicación de memoria inicial (0x00):
assembly {
mstore(0x00, 0x08c379a000000000000000000000000000000000000000000000000000000000) //Store the function selector
}
Puedes derivar el function selector (los primeros 4 bytes de keccak256(Error(string))) con abi.encodeWithSignature("Error(string)") y luego convertirlo a una palabra de 32 bytes con el tipo bytes32 de esta manera:
bytes32 selector = bytes32(abi.encodeWithSignature("Error(string)"));
El resultado será:
0x08c379a000000000000000000000000000000000000000000000000000000000
Los primeros 4 bytes (0x08c379a0) son el selector rellenado con ceros para cumplir con el requisito de 32 bytes.

2. Almacenar el desplazamiento (offset) hacia la cadena de texto del mensaje de error
La siguiente parte del error de cadena que almacenamos es el desplazamiento (offset). El offset es de 32 bytes (0x20 en hexadecimal).
mstore(0x04, 0x20) // 4 is 0x04 in hex
Recuerda que mencionamos que es posible sobrescribir la memoria si dos ubicaciones de memoria se superponen, ¿verdad? Inicialmente, el function selector se almacenó comenzando en el byte 0 como una palabra de 32 bytes. Ahora, estamos almacenando el offset comenzando en el byte 4.
Esto significa que los datos restantes del function selector (los ceros de relleno en este caso) serán reemplazados, comenzando desde el byte 4 como se muestra en el diagrama a continuación:

3. Almacenar la longitud de la cadena de texto del mensaje de error
La tercera parte de la cadena que necesitamos almacenar es la longitud de los datos de la cadena. Recuerda que almacenamos el function selector en la ubicación 0x00 y ocupó 4 bytes. Luego, la siguiente ubicación de memoria fue el offset en la ubicación de memoria 0x04, el cual ocupó 32 bytes.
Eso significa que los 4 bytes del selector + los 32 bytes del offset nos indican que la siguiente ranura de memoria debería estar en los 36 bytes, que es donde almacenaremos la longitud de la cadena.
La longitud de la cadena Unauthorized es de 12 (0xc) bytes.
mstore(0x24, 0xc) // 36 is 0x24 in hex

4. Almacenar la cadena de texto del mensaje de error real
La cadena real Unauthorized se almacena comenzando en los 68 (0x44) bytes desde el principio, lo que corresponde a los 4 bytes para el selector + 32 bytes del offset + 32 bytes para la longitud. Hasta ahora, hemos escrito 100 bytes de datos.
mstore(0x44, "Unauthorized") //68 is 0x44 in hex
// We can store Unathorized as hex as well. Unauthorized in hex is ⤵️
// 0x556E617574686F72697A65640000000000000000000000000000000000000000

5. Activar el revert:
La operación revert usa la ubicación de memoria inicial y el tamaño total de los datos para activar el revert.
El tamaño total será de 100 (0x64) bytes al sumar los 4 bytes para el selector, 32 bytes para el offset, 32 bytes para la longitud de la cadena y 32 bytes para el contenido de la cadena “Unauthorized”.
Recuerda la plantilla para el revert en assembly:
revert(StartingMemorySlot, totalMemorySize)
Aquí te mostramos cómo activaremos el revert:
revert(0x00, 0x64) // 100 is 0x64 in hex
Por lo tanto, el revert devolverá los siguientes datos con exactamente 100 bytes cuando se active:

Aunque la cadena Unauthorized no utiliza los 32 bytes completos, el receptor sabrá que solo debe leer 12 bytes de datos debido al parámetro de longitud 0x0c.
Si juntamos todos los pasos, llegaremos a este código:
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
contract ContractA {
function revertWithAssembly() external pure {
assembly {
mstore(
0x00,
0x08c379a000000000000000000000000000000000000000000000000000000000
) // store the selector
mstore(0x04, 0x20) // store the offset
mstore(0x24, 0xc) // store the length of the string
mstore(
0x44,
0x556E617574686F72697A65640000000000000000000000000000000000000000
) // store the actual data
revert(0x00, 0x64) // trigger a revert
}
}
}
}
Aquí hay una captura de pantalla que muestra la salida del revert cuando llamas a la función revertWithAssembly(). El resultado es el mismo que vimos cuando activamos revert("Unauthorized") en Solidity.

Sin embargo, la diferencia radica en la cantidad de gas que consumen ambos. Ejecuta los reverts en los siguientes contratos para ver la diferencia en el costo de gas. A continuación se encuentra el código que usamos para probar los costos de gas:
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
contract ContractA {
function revertWithAssembly() external pure {
assembly {
mstore(
0x00,
0x08c379a000000000000000000000000000000000000000000000000000000000
) // store the selector
mstore(0x04, 0x20) // store the offset
mstore(0x24, 0xc) // store the length of the string
mstore(
0x44,
0x556E617574686F72697A65640000000000000000000000000000000000000000
) // store the actual data
revert(0x00, 0x64) // trigger a revert
}
}
}
contract ContractB {
function revertWithoutAssembly() external pure {
revert("Unauthorized");
}
}
La ilustración a continuación muestra la diferencia en el costo de gas para la función revertWithAssembly y revertWithoutAssembly.

A partir de la prueba anterior, ahorramos 273 de gas ya que el revert sin assembly costó 428 de gas, mientras que el revert con assembly costó 155 de gas. La diferencia es 273.
Para verificar aún más que el error se formó correctamente, podemos intentar capturar el error en un bloque try/catch como se muestra en la captura de pantalla a continuación:

A partir de la captura de pantalla anterior, podemos ver que el error fue capturado en el bloque catch de Error como se esperaba, y se imprimió la razón Unauthorized.
Conclusión
En esta guía, hemos aprendido cómo funciona el revert implementando manualmente reverts de Solidity usando assembly en línea (inline assembly).
Cubrimos:
- cómo funcionan
mstoreymstore8 - cómo imitar los siguientes tipos de reverts:
- reverts sin razones
- reverts de errores personalizados (custom errors)
- y reverts con razón
También vimos cómo podríamos ahorrar algo de gas utilizando el revert a través de assembly. Te animo a experimentarlo tú mismo, ya que es la mejor manera de entender completamente cómo se integra todo.
Feliz programación
Este artículo fue escrito por Eze Sunday en colaboración con RareSkills.