WEB3DEV Español

Cover image for La Sintaxis try-catch de Solidity: Manejo de Errores con Ejemplos
Banana Labs
Banana Labs

Posted on

La Sintaxis try-catch de Solidity: Manejo de Errores con Ejemplos

capa

Introducción

Al crear contratos inteligentes en la blockchain Ethereum, manejar los errores puede ser una parte muy importante del proceso, especialmente cuando no hay muchas herramientas disponibles. La adición de la sintaxis try/catch en la versión 0.6.0 de Solidity fue un gran paso en la dirección correcta para el manejo de errores. Estas nuevas características se basan en funciones anteriores, como la adición de cadenas de razón en las declaraciones revert y requiererequire de la versión 0.4.22.

Es posible que te estés preguntando por qué las habilidades de manejo de errores son tan importantes en el desarrollo de contratos basados en Solidity. En muchos casos, los contratos inteligentes representan activos del mundo real y tienen un alto valor monetario. El enfoque de "todo o nada" de Solidity, en relación con las transacciones, no siempre ha hecho posible manejar errores de manera detallada. Imagina poner mucho dinero en un contrato inteligente, solo para que la transacción falle en el último minuto y quedes preguntándote por qué no hubo un manejo de errores más detallado.

Con la sintaxis try/catch, añadida en la versión 0.6.0, los desarrolladores ahora tienen las herramientas necesarias para manejar fallas complejas en llamadas externas sin tener que revertir toda la transacción. Aunque los cambios de estado en la función llamada aún se revierten, el manejo de errores en una base por transacción ofrece una mejor alineación de comportamiento práctico.

En este artículo, exploraremos en detalle la sintaxis try/catch de Solidity, con ejemplos.

Usando 'try catch' en Contratos Inteligentes

La declaración try/catch permite localizar y responder a llamadas externas fallidas y llamadas fallidas para crear un contrato. Esto proporciona un mayor control sobre cómo se manejan los errores en los contratos Solidity. Sin embargo, es importante saber que la declaración try/catch no se puede utilizar para llamadas de función internas.

Observa este ejemplo sencillo para ver cómo usar la declaración try/catch. Tenemos dos contratos: HelloWorld y HelloWorldFactory.

El contrato HelloWorld tiene una función muy simple que devuelve una cadena de mensaje:

El contrato HelloWorldFactory crea y gestiona instancias de HelloWorld. La función createHelloWorld produce una nueva instancia de HelloWorld y la guarda en el mapeo de contratos. Si la transacción falla, el bloque try/catch detecta el error y lo añade a la variable errorCount.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract HelloWorld {
    function showMessage() public pure returns (string memory) {
        return "Hello, World!";
    }
}

