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.

admin.gno

4.24 Kb · 154 lines
  1package game
  2
  3import "chain"
  4
  5// Roles: one owner, a set of admins, a set of referees.
  6//
  7//   - The owner manages the admins and the treasury, and can hand the realm
  8//     over. The owner is always an admin.
  9//   - Admins tune the game and manage the referees.
 10//   - Referees are the game servers. They record kills and nothing else.
 11
 12// callerOf returns the verified caller of a crossing function. rlm must be
 13// the cur of the crossing function calling this helper: a stale or forged
 14// realm value fails IsCurrent, and Previous is only meaningful on a live one.
 15//
 16// It takes the realm in second position on purpose, like p/nt/ownable does:
 17// a function whose first parameter is a realm is a crossing function.
 18func callerOf(_ int, rlm realm) address {
 19	if !rlm.IsCurrent() {
 20		panic(errSpoofedRealm)
 21	}
 22	return rlm.Previous().Address()
 23}
 24
 25// assertOwner panics unless the caller is the owner, and returns the caller.
 26func assertOwner(_ int, rlm realm) address {
 27	caller := callerOf(0, rlm)
 28	if !owner.OwnedBy(caller) {
 29		panic(errNotOwner)
 30	}
 31	return caller
 32}
 33
 34// assertAdmin panics unless the caller is an admin, and returns the caller.
 35func assertAdmin(_ int, rlm realm) address {
 36	caller := callerOf(0, rlm)
 37	if !IsAdmin(caller) {
 38		panic(errNotAdmin)
 39	}
 40	return caller
 41}
 42
 43// assertReferee panics unless the caller is a referee, and returns the caller.
 44func assertReferee(_ int, rlm realm) address {
 45	caller := callerOf(0, rlm)
 46	if !IsReferee(caller) {
 47		panic(errNotReferee)
 48	}
 49	return caller
 50}
 51
 52// TransferOwnership hands the realm over to newOwner. Owner only.
 53//
 54// The previous owner keeps no privilege, unless it was also added to the
 55// admin or referee lists.
 56func TransferOwnership(cur realm, newOwner address) {
 57	// ownable checks the caller and the address. It would take the address
 58	// written in capitals though, and an owner under that key could never be
 59	// matched to a caller again: see validAddress.
 60	if newOwner.IsValid() && !validAddress(newOwner) {
 61		panic(errInvalidAddress)
 62	}
 63	if err := owner.TransferOwnership(0, cur, newOwner); err != nil {
 64		panic(err)
 65	}
 66	bump()
 67}
 68
 69// AddAdmin adds addr to the admin list. Owner only.
 70func AddAdmin(cur realm, addr address) {
 71	assertOwner(0, cur)
 72	if !validAddress(addr) {
 73		panic(errInvalidAddress)
 74	}
 75	if admins.Set(addr.String(), nil) {
 76		panic(errAlreadyAdmin)
 77	}
 78	bump()
 79	chain.Emit("AdminAdded", "address", addr.String())
 80}
 81
 82// RemoveAdmin removes addr from the admin list. Owner only.
 83//
 84// The owner is an admin by definition and cannot be demoted this way, use
 85// TransferOwnership.
 86func RemoveAdmin(cur realm, addr address) {
 87	assertOwner(0, cur)
 88	if _, removed := admins.Remove(addr.String()); !removed {
 89		panic(errNoSuchAdmin)
 90	}
 91	bump()
 92	chain.Emit("AdminRemoved", "address", addr.String())
 93}
 94
 95// SetTreasury sets the address the sales of skins and planes are forwarded
 96// to. Owner only.
 97func SetTreasury(cur realm, addr address) {
 98	assertOwner(0, cur)
 99	if !validAddress(addr) {
100		panic(errInvalidAddress)
101	}
102	// Coins sent to the realm's own address would be stuck: nothing here
103	// ever spends the realm balance.
104	if addr == cur.Address() {
105		panic(errTreasurySelf)
106	}
107	treasury = addr
108	bump()
109	chain.Emit("TreasurySet", "address", addr.String())
110}
111
112// AddReferee allows addr to submit kills. Admin only.
113func AddReferee(cur realm, addr address) {
114	assertAdmin(0, cur)
115	if !validAddress(addr) {
116		panic(errInvalidAddress)
117	}
118	if referees.Set(addr.String(), nil) {
119		panic(errAlreadyReferee)
120	}
121	bump()
122	chain.Emit("RefereeAdded", "address", addr.String())
123}
124
125// RemoveReferee stops addr from submitting kills. Admin only.
126func RemoveReferee(cur realm, addr address) {
127	assertAdmin(0, cur)
128	if _, removed := referees.Remove(addr.String()); !removed {
129		panic(errNoSuchReferee)
130	}
131	bump()
132	chain.Emit("RefereeRemoved", "address", addr.String())
133}
134
135// Owner returns the owner of the realm.
136func Owner() address {
137	return owner.Owner()
138}
139
140// Treasury returns the address the sales of skins and planes are forwarded
141// to.
142func Treasury() address {
143	return treasury
144}
145
146// IsAdmin reports whether addr is an admin. The owner always is.
147func IsAdmin(addr address) bool {
148	return owner.OwnedBy(addr) || admins.Has(addr.String())
149}
150
151// IsReferee reports whether addr may submit kills.
152func IsReferee(addr address) bool {
153	return referees.Has(addr.String())
154}