Blockchain/Niveau IV · Le protocole en profondeur/4.1 Script/Leçon 1
Script : un langage à pile
La pile qui borne l’exécution et les opcodes désactivés par Satoshi
MatérielUne feuille de papier et un styloAccès à un explorateur de blocs BitcoinLa page « Script » du Bitcoin Wiki
Curiosité
- Pourquoi un langage sans boucles protège-t-il chaque nœud des calculs infinis ?
- Quel bug précis, en 2010, permettait à quiconque de dépenser les pièces des autres avant d’être corrigé ?
- Comment une sortie peut-elle être marquée comme non dépensable de manière prouvable tout en transportant des données ?
Explorer
- Bitcoin Script est un petit langage à pile, dans le style de Forth. Il ne dispose ni de boucles ni de récursion, ce qui le rend délibérément non Turing-complet. Cette conception garantit que le coût d’exécution de chaque script reste borné et prévisible. Aucun script ne peut s’exécuter indéfiniment ni consommer des ressources illimitées, ce qui protège le réseau contre les attaques par déni de service inhérentes au code généraliste. Cette simplicité permet à n’importe quel nœud de valider les transactions de manière déterministe, sans risque d’épuisement des ressources.
- Chaque sortie porte un script de verrouillage (scriptPubKey) qui définit les conditions de dépense. Celui qui dépense fournit les données de déverrouillage via le scriptSig ou, depuis SegWit, via les données de témoin (witness). L’exécution empile les données et applique les opcodes de gauche à droite. La dépense est valide si l’exécution se termine sans erreur et laisse une valeur vraie au sommet de la pile. Ce résultat binaire sécurise les bitcoins sans jamais révéler les clés privées, en s’appuyant sur une vérification cryptographique plutôt que sur des contrôles d’identité.
- En 2010, Satoshi Nakamoto a désactivé plusieurs opcodes, dont OP_CAT et OP_MUL, par précaution après la découverte de bugs, dont l’un (dans OP_LSHIFT) pouvait faire planter les nœuds. Une faille plus grave encore tenait à la manière dont scriptSig et scriptPubKey étaient concaténés et exécutés comme un seul script : un scriptSig se terminant par OP_RETURN pouvait achever l’exécution avec la valeur « true » avant même que le script de verrouillage ne soit exécuté, permettant à n’importe qui de dépenser les pièces de n’importe qui. Le premier correctif a fait échouer OP_RETURN purement et simplement ; une version ultérieure est allée plus loin en exécutant scriptSig et scriptPubKey comme des scripts distincts. Ce changement a renforcé le modèle de sécurité et éliminé des opérations dangereuses qui auraient pu être exploitées ou provoquer un comportement imprévisible.
- OP_RETURN marque une sortie comme non dépensable de manière prouvable. Il sert à intégrer de petites quantités de données on-chain sans créer de chemin de dépense valide. Comme aucune signature ne peut satisfaire OP_RETURN, les pièces sont verrouillées définitivement, mais les données associées restent inscrites dans l’historique de la blockchain. Comme de telles sorties ne peuvent jamais être dépensées, les nœuds les excluent de l’ensemble des pièces dépensables.
- Pour comprendre la mécanique, exécutez pas à pas « 2 3 OP_ADD 5 OP_EQUAL » sur papier. Commencez avec une pile vide. Empilez 2, puis empilez 3. Appliquez OP_ADD, qui dépile les deux valeurs et empile leur somme (5). Empilez à nouveau 5. Appliquez OP_EQUAL pour comparer les deux éléments du sommet ; comme ils sont identiques, il empile true (1). La pile se termine avec une seule valeur true, ce qui satisfait la condition de validité. Cette simple opération arithmétique montre comment les opcodes manipulent la pile pour évaluer des conditions.
- Ouvrez un explorateur de blocs et repérez n’importe quelle transaction standard. Identifiez le scriptPubKey dans la section des sorties : il commence par OP_DUP pour une sortie P2PKH legacy, par OP_0 pour du SegWit natif ou par OP_1 pour du Taproot. Ouvrez ensuite une transaction qui dépense une telle sortie et trouvez la signature et la clé qui la satisfont, dans le scriptSig pour les sorties legacy ou dans le witness pour SegWit et Taproot, en laissant une valeur vraie sur la pile d’exécution pour tous les nœuds qui valident.
Faits clés
- Bitcoin Script n’est pas Turing-complet ; il ne possède ni boucles ni récursion.
- En 2010, Satoshi a désactivé OP_CAT, OP_MUL et d’autres opcodes par précaution, après la découverte de bugs.
- Depuis 2010, scriptSig et scriptPubKey sont exécutés séparément plutôt que concaténés.
- OP_RETURN marque une sortie comme non dépensable de manière prouvable, afin d’y intégrer des données.
- Une dépense valide laisse une valeur vraie au sommet de la pile d’exécution.
- Le coût de chaque script est limité en raison de l’absence de calcul arbitraire.
Exercice neuf, six, trois, un
9RassemblerListez 9 opcodes de Bitcoin Script. Indiquez lesquels sont désactivés, lesquels modifient directement la pile et lesquels effectuent des vérifications cryptographiques.
6RegrouperRegroupez les 9 en 6 catégories selon leur fonction : arithmétique, comparaison, manipulation de pile, vérification cryptographique, intégration de données, ou obsolète/supprimé.
3DistillerRéduisez les 6 à 3 raisons pour lesquelles Script a été délibérément maintenu limité.
1CristalliserRédigez 1 phrase expliquant comment l’exécution bornée protège le réseau contre les scripts malveillants.
Vérification des faits
Les dates, les chiffres et les affirmations ont été vérifiés à l’aide des sources publiées listées ci-dessous.