Volver a la página principal
martes 10 diciembre 2024
5

Cómo usar errores personalizados en Solidity para lanzar mensajes de error personalizados

Un error personalizado es una definición de error que se puede declarar y lanzar desde el contrato. Cuando se lanza un error, se incluyen su nombre y los datos relevantes asociados, permitiendo una mejor depuración y manejo de errores.

Características principales:

1. Eficiencia en gas:

  • Los errores personalizados consumen menos gas que las cadenas de texto en revert o require.

2. Información detallada:

  • Puedes incluir parámetros en los errores para proporcionar contexto adicional.

3. Reutilización:

  • Los errores pueden definirse una vez y reutilizarse en múltiples lugares.

Declaración y uso de errores personalizados

Sintaxis básica

error NombreError(parametro1 tipo, parametro2 tipo, ...);

Ejemplo básico

pragma solidity ^0.8.4;

contract EjemploErrores {
    error SaldoInsuficiente(address usuario, uint saldoDisponible, uint montoRequerido);

    function retirarFondos(uint monto) public view {
        uint saldo = 100; // Ejemplo de saldo
        if (saldo < monto) {
            revert SaldoInsuficiente(msg.sender, saldo, monto);
        }
    }
}

En este ejemplo:

  • El error SaldoInsuficiente incluye información adicional sobre el usuario, el saldo disponible y el monto requerido.
  • revert SaldoInsuficiente(...) lanza el error con los valores correspondientes.

Comparación con require y revert tradicionales

Usando require con un mensaje de error

require(saldo >= monto, "Saldo insuficiente");

Usando un error personalizado

error SaldoInsuficiente(address usuario, uint saldoDisponible, uint montoRequerido);
revert SaldoInsuficiente(msg.sender, saldo, monto);

Ventaja clave:

  • Los errores personalizados son más eficientes en gas, especialmente si contienen información adicional, ya que no se almacenan cadenas de texto completas en los logs.

Ejemplos prácticos

1. Validación de permisos

contract Permisos {
    address public owner;

    error NoAutorizado(address usuario);

    constructor() {
        owner = msg.sender;
    }

    function soloPropietario() public view {
        if (msg.sender != owner) {
            revert NoAutorizado(msg.sender);
        }
    }
}

En este caso:

  • Si alguien que no es el propietario intenta acceder a una función restringida, se lanza el error NoAutorizado con la dirección del usuario no autorizado.

2. Validación de parámetros

contract ValidacionParametros {
    error ValorFueraDeRango(uint valorIngresado, uint limiteInferior, uint limiteSuperior);

    function establecerValor(uint valor) public pure {
        if (valor < 10 || valor > 100) {
            revert ValorFueraDeRango(valor, 10, 100);
        }
    }
}

En este ejemplo:

  • Si el valor está fuera del rango permitido, se lanza un error con detalles sobre los límites.

3. Validación de transferencias

contract Transferencias {
    error TransferenciaFallida(address destinatario, uint monto);

    function enviarFondos(address destinatario, uint monto) public payable {
        if (!payable(destinatario).send(monto)) {
            revert TransferenciaFallida(destinatario, monto);
        }
    }
}
  • Si la transferencia falla, se lanza el error TransferenciaFallida con información sobre el destinatario y el monto.

Ventajas de los errores personalizados

1. Eficiencia en gas:

  • Los errores personalizados ahorran gas al no incluir cadenas de texto grandes en los logs.

2. Legibilidad:

  • Los nombres de los errores describen claramente la causa del problema.

3. Depuración más sencilla:

  • La inclusión de parámetros adicionales en los errores permite entender mejor las condiciones que llevaron al fallo.

Buenas prácticas

1. Usa errores personalizados para condiciones críticas:

  • Implementa errores para validar permisos, valores de parámetros y estados de contrato.

2. Incluye información relevante:

  • Los parámetros en los errores deben proporcionar contexto suficiente para depurar el fallo.

3. Evita el uso excesivo de cadenas de texto:

  • Reemplaza los mensajes de error largos de require o revert con errores personalizados.

Limitaciones de los errores personalizados

1. Compatibilidad:

  • Los errores personalizados son compatibles solo con Solidity 0.8.4 y posteriores.

2. Lectura externa:

  • Los errores personalizados no son directamente visibles para usuarios finales; requieren herramientas como ethers.js o web3.js para interpretar los datos devueltos.

Ejemplo avanzado: Múltiples validaciones con errores personalizados

contract ContratoComplejo {
    address public owner;

    error NoAutorizado(address usuario);
    error FondosInsuficientes(uint saldoDisponible, uint montoRequerido);
    error OperacionNoPermitida(string razon);

    constructor() {
        owner = msg.sender;
    }

    function retirarFondos(uint monto) public view {
        if (msg.sender != owner) {
            revert NoAutorizado(msg.sender);
        }

        uint saldo = 100; // Ejemplo
        if (saldo < monto) {
            revert FondosInsuficientes(saldo, monto);
        }

        if (monto > 50) {
            revert OperacionNoPermitida("No se pueden retirar más de 50 Ether");
        }
    }
}

En este contrato:

  • Se implementan tres errores personalizados para diferentes validaciones.
  • Cada error proporciona detalles específicos sobre la causa del fallo.

Referencias oficiales

Para más información sobre los errores personalizados, consulta la documentación oficial de Solidity.

Etiquetas:
solidity
Compartir:
Creado por:
Author photo

Jorge García

Fullstack developer