El que CTV es nega a mirar


Aquest post va començar com la transcripció d’una xerrada i ha acabat sent la pàgina que m’hauria agradat tenir mentre la preparava. Espero que sigui útil per a més gent que intenti entendre què són realment els covenants.

La facilitat de l’ésser humà per generar una economia complexa és increïble. Tot i que, al nivell més baix, tot es redueix a transaccions, la necessitat de pagaments més sofisticats acaba derivant en creacions com els contractes o els préstecs. A Bitcoin això també s’ha vist com una necessitat, i aquestes tasques complexes s’aconsegueixen mitjançant Bitcoin Script. Per què fer servir Bitcoin per a aquests contractes? Perquè aquests scripts s’executen directament com a codi: una seqüència de condicions immutables que, a diferència del món real, no depenen de la confiança en un tercer.

Bitcoin Script pot dir qui pot gastar una moneda, i quan. Tot i així, no pot fixar per avançat cap condició sobre els UTXO que genera.

Introducció als covenants

Un covenant trasllada aquesta promesa al consens. Podríem definir un covenant com:

Tècnicament es defineix com covenant quan el scriptPubKey d’un UTXO restringeix el scriptPubKey de les sortides de la transacció que el gasta.

De manera simplificada, tractem els covenants com a primitives que permeten a les transaccions restringir com es podran gastar en el futur.

Breu història

any esdeveniment
2013 El fil “CoinCovenants” de Greg Maxwell a bitcointalk. Invito a llegir la proposta inicial de Maxwell i revisar les propostes de contractes que van sorgir en aquella època.
2015 S’activa OP_CHECKLOCKTIMEVERIFY (BIP-65). Script ja pot dir quan es pot gastar una moneda, fixant una alçada o data absoluta.
2016 • S’activa OP_CHECKSEQUENCEVERIFY (BIP-112), permet esperar un nombre de blocs des que es confirma per poder fer la despesa.
• Möser, Eyal i Sirer publiquen Bitcoin Covenants i proposen vaults amb un opcode OP_CHECKOUTPUTVERIFY.
2017 O’Connor i Piekarska, Enhancing Bitcoin Transactions with Covenants. Mencionen OP_CHECKSIGFROMSTACK i l’apliquen en una sidechain (Elements).
2018 Decker, Russell i Osuntokun publiquen eltoo: un canal de Lightning on l’estat més recent sempre guanya i ningú ha de guardar secrets de revocació. Necessita SIGHASH_NOINPUT, i és l’origen del que avui anomenem LN-Symmetry.
2019 • Jeremy Rubin proposa OP_CHECKOUTPUTSHASHVERIFY, rebatejat OP_CHECKTEMPLATEVERIFY aquell desembre.
• SIGHASH_NOINPUT es converteix en ANYPREVOUT (BIP-118).
2021 • S’activa Taproot. Els opcodes OP_SUCCESSx de tapscript fan que afegir opcodes nous sigui molt més barat.
• Andrew Poelstra publica CAT and Schnorr Tricks, on mostra que amb OP_CAT i una signatura Schnorr amb clau coneguda un script pot llegir la transacció; en parlem a la secció d’OP_CAT.
2022 • Un intent de publicar un client d’activació de CTV via Speedy Trial provoca un rebuig fort i no prospera.
• Bitcoin Inquisition arrenca a signet amb CTV i APO actius.
2023 • OP_VAULT (BIP-345), MATT, OP_TXHASH (BIP-346) i OP_CAT proposat de nou (BIP-347).
• Burak Keceli proposa Ark i John Law els timeout trees, dos dissenys que amb covenants deixarien de necessitar que tothom signi alhora.
• Robin Linus publica BitVM i torna a obrir el debat sobre verificar càlculs a Bitcoin.
2024 • OP_CAT s’activa a Inquisition signet.
• CSFS rep el BIP-348.
• LNHANCE agrupa CTV, CSFS, OP_INTERNALKEY i OP_PAIRCOMMIT.
• moonsettler llança “CTV++”.
2025 • OP_VAULT es retira en favor de propostes més generals.
• Una carta oberta de desenes de desenvolupadors dona suport a CTV+CSFS.
• OP_CHECKCONTRACTVERIFY rep el BIP-443.
2026 • OP_TEMPLATEHASH (BIP-446) i el seu paquet de tapscript (BIP-448) arriben a Draft.
• La Great Script Restoration rep els BIP 440 i 441.
• Un client d’activació de CTV obre una finestra de senyalització.

Posem-nos tècnics :=)

Un UTXO sempre està limitat a l’hora de gastar-se pel seu scriptPubKey. De fet, no només el limita sinó que el defineix: quan parlem d’adreces, en realitat parlem del que hi ha dins d’aquest camp. Per exemple, una sortida P2PKH porta dins l’scriptPubKey el hash d’una clau pública (un SHA-256 seguit d’un RIPEMD-160), a més de diversos opcodes auxiliars per validar que qui gasta l’UTXO aporta un scriptSig correcte.

// Definir un OP_CODE

// Tal vez se podria añadir una aplicación de ejecución del stack de bitcoin de manera sencilla.

Aquests opcodes obren la porta a condicions de despesa molt més sofisticades.

Propietats dels covenants

Els timelocks omplen el quan. OP_CHECKLOCKTIMEVERIFY (BIP-65) i OP_CHECKSEQUENCEVERIFY (BIP-112) permeten que un script es negui a ser gastat abans d’una alçada absoluta o abans que hagin passat un cert nombre de blocs des que la moneda es va confirmar. També poden funcionar amb temps (una data) en lloc de blocs, però és menys habitual.

