Aller au contenu principal
BlockchainMar 28, 2026

Deep EVM #5 : Introduction à Yul — Le langage d'assemblage secret de Solidity

OS
Open Soft Team

Engineering Team

Qu’est-ce que Yul ?

Yul est un langage d’assemblage intermédiaire conçu pour l’EVM. Il sert deux rôles : c’est la représentation intermédiaire du compilateur Solidity (ce en quoi Solidity compile avant de devenir bytecode), et c’est un langage que vous pouvez écrire directement dans des blocs assembly {} à l’intérieur de Solidity.

Contrairement au bytecode EVM brut, Yul offre :

  • Des variables nommées (pas de gestion manuelle de la pile)
  • Des fonctions avec paramètres et valeurs de retour
  • Des structures de contrôle (if, switch, for)
  • Un accès direct à tous les opcodes EVM

Yul inline dans Solidity

Vous pouvez intégrer du Yul dans n’importe quelle fonction Solidity :

function efficientAdd(uint256 a, uint256 b) external pure returns (uint256 result) {
    assembly {
        result := add(a, b)
    }
}

Dans ce bloc assembly, add est l’opcode EVM ADD, pas une fonction Solidity. Les variables Solidity (a, b, result) sont automatiquement accessibles.

Syntaxe de Yul

Variables

let x := 42
let y := add(x, 1)  // y = 43
let z := 0           // déclaration avec initialisation à zéro

Les variables Yul sont toujours de 32 octets (256 bits). Il n’y a pas de types — tout est un uint256.

Structures de contrôle

// If (pas de else en Yul)
if gt(x, 100) {
    // exécuté si x > 100
}

// Switch
switch selector
case 0x70a08231 { /* balanceOf */ }
case 0xa9059cbb { /* transfer */ }
default { revert(0, 0) }

// Boucle for
for { let i := 0 } lt(i, 10) { i := add(i, 1) } {
    // corps de la boucle
}

Fonctions

function safeAdd(a, b) -> result {
    result := add(a, b)
    if lt(result, a) {
        revert(0, 0) // débordement
    }
}

Accès à la mémoire

// Écrire en mémoire
mstore(0x00, 0x42)     // memory[0x00..0x20] = 0x42
mstore8(0x20, 0xff)    // memory[0x20] = 0xff (1 octet)

// Lire depuis la mémoire
let value := mload(0x00)  // value = memory[0x00..0x20]

Accès au stockage

// Lire un slot de stockage
let bal := sload(slot)

// Écrire dans un slot de stockage
sstore(slot, newValue)

Quand utiliser Yul

  1. Optimisation du gas — Quand Solidity génère un bytecode sous-optimal
  2. Opérations non supportées — Certaines opérations EVM n’ont pas d’équivalent Solidity
  3. Manipulation de mémoire — Encodage/décodage ABI personnalisé
  4. Gestion fine du gas — Contrôle précis de chaque opcode

Risques du Yul inline

  • Pas de vérification de types
  • Possibilité d’écraser le pointeur de mémoire libre de Solidity
  • Les bugs sont plus difficiles à détecter et auditer
  • Le compilateur ne peut pas optimiser autour des blocs assembly

Conclusion

Yul est le pont entre le confort de Solidity et la puissance brute de l’EVM. Il vous permet d’optimiser les chemins critiques sans abandonner complètement les abstractions de haut niveau.

Dans le prochain article, nous approfondirons la gestion mémoire en Yul : mstore, mload et le pointeur de mémoire libre.