Débogage des transactions

(voir aussi le compagnon de cette page : la visite du débogueur)

Il existe deux façons de démarrer une session de débogage, chacune correspondant à un cas d’utilisation différent.

  • Cas d’utilisation 1 : pour déboguer une transaction effectuée dans Remix - cliquez sur le bouton de débogage dans le journal des transactions dans le terminal de Remix.

  • Cas d’utilisation 2 : pour le débogage d’une transaction pour laquelle vous disposez d’un txn hash provenant d’un contrat vérifié ou pour laquelle vous disposez du txn hash et du code source compilé avec les mêmes paramètres de compilation que le contrat déployé.

Lancez le débogage à partir du journal des transactions dans le terminal.

Commençons par un contrat de base ( ou remplacez le contrat ci-dessous par le vôtre )

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);
    }
}
  • Créez un nouveau fichier dans Remix et copiez-y le code ci-dessus.

  • Compilez le code.

  • Allez dans le module Exécuter et déployer.

Pour les besoins de ce tutoriel, nous allons exécuter la VM Remix.

  • Déployez le contrat :

Cliquez sur le bouton « Déployer

Vous verrez l’instance déployée (AKA l’udapp).

Ensuite, ouvrez-le (en cliquant sur le caret).

Nous allons appeler la fonction Donate et envoyer 2 Ethers.

Pour ce faire : dans le champ de saisie de la valeur, entrez 2 et sélectionnez Ether comme unité (ne laissez pas l’unité par défaut gwei, sinon le changement sera difficile à détecter).

Cliquez ensuite sur le bouton « Don ».

Ceci enverra l’Ether à la fonction.

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 affiche les informations relatives à chaque résultat de transaction dans le terminal.

Vérifiez dans le terminal où la transaction que vous venez d’effectuer est enregistrée.

Cliquez sur le bouton de débogage.

Mais avant d’aborder l’outil de débogage proprement dit, la section suivante montre comment démarrer une session de débogage directement à partir du débogueur.

Lancer le débogage à partir du débogueur

Cliquez sur l’icône de bogue dans le panneau d’icônes pour accéder au débogueur dans le panneau latéral.

Si vous ne voyez pas l’icône de bogue, allez dans le gestionnaire de plugins et activez le débogueur.

Vous pouvez démarrer une session de débogage en fournissant un transaction hash.

Pour trouver un hachage de transaction :

  1. Accédez à une transaction dans le terminal.

  2. Cliquez sur une ligne comportant une transaction - pour développer le journal.

  3. Le hachage de la transaction est là - copiez-le.

Ensuite, cliquez dans le débogueur, collez le hachage et cliquez sur le bouton Démarrer le débogage.

Utilisation du débogueur

Le débogueur permet de voir des informations détaillées sur l’exécution de la transaction. Il utilise l’éditeur pour afficher l’endroit du code source où se trouve l’exécution en cours.

La partie navigation contient un curseur et des boutons qui peuvent être utilisés pour avancer dans l’exécution de la transaction.

Explication des fonctionnalités des boutons du débogueur

  1. Step Over Back Retourne à l’étape précédente, mais ignore les appels de fonction : le débogueur N’ENTRE PAS dans une fonction.

  2. Retour Retourne à l’étape précédente. N’ignore pas les appels de fonction : le débogueur entrera dans n’importe quelle fonction en cours de route.

  3. Step Into Passe à l’étape suivante. N’ignore pas les appels de fonction : le débogueur entrera dans n’importe quelle fonction en cours de route.

  4. Step Over Forward Passe à l’étape suivante, mais ignore les appels de fonction : le débogueur n’entrera PAS dans une fonction.

  5. Sauter au point d’arrêt précédent Envoie le débogueur au dernier point d’arrêt visité. Notez que les points d’arrêt peuvent être définis en cliquant sur le numéro de ligne dans le code source.

  6. Jump Out Envoie le débogueur à la fin de la fonction

  7. Sauter au point d’arrêt suivant Envoie le débogueur au point d’arrêt suivant

11 panneaux donnent des informations détaillées sur l’exécution :

Instructions

Le panneau Instructions affiche le bytecode du contrat en cours d’exécution, l’étape en cours étant mise en évidence.

Remarque importante : lorsque ce panneau est caché, le curseur a une granularité plus grossière et ne s’arrête qu’aux limites d’expression, même si elles sont compilées en plusieurs instructions EVM. Lorsque le panneau est affiché, il est possible de passer sur toutes les instructions, même celles qui se réfèrent à la même expression.

Solidité Locale

Le panneau Solidity Locals affiche les variables locales associées au contexte actuel.

État de Solidité

Le panneau Solidity State affiche les variables d’état du contrat en cours d’exécution.

Panneaux de bas niveau

Ces panneaux affichent des informations de bas niveau sur l’exécution :

  • Pile

  • Changements dans les entrepôts

  • Mémoire

  • Données d’appel

  • Pile d’appels

  • Valeur de retour (uniquement si l’étape en cours est un opcode RETURN)

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

Transaction annulée

Une transaction peut être reverted (à cause d’une out of gas exception, d’une déclaration revert de Solidity ou d’une exception de bas niveau).

Il est important d’être conscient de l’exception et de localiser l’endroit où elle se trouve dans le code source.

Remix vous avertira lorsque l’exécution lancera une exception. Le bouton warning sautera au dernier opcode avant que l’exception ne se produise.

Points d’arrêt

Les deux derniers boutons de la zone de navigation permettent de revenir au point d’arrêt précédent ou d’avancer au point d’arrêt suivant.

Les points d’arrêt peuvent être ajoutés et supprimés en cliquant sur le numéro de ligne dans l”Éditeur.

Lors de l’utilisation d’une session de débogage avec des points d’arrêt, l’exécution sautera au premier point d’arrêt rencontré.

Note importante: Si vous ajoutez un point d’arrêt à une ligne qui déclare une variable, il risque d’être déclenché deux fois : une première fois pour initialiser la variable à zéro et une seconde fois pour lui assigner sa valeur réelle.

Voici un exemple de ce problème. Si vous déboguez le contrat suivant :

pragma solidity >=0.5.1 <0.6.0;

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

Et des points d’arrêt sont définis pour les lignes

uint p = 45;

m = 89;

uint l = 34;

puis en cliquant sur le bouton Sauter au point d'arrêt suivant, vous vous arrêterez aux lignes suivantes dans l’ordre donné :

uint p = 45; (déclaration de p)

uint l = 34; (déclaration de l)

uint p = 45; (45 attribué à p)

m = 89; (89 attribué à m)

uint l = 34; (34 assigné à l)