contract HelloWorldFactory {
    mapping (address => HelloWorld) public contracts;
    uint public errorCount;

    function createHelloWorld() public {
        try new HelloWorld()
            returns (HelloWorld newContract)
        {
            contracts[msg.sender] = newContract;
        } catch {
            errorCount++;
        }
    }
Enter fullscreen mode Exit fullscreen mode

Usar la sintaxis try/catch de esta manera facilita la alineación del comportamiento en los ciclos de vida de las transacciones y da a los contratos Solidity un control más preciso sobre cómo manejar los errores.

Recuperando el mensaje de error

Al utilizar la sintaxis try/catch, es posible obtener más información sobre la razón del fracaso de una transacción. Solidity ofrece dos formas de obtener mensajes de error.

En el último ejemplo, creamos dos contratos: HelloWorld y HelloWorldFactory. El contrato HelloWorld tenía una función que devuelve una cadena de mensaje, y el contrato HelloWorldFactory creó y gestionó instancias de HelloWorld.

Para ilustrar los dos métodos de recuperación de mensajes de error, vamos a modificar la función createHelloWorld en el contrato HelloWorldFactory:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract HelloWorld {
    function showMessage() public pure returns (string memory) {
        return "Hello, World!";
    }
}

contract HelloWorldFactory {
    mapping (address => HelloWorld) public contracts;
    string public errorMessage;
    bytes public errorData;

    function createHelloWorld() public {
        try new HelloWorld()
            returns (HelloWorld newContract)
        {
            contracts[msg.sender] = newContract;
        } catch Error(string memory reason) {
            errorMessage = reason;
        } catch (bytes memory data) {
            errorData = data;
Enter fullscreen mode Exit fullscreen mode

En este ejemplo, modificamos la función createHelloWorld para incluir dos declaraciones catch. La primera declaración catch, catch Error(string memory reason), captura el error y pasa el mensaje de error con la variable reason, que almacenamos en la cadena errorMessage.

La segunda declaración catch, catch (bytes memory data), recupera un buffer de memoria de byte si ocurre un error. En este caso, almacenamos el buffer de memoria de byte en la variable de bytes errorData.

El uso de mensajes de error en los contratos de Solidity, puede ser una herramienta de depuración efectiva para los desarrolladores, ya que ofrece un control más preciso sobre el manejo de errores en contratos Solidity.

solidity

Ventajas y desventajas de cada método

Ventajas de catch Error(string memory reason)

Una ventaja de usar la declaración catch Error(string memory reason) es que proporciona un mensaje de error legible para humanos, lo cual es más fácil de interpretar y depurar para los desarrolladores. La variable de cadena también permite una filtración y categorización más fácil de los errores.

Desventajas de catch Error(string memory reason)

La principal desventaja de usar catch Error(string memory reason) es que puede ser más costoso en términos de uso de gas. Esto se debe a que, en Solidity, las variables de cadena se almacenan después del código del contrato, lo que requiere más gas.

Ventajas de catch (bytes memory reason)

Una ventaja de usar la declaración catch (bytes memory reason) es que recupera un buffer de memoria de byte que puede contener datos arbitrarios, incluyendo varios tipos de datos. Esto puede ser útil para depurar errores más complejos y diversos.

Otra ventaja es que el uso de variables de bytes es más barato en términos de uso de gas. Esto se debe a que las variables de bytes se almacenan en los primeros 32 bytes de memoria, lo que requiere menos gas.

Desventajas de catch (bytes memory reason)

La principal desventaja de usar catch (bytes memory reason) es que el mensaje de error no es legible por humanos, lo que dificulta la depuración y la comprensión del error por parte de los desarrolladores. Además, dado que la variable de bytes puede contener datos arbitrarios, puede ser más difícil filtrar y categorizar los errores.

Conclusión

La sintaxis try/catch en Solidity es una herramienta importante para manejar errores en el desarrollo de contratos inteligentes. Al usar la declaración try/catch, los desarrolladores pueden capturar errores en llamadas externas y recuperar mensajes de error usando la declaración catch Error(string memory reason) o la declaración catch (bytes memory reason).

Cada método tiene sus propias ventajas y desventajas, dependiendo del contexto del manejo de errores. La declaración catch Error(string memory reason) proporciona mensajes de error legibles para humanos, mientras que la declaración catch (bytes memory reason) es más barata en términos de uso de gas y soporta tipos de datos arbitrarios.

Además, la versión 0.8.0 de Solidity introdujo el tipo Error, el cual permite a los desarrolladores definir sus propios tipos de error y proporcionar mensajes de error más específicos y detallados a los usuarios. Lea más sobre errores personalizados aquí.

¡Gracias por leer! Si encontraste útil este artículo, no dudes en seguir mis redes sociales para obtener más actualizaciones sobre el desarrollo con Solidity y las mejores prácticas de contratos inteligentes.

PD: Además, recientemente escribí un nuevo libro, "Proof-of-Stake para principiantes: una guía para entender el funcionamiento interno del protocolo Proof-of-Stake de Ethereum", el cual puedes acceder en este enlace. Cubre todo lo que necesitas saber sobre la transición de Ethereum, del Proof-of-Work (prueba de trabajo) al Proof-of-Stake (prueba de participación), incluyendo conceptos básicos, staking, recompensas y mucho más. ¡Espero que pueda ayudarte a entender los cambios revolucionarios que están llegando al ecosistema de Ethereum!

Nuevamente, gracias por tu interés en el desarrollo con Solidity, y espero compartir más contigo en el futuro.

Este artículo es una traducción realizada por @bananlabs. Puedes encontrar el artículo original aquí

Discussion (0)