Aller au contenu
buybitcoinsmart

Glossaire / Référence pour développeurs

OP_VERIFY

Qu'est-ce qu'OP_VERIFY ?
OP_VERIFY retire l'élément situé au sommet de la pile et interrompt tout le script si cet élément n'est pas vrai, ce qui transforme tout test dans Bitcoin Script en exigence absolue.

L'octet 0x69 est l'assertion polyvalente du langage. Un script peut bifurquer avec OP_IF, mais il n'a aucun moyen de lever une erreur et aucune valeur de retour en dehors de ce qui subsiste sur la pile, si bien qu'un contrat impose une condition en calculant le résultat et en le confiant à cette instruction. Presque tous les paiements jamais effectués sont passés par là, généralement dissimulé dans un opcode fusionné.

Comment cela fonctionne

OP_VERIFY retire un élément de la pile et pose une seule question : est-ce vrai ?

La vérité ici est une notion au niveau de l'octet, non une notion numérique. Un élément vide est faux. Une suite d'octets nuls l'est aussi, tout comme le zéro négatif, une suite de zéros se terminant par 0x80. Tout le reste compte comme vrai, y compris un hash de 20 octets ou une clé publique de 33 octets. Si l'élément est faux, le script se termine sur-le-champ et l'entrée qui le contient est invalide, ce qui invalide la transaction qui l'entoure. Si l'élément est vrai, rien n'est remis sur la pile et l'évaluation passe à l'opcode suivant.

C'est ce comportement qui permet à un script de vérifier plusieurs choses à la suite. Un script ne réussit que lorsqu'il reste exactement une valeur vraie à la fin, si bien que sans assertions chaque condition devrait être repliée dans un unique booléen final. Avec elles, un contrat peut exiger un verrou temporel, puis exiger une préimage de hachage, puis exiger une signature, en échouant au premier échec.

Quatre opcodes intègrent l'assertion et n'existent que pour économiser un octet : OP_EQUALVERIFY, OP_CHECKSIGVERIFY, OP_CHECKMULTISIGVERIFY et OP_NUMEQUALVERIFY. Comme ceux-ci couvrent les cas courants, un 0x69 autonome est rare sur le mainnet.

Deux opcodes portent VERIFY dans leur nom et ne se comportent pas du tout ainsi. OP_CHECKLOCKTIMEVERIFY du BIP65 et OP_CHECKSEQUENCEVERIFY du BIP112 ont été ajoutés par soft fork sur des codes no-op jusque-là sans signification ; aussi, pour ne pas perturber les anciens nœuds, ils devaient laisser la pile exactement comme ils l'avaient trouvée. Tous deux inspectent l'élément du sommet et échouent lorsque la condition n'est pas remplie, mais aucun ne le consomme, c'est pourquoi les scripts réels les font toujours suivre de OP_DROP.

Où le voit-on

Les assertions se concentrent partout où un script a plus d'une chose à prouver.

Un coffre-fort simple à verrou temporel se lit comme une clé publique, OP_CHECKSIGVERIFY, un délai tel que 144 blocs (environ un jour), puis OP_CHECKSEQUENCEVERIFY. Les scripts d'engagement et HTLC de Lightning sont construits de la même manière, en enchaînant une vérification de préimage et une vérification de signature pour qu'aucune des deux ne suffise à elle seule à déplacer des fonds. Les dépenses de script Taproot s'appuient largement sur ce schéma, puisque tapscript a remplacé OP_CHECKMULTISIG par OP_CHECKSIGADD et utilise les formes verify pour garder compactes les politiques à clés multiples.

Miniscript, le compilateur de politiques que plusieurs portefeuilles de bureau utilisent désormais pour décrire des conditions de dépense sous forme lisible, émet ces opcodes à votre place. C'est le moyen le plus simple d'observer la génération d'assertions sans écrire de script brut à la main.

OP_VERIFY vs OP_RETURN

OP_VERIFY et OP_RETURN terminent tous deux mal un script, mais un seul pose d'abord une question. OP_VERIFY échoue lorsque la valeur qui lui est remise est fausse, si bien qu'une dépense correcte le franchit sans laisser de trace. OP_RETURN, octet 0x6a, échoue chaque fois qu'il est exécuté, sans aucune condition attachée, ce qui explique précisément pourquoi il sert à construire des sorties qui ne pourront jamais être dépensées et à attacher des données à une transaction. Un script qui meurt sur le premier a reçu quelque chose de faux. Un script qui meurt sur le second n'a jamais été destiné à être dépensable au départ.

À ne pas confondre avec

Questions fréquentes

Qu'est-ce qui compte comme vrai dans Bitcoin Script ?

Tout ce qui n'est pas un élément vide, pas une chaîne d'octets nuls et pas le zéro négatif. Un hash, une clé publique ou l'octet unique 0x01 comptent comme vrai, et l'interpréteur ne regarde jamais ce que les octets étaient censés signifier.

Pourquoi OP_CHECKLOCKTIMEVERIFY et OP_CHECKSEQUENCEVERIFY laissent-ils la pile intacte ?

Parce qu'ils ont été ajoutés par soft fork sur des opcodes que les anciens nœuds considèrent comme ne faisant rien. Consommer un élément aurait fait diverger ces nœuds sur l'état de la pile, aussi les nouveaux opcodes ne font que l'inspecter et les scripts ajoutent OP_DROP ensuite.

Termes associés

Plus de termes : Référence pour développeurs

Lire cette page en anglais