El on no té opcode. Qui el necessiti té tres opcions:

  • Confiar en algú. Un custodi, una federació, un comitè multisig.
  • Signar per avançat i esborrar. Crear una clau efímera, bloquejar-hi fons, signar les úniques transaccions que vols permetre i destruir la clau.
  • Signar per avançat amb tothom. Moltes aplicacions actuals signen per avançat en comunitat i produeixen una signatura n-de-n (avui amb MuSig2) sobre un arbre de transaccions futures. Tots els protocols que ho fan, des dels canals de Lightning fins a Ark, ho paguen amb interacció activa dels usuaris.

Els covenants substitueixen les tres opcions per una regla que fa complir el consens. Per fer-ho, l’script necessita conèixer informació de la transacció que el gasta, i aquesta capacitat s’anomena introspecció.

Introspecció

// Explicació

Origen dels covenants

El 20 d’agost del 2013, Greg Maxwell va obrir a bitcointalk el fil CoinCovenants using SCIP signatures, an amusingly bad idea. Proposava que un script pogués fer introspecció de la transacció que el gasta i exigir que totes les sortides futures portessin la mateixa regla, creant una moneda «subjecta per sempre a un covenant». Van sorgir diverses idees molt interessants sobre possibles contractes, la majoria horribles, com UTXO que per consens només es poden gastar si la transacció crea una sortida més gran que la moneda que gasta, de manera que cada despesa hi ha d’afegir bitcoins nous i la moneda creix com una bola de neu sense poder tornar a fer-se petita. Però també n’hi va haver algunes que van marcar l’inici del que ara són els covenants.

OP_CHECKOUTPUTVERIFY i OP_PATTERN

El 2016, Möser, Eyal i Sirer van proposar el primer covenant específic per a Bitcoin. Aquest incluia un opcode nou, OP_CHECKOUTPUTVERIFY, que rep tres coses: un índex de sortida, un import i un patró. Comprova que la sortida existeix, que porta exactament aquest import i que el seu script coincideix amb el patró. El patró és un script amb forats: els placeholders PubKey i PubKeyHash accepten qualsevol clau o hash de clau. Si l’import o el patró es posen a 0, aquell camp no es comprova.

L’exemple del paper és una moneda que representa un actiu real, posem 1 BTC:

0 <100000000> <PubKey CHECKSIG> OP_CHECKOUTPUTVERIFY

La sortida 0 de la transacció següent ha de portar exactament 1 BTC (100.000.000 sats) cap a qualsevol clau pública, així que la moneda no es pot partir ni barrejar amb altres. El problema és que només aguanta un salt: a la transacció següent la restricció desapareix.

Per fer-la durar es podria niar el covenant dins del patró, però caldria fer-ho infinites vegades. En lloc d’escriure un script que es reprodueixi a si mateix (un quine), afegeixen un altre placeholder, OP_PATTERN, que l’intèrpret substitueix pel mateix patró. Així la regla es copia a cada sortida i la moneda queda lligada per sempre, que és justament el tipus de covenant recursiu que preocupava a Maxwell.

OP_CTV

La idea d’OP_CHECKTEMPLATEVERIFY és senzilla: quan crees l’adreça, escrius per avançat la transacció que vols permetre i en guardes un hash a l’script. Quan algú intenta gastar la moneda, el node calcula el mateix hash sobre la transacció real i només l’accepta si coincideix. Així, la moneda només es pot gastar de la manera que es va decidir quan es va crear.

OP_CHECKTEMPLATEVERIFY reutilitza OP_NOP4 (0xb3).

  • Si l’element del cim no fa exactament 32 bytes, es comporta com un NOP; això és el que permet introduir-lo amb un soft fork.
  • Si fa 32 bytes, calcula el hash de plantilla de la transacció que gasta i compara. Si no coincideix, l’script falla.

El hash, DefaultCheckTemplateVerifyHash, és un únic SHA256 sobre la concatenació dels següents camps de la transacció en aquest ordre:

# camp serialització
1 nVersion 4 bytes, little-endian
2 nLockTime 4 bytes, little-endian
3 sha256(scriptSigs) només si algun scriptSig no és buit
4 input_count 4 bytes, little-endian
5 sha256(sequences) sobre les seqüències de 4 bytes
6 output_count 4 bytes, little-endian
7 sha256(outputs) sobre cada CTxOut: valor de 8 bytes i després l’script amb prefix de longitud
8 input_index 4 bytes, little-endian

Cada camp compromès hi és per tapar un forat concret. Repassar-los és la manera més ràpida d’entendre què promet realment una plantilla.

  • nVersion és el número de versió de la transacció, i decideix quines regles se li apliquen.
  • nLockTime i sha256(sequences) fixen tots els timelocks absoluts i relatius. Sense ells, qualsevol podria agafar una plantilla pensada per gastar-se després d’un retard i gastar-la abans, o treure-li el senyal de RBF.
  • sha256(scriptSigs) existeix per l’estabilitat del txid. Les entrades legacy i P2SH porten dades a l’scriptSig, i un scriptSig canvia el txid. Si la plantilla no el fixés, un tercer podria mal·lear una transacció CTV i deixar orfes tots els fills precalculats que la gasten.
  • input_count i input_index asseguren que la moneda es gasta sola i en la posició prevista. Així ningú pot ajuntar dues monedes amb la mateixa plantilla en una sola transacció, cosa que deixaria el valor d’una d’elles al miner.
  • output_count i sha256(outputs) fixen quantes sortides hi ha, quant va a cada una i a quin script. És aquí on el covenant obliga que els diners vagin on prèviament s’ha decidit.

Una conseqüència que ningú no havia demanat: txids predictibles

