Imagine un Timelock comme une règle disant « par cette voie, seulement plus tard ». Il peut dépendre d’une hauteur de bloc, c’est-à-dire sa position dans la chaîne, d’un temps calculé à partir de la chaîne ou d’un délai depuis la confirmation d’une sortie précise. Une sortie est un montant assorti de règles indiquant qui peut le dépenser et sous quelles conditions. Attendre ne remplace ni une signature ni les autres exigences, et n’envoie pas l’argent. Il faut aussi distinguer une limite appliquée à une seule transaction préparée d’une condition imposée par les règles de dépense des fonds eux-mêmes.
Anna et Pavel peuvent organiser leurs fonds communs pour les dépenser ensemble à tout moment, mais permettre à Anna de les dépenser seule uniquement après un délai. Si Pavel ne répond plus, cette branche différée offre une voie de récupération convenue à l’avance. Une branche désigne ici une possibilité de dépense autorisée ; chacune peut avoir ses propres conditions. Le verrou ne bloque donc pas nécessairement toutes les possibilités à la fois. Ces règles doivent faire partie de la sortie dès sa création. Ajouter ensuite « débloquer dans une semaine » dans un portefeuille ordinaire ne suffit pas. Même après l’attente, Anna aura besoin de la clé correspondante et des informations nécessaires à une transaction valide. Timelock aide à gérer l’accès, mais ne restaure pas les clés perdues. [3]
Un verrou absolu se rapporte à une limite fixe, inscrite dans le champ nLockTime de la transaction. Si une transaction possède un nLockTime effectif de hauteur 1 000 000, le premier bloc satisfaisant cette condition est le bloc 1 000 001 : l’égalité ne suffit pas. Un verrou relatif mesure plutôt un délai depuis la confirmation de la sortie dépensée. Si la sortie d’Anna est créée dans le bloc 1 000 000 et que la branche impose 6 blocs d’attente, sa dépense peut satisfaire cette condition au plus tôt dans le bloc 1 000 006. Ce sont des valeurs d’exemple, pas la hauteur actuelle du réseau. Les exigences de signatures, des autres entrées et d’éventuels verrous supplémentaires restent applicables. Six blocs ne font pas non plus exactement une heure : leur arrivée est irrégulière. Le délai relatif ne commence ni à la création du portefeuille ni quand Anna décide d’utiliser l’argent. [1] [2] [5]
Supposons que le délai d’Anna vient de s’écouler. Le réseau n’agit pas à sa place. Quelqu’un doit encore construire une transaction ou utiliser une transaction préparée, fournir les signatures, payer les frais et la transmettre au réseau. Un mineur pourra alors l’inclure dans un bloc. Un Timelock satisfait est une condition remplie, pas une réservation de place ni un virement automatique. Il définit généralement le début d’une possibilité de dépense, pas son expiration spontanée. Lors d’une réorganisation, une partie de la chaîne est remplacée par une autre branche valide. Cela peut modifier la confirmation d’une sortie et le calcul de son délai relatif. Pour un montage personnalisé, il faut vérifier à l’avance chaque branche, la prise en charge par le portefeuille et les sauvegardes des clés comme des règles de dépense ; le temps ne corrige pas une condition mal définie. [2] [5]
Les conditions temporelles utilisent Median Time Past, ou MTP. Pour le bloc examiné, il s’agit de la médiane des horodatages des 11 derniers blocs, jusqu’au bloc précédent inclus. Trie leurs heures et prends celle du milieu, la sixième : c’est la médiane, pas la moyenne arithmétique. BIP113 décrit cette règle et Bitcoin Core emploie GetMedianTimePast pour la calculer. Le temps pertinent n’est donc ni l’heure actuelle du téléphone d’Anna ni l’horodatage du bloc proposé. Minuit sur un calendrier ne coïncide pas forcément avec la satisfaction du verrou. Les verrous fondés sur la hauteur attendent des blocs ; ils ne décomptent pas des secondes. [4]
On peut maintenant distinguer quatre noms de la documentation. nLockTime est un champ de la transaction entière qui définit une limite absolue. nSequence sur une entrée porte un délai relatif selon BIP68. Mais nLockTime seul ne verrouille pas un UTXO, une sortie encore non dépensée, contre une autre transaction avec des réglages différents. La personne autorisée à dépenser peut créer cette autre transaction si les règles de la sortie ne l’en empêchent pas. Bitcoin Script est le langage qui permet d’exprimer ces règles de dépense. OP_CHECKLOCKTIMEVERIFY, ou CLTV selon BIP65, exige le réglage absolu correspondant dans la branche utilisée. OP_CHECKSEQUENCEVERIFY, ou CSV selon BIP112, contrôle le réglage relatif ; BIP68 impose le délai réel. Ni CLTV ni CSV n’envoient de fonds ou n’ajoutent une signature manquante. Une autre branche autorisée peut être utilisable sous d’autres conditions. [1] [2] [3]
Les sections suivantes constituent une référence technique. Un champ est une donnée enregistrée dans la transaction ; une entrée référence une sortie à dépenser. Chaque entrée possède un champ nSequence. Une valeur spéciale peut neutraliser nLockTime : saisir une date ne suffit donc pas. nLockTime est un champ de 32 bits non négatif ; zéro désactive la condition temporelle absolue. Si toutes les entrées sont réglées sur SEQUENCE_FINAL, de valeur 0xffffffff, un nLockTime non satisfait est ignoré. Un verrou absolu effectif exige qu’au moins une entrée possède un autre nSequence. L’évaluation porte sur cette transaction précise, pas sur un gel permanent de ses entrées. [5] [7]
Un même champ peut exprimer deux choses différentes, séparées par un seuil numérique. Un timestamp Unix représente le temps en secondes depuis le début de 1970 en UTC. Le bloc candidat est celui dans lequel la transaction examinée serait incluse. LOCKTIME_THRESHOLD vaut 500000000. Un nLockTime inférieur désigne une hauteur de bloc ; une valeur égale ou supérieure désigne un timestamp Unix. Lorsque le contrôle absolu est actif, nLockTime doit être strictement inférieur à la hauteur du bloc candidat ou au MTP pertinent. L’égalité ne suffit pas ; il ne s’agit ni d’un montant, ni d’une hauteur moyenne, ni d’une date d’activation du protocole. [5] [8]
Un opérande est une valeur fournie à une instruction ; un opcode est l’instruction Script elle-même. CLTV compare l’exigence enregistrée dans la branche au réglage de la transaction. Un autre contrôle détermine si la chaîne a suffisamment avancé. Cela dépasse une simple comparaison entre la date du jour et un nombre. OP_CHECKLOCKTIMEVERIFY exige un opérande non négatif, un type hauteur/temps identique à celui de nLockTime et un opérande inférieur ou égal à nLockTime. L’entrée qui dépense la sortie concernée ne doit pas avoir nSequence égal à 0xffffffff. L’opcode ne lit directement ni l’horloge ni la hauteur de la chaîne ; les réglages de la transaction sont vérifiés séparément lors du contrôle de sa validité temporelle. Les autres conditions de Script restent nécessaires. [1] [6]
Le nombre nSequence contient à la fois une durée d’attente et des interrupteurs précisant son sens. Un bit est un zéro ou un un dans cette représentation ; l’activer peut sélectionner une option. Les positions de bits ci-dessous appartiennent au format technique, pas à un nombre de confirmations. Pour les transactions de version 2 ou supérieure, BIP68 active la condition relative pour les entrées dont le bit 31 n’est pas activé. Les 16 bits de poids faible déterminent le délai ; le bit 22 sélectionne des unités de 512 secondes, sinon des blocs. Le délai en blocs se calcule depuis la hauteur de confirmation de la sortie dépensée. Le délai temporel va du MTP du bloc précédant sa confirmation au MTP précédant le bloc candidat. Il ne s’agit pas du temps écoulé depuis la création de la transaction dans le portefeuille. [2] [5]
CSV effectue un contrôle analogue pour l’attente relative. Un masque sélectionne les bits pertinents de nSequence ; un disable flag est un indicateur de désactivation. Lightning Network est un réseau de canaux de paiement : les participants y actualisent la répartition convenue de fonds bloqués ensemble. Le délai laisse à l’autre partie le temps de réagir si un ancien état déjà révoqué est publié. Une commitment transaction décrit cette répartition ; une clé de révocation permet à l’autre partie de dépenser la sortie concernée d’une version révoquée par une branche de pénalité. Avec un opérande actif non négatif, OP_CHECKSEQUENCEVERIFY exige une version au moins égale à 2, le drapeau de désactivation de l’entrée désactivé, un type de délai identique et une valeur de nSequence suffisante après application du masque. BIP68 impose séparément l’âge réel. CSV permet une branche de récupération différée. Pour une sortie Lightning to_local, le délai to_self_delay limite le propriétaire de la transaction de commitment ; l’autre partie, munie de la bonne clé de révocation, peut utiliser la branche de pénalité sans ce délai. [3] [9]
Deux nombres presque identiques peuvent agir différemment. Les valeurs commençant par 0x ci-dessous sont en hexadécimal. NOP désigne une instruction qui n’ajoute ici aucune restriction temporelle. Il faut aussi distinguer l’interrupteur de l’entrée de transaction de celui de la valeur fournie à CSV. Le bit 31 est SEQUENCE_LOCKTIME_DISABLE_FLAG et désactive l’interprétation relative de BIP68 uniquement pour l’entrée concernée. La valeur 0xfffffffe contient ce bit, mais n’est pas SEQUENCE_FINAL : elle permet un nLockTime effectif et CLTV. La valeur 0xffffffff est finale. Un opérande CSV non négatif avec le drapeau de désactivation activé se comporte comme NOP ; en revanche, ce drapeau activé dans l’entrée ne satisfait pas une exigence CSV active. Ces deux cas ne doivent pas être confondus. [3] [7]
Un RPC est une commande pour utiliser ton nœud, le logiciel qui vérifie les blocs et les transactions Bitcoin. Le décodage rend simplement lisibles les données enregistrées ; la commande de test vérifie ensuite si une transaction signée précise passerait. Un Mempool est la liste locale des transactions en attente du nœud. La RPC decoderawtransaction de Core 31 affiche version, locktime et sequence de chaque entrée. Pour CLTV/CSV, vérifie le Script réellement utilisé et la sortie dépensée ; le simple décodage ne prouve pas la validité. La RPC testmempoolaccept teste un candidat signé par rapport à la chaîne actuelle, aux règles de validité de Bitcoin et aux règles locales d’acceptation des transactions du nœud, sans l’accepter dans le mempool ni le diffuser. Vérifie allowed et le motif de rejet ; un succès ne promet pas de confirmation future. [10] [11] [12]
Pour une vision complète, lisez aussi CLTV, CSV, Lightning Network, Payment Channel, Transaction, Bitcoin Script. Cette entrée est également citée par Confirmation, Bitcoin Script, HTLC, CLTV.