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."}