Ajunta el compromís amb l’scriptSig i les entrades segwit, i en surt una cosa útil. Un cop finançada l’arrel d’un arbre CTV, totes les transaccions de sota tenen un txid totalment determinat: les entrades són sortides de transaccions el contingut de les quals fixen les plantilles, i en aquestes transaccions no queda res que es pugui mal·lear.

Això vol dir que pots donar a cada destinatari d’un arbre la cadena exacta de txids que porta a la seva moneda abans que cap d’aquestes transaccions existeixi a la cadena. Els arbres de control de congestió, els timeout trees, les obertures de canal no interactives i Ark depenen d’aquesta propietat.

On pot viure l’opcode

CTV es va construir sobre un OP_NOP, no sobre un OP_SUCCESS de tapscript, i aquesta decisió té una conseqüència que poca gent menciona: funciona a tots els contextos d’script que té Bitcoin.

context script notes
bare <H> OP_CHECKTEMPLATEVERIFY sortida de 34 bytes, gastada amb un scriptSig buit i sense witness. La implementació de referència la retransmet com a estàndard. La forma més barata possible.
P2WSH el mateix script, passat pel hash la plantilla queda privada fins que es gasta la moneda
tapscript una fulla d’un arbre Taproot pot conviure amb el key path i altres fulles; l’únic context on existeix CSFS per combinar-s’hi
P2SH embolcall legacy funciona, però el seu hash de 160 bits és un compromís més feble del que voldries

Gairebé totes les altres propostes d’aquest post viuen només a tapscript. Guarda-t’ho; resulta que importa molt a la continuació post-quàntica.1

Primera omissió: sense outpoint, la plantilla flota

Una plantilla no sap quina moneda està gastant. Descriu una forma: tantes entrades, tantes sortides, aquests imports, aquests scripts, aquest locktime.

Això és el que la fa una plantilla i no una transacció prèviament signada. Qualsevol UTXO l’script del qual es comprometi amb aquest hash es pot gastar amb qualsevol transacció que tingui la forma correcta. Envia fons a la mateixa adreça dues vegades i totes dues monedes accepten la mateixa despesa, perquè cap no apareix anomenada enlloc del que s’ha passat pel hash.

Ara posa-hi CSFS al costat. OP_CHECKSIGFROMSTACK reutilitza OP_SUCCESS204 (0xcc), només funciona a tapscript i es diferencia d’OP_CHECKSIG en un sol aspecte: el missatge signat surt de la pila en lloc de derivar-se de la transacció. Consumeix, de dalt a baix, una clau pública, un missatge i una signatura, i no fa el hash del missatge abans, ja que BIP-340 accepta missatges de qualsevol longitud.

Tapscript:  OP_CHECKTEMPLATEVERIFY <PubKey> OP_CHECKSIGFROMSTACK
Witness:    <sig> <TemplateHash>

Llegeix què cobreix realment aquesta signatura. No un txid. No un outpoint. Cobreix el hash de plantilla, és a dir, la forma de la despesa. Per tant, la mateixa signatura continua sent vàlida per a qualsevol moneda que arribi a aquest script.

És una signatura re-vinculable, i és la propietat per a la qual es va dissenyar ANYPREVOUT. CTV+CSFS hi arriba sense tocar gens la lògica del sighash: signa un hash que mai no va mencionar l’entrada, i la signatura no hi va estar mai lligada.

Tot el que la gent vol d’aquesta parella surt d’aquí. LN-Symmetry, on l’estat més recent del canal simplement guanya i ningú no guarda secrets de revocació. Ark i les channel factories, on un arbre de despeses s’acorda una vegada i es re-vincula quan canvien els membres. Vaults sense claus efímeres per esborrar, perquè no hi ha res per esborrar.

Segona omissió: sense import d’entrada, la moneda es pot quedar encallada

Aquesta és la mateixa omissió amb una altra cara.

El hash fixa les teves sortides, imports inclosos. No diu res del que ha entrat. El consens continua aplicant l’única regla que sempre hi ha estat: una transacció no pot crear bitcoins.

Imagina’t una adreça la plantilla de la qual diu una entrada, una sortida de 0,99 BTC, 0,01 de comissió. Es va construir esperant 1,0 BTC. Algú hi envia 0,5 BTC.

La plantilla continua sent satisfactible en el sentit que existeix una transacció que hi coincideix. Simplement no pot ser vàlida: mouria 0,99 BTC a partir d’una entrada de 0,5 BTC. Tota despesa que compleix el covenant és invàlida, i tota despesa vàlida incompleix el covenant. Res no pot moure la moneda, mai.

Això és l’UTXO insatisfactible (Unsatisfiable UTXO), i no és un error de CTV. Comprometre’s amb l’import d’entrada és exactament el que impediria que la plantilla fos una plantilla: fixa l’entrada i hauràs fixat la moneda, i les signatures re-vinculables moren amb ella.

Te’n pots defensar. La resposta habitual és una sortida d’emergència pel key path de Taproot, de manera que el script path sigui una opció i no l’única, cosa que renuncia discretament a part de la manca de confiança que buscava el covenant. El que no pots fer és tenir l’import compromès i no compromès alhora.

La mateixa elecció, dues vegades

Posa-les una al costat de l’altra i la forma de l’intercanvi és difícil de no veure.

omès del hash què hi guanyes què costa
l’outpoint d’entrada les plantilles floten; les signatures es re-vinculen; semàntica d’APO de franc subtil: reutilitza una adreça i la segona moneda es pot empènyer per la mateixa plantilla, amb qualsevol excedent cap al miner
l’import d’entrada la plantilla continua sent una plantilla un dipòsit equivocat pot inutilitzar la moneda per sempre

