nslogic
gno.land/r/g1xr6tgxnpled50h74eafmvxway7z0ytr5rsmeme/nslogic/v2
Contract Source Code
reserved.gno
Preparing the Explorer shell…
package nslogic
import (
"strconv"
"gno.land/r/g1xr6tgxnpled50h74eafmvxway7z0ytr5rsmeme/nsdata/v2"
)
// GENERATED BY tools/gen-reserved.py FROM collections/reserved-labels.json.
// Do not edit by hand: the site reads the same source, and a change made
// in one place only is a label the site offers and the chain refuses.
//
// STRUCTURAL RULES ONLY. The wordlists live off chain, in that JSON,
// because storage is 100 ugnot per byte and a ten-thousand-word
// dictionary is about 57 GNOT paid forever to encode a marketing
// decision that will change. This is the backstop against a bug in the
// issuer, not the place the policy lives.
//
// THE NUMBERS ARE SETTABLE, the shape is not. A minimum length is a
// promotion knob and belongs in the panel — redeploying this realm to
// change a 5 to a 4 costs about 22 GNOT. So the lengths read from the
// vault's globals and fall back to the values generated here; the
// pattern rules are structural facts about what a handle looks like and
// stay in code.
const (
defaultFreeMinLength = 5
defaultFreeMaxLength = 63
keyFreeMin = "freemin"
keyFreeMax = "freemax"
)
// FreeMinLength is the shortest label the free tier will issue. Settable
// from the panel, because which lengths are worth money is a commercial
// judgement that moves.
func FreeMinLength() int {
if v := nsdata.GetGlobal(keyFreeMin); v != "" {
if n, err := strconv.Atoi(v); err == nil && n > 0 && n <= 63 {
return n
}
}
return defaultFreeMinLength
}
func FreeMaxLength() int {
if v := nsdata.GetGlobal(keyFreeMax); v != "" {
if n, err := strconv.Atoi(v); err == nil && n > 0 && n <= 63 {
return n
}
}
return defaultFreeMaxLength
}
/*
FreeLabelAllowed reports whether a label may be ISSUED on the free tier.
ISSUED, and never renewed. This is called by GrantFreeName and by
nothing else, deliberately: if the minimum length rises from three to
five, somebody who already holds a three-character free name keeps it
and keeps renewing it free. Tightening a rule must not reach backwards
and take away what was already given — that is the single fastest way to
make a giveaway cost more trust than it ever bought.
A name that LAPSES and is registered again is a new issuance, and gets
whatever the rules say that day. That is not retroactive; it is a
different name event.
*/
func FreeLabelAllowed(label string) bool {
n := len(label)
if n < FreeMinLength() || n > FreeMaxLength() {
return false
}
// Pure digits: 1337, 420, years. Collectible, and no handle is one.
digits := true
for i := 0; i < n; i++ {
if label[i] < '0' || label[i] > '9' {
digits = false
break
}
}
if digits {
return false
}
// aaaa — every character the same.
same := true
for i := 1; i < n; i++ {
if label[i] != label[0] {
same = false
break
}
}
if same {
return false
}
// abab — a two-character cycle. Also collectible, also not a handle.
if n >= 4 {
cycle := true
for i := 2; i < n; i++ {
if label[i] != label[i-2] {
cycle = false
break
}
}
if cycle {
return false
}
}
return true
}