Il s’agit de la partie 5 de la série d’articles techniques de Cointelegraph Research sur les covenants Bitcoin. Pour lire l’article précédent, cliquez ici. 

MATT (Merkleize All The Things) est un framework de contrats intelligents pour Bitcoin qui permet de créer des contrats avec état et des preuves de fraude évolutives. Un contrat avec état conserve des informations d’une transaction à l’autre et peut les mettre à jour à mesure qu’il évolue. Les scripts Bitcoin standard ne permettent pas cela, car chaque transaction est évaluée indépendamment, sans mémoire des exécutions précédentes.

Toute proposition de covenant permet, dans une certaine mesure, aux UTXO de transporter un état, comme l’illustrent des langages de script tels que Sapio, qui s’appuie sur OP_CTV. Le principe consiste à utiliser des adresses pour représenter un automate à états finis, les transactions faisant office de transitions d’état. Cependant, ce paradigme ne permet pas d’implémenter élégamment une logique numérique : c’est cette lacune que vient combler MATT, et plus particulièrement son implémentation proposée au moyen d’OP_CCV. Comme MATT permet de calculer des données engagées au moment de la dépense, puis de les réintégrer dans la sortie suivante, chaque dépense peut produire dynamiquement un nouvel état au lieu de choisir parmi un ensemble d’états prédéterminé. 

Comment OP_CCV engage l’état dans une clé Taproot

Pour comprendre la proposition MATT, il est utile de commencer par voir comment Taproot engage des données au moyen de clés publiques. Chaque sortie Taproot contient une clé publique de base, appelée clé interne, qui peut être modifiée cryptographiquement, ou « ajustée » (tweaked), afin d’engager des informations supplémentaires. Formellement, la clé publique ajustée est Q = P + t·G, où P est la clé interne, G le générateur de la courbe elliptique secp256k1, et t un hachage avec étiquette de P et des données engagées. 

Dans une sortie Taproot classique, cet engagement encode généralement la racine de Merkle d’un arbre Taproot, qui contient des chemins de dépense cachés. MATT s’appuie sur ce mécanisme pour intégrer également l’état du contrat dans la clé. Au lieu d’intégrer une logique complexe directement dans le langage de script de Bitcoin, MATT encode le calcul sous la forme d’une séquence d’engagements d’état, et la chaîne vérifie uniquement la validité de chaque transition d’état.

MATT peut être réalisé au moyen de différentes combinaisons d’opcodes. L’implémentation la plus directe et la mieux spécifiée repose sur OP_CHECKCONTRACTVERIFY (OP_CCV). OP_CCV fournit la primitive qui rend possibles les UTXO porteurs d’état dans Taproot.  OP_CCV permet à un script de vérifier qu’une clé d’entrée ou de sortie Taproot a été ajustée pour engager une donnée d’état spécifique. La clé interne est d’abord ajustée à l’aide d’un hachage de l’état actuel du contrat, puis l’ajustement standard de l’arbre Taproot est appliqué par-dessus. La clé de sortie obtenue engage donc à la fois le tapscript (l’ensemble des conditions de dépense) et l’état actuel du contrat.

OP_CCV peut ensuite imposer l’état transmis à la sortie suivante. Il permet au script d’examiner les données d’état fournies sur la pile witness, d’effectuer des calculs à partir de celles-ci et d’exiger que l’état mis à jour qui en résulte soit correctement engagé dans une sortie spécifiée. C’est ainsi que les transitions d’état sont imposées sur la chaîne. Le format de la pile est le suivant :

<data> <index> <pk> <taptree> <mode> OP_CHECKCONTRACTVERIFY

L’opcode prend en charge trois modes de vérification d’une sortie, ainsi qu’un mode distinct pour les entrées. En mode par défaut, la totalité de la valeur en BTC de l’UTXO d’entrée est affectée à la sortie spécifiée ; en mode déduction, seule une partie correspondant au montant de la sortie est affectée, le reste demeurant disponible pour d’autres sorties ; et en mode ignore, le script et l’engagement des données sont vérifiés sans imposer de contrainte sur le montant.  Comme les modes par défaut et déduction sont conçus pour préserver la valeur dans les sorties vérifiées, les frais de transaction doivent être payés au moyen d’entrées distinctes dédiées aux frais. Une entrée dédiée aux frais et une sortie de monnaie peuvent être ajoutées à la transaction sans entrer en conflit avec les contraintes du covenant. Cela évite la destruction accidentelle de fonds qui peut survenir avec des implémentations de covenant plus rudimentaires, telles qu’OP_CTV ou SIGHASH_ANYPREVOUT. Cela répond également à une limite importante des covenants fondés sur des transactions pré-signées, qui fixent généralement les montants à l’avance et ne peuvent donc pas s’adapter à des ajustements dynamiques des frais ou à des déverrouillages partiels.

OP_CCV + OP_CAT : preuves de Merkle et preuves de fraude

Lorsque OP_CCV est combiné à OP_CAT, le cadre MATT gagne encore en expressivité. OP_CAT permet de concaténer des octets dans Script, ce qui rend possible la construction et la vérification de preuves de Merkle directement sur la chaîne. Dans une telle configuration, une sortie Taproot est associée à deux arbres de Merkle distincts. Le premier est l’arbre de scripts Taproot classique (l’arbre Taproot), dont les feuilles sont les scripts de dépense du contrat. Le second est un arbre d’état distinct, dont les feuilles contiennent les données du contrat, par exemple les étapes intermédiaires d’un calcul.  Le script OP_CCV + OP_CAT peut vérifier une preuve de Merkle par rapport à la racine de l’arbre d’état actuel, calculer la racine mise à jour après une transition, puis utiliser OP_CCV pour obliger la sortie suivante à l’engager. 

Cette construction permet de créer des systèmes de preuve de fraude assortis d’une condition de pénalité, dans lesquels un long calcul est engagé hors chaîne et seule l’étape contestée (avec son chemin dans l’arbre binaire) doit être révélée et vérifiée sur la chaîne. Des systèmes similaires existent sous la forme de rollups optimistes sur d’autres blockchains : l’intégralité du calcul s’effectue hors chaîne, et le contrat sur la chaîne n’intervient que lorsqu’une contestation est soulevée. Les preuves de fraude nécessitent de compiler le calcul sous la forme d’un circuit binaire ou d’une représentation équivalente, étape par étape, qui puisse être engagée dans un arbre de Merkle. OP_CCV + OP_CAT éviterait le recours aux signatures à usage unique de Lamport et aux graphes de transactions pré-signées dont BitVM dépend pour imposer la cohérence de l’état.

Au-delà des preuves de fraude, la combinaison d’OP_CCV et d’OP_CAT a également des implications pour les coffres-forts. OP_CCV seul permet d’implémenter des coffres-forts, mais combiné à OP_CAT, il permet de créer des coffres-forts complets, dont les fonctionnalités sont essentiellement équivalentes à celles proposées par OP_VAULT. Comme l’a fait remarquer James O’Beirne, l’auteur d’OP_VAULT, OP_CCV constitue une conception plus générale et plus robuste, qui remplace de fait sa proposition antérieure.

Dans le prochain article de cette série, nous délaisserons les propositions générales de covenants pour examiner des opcodes propres à certaines applications, tels qu’OP_VAULT, OP_UNVAULT et OP_EVICT. Chacun de ces opcodes est conçu pour résoudre un problème précis plutôt que pour offrir une programmabilité générale.

Magazine : les détenteurs de bitcoins ont reçu de l’eCash — qu’en faire ?