Skip to content Search Apps Documentation Source Content File Folder Download Copy Actions State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

Community realm. Read the code first. Community realm, deployed by its author. Read the code before you interact or send coins.

names.gno

3.84 Kb · 79 lines
 1// Onyx v1.5.1-rc.1. No administrator, withdrawal, upgrade or arbitrary callback.
 2package ggg_names_v1
 3
 4import (
 5 "chain"
 6 "chain/banker"
 7 "chain/runtime/unsafe"
 8 "strconv"
 9 "strings"
10 "time"
11)
12
13const beneficiary = address("g1kw3pcg8std2w989me6akdj3lkv7m8fhefldc0t")
14const renamePrice = int64(100000000)
15type record struct { name string; revision int; history []change }
16type change struct { oldName string; newName string; at int64 }
17var profiles = make(map[address]record)
18var active = make(map[string]address)
19// Testnet policy: former names are permanently retired, preventing impersonation.
20var retired = make(map[string]bool)
21
22func Normalize(name string) string {
23 if len(name)<3 || len(name)>16 { panic("NAME_LENGTH") }
24 for _,c := range []byte(name) { if !((c>='a'&&c<='z')||(c>='A'&&c<='Z')||(c>='0'&&c<='9')||c=='_') { panic("NAME_CHARACTERS") } }
25 n:=strings.ToLower(name)
26 for _,r:=range []string{"admin","administrator","moderator","support","official","gnognogo","gnogno","gno_land","gnoland","gnot","adena","kiado","system"} { if n==r || strings.HasPrefix(n,r+"_") {panic("NAME_RESERVED")} }
27 return n
28}
29func direct(cur realm) address {
30 if !cur.IsCurrent() || !cur.Previous().IsUserCall() {panic("DIRECT_USER_CALL_REQUIRED")}
31 return cur.Previous().Address()
32}
33// OriginSend alone is NOT proof. Both crossing entry points first verify the live
34// realm and direct EOA caller; OriginSend banker additionally scopes spending to
35// THIS message's envelope and recipient, never preexisting realm balances.
36func envelope() chain.Coins { return unsafe.OriginSend() }
37func available(name string) string {
38 n:=Normalize(name)
39 if active[n]!="" || retired[n] {panic("NAME_UNAVAILABLE")}
40 return n
41}
42func Register(cur realm,name string) {
43 owner:=direct(cur)
44 if len(envelope())!=0 {panic("FIRST_REGISTRATION_NO_COMMERCIAL_PAYMENT")}
45 if profiles[owner].name!="" {panic("ALREADY_REGISTERED")}
46 n:=available(name)
47 profiles[owner]=record{name:name,revision:1,history:[]change{{oldName:"",newName:name,at:time.Now().Unix()}}}
48 active[n]=owner
49}
50func Rename(cur realm,expected string,revision int,name string) {
51 owner:=direct(cur)
52 previous:=profiles[owner]
53 if previous.name=="" || previous.name!=expected || previous.revision!=revision {panic("OWNER_OR_REVISION_MISMATCH")}
54 n:=available(name)
55 coins:=envelope()
56 if len(coins)!=1 || coins[0].Denom!="ugnot" || coins[0].Amount!=renamePrice {panic("EXACT_100_GNOT_REQUIRED")}
57 b:=banker.NewBanker(banker.BankerTypeOriginSend,cur)
58 // Send first: insufficient/consumed envelope aborts before indexes. A later
59 // panic or storage-deposit failure rolls back the entire MsgCall, coins too.
60 b.SendCoins(cur.Address(),beneficiary,chain.NewCoins(chain.Coin{Denom:"ugnot",Amount:renamePrice}))
61 delete(active,strings.ToLower(previous.name))
62 retired[strings.ToLower(previous.name)]=true
63 previous.history=append(previous.history,change{oldName:previous.name,newName:name,at:time.Now().Unix()})
64 previous.name=name;previous.revision++
65 profiles[owner]=previous;active[n]=owner
66}
67func Lookup(addr string) string {
68 p:=profiles[address(addr)]
69 return "{\"name\":"+strconv.Quote(p.name)+",\"revision\":"+strconv.Itoa(p.revision)+"}"
70}
71func Owner(name string) string {return string(active[Normalize(name)])}
72func Available(name string) bool {n:=Normalize(name);return active[n]==""&&!retired[n]}
73func History(addr string) string {
74 out:="["
75 for i,c:=range profiles[address(addr)].history {if i>0 {out+=","};out+="{\"old\":"+strconv.Quote(c.oldName)+",\"name\":"+strconv.Quote(c.newName)+",\"at\":"+strconv.FormatInt(c.at,10)+"}"}
76 return out+"]"
77}
78func RegistryVersion() string {return "GGG_NAMES_ONYX_V1:100000000ugnot:"+string(beneficiary)}
79func Render(_ string) string {return "# GnoGno Go! · Onyx names\nPublic pseudonyms. First registration: network costs only. Rename: 100 GNOT plus network costs. Former names are retired. No gameplay, lives or Fast rights are granted here."}