Depuración de transacciones

(consulte también el compañero de esta página: el recorrido del depurador)

Hay dos formas de iniciar una sesión de depuración, cada una corresponde a un caso de uso diferente.

  • Caso de uso 1: para depurar una transacción realizada en Remix - haga clic en el botón Depurar del registro de transacciones en el Terminal de Remix.

  • Caso de uso 2: para depurar una transacción en la que disponga de un hash de txn de contrato verificado o en la que disponga del hash de txn y del código fuente compilado con los mismos ajustes de compilación que el contrato desplegado.

Iniciar la depuración desde el registro de transacciones en el Terminal

Empecemos con un contrato básico ( o sustituya el contrato de abajo por el suyo propio )

pragma solidity >=0.5.1 <0.6.0;
contract Donation {
    address owner;
    event fundMoved(address _to, uint _amount);
    modifier onlyowner { if (msg.sender == owner) _; }
    address[] _giver;
    uint[] _values;

    constructor() public {
        owner = msg.sender;
    }

    function donate() public payable {
        addGiver(msg.value);
    }

    function moveFund(address payable _to, uint _amount) onlyowner  public {
        uint balance = address(this).balance;
        uint amount = _amount;
        if (amount <= balance) {
            if (_to.send(balance)) {
                emit fundMoved(_to, amount);    
            } else {
               revert();
            }
        } else {
            revert();
        }
    }

    function addGiver(uint _amount) internal {
        _giver.push(msg.sender);
        _values.push(_amount);
    }
}
  • Cree un nuevo archivo en Remix y copie en él el código anterior.

  • Compile el código.

  • Vaya al módulo Ejecutar e implantar.

Para el propósito de este tutorial, ejecutaremos la Remix VM.

  • Despliegue el contrato:

Pulse el botón Desplegar.

Verá la instancia desplegada (alias la udapp).

Open it up (by clicking the caret).

Vamos a llamar a la función Donar y enviaremos 2 éteres.

Para ello: en la casilla de introducción de valores ponga 2 y seleccione Éter como unidad (NO DEJE LA UNIDAD POR DEFECTO como gwei o el cambio será difícil de detectar).

A continuación, pulse el botón Donar.

Esto enviará el éter a la función.

Because we are using the Remix VM, everything happens almost instantly. (If we had been using Injected Web 3, then we would have needed to approve the transaction, pay for gas and wait for the transaction to get mined.)

Remix muestra información relacionada con el resultado de cada transacción en el terminal.

Compruebe en el terminal donde está registrada la transacción que acaba de realizar.

Pulse el botón de depuración.

Pero antes de llegar a la herramienta de depuración propiamente dicha, la siguiente sección muestra cómo iniciar una sesión de depuración directamente desde el depurador.

Iniciar la depuración desde el depurador

Pulse el icono del error en el panel de iconos para acceder al depurador en el panel lateral.

Si no ve el icono del error, vaya al gestor de plugins y active el depurador.

Puede iniciar una sesión de depuración proporcionando un hash de transacción.

Para encontrar el hash de una transacción:

  1. Vaya a una transacción en el terminal.

  2. Haga clic en una línea con una transacción - para ampliar el registro.

  3. El hash de la transacción está ahí - cópielo.

A continuación, haga clic en el depurador pegue el hash y pulse el botón Iniciar depuración.

Uso del depurador

El depurador permite ver información detallada sobre la ejecución de la operación. Utiliza el editor para mostrar la ubicación en el código fuente en la que se encuentra la ejecución actual.

La parte de navegación contiene un control deslizante y botones que pueden utilizarse para recorrer la ejecución de la transacción.

Explicación de las funciones de los botones del depurador

  1. Step Over Back Vuelve al paso anterior, pero ignora/salta las llamadas a función: el depurador NO entrará en una función

  2. Paso atrás Vuelve al paso anterior. No ignora las llamadas a funciones: el depurador ENTRARÁ en cualquier función a lo largo del camino

  3. Paso Dentro Avanza al siguiente paso. No ignora las llamadas a funciones: el depurador ENTRARÁ en cualquier función a lo largo del camino

  4. Step Over Forward Avanza al siguiente paso, pero ignora/supera las llamadas a funciones: el depurador NO INTRODUCIRÁ una función

  5. Saltar al punto de interrupción anterior Envía el depurador al último punto de interrupción visitado. Tenga en cuenta que los puntos de interrupción pueden establecerse pulsando el número de línea en el código fuente

  6. Jump Out Envía el depurador al final de la función

  7. Saltar al siguiente punto de interrupción Envía el depurador al siguiente punto de interrupción

11 paneles ofrecen información detallada sobre la ejecución:

Instrucciones

El panel de instrucciones muestra el bytecode del contrato en ejecución, con el paso actual resaltado.

Nota importante: Cuando este panel esté oculto, el deslizador tendrá una granularidad más gruesa y sólo se detendrá en los límites de las expresiones, aunque estén compiladas en múltiples instrucciones EVM. Cuando el panel esté desplegado, será posible pasar por encima de cada instrucción, incluso aquellas que se refieran a la misma expresión.

Locales Solidarios

El panel Solidity Locals muestra las variables locales asociadas al contexto actual.

Estado de solidez

El panel Estado de Solidity muestra las variables de estado del contrato en ejecución.

Paneles de bajo nivel

Estos paneles muestran información de bajo nivel sobre la ejecución:

  • Pila

  • Cambios en los almacenes

  • Memoria

  • Datos de llamada

  • Pila de llamadas

  • Valor de retorno (sólo si el paso actual es un opcode RETURN)

  • Full Storages Changes (only at the end of the execution & it displays all the storage changes)

Transacción revertida

Una transacción puede ser revertida (a causa de una excepción fuera de gas, una sentencia Solidity revert o una excepción de bajo nivel).

Es importante ser consciente de la excepción y localizar dónde se encuentra en el código fuente.

Remix le avisará cuando la ejecución lance una excepción. El botón warning saltará al último opcode antes de que se produjera la excepción.

Puntos de interrupción

Los dos últimos botones del área de navegación se utilizan para saltar hacia atrás al punto de ruptura anterior o hacia adelante al siguiente punto de ruptura.

Los puntos de interrupción pueden añadirse y eliminarse pulsando sobre el número de línea en el Editor.

Cuando utilice una sesión de depuración con puntos de interrupción, la ejecución saltará al primer punto de interrupción encontrado.

Nota importante: Si añade un punto de interrupción a una línea que declara una variable, es posible que se active dos veces: una para inicializar la variable a cero y otra para asignarle el valor real.

He aquí un ejemplo de esta cuestión. Si está depurando el siguiente contrato:

pragma solidity >=0.5.1 <0.6.0;

contract ctr {
    function hid() public {
        uint p = 45;
        uint m;
        m = 89;
        uint l = 34;
    }
}

Y se establecen puntos de interrupción para las líneas

uint p = 45;

m = 89;

uint l = 34;

entonces al pulsar el botón Saltar al siguiente punto de interrupción se detendrá en las siguientes líneas en el orden dado:

uint p = 45; (declaración de p)

uint l = 34; (declaración de l)

uint p = 45; (45 asignado a p)

m = 89; (89 asignado a m)

uint l = 34; (34 asignado a l)