Totes dues surten de la mateixa decisió: descriure la despesa, no la moneda. Una lectura dona a CTV el seu millor truc, l’altra el seu pitjor mode de fallada, i cap quantitat de cura al programari de la cartera fa desaparèixer el segon, perquè l’omissió és al consens.

Hi ha una cosa més que la plantilla ha de fixar per avançat, i és la que mossega primer a la pràctica.

Comissions: la plantilla ha de pagar a algú

Una plantilla fixa l’import de cada sortida. La comissió és el que queda de l’entrada, així que la comissió també queda fixada, en el moment de crear l’adreça. Per a un vault que potser no es gastarà en cinc anys, això vol dir endevinar el mercat de comissions d’aquí a cinc anys. Si et quedes curt, la transacció es queda a la mempool per sempre; si et passes, pagues de més a cada despesa.

Hi ha quatre maneres d’esquivar-ho, i els dissenys reals solen combinar-ne dues.

  1. Una escala de plantilles. Comprometre’s amb diverses plantilles que només es diferencien en la comissió (1, 4, 16, 64 sat/vB, per exemple) i posar cadascuna a la seva fulla de tapscript. Funciona, però cada nivell de comissió extra multiplica el nombre de fulles, i l’escala només és tan bona com el seu graó més alt.
  2. Una sortida àncora. Afegir una sortida minúscula que qualsevol pot gastar i pujar la comissió amb una transacció filla (CPFP). Des de Bitcoin Core 28.0 hi ha un tipus de sortida estàndard fet exactament per a això, pay-to-anchor (P2A, OP_1 <0x4e73>), i Core 29.0 permet que porti valor zero com a ephemeral dust sempre que la filla la gasti immediatament. Una plantilla que es compromet amb nVersion = 3 obté a més les proteccions de TRUC contra el pinning.
  3. Transaction sponsors. Una proposta, també de Jeremy Rubin, que permetria que una transacció no relacionada pagués per una altra. Mai no es va incorporar.
  4. Signar tard. CTV+CSFS o OP_TEMPLATEHASH+CSFS permeten que una clau signi el hash de plantilla en el moment de gastar, de manera que la comissió es pot triar quan es construeix la transacció i no quan es va crear l’adreça. El preu és que tornes a confiar en una clau per a aquesta elecció.

La via de l’àncora és cap on convergeixen els dissenys actuals de CTV. També és on el segon post hi trobarà un problema, perquè una filla CPFP necessita una entrada pròpia, i aquesta entrada l’ha de poder gastar algú.

OP_CTV pas a pas

Fins ara hem vist les peces per separat: quins camps entren al hash, quins se’n queden fora i què passa amb els imports. L’executor de sota les ajunta i mostra què fa un node quan valida una moneda bloquejada amb CTV.

El punt de partida. Algú ha creat una adreça amb l’script <H> OP_CHECKTEMPLATEVERIFY. Per obtenir H, primer va escriure la transacció que vol permetre, que anomenarem la transacció prevista: una entrada i una sortida de 0,99 BTC cap al destinatari previst (els 0,01 BTC que falten són la comissió). En va calcular el hash de plantilla, i aquest hash és H. Després va enviar 1 BTC a l’adreça.

Les quatre transaccions. Cada botó és una transacció diferent que intenta gastar aquesta moneda:

  • La transacció prevista: exactament la que es va fixar.
  • Una altra moneda: la mateixa transacció, però gastant una altra moneda que també es va enviar a la mateixa adreça. Només canvien el txid i el vout de l’entrada.
  • Una altra adreça de destí: el mateix import, però la sortida paga a una altra adreça, com faria un atacant.
  • Dues monedes juntes: gasta alhora dues monedes bloquejades amb la mateixa plantilla, amb una sola sortida.

Com llegir-lo. A l’esquerra hi ha la moneda que es gasta i la transacció que ho intenta. Els camps amb vora verda entren al hash, els grisos amb vora puntejada no, i la marca taronja indica què és diferent de la transacció prevista. A la dreta, el botó Endavant executa l’script instrucció a instrucció: veuràs com canvia la pila, quins bytes agafa el node de la transacció i, al final, si el hash que calcula (T) coincideix amb el que hi ha a l’adreça (H). Els hashes es mostren com els primers caràcters i una tira de colors: si les dues tires són iguals, els hashes també.

Execució d'OP_CTV
Moneda que es gasta
scriptPubKey <H> OP_CHECKTEMPLATEVERIFY
H
H es va fixar en crear l'adreça, a partir de la transacció prevista.
Transacció que la vol gastar
entra al hash CTV no ho mira diferent de la prevista
Execució de l'script
<H> OP_CHECKTEMPLATEVERIFY
pila

Què vol construir-hi la gent

Els casos d’ús són, al capdavall, de què va tot el debat, així que val la pena ser concret amb cadascun.

Control de congestió i pagaments en lot

Un exchange vol pagar 1.000 retirades mentre les comissions són altes. Amb CTV pot confirmar avui una sola transacció petita la sortida de la qual es compromet amb un arbre de transaccions que acaba pagant els 1.000 destinataris. El pagament de cada destinatari és definitiu en el moment que aquesta transacció petita es confirma, perquè ningú no la pot gastar d’una altra manera, i l’arbre es pot desplegar quan baixin les comissions. Els destinataris que necessitin les monedes abans despleguen la seva branca i només paguen per ella.

No és gratis. Cada transacció interna afegeix sobrecost, així que l’arbre complet costa més espai de bloc que un sol lot gran. El que compres és quan ho pagues. Juga amb els números:

Arbre de control de congestió
–vB confirmats ara
–vB per a l'arbre complet
–vB com a un sol lot
–profunditat / txs a l'arbre

Vaults

Un vault és una moneda que no pot anar directament a una adreça arbitrària. Primer ha d’anunciar que se’n va, esperar, i durant l’espera el seu propietari encara la pot recuperar cap a l’emmagatzematge en fred. Si un atacant et roba la clau calenta, pot començar una retirada però no acabar-la abans que te n’adonis.

El vault CTV més senzill, el que James O’Beirne va publicar el 2022, són tres plantilles:

flowchart LR
    D([dipòsit]) --> V["UTXO del vault<br/>CTV(tx d'unvault)"]
    V -- "CTV: tx d'unvault" --> U["UTXO d'unvault"]
    U -- "després de N blocs (CSV)<br/>signa la clau calenta" --> W([retirada])
    U -- "en qualsevol moment<br/>CTV: tx de sweep" --> C([emmagatzematge en fred])

Un watchtower vigila la transacció d’unvault. Si no l’has fet tu, emet el sweep, que no necessita cap clau perquè la plantilla ja fixa on va. Aquest últim detall és el que em sembla elegant: el camí d’emergència no requereix cap secret, així que no hi ha res que l’atacant hagi pogut robar.

Els límits tenen a veure amb la rigidesa. Tot el saldo surt del vault de cop. L’import es fixa quan es crea el vault, així que un segon dipòsit a la mateixa adreça o bé no es pot gastar o bé és un regal per al miner (les omissions de dalt, un altre cop). Les retirades parcials necessiten un arbre nou per cada import possible. OP_VAULT es va dissenyar per arreglar exactament això amb imports dinàmics i més tard es va retirar en favor d’eines més generals; OP_CHECKCONTRACTVERIFY i els opcodes d’import d’entrada que es comenten més avall són els intents actuals.

Channel factories, timeout trees i Ark

Tots comparteixen una forma: molts usuaris tenen drets sobre un sol UTXO a la cadena, i cadascun pot sortir unilateralment publicant la branca d’un arbre de transaccions que porta a la seva fulla.

  • Els timeout trees, proposats per John Law el 2023, posen un canal o un saldo a cada fulla i retornen l’UTXO sencer a l’operador després d’un temps límit. Els usuaris o surten per la seva branca a temps o es passen al següent arbre.
  • Ark fa el mateix amb UTXO virtuals. Un operador agrupa molts usuaris en una ronda, i el dret de cada usuari és una fulla de l’arbre de la ronda.
  • Els payment pools i les channel factories permeten que un grup comparteixi un UTXO i obri canals entre ells sense tocar la cadena.

Sense covenants, tots aquests necessiten que l’arbre el signin per avançat els seus participants amb un n-de-n, i d’aquí ve el cost d’interacció: tothom de la ronda ha d’estar connectat per cosignar. L’Ark sense covenants, la variant que s’està construint i desplegant avui, fa exactament això. Amb CTV, l’arbre és un conjunt de plantilles i ningú no ha de signar res. L’operador el construeix, els usuaris el comproven i la cadena el fa complir.

LN-Symmetry

Els canals de Lightning d’avui es basen en penalitzacions. Cada vegada que canvia el saldo, les dues parts revoquen l’estat anterior intercanviant-se un secret; si mai emets un estat antic, el teu company fa servir aquest secret per quedar-s’ho tot. Funciona, però fa que les còpies de seguretat siguin perilloses (restaura’n una d’antiga i pots emetre un estat revocat per accident) i fa impracticables els canals de més de dues parts.

LN-Symmetry (abans eltoo) substitueix el càstig per l’ordre. Cada estat és una transacció d’actualització que pot gastar qualsevol transacció d’actualització anterior, així que qui emet un estat antic simplement queda superat pel més recent. Això requereix una signatura que no estigui lligada a una sortida anterior concreta, que és exactament la signatura re-vinculable de CTV+CSFS de la secció anterior. Abans de CSFS requeria SIGHASH_ANYPREVOUT. Hi ha esborranys de BOLT i una implementació a Core Lightning construïda sobre el paquet BIP-448.

Discreet Log Contracts

Un DLC paga segons l’atestació d’un oracle. Avui cada part ha d’intercanviar una adaptor signature per cada resultat possible, cosa que, per a un contracte amb milers de resultats, és molta signatura interactiva.

Amb CTV, cada resultat pot ser en canvi una fulla de tapscript: “la plantilla del resultat, més una signatura vàlida sota el punt d’atestació de l’oracle per a aquest resultat”. Quan l’oracle fa l’atestació, el secret d’aquest punt es fa públic i qualsevol pot completar la despesa. No passa res, perquè la plantilla ja fixa on van els diners. La configuració passa a ser no interactiva.

Aquest patró, revelar el secret públicament i confiar que la plantilla faci inofensiva la revelació, és petit aquí i central a el següent post.

I uns quants més

  • Obertures de canal no interactives. Pagar a una plantilla la sortida de la qual és un canal amb el destinatari, sense que estigui connectat.
  • Spacechains. El disseny de Ruben Somsen per al blind merged mining fa servir una llarga cadena de transaccions precompromeses, cadascuna una subhasta de comissions per a un bloc de la sidechain.
  • Ponts a l’estil BitVM. Avui depenen de comitès que signen per avançat grafs de transaccions grans. Les plantilles podrien substituir part d’aquesta signatura prèvia, i detalls com el compromís de CTV amb l’scriptSig són part del motiu pel qual als desenvolupadors de BitVM els importa quin opcode de plantilla s’acaba incorporant.

La resta del camp

CTV és la proposta més petita, no l’única. Aquí hi ha tot el que hi ha ara mateix sobre la taula, aproximadament de menys a més expressiu.

SIGHASH_ANYPREVOUT (BIP-118)

Nous flags de sighash que permeten que una signatura deixi fora l’outpoint que gasta (ANYPREVOUT) o també l’script (ANYPREVOUTANYSCRIPT). És la via original cap a les signatures re-vinculables i LN-Symmetry. No és un opcode de covenant com a tal, però combinat amb una signatura d’una clau coneguda pot emular una plantilla semblant a CTV. És actiu a Inquisition signet des del 2022 i ha perdut impuls davant de CTV+CSFS, que arriba al mateix lloc sense tocar la lògica del sighash.

OP_CHECKSIGFROMSTACK (BIP-348)

Verifica una signatura BIP-340 sobre un missatge arbitrari de la pila. Per si sol no és un covenant; és delegació i oracles. Al costat d’un opcode de plantilla es converteix en signatures re-vinculables, com s’ha vist abans. Només a tapscript.

OP_INTERNALKEY (BIP-349) i OP_PAIRCOMMIT (BIP-442)

Dos ajudants petits. OP_INTERNALKEY posa a la pila la clau interna de Taproot, i estalvia 32 bytes a cada script que la vulgui reutilitzar amb CSFS. OP_PAIRCOMMIT fa el hash de dos elements de la pila juntament amb les seves longituds, un cosí deliberadament limitat d’OP_CAT que n’hi ha prou per als compromisos d’estat de LN-Symmetry sense permetre manipulació a nivell de byte. CTV, CSFS i aquests dos formen el paquet LNHANCE.

De CTV++ a OP_TEMPLATEHASH (BIP-446, BIP-448)

Aquí dues idees diferents comparteixen nom, i és fàcil confondre-les.

La primera és l’esbós CTV++ de moonsettler, del desembre del 2024. Afegeix un OP_TEMPLATEHASH que construeix un hash CTV a partir d’elements de la pila, de manera que un script pot muntar una plantilla amb, per exemple, un import calculat, i un OP_INPUTAMOUNTS que posa a la pila la suma dels imports de les entrades seleccionades. Junts ataquen l’UTXO insatisfactible de costat: un script per fi pot raonar sobre quant ha entrat.

La segona és el BIP-446, de Greg Sanders, Antoine Poinsot i Steven Roose, que va arribar a Draft el març del 2026. El seu OP_TEMPLATEHASH no pren res i posa a la pila el hash de plantilla de la transacció que gasta. És un redisseny de CTV natiu de Taproot més que no pas una extensió:

  • viu a tapscript com a OP_SUCCESS206, no en un OP_NOP;
  • posa el hash a la pila en lloc de verificar-lo, de manera que es combina directament amb CSFS o OP_EQUALVERIFY;
  • elimina el compromís amb l’scriptSig, que no té sentit a Taproot, i n’afegeix un amb l’annex;
  • continua sense comprometre’s amb els prevouts ni amb els imports d’entrada, així que l’UTXO insatisfactible continua allà.

El BIP-448 l’agrupa amb CSFS i OP_INTERNALKEY com a “Taproot-native (Re)bindable Transactions”. Els seus partidaris diuen que és més net que CTV. Els crítics assenyalen que renuncia a l’ús de CTV fora de tapscript i a algunes propietats de les quals depenen els dissenys de BitVM. Al setembre del 2026 hi ha un pedaç de Bitcoin Inquisition, feina a miniscript i PSBT, i una demo d’Ark a signet.

OP_TXHASH i OP_CHECKTXHASHVERIFY (BIP-346)

La generalització de Steven Roose: un argument selector de camps tria quines parts de la transacció entren al hash. CTV passa a ser un selector concret. La mateixa maquinària pot expressar tots els modes de sighash del BIP-341 i molts més, cosa que la converteix en el substrat natural per a protocols del tipus “signa exactament els camps que m’importen”. El preu és una especificació molt més gran per revisar.

OP_CAT (BIP-347)

Concatena dos elements de la pila. Satoshi el va desactivar el 2010 juntament amb la majoria d’opcodes de manipulació de bytes, per por de denegacions de servei que ara limita el màxim de 520 bytes per element de tapscript. Ethan Heilman i Armin Sabouri el van tornar a proposar el 2023, i és actiu a Inquisition signet des del 2024.

Sona inofensiu. És la proposta més potent d’aquesta llista per culpa d’un sol truc.

El truc de Schnorr d’Andrew Poelstra funciona així. Una signatura Schnorr és \((R, s)\) amb \(s = k + e \cdot x\), on \(e\) és un hash de \(R\), la clau pública i el missatge. Tria la clau secreta \(x = 1\) i el nonce \(k = 1\), de manera que tant la clau pública com \(R\) són el generador \(G\). Aleshores \(s = 1 + e\), i qualsevol el pot calcular. Ara fes que el witness aporti les peces de la preimatge del sighash del BIP-341, que l’script les ajunti amb OP_CAT i en faci el hash per obtenir \(e\), construeix la signatura \((G, 1 + e)\) a la pila (amb una mica de grinding perquè el “+1” mai no arrossegui més enllà de l’últim byte), i passa-la a OP_CHECKSIG amb la clau \(G\).

OP_CHECKSIG només passa si el missatge que ha muntat l’script és el sighash real de la transacció que gasta. L’script acaba de llegir la transacció. Tots els camps que cobreix el sighash, sortides incloses, són ara a la pila per fer-hi comprovacions arbitràries. Això és introspecció completa, covenants recursius i, amb prou d’això, verificació a la cadena de signatures basades en hash i fins i tot de proves STARK, tot a partir d’un opcode que enganxa dues cadenes.

Que és precisament per què fa por.

MATT i OP_CHECKCONTRACTVERIFY (BIP-443)

El Merkleize All The Things de Salvatore Ingala dona estat a cada UTXO: les dades s’incorporen (tweak) a la clau interna de Taproot, i OP_CHECKCONTRACTVERIFY comprova que una entrada porta certes dades, o que una sortida porta les dades correctes i l’arbre d’scripts correcte. Amb això, un UTXO pot executar una màquina d’estats, i dues parts poden jugar a un joc de bisecció per demostrar a la cadena un càlcul en disputa, que és el nucli dels optimistic rollups i de les fraud proofs a l’estil BitVM. CCV també té una semàntica d’imports, així que pot fer els vaults flexibles per als quals estava pensat OP_VAULT. Hi ha una pull request a Bitcoin Core (#32080). Cap proposta d’activació.

OP_VAULT (BIP-345)

L’opcode de vault d’ús específic de James O’Beirne, amb imports dinàmics, retirades agrupades i un camí de recuperació. Va ser el disseny de vault més polit durant dos anys i es va retirar el 2025, amb l’argument que els primitius generals (CTV+CSFS ara, CCV més endavant) cobreixen la necessitat. L’incloc perquè mostra el patró: les propostes d’ús específic continuen perdent davant de les generals.

La Great Script Restoration (BIP 440 i 441)

El projecte de llarg recorregut de Rusty Russell, publicat com a BIP l’abril del 2026. El BIP-441 defineix una nova versió de tapleaf, 0xc2, en què tornen tots els opcodes que Satoshi va desactivar, i els nombres poden ser grans. El BIP-440 substitueix els antics límits per opcode per un pressupost de varops: cada operació es cobra segons quants bytes toca, i el pressupost està dimensionat perquè el pitjor bloc possible no sigui més car de validar que el pitjor bloc d’avui ple de comprovacions de signatura. És la resposta maximalista: deixar d’afegir opcodes d’un en un i tornar a Script tot el seu vocabulari, amb un model de cost que ho faci segur.

Simplicity, a la casa del costat

Encara no és una proposta per a Bitcoin, però val la pena conèixer-la: Simplicity, de Blockstream, un llenguatge de baix nivell especificat formalment amb límits de cost estàtics, es va activar a Liquid el 2025. És el que molta gent s’imagina com a destinació a llarg termini.

Tot plegat en una taula

proposta BIP què obté l’script recursiu? on funciona estat (set. 2026)
CTV 119 “la despesa és aquesta plantilla?” no tots els contextos d’script client d’activació senyalitzant, 0% de suport
APO 118 signatures que ometen l’outpoint no tapscript només Inquisition
CSFS 348 verificar una signatura sobre qualsevol missatge no tapscript proposat amb CTV i al BIP-448
INTERNALKEY 349 la clau interna de Taproot no tapscript a LNHANCE i al BIP-448
PAIRCOMMIT 442 hash de dos elements no tapscript a LNHANCE
TEMPLATEHASH 446 / 448 el hash de plantilla, a la pila no tapscript Draft, pedaç d’Inquisition
TXHASH 346 hash de camps seleccionats no, sol tapscript + slot NOP Draft
CAT 347 concatenació de bytes, i per tant introspecció sí tapscript Inquisition des del 2024
CCV 443 estat portat a la clau interna, imports sí tapscript Draft, PR a Core
OP_VAULT 345 específic per a vaults no tapscript retirat
GSR 440 / 441 l’Script original complet, amb cost sí nova tapleaf publicat l’abril del 2026

L’escala d’expressivitat, si la vols en una línia:

\[\text{CTV} \rightarrow \text{TEMPLATEHASH} + \text{CSFS} \rightarrow \text{TXHASH} \rightarrow \text{CCV} \rightarrow \texttt{OP\_CAT} \rightarrow \text{GSR}\]

Cada graó amunt compra capacitat i gasta pressupost de revisió, i la discussió sobre on aturar-se ha estat la major part del debat sobre covenants.

Per què això ha trigat vuit anys

És temptador llegir el retard com a disfunció. Crec que és millor llegir-lo com una llista de preguntes realment difícils, unes de tècniques i unes altres que no.

  • Recursió. Un covenant recursiu pot restringir una moneda per sempre. La preocupació original de Maxwell era un govern exigint monedes que només es poguessin moure a adreces d’una llista blanca. La resposta habitual és que això ja es pot fer amb un multisig que cosigni el govern; els covenants no creen aquest poder, només treuen el cosignant. És cert, i no ha acabat de dissipar la preocupació.
  • MEV. Uns covenants prou expressius fan possibles exchanges i AMM a la cadena i, amb ells, el miner extractable value: l’incentiu perquè els miners reordenin i censurin transaccions per treure’n profit. La descentralització de Bitcoin depèn que la mineria sigui un negoci de commodity. Ningú no vol importar el mercat de block builders d’Ethereum.
  • Cost de validació. Cada opcode nou és una nova manera d’escriure un script car. El pressupost de varops del BIP-440 és l’intent més seriós de respondre-ho en general i no opcode per opcode.
  • “Quin?” Els defensors de cada proposta coincideixen que els covenants són útils i discrepen sobre quin incorporar. Cada alternativa treu atenció de revisió a les altres i, sense consens sobre un objectiu, no s’incorpora res. La carta del 2025 a favor de CTV+CSFS era, en bona part, un intent de desencallar-ho.
  • Trauma d’activació. L’activació de SegWit el 2017 gairebé va partir la xarxa; la de Taproot el 2021 va ser tranquil·la però controvertida en el mètode. L’intent del 2022 d’activar CTV amb un client fora de Bitcoin Core va cremar molta bona voluntat. Des d’aleshores, cada soft fork es jutja en part pel seu procés.
  • Prioritats en competència. La Great Consensus Cleanup (BIP-54) arregla atacs reals, i la migració post-quàntica s’ha convertit, el 2026, en el tema que fa més soroll. Els soft forks són escassos, i els covenants són un dels diversos candidats per al proper.
  • Ossificació. Hi ha una facció real que creu que les regles de Bitcoin haurien de deixar essencialment de canviar. No cal estar-hi d’acord per veure que puja el llistó per a totes les propostes.

On som realment

A finals de setembre del 2026, res activat. Res d’aquesta pàgina funciona a mainnet.

  • CTV té un client d’activació amb paràmetres formals: una finestra de senyalització que es va obrir el 30 de març del 2026, un límit el 30 de març del 2027 i un llindar del 90% (1.815 de 2.016 blocs en un període de reajustament). No és una versió de Bitcoin Core i, als recomptes públics més recents que he trobat, de finals de maig, la senyalització dels miners era zero.
  • CTV+CSFS és la combinació amb el suport més ampli entre desenvolupadors. Una carta oberta signada per 66 desenvolupadors defensa que són les dues propostes prou madures per incorporar: revisades a fons, petites i demanades repetidament.
  • BIP-448 (OP_TEMPLATEHASH + CSFS + OP_INTERNALKEY) és l’alternativa principal. Segons l’Optech #421, el paquet complet es podrà fer servir al signet per defecte amb la propera versió de Bitcoin Inquisition.
  • LNHANCE manté viu el paquet centrat en Lightning com a opció intermèdia.
  • OP_CAT fa dos anys que viu a signet, amb un flux constant de demos: vaults, verificadors STARK, signatures basades en hash. Cap impuls d’activació.
  • CCV i la GSR són de nivell de recerca i apunten explícitament a forks posteriors.
  • OP_VAULT està retirat.

Aquesta distància em sona. Vaig passar l’últim post comptant una optimització d’un byte que fa vuit anys que és gratuïta i documentada i que dos terços de les signatures ECDSA encara no fan servir. Codi publicat i codi adoptat són quantitats diferents, i la distància entre totes dues no sol ser tècnica. La distància entre codi especificat i codi activat és encara més gran.

Problemes oberts que valen el temps d’algú

Llegint tot l’anterior, unes quantes preguntes em semblen alhora obertes i abordables, del tipus en què una tesi o un estiu ben aprofitat poden fer progressos.

  1. Convertir l’UTXO insatisfactible en un problema de la cartera. El consens no ho pot arreglar sense renunciar a les plantilles flotants, però les carteres es podrien negar a crear-lo. Un format d’adreça (o una extensió del BIP-21) que porti l’import exacte que espera una adreça amb covenant, més suport als descriptors perquè totes les carteres ho comprovin abans d’enviar, eliminaria la major part del risc sense cap soft fork. Les peces existeixen, com la feina sobre output descriptors per a vaults CTV a Delving; ningú no ha estandarditzat la vinculació de l’import.
  2. Triar una escala de comissions amb dades. Quantes plantilles de nivell de comissió necessita un vault, i a quines tarifes, per ser confirmable amb, per exemple, un 99% de probabilitat en un horitzó de cinc anys, i quan surt més barata una sortida àncora? És un problema d’optimització sobre dades històriques de la mempool, el mateix tipus d’arqueologia de cadena que el post del grinding, i no l’he vist fet.
  3. Comprovació de vivacitat per a arbres de covenants. Un arbre CTV és un graf finit. Cada fulla hauria d’acabar arribant a una clau que algú té, cap camí no hauria d’exigir un import impossible i cap comissió no hauria de ser negativa. És un problema de model checking prou petit per resoldre’l exhaustivament quan es crea l’adreça, i atraparia la majoria de les trampes d’aquest post abans que hi hagi diners en risc.
  4. Com són els covenants després d’un ordinador quàntic. La majoria de les propostes anteriors depenen, en algun punt, de signatures de corba el·líptica. CTV no. I els covenants poden fer una cosa que les signatures no poden: fer que les monedes siguin impossibles de robar fins i tot quan les signatures es poden falsificar, anunciant una despesa abans d’executar-la. Va resultar prou gran per tenir el seu propi post: Covenants després de Shor.

La mateixa llista, dues vegades

El que crec que val la pena retenir és més petit i més concret que la pregunta de l’activació. CTV és un hash de vuit camps. Llegir la llista del que passa pel hash et diu què pot fer; llegir la llista del que se salta et diu alhora per què és potent i com pot fallar. Resulta que són la mateixa llista, i cada proposta posterior és, al final, una resposta diferent a la pregunta de quins camps hauria de poder veure un script.

Escrit a partir d’una xerrada que vaig fer sobre covenants de Bitcoin i ampliat des d’aleshores. Definicions dels camps comprovades amb el BIP-119, el BIP-348 i el BIP-446; estat a finals de setembre del 2026, segons Bitcoin Optech i el repositori de BIP.

  1. L’excepció és OP_CHECKTXHASHVERIFY del BIP-346, que reclamaria el mateix slot OP_NOP4 que CTV. És una de les raons per les quals no es poden incorporar tots dos tal com estan escrits ara. ↩




Enjoy Reading This Article?

Here are some more articles you might like to read next:

  • What Grinding Has Actually Saved on Chain
  • Modifying the bdk_wallet Balance API for My Summer of Bitcoin Project
  • Is Hardware Wallet Fingerprinting Even Possible?
  • Covert-Nonce Channel Attacks on Bitcoin Hardware Wallets
  • Build Your Own Bitcoin Main-net