registry covenant v1: the contract that holds a name and enforces its lifecycle (draft)
Expiry was always going to be the chain refusing, not resolvers agreeing. This
is that contract: a certificate sits in a covenant whose address encodes its
owner and expiry, and five paths move it. The owner renews, transfers,
releases or migrates; anyone takes over an expired name at a price that
glides from a premium to a floor, paying the previous owner a share while the
grace period lasts and committing to the name a block ahead.
The two changing values are the last constructor arguments, so they sit first
in the redeem script and the contract re-creates itself by swapping 26 bytes.
A resolver that knows the code can check any claimed owner and expiry against
the address.
Every number comes from registry-lifecycle.js, which was written as the
fixture for this. The tests run each path in libauth's VM under the 2025 and
2026 rules, compare price and split to that model along the glide, and then
break one rule at a time with valid signatures; the suite counts that the VM
itself refused them.
Draft, not reviewed, and not wired into any resolver. REGISTRY-COVENANT-v1.md
says where it departs from the design: script cannot bound a height from
above, so reclaim has no deadline and a commit cannot expire, which leaves
commit hoarding open. That is the first thing a reviewer should read.
2026-10-04 15:42:36 +02:00
{
"contractName" : "NameRegistry" ,
"constructorInputs" : [
{ "name" : "fundLock" , "type" : "bytes" } ,
{ "name" : "stewardPk" , "type" : "pubkey" } ,
{ "name" : "commitBoxCode" , "type" : "bytes" } ,
{ "name" : "renewalSats" , "type" : "int" } ,
{ "name" : "premiumSats" , "type" : "int" } ,
{ "name" : "floorSats" , "type" : "int" } ,
{ "name" : "graceBlocks" , "type" : "int" } ,
{ "name" : "blocksPerYear" , "type" : "int" } ,
{ "name" : "ownerPercentIdle" , "type" : "int" } ,
{ "name" : "expiry" , "type" : "bytes4" } ,
{ "name" : "ownerPkh" , "type" : "bytes20" }
] ,
"abi" : [
{
"name" : "renew" ,
"inputs" : [
{ "name" : "pk" , "type" : "pubkey" } ,
{ "name" : "s" , "type" : "sig" } ,
{ "name" : "years" , "type" : "int" }
]
} ,
{
"name" : "transfer" ,
"inputs" : [
{ "name" : "pk" , "type" : "pubkey" } ,
{ "name" : "s" , "type" : "sig" } ,
{ "name" : "newOwnerPkh" , "type" : "bytes20" }
]
} ,
{
"name" : "takeover" ,
"inputs" : [
{ "name" : "newOwnerPkh" , "type" : "bytes20" } ,
{ "name" : "salt" , "type" : "bytes" }
]
} ,
{
"name" : "release" ,
"inputs" : [
{ "name" : "pk" , "type" : "pubkey" } ,
{ "name" : "s" , "type" : "sig" }
]
} ,
{
"name" : "migrate" ,
"inputs" : [
{ "name" : "pk" , "type" : "pubkey" } ,
{ "name" : "s" , "type" : "sig" } ,
{ "name" : "approval" , "type" : "datasig" } ,
2026-10-04 16:53:56 +02:00
{ "name" : "newCode" , "type" : "bytes" }
registry covenant v1: the contract that holds a name and enforces its lifecycle (draft)
Expiry was always going to be the chain refusing, not resolvers agreeing. This
is that contract: a certificate sits in a covenant whose address encodes its
owner and expiry, and five paths move it. The owner renews, transfers,
releases or migrates; anyone takes over an expired name at a price that
glides from a premium to a floor, paying the previous owner a share while the
grace period lasts and committing to the name a block ahead.
The two changing values are the last constructor arguments, so they sit first
in the redeem script and the contract re-creates itself by swapping 26 bytes.
A resolver that knows the code can check any claimed owner and expiry against
the address.
Every number comes from registry-lifecycle.js, which was written as the
fixture for this. The tests run each path in libauth's VM under the 2025 and
2026 rules, compare price and split to that model along the glide, and then
break one rule at a time with valid signatures; the suite counts that the VM
itself refused them.
Draft, not reviewed, and not wired into any resolver. REGISTRY-COVENANT-v1.md
says where it departs from the design: script cannot bound a height from
above, so reclaim has no deadline and a commit cannot expire, which leaves
commit hoarding open. That is the first thing a reviewer should read.
2026-10-04 15:42:36 +02:00
]
}
] ,
2026-10-04 16:53:56 +02:00
"bytecode" : " O P _ 11 O P _ P I C K O P _ 0 O P _ N U M E Q U A L O P _ I F O P _ 12 O P _ P I C K O P _ H A S H 160 O P _ 11 O P _ P I C K O P _ E Q U A L V E R I F Y O P _ 13 O P _ R O L L O P _ 13 O P _ R O L L O P _ C H E C K S I G V E R I F Y O P _ 12 O P _ P I C K O P _ 1 O P _ G R E A T E R T H A N O R E Q U A L O P _ V E R I F Y O P _ 9 O P _ R O L L O P _ B I N 2 N U M O P _ 12 O P _ P I C K O P _ 9 O P _ R O L L O P _ M U L O P _ A D D O P _ D U P 0 0 65 c d 1 d O P _ L E S S T H A N O P _ V E R I F Y 14 O P _ 10 O P _ R O L L O P _ C A T O P _ 4 O P _ C A T O P _ S W A P O P _ 4 O P _ N U M 2 B I N O P _ C A T O P _ A C T I V E B Y T E C O D E 1 a O P _ S P L I T O P _ N I P O P _ C A T O P _ H A S H 256 O P _ 0 O P _ O U T P U T B Y T E C O D E a a 20 O P _ R O T O P _ C A T 87 O P _ C A T O P _ E Q U A L V E R I F Y O P _ 0 O P _ O U T P U T T O K E N C A T E G O R Y O P _ I N P U T I N D E X O P _ U T X O T O K E N C A T E G O R Y O P _ E Q U A L V E R I F Y O P _ 0 O P _ O U T P U T T O K E N C O M M I T M E N T O P _ I N P U T I N D E X O P _ U T X O T O K E N C O M M I T M E N T O P _ E Q U A L V E R I F Y O P _ 0 O P _ O U T P U T V A L U E O P _ I N P U T I N D E X O P _ U T X O V A L U E O P _ G R E A T E R T H A N O R E Q U A L O P _ V E R I F Y O P _ 1 O P _ O U T P U T B Y T E C O D E O P _ E Q U A L V E R I F Y O P _ 1 O P _ O U T P U T V A L U E O P _ 3 O P _ R O L L O P _ 9 O P _ R O L L O P _ M U L O P _ G R E A T E R T H A N O R E Q U A L O P _ V E R I F Y O P _ 1 O P _ O U T P U T T O K E N C A T E G O R Y O P _ 0 O P _ E Q U A L V E R I F Y O P _ 2 D R O P O P _ 2 D R O P O P _ 2 D R O P O P _ D R O P O P _ 1 O P _ E L S E O P _ 11 O P _ P I C K O P _ 1 O P _ N U M E Q U A L O P _ I F O P _ 14 O P _ R O L L O P _ S I Z E 14 O P _ E Q U A L V E R I F Y O P _ 13 O P _ P I C K O P _ H A S H 160 O P _ 12 O P _ R O L L O P _ E Q U A L V E R I F Y O P _ 13 O P _ R O L L O P _ 13 O P _ R O L L O P _ C H E C K S I G V E R I F Y 14 O P _ S W A P O P _ C A T O P _ 4 O P _ C A T O P _ 10 O P _ R O L L O P _ C A T O P _ A C T I V E B Y T E C O D E 1 a O P _ S P L I T O P _ N I P O P _ C A T O P _ H A S H 256 O P _ 0 O P _ O U T P U T B Y T E C O D E a a 20 O P _ R O T O P _ C A T 87 O P _ C A T O P _ E Q U A L V E R I F Y O P _ 0 O P _ O U T P U T T O K E N C A T E G O R Y O P _ I N P U T I N D E X O P _ U T X O T O K E N C A T E G O R Y O P _ E Q U A L V E R I F Y O P _ 0 O P _ O U T P U T T O K E N C O M M I T M E N T O P _ I N P U T I N D E X O P _ U T X O T O K E N C O M M I T M E N T O P _ E Q U A L V E R I F Y O P _ 0 O P _ O U T P U T V A L U E O P _ I N P U T I N D E X O P _ U T X O V A L U E O P _ G R E A T E R T H A N O R E Q U A L O P _ V E R I F Y O P _ 2 D R O P O P _ 2 D R O P O P _ 2 D R O P O P _ 2 D R O P O P _ 2 D R O P O P _ 1 O P _ E L S E O P _ 11 O P _ P I C K O P _ 2 O P _ N U M E Q U A L O P _ I F O P _ 12 O P _ R O L L O P _ S I Z E 14 O P _ E Q U A L V E R I F Y O P _ 10 O P _ R O L L O P _ B I N 2 N U M O P _ D U P O P _ C H E C K L O C K T I M E V E R I F Y O P _ D R O P O P _ T X L O C K T I M E O P _ D U P 0 0 65 c d 1 d O P _ L E S S T H A N O P _ V E R I F Y O P _ S W A P O P _ 9 O P _ P I C K O P _ A D D O P _ 8 O P _ P I C K O P _ 0 O P _ 2 O V E R O P _ L E S S T H A N O P _ I F O P _ 10 O P _ P I C K O P _ 10 O P _ P I C K O P _ 12 O P _ P I C K O P _ S U B O P _ 4 O P _ P I C K O P _ 6 O P _ P I C K O P _ S U B O P _ M U L O P _ 13 O P _ P I C K O P _ D I V O P _ A D D O P _ R O T O P _ D R O P O P _ S W A P O P _ O V E R O P _ 14 O P _ P I C K O P _ M U L 64 O P _ D I V O P _ N I P O P _ E N D I F O P _ 16 O P _ P I C K O P _ S I Z E O P _ N I P 20 O P _ N U M E Q U A L V E R I F Y O P _ I N P U T I N D E X O P _ U T X O T O K E N C O M M I T M E N T 11 O P _ R O L L O P _ C A T O P _ H A S H 256 14 O P _ 6 O P _ P I C K O P _ C A T 20 O P _ C A T O P _ S W A P O P _ C A T O P _ 8 O P _ R O L L O P _ C A T O P _ 1 O P _ U T X O B Y T E C O D E a a 20 O P _ R O T O P _ H A S H 256 O P _ C A T 87 O P _ C A T O P _ E Q U A L V E R I F Y O P _ 3 O P _ P I C K O P _ 12 O P _ P I C K O P _ A D D 0 0 65 c d 1 d O P _ L E S S T H A N O P _ V E R I F Y 14 O P _ 5 O P _ R O L L O P _ C A T O P _ 4 O P _ C A T O P _ 4 O P _ R O L L O P _ 11 O P _ R O L L O P _ A D D O P _ 4 O P _ N U M 2 B I N O P _ C A T O P _ A C T I V E B Y T E C O D E 1 a O P _ S P L I T O P _ N I P O P _ C A T O P _ H A S H 256 O P _ 0 O P _ O U T P U T B Y T E C O D E a a 20 O P _ R O T O P _ C A T 87 O P _ C A T O P _ E Q U A L V E R I F Y O P _ 0 O P _ O U T P U T T O K E N C A T E G O R Y O P _ I N P U T I N D E X O P _ U T X O T O K E N C A T E G O R Y O P _ E Q U A L V E R I F Y O P _ 0 O P _ O U T P U T T O K E N C O M M I T M E N T O P _ I N P U T I N D E X O P _ U T X O T O K E N C O M M I T M E N T O P _ E Q U A L V E R I F Y O P _ 0 O P _ O U T P U T V A L U E O P _ I N P U T I N D E X O P _ U T X O V A L U E O P _ G R E A T E R T H A N O R E Q U A L O P _ V E R I F Y O P _ 1 O P _ O U T P U T B Y T E C O D E O P _ 4 O P _ R O L L O P _ E Q U A L V E R I F Y O P _ 1 O P _ O U T P U T V A L U E O P _ R O T O P _ 2 O P _ P I C K O P _ S U B O P _ G R E A T E R T H A N O R E Q U A L O P _ V E R I F Y O P _ 1 O P _ O U T P U T T O K E N C A T E G O R Y O P _ 0 O P _ E Q U A L V E R I F Y O P _ D U P O P _ 0 O P _ G R E A T E R T H A N O P _ I F O P _ 2 O P _ O U T P U T B Y T E C O D E 76 a 914 O P _ 10 O P _ P I C K O P _ C A T 88 a c O P _ C A T O P _ E Q U A L V E R I F Y O P _ 2 O P _ O U T P U T V A L U E O P _ O V E R O P _ G R E A T E R T H A N O R E Q U A L O P _ V E R I F Y O P _ 2 O P _ O U T P U T T O K E N C A T E G O R Y O P _ 0 O P _ E Q U A L V E R I F Y O P _ E N D I F O P _ 2 D R O P O P _ 2 D R O P O P _ 2 D R O P O P _ 2 D R O P O P _ 2 D R O P O P _ 1 O P _ E L S E O P _ 11 O P _ P I C K O P _ 3 O P _ N U M E Q U A L O P _ I F O P _ 12 O P _ P I C K O P _ H A S H 160 O P _ 11 O P _ R O L L O P _ E Q U A L V E R I F Y O P _ 12 O P _ R O L L O P _ 12 O P _ R O L L O P _ C H E C K S I G V E R I F Y O P _ I N P U T I N D E X O P _ U T X O T O K E N C A T E G O R Y O P _ T X O U T P U T C O U N T O P _ 4 O P _ L E S S T H A N O R E Q U A L O P _ V E R I F Y O P _ 0 O P _ O U T P U T T O K E N C A T E G O R Y O P _ O V E R O P _ E Q U A L O P _ N O T O P _ V E R I F Y O P _ T X O U T P U T C O U N T O P _ 1 O P _ G R E A T E R T H A N O P _ I F O P _ 1 O P _ O U T P U T T O K E N C A T E G O R Y O P _ O V E R O P _ E Q U A L O P _ N O T O P _ V E R I F Y O P _ E N D I F O P _ T X O U T P U T C O U N T O P _ 2 O P _ G R E A T E R T H A N O P _ I F O P _ 2 O P _ O U T P U T T O K E N C A T E G O R Y O P _ O V E R O P _ E Q U A L O P _ N O T O P _ V E R I F Y O P _ E N D I F O P _ T X O U T P U T C O U N T O P _ 3 O P _ G R E A T E R T H A N O P _ I F O P _ 3 O P _ O U T P U T T O K E N C A T E G O R Y O P _ O V E R O P _ E Q U A L O P _ N O T O P _ V E R I F Y O P _ E N D I F O P _ 2 D R O P O P _ 2 D R O P O P _ 2 D R O P O P _ 2 D R O P O P _ 2 D R O P O P _ 2 D R O P O P _ 1 O P _ E L S E O P _ 11 O P _ R O L L O P _ 4 O P _ N U M E Q U A L V E R I F Y O P _ 11 O P _ P I C K O P _ H A S H 160 O P _ 11 O P _ P I C K O P _ E Q U A L V E R I F Y O P _ 12 O P
"source" : "pragma cashscript ^0.13.0;\n\n// NameRegistry v1 — the covenant that holds a name certificate and enforces\n// its lifecycle (Decentralized.DNS/DESIGN-covenant-registry.md).\n//\n// STATUS: chipnet draft. NOT REVIEWED. A flaw here either locks every name\n// forever or lets anyone take one; nothing built from this file may hold a\n// mainnet name until someone who did not write it has reviewed it.\n//\n// The certificate (an immutable NFT whose commitment is the name) sits in an\n// output locked by this script. Two values change over a name's life — who\n// owns it and when it expires — and they are the LAST two constructor\n// arguments, which CashScript pushes FIRST. The redeem script therefore begins\n//\n// 0x14 <ownerPkh:20> 0x04 <expiry:4> <everything else>\n//\n// and every path that keeps the name re-creates the covenant by replacing\n// those 26 bytes and requiring output 0 to be locked to the result. One\n// contract, one code hash per price tier; the state is in the address.\n//\n// Numbers must match Argus/src/lib/registry-lifecycle.js, which is the\n// reference: integer arithmetic, multiply before dividing.\n//\n// What script cannot do, stated once: it can prove a block height has been\n// REACHED (tx.time), never that one has NOT. So \"the owner may reclaim only\n// until the grace period ends\" i s n o t e n f o r c e a b l e ; a n o w n e r c a n r e n e w f o r a s \ n // long as nobody has taken the name over. The takeover price is safe against\n// this: a taker can only claim a height that is already past, and a later\n// height means a lower price they are entitled to anyway.\ncontract NameRegistry(\n // ---- fixed for this covenant version and price tier ----\n bytes fundLock, // locking bytecode the fund's payments must go to\n pubkey stewardPk, // approves moving from this code to a newer version's (migrate)\n bytes commitBoxCode, // redeem-script body of the CommitBox contract\n int renewalSats, // price of one year, for the owner\n int premiumSats, // takeover price at the moment of expiry\n int floorSats, // takeover price once the grace period has run out\n int graceBlocks, // length of the grace period\n int blocksPerYear,\n int ownerPercentIdle, // previous owner's share of a takeover during grace\n // ---- state: keep these LAST, in this order ----\n bytes4 expiry, // block height the paid period ends at\n bytes20 ownerPkh\n) {\n // Keep the name: pay for `years` more. Also the reclaim path — an expired\n // name renews exactly the same way, from its old expiry.\n function renew(pubkey pk, sig s, int years) {\n require(hash160(pk) == ownerPkh);\n require(checkSig(s, pk));\n require(years >= 1);\n\n int newExpiry = int(expiry) + years * blocksPerYear;\n // Stay a block height. At 500,000,000 a locktime is read as a\n // timestamp, takeover could never satisfy its height check, and the\n // name would be untakeable for ever.\n require(newExpiry < 500000000);\n bytes newState = 0x14 + ownerPkh + 0x04 + toPaddedBytes(newExpiry, 4);\n bytes32 newHash = hash256(newState + this.activeBytecode.split(26)[1]);\n\n require(tx.outputs[0].lockingBytecode == new LockingBytecodeP2SH32(newHash));\n require(tx.outputs[0].tokenCategory == tx.inputs[this.activeInputIndex].tokenCategory);\n require(tx.outputs[0].nftCommitment == tx.inputs[this.activeInputIndex].nftCommitment);\n require(tx.outputs[0].value >= tx.inputs[this.activeInputIndex].value);\n\n require(tx.outputs[1].lockingBytecode == fundLock);\n require(tx.outputs[1].value >= renewalSats * years);\n require(tx.outputs[1].tokenCategory == 0x);\n }\n\n // Hand the name to another key (a sale, a gift), or re-create it for the\n // same key — which is how records are updated: the certificate has to move\n // for a resolver to accept an UPD. Expiry is untouched.\n function transfer(pubkey pk, sig s,
"fingerprint" : "c48440f8b9d46a8183c4c2326a691a281963febd642858667f3343fabc792736" ,
registry covenant v1: the contract that holds a name and enforces its lifecycle (draft)
Expiry was always going to be the chain refusing, not resolvers agreeing. This
is that contract: a certificate sits in a covenant whose address encodes its
owner and expiry, and five paths move it. The owner renews, transfers,
releases or migrates; anyone takes over an expired name at a price that
glides from a premium to a floor, paying the previous owner a share while the
grace period lasts and committing to the name a block ahead.
The two changing values are the last constructor arguments, so they sit first
in the redeem script and the contract re-creates itself by swapping 26 bytes.
A resolver that knows the code can check any claimed owner and expiry against
the address.
Every number comes from registry-lifecycle.js, which was written as the
fixture for this. The tests run each path in libauth's VM under the 2025 and
2026 rules, compare price and split to that model along the glide, and then
break one rule at a time with valid signatures; the suite counts that the VM
itself refused them.
Draft, not reviewed, and not wired into any resolver. REGISTRY-COVENANT-v1.md
says where it departs from the design: script cannot bound a height from
above, so reclaim has no deadline and a commit cannot expire, which leaves
commit hoarding open. That is the first thing a reviewer should read.
2026-10-04 15:42:36 +02:00
"debug" : {
2026-10-04 16:53:56 +02:00
"bytecode" : "5b79009c635c79a95b79885d7a5d7aad5c7951a269597a815c79597a959376040065cd1d9f6901145a7a7e547e7c54807ec1011a7f777eaa00cd02aa207b7e01877e8800d1c0ce8800d2c0cf8800ccc0c6a26951cd8851cc537a597a95a26951d100886d6d6d7551675b79519c635e7a820114885d79a95c7a885d7a5d7aad01147c7e547e5a7a7ec1011a7f777eaa00cd02aa207b7e01877e8800d1c0ce8800d2c0cf8800ccc0c6a2696d6d6d6d6d51675b79529c635c7a820114885a7a8176b175c576040065cd1d9f697c597993587900709f635a795a795c79945479567994955d7996937b757c785e799501649677686079827701209dc0cf01117a7eaa011456797e01207e7c7e587a7e51c702aa207baa7e01877e8853795c7993040065cd1d9f690114557a7e547e547a5b7a9354807ec1011a7f777eaa00cd02aa207b7e01877e8800d1c0ce8800d2c0cf8800ccc0c6a26951cd547a8851cc7b527994a26951d100887600a06352cd0376a9145a797e0288ac7e8852cc78a26952d10088686d6d6d6d6d51675b79539c635c79a95b7a885c7a5c7aadc0cec454a16900d178879169c451a06351d17887916968c452a06352d17887916968c453a06353d178879169686d6d6d6d6d6d51675b7a549d5b79a95b79885c7a5c7aadc1011a7f77aa5c7a7c5d79aa7eaa537abb01145a7a7e547e597a7e597a7eaa00cd02aa207b7e01877e8800d1c0ce8800d2c0cf8800ccc0c6a2696d6d6d6d5168686868" ,
"sourceMap" : "47:4:68:5;;;;;48:24:48:26;;:16::27:1;:31::39:0;;:8::41:1;49:25:49:26:0;;:28::30;;:8::33:1;50:16:50:21:0;;:25::26;:16:::1;:8::28;52:28:52:34:0;;:24::35:1;:38::43:0;;:46::59;;:38:::1;:24;56:16:56:25:0;:28::37;:16:::1;:8::39;57:25:57:29:0;:32::40;;:25:::1;:43::47:0;:25:::1;:64::73:0;:75::76;:50::77:1;:25;58:45:58:64:0;:71::73;:45::74:1;:::77;:34;:26::78;60:27:60:28:0;:16::45:1;:49::83:0;:75::82;:49::83:1;;;:8::85;61:27:61:28:0;:16::43:1;:57::78:0;:47::93:1;:8::95;62:27:62:28:0;:16::43:1;:57::78:0;:47::93:1;:8::95;63:27:63:28:0;:16::35:1;:49::70:0;:39::77:1;:16;:8::79;65:27:65:28:0;:16::45:1;:8::59;66:27:66:28:0;:16::35:1;:39::50:0;;:53::58;;:39:::1;:16;:8::60;67:27:67:28:0;:16::43:1;:47::49:0;:8::51:1;47:48:68:5;;;;;:4;73::84::0;;;;;:40:73:59;;;;;74:24:74:26;;:16::27:1;:31::39:0;;:8::41:1;75:25:75:26:0;;:28::30;;:8::33:1;77:25:77:29:0;:32::43;:25:::1;:46::50:0;:25:::1;:53::59:0;;:25:::1;78:45:78:64:0;:71::73;:45::74:1;:::77;:34;:26::78;80:27:80:28:0;:16::45:1;:49::83:0;:75::82;:49::83:1;;;:8::85;81:27:81:28:0;:16::43:1;:57::78:0;:47::93:1;:8::95;82:27:82:28:0;:16::43:1;:57::78:0;:47::93:1;:8::95;83:27:83:28:0;:16::35:1;:49::70:0;:39::77:1;:16;:8::79;73:61:84:5;;;;;;:4;95::136::0;;;;;:22:95:41;;;;;96:31:96:37;;:27::38:1;97::97:39:0;:8::41:1;;98:21:98:32:0;99:16:99:22;:25::34;:16:::1;:8::36;101:22:101:34:0;:37::48;;:22:::1;102:20:102:29:0;;103:24:103:25;104:12:104:28;::::1;:30:107:9:0;105:20:105:29;;:33::44;;:47::56;;:33:::1;:61::68:0;;:71::77;;:61:::1;:32::78;:81::92:0;;:32:::1;:20;:12::93;;;106:24:106:29:0;:32::48;;:24:::1;:51::54:0;:24:::1;:12::55;104:30:107:9;113:16:113:20:0;;:::27:1;;:31::33:0;:8::35:1;114:47:114:68:0;:37::83:1;:86::90:0;;:37:::1;:29::91;115:26:115:30:0;:33::44;;:26:::1;:47::51:0;:26:::1;:54::64:0;:26:::1;:67::80:0;;:26:::1;116::116:27:0;:16::44:1;:48::93:0;:82::91;:74::92:1;:48::93;;;:8::95;119:16:119:22:0;;:25::38;;:16:::1;:41::50:0;:16:::1;:8::52;120:25:120:29:0;:32::43;;:25:::1;:46::50:0;:25:::1;:67::73:0;;:76::89;;:67:::1;:91::92:0;:53::93:1;:25;121:45:121:64:0;:71::73;:45::74:1;:::77;:34;:26::78;122:27:122:28:0;:16::45:1;:49::83:0;:75::82;:49::83:1;;;:8::85;123:27:123:28:0;:16::43:1;:57::78:0;:47::93:1;:8::95;124:27:124:28:0;:16::43:1;:57::78:0;:47::93:1;:8::95;125:27:125:28:0;:16::35:1;:49::70:0;:39::77:1;:16;:8::79;128:27:128:28:0;:16::45:1;:49::57:0;;:8::59:1;129:27:129:28:0;:16::35:1;:39::44:0;:47::56;;:39:::1;:16;:8::58;130:27:130:28:0;:16::43:1;:47::49:0;:8::51:1;131:12:131:21:0;:24::25;:12:::1;:27:135:9:0;132:31:132:32;:20::49:1;:53::87:0;:78::86;;:53::87:1;;;:12::89;133:31:133:32:0;:20::39:1;:43::52:0;:20:::1;:12::54;134:31:134:32:0;:20::47:1;:51::53:0;:12::55:1;131:27:135:9;95:55:136:5;;;;;;:4;141::151::0;;;;;142:24:142:26;;:16::27:1;:31::39:0;;:8::41:1;143:25:143:26:0;;:28::30;;:8::33:1;145:35:145:56:0;:25::71:1;146:16:146:33:0;:37::38;:16:::1;:8::40;147:27:147:28:0;:16::43:1;:47::55:0;:16:::1;;:8::57;148:12:148:29:0;:32::33;:12:::1;:35::88:0;:56::57;:45::72:1;:76::84:0;:45:::1;;:37::86;:35::88;149:12:149:29:0;:32::33;:12:::1;:35::88:0;:56::57;:45::72:1;:76::84:0;:45:::1;;:37::86;:35::88;150:12:150:29:0;:32::33;:12:::1;:35::88:0;:56::57;:45::72:1;:76::84:0;:45:::1;;:37::86;:35::88;141:39:151:5;;;;;;;:4;167::179::0;;;;168:24:168:26;;:16::27:1;:31::39:0;;:8::41:1;169:25:169:26:0;;:28::30;;:8::33:1;171:35:171:54:0;:61::63;:35::64:1;:::67;:27::68;172:29:172:37:0;;:47::55;:66::73;;:58::74:1;:47;:39::75;:77::86:0;;:8::89:1;174:34:174:38:0;:41::49;;:34:::1;:52::56:0;:34:::1;:59::65:0;;:34:::1;:68::75:0;;:34:::1;:26::76;175:27:175:28:0;:16::45:1;:49::83:0;:75::82;:49::83:1;;;:8::85;176:27:176:28:0;:16::43:1;:57::78:0;:47::93:1;:8::95;177:27:177:28:0;:16::43:1;:57::78:0;:47::93:1;:8::95;178:27:178:28:0;:16::35:1;:49::70:0;:39::77:1;:16;:8::79;167:72:179:5;;;;;30:0:180:1;;;" ,
registry covenant v1: the contract that holds a name and enforces its lifecycle (draft)
Expiry was always going to be the chain refusing, not resolvers agreeing. This
is that contract: a certificate sits in a covenant whose address encodes its
owner and expiry, and five paths move it. The owner renews, transfers,
releases or migrates; anyone takes over an expired name at a price that
glides from a premium to a floor, paying the previous owner a share while the
grace period lasts and committing to the name a block ahead.
The two changing values are the last constructor arguments, so they sit first
in the redeem script and the contract re-creates itself by swapping 26 bytes.
A resolver that knows the code can check any claimed owner and expiry against
the address.
Every number comes from registry-lifecycle.js, which was written as the
fixture for this. The tests run each path in libauth's VM under the 2025 and
2026 rules, compare price and split to that model along the glide, and then
break one rule at a time with valid signatures; the suite counts that the VM
itself refused them.
Draft, not reviewed, and not wired into any resolver. REGISTRY-COVENANT-v1.md
says where it departs from the design: script cannot bound a height from
above, so reclaim has no deadline and a commit cannot expire, which leaves
commit hoarding open. That is the first thing a reviewer should read.
2026-10-04 15:42:36 +02:00
"logs" : [ ] ,
"requires" : [
{ "ip" : 21 , "line" : 48 } ,
{ "ip" : 26 , "line" : 49 } ,
{ "ip" : 31 , "line" : 50 } ,
2026-10-04 16:53:56 +02:00
{ "ip" : 44 , "line" : 56 } ,
{ "ip" : 68 , "line" : 60 } ,
{ "ip" : 73 , "line" : 61 } ,
{ "ip" : 78 , "line" : 62 } ,
{ "ip" : 84 , "line" : 63 } ,
{ "ip" : 87 , "line" : 65 } ,
{ "ip" : 96 , "line" : 66 } ,
{ "ip" : 100 , "line" : 67 } ,
{ "ip" : 122 , "line" : 74 } ,
{ "ip" : 127 , "line" : 75 } ,
{ "ip" : 149 , "line" : 80 } ,
{ "ip" : 154 , "line" : 81 } ,
{ "ip" : 159 , "line" : 82 } ,
{ "ip" : 165 , "line" : 83 } ,
{ "ip" : 187 , "line" : 97 } ,
{ "ip" : 193 , "line" : 99 } ,
{ "ip" : 237 , "line" : 113 } ,
{ "ip" : 263 , "line" : 116 } ,
{ "ip" : 271 , "line" : 119 } ,
{ "ip" : 299 , "line" : 122 } ,
{ "ip" : 304 , "line" : 123 } ,
{ "ip" : 309 , "line" : 124 } ,
{ "ip" : 315 , "line" : 125 } ,
{ "ip" : 320 , "line" : 128 } ,
{ "ip" : 328 , "line" : 129 } ,
{ "ip" : 332 , "line" : 130 } ,
{ "ip" : 345 , "line" : 132 } ,
{ "ip" : 350 , "line" : 133 } ,
{ "ip" : 354 , "line" : 134 } ,
{ "ip" : 373 , "line" : 142 } ,
{ "ip" : 378 , "line" : 143 } ,
{ "ip" : 384 , "line" : 146 } ,
{ "ip" : 390 , "line" : 147 } ,
{ "ip" : 400 , "line" : 148 } ,
{ "ip" : 411 , "line" : 149 } ,
{ "ip" : 422 , "line" : 150 } ,
{ "ip" : 441 , "line" : 168 } ,
{ "ip" : 446 , "line" : 169 } ,
{ "ip" : 462 , "line" : 172 } ,
{ "ip" : 483 , "line" : 175 } ,
{ "ip" : 488 , "line" : 176 } ,
{ "ip" : 493 , "line" : 177 } ,
{ "ip" : 499 , "line" : 178 }
registry covenant v1: the contract that holds a name and enforces its lifecycle (draft)
Expiry was always going to be the chain refusing, not resolvers agreeing. This
is that contract: a certificate sits in a covenant whose address encodes its
owner and expiry, and five paths move it. The owner renews, transfers,
releases or migrates; anyone takes over an expired name at a price that
glides from a premium to a floor, paying the previous owner a share while the
grace period lasts and committing to the name a block ahead.
The two changing values are the last constructor arguments, so they sit first
in the redeem script and the contract re-creates itself by swapping 26 bytes.
A resolver that knows the code can check any claimed owner and expiry against
the address.
Every number comes from registry-lifecycle.js, which was written as the
fixture for this. The tests run each path in libauth's VM under the 2025 and
2026 rules, compare price and split to that model along the glide, and then
break one rule at a time with valid signatures; the suite counts that the VM
itself refused them.
Draft, not reviewed, and not wired into any resolver. REGISTRY-COVENANT-v1.md
says where it departs from the design: script cannot bound a height from
above, so reclaim has no deadline and a commit cannot expire, which leaves
commit hoarding open. That is the first thing a reviewer should read.
2026-10-04 15:42:36 +02:00
] ,
2026-10-04 16:53:56 +02:00
"sourceTags" : "101:105:pv;167:171:pv"
registry covenant v1: the contract that holds a name and enforces its lifecycle (draft)
Expiry was always going to be the chain refusing, not resolvers agreeing. This
is that contract: a certificate sits in a covenant whose address encodes its
owner and expiry, and five paths move it. The owner renews, transfers,
releases or migrates; anyone takes over an expired name at a price that
glides from a premium to a floor, paying the previous owner a share while the
grace period lasts and committing to the name a block ahead.
The two changing values are the last constructor arguments, so they sit first
in the redeem script and the contract re-creates itself by swapping 26 bytes.
A resolver that knows the code can check any claimed owner and expiry against
the address.
Every number comes from registry-lifecycle.js, which was written as the
fixture for this. The tests run each path in libauth's VM under the 2025 and
2026 rules, compare price and split to that model along the glide, and then
break one rule at a time with valid signatures; the suite counts that the VM
itself refused them.
Draft, not reviewed, and not wired into any resolver. REGISTRY-COVENANT-v1.md
says where it departs from the design: script cannot bound a height from
above, so reclaim has no deadline and a commit cannot expire, which leaves
commit hoarding open. That is the first thing a reviewer should read.
2026-10-04 15:42:36 +02:00
} ,
"compiler" : {
"name" : "cashc" ,
"version" : "0.13.3" ,
"options" : {
"enforceFunctionParameterTypes" : true ,
"enforceLocktimeGuard" : true
}
} ,
2026-10-04 16:53:56 +02:00
"updatedAt" : "2026-10-04T14:37:27.164Z"
registry covenant v1: the contract that holds a name and enforces its lifecycle (draft)
Expiry was always going to be the chain refusing, not resolvers agreeing. This
is that contract: a certificate sits in a covenant whose address encodes its
owner and expiry, and five paths move it. The owner renews, transfers,
releases or migrates; anyone takes over an expired name at a price that
glides from a premium to a floor, paying the previous owner a share while the
grace period lasts and committing to the name a block ahead.
The two changing values are the last constructor arguments, so they sit first
in the redeem script and the contract re-creates itself by swapping 26 bytes.
A resolver that knows the code can check any claimed owner and expiry against
the address.
Every number comes from registry-lifecycle.js, which was written as the
fixture for this. The tests run each path in libauth's VM under the 2025 and
2026 rules, compare price and split to that model along the glide, and then
break one rule at a time with valid signatures; the suite counts that the VM
itself refused them.
Draft, not reviewed, and not wired into any resolver. REGISTRY-COVENANT-v1.md
says where it departs from the design: script cannot bound a height from
above, so reclaim has no deadline and a commit cannot expire, which leaves
commit hoarding open. That is the first thing a reviewer should read.
2026-10-04 15:42:36 +02:00
}