ownable.gno

1.93 Kb ยท 92 lines
 1package ownable
 2
 3import "std"
 4
 5const OwnershipTransferEvent = "OwnershipTransfer"
 6
 7// Ownable is meant to be used as a top-level object to make your contract ownable OR
 8// being embedded in a Gno object to manage per-object ownership.
 9// Ownable is safe to export as a top-level object
10type Ownable struct {
11	owner std.Address
12}
13
14func New() *Ownable {
15	return &Ownable{
16		owner: std.PreviousRealm().Address(),
17	}
18}
19
20func NewWithAddress(addr std.Address) *Ownable {
21	return &Ownable{
22		owner: addr,
23	}
24}
25
26// TransferOwnership transfers ownership of the Ownable struct to a new address
27func (o *Ownable) TransferOwnership(newOwner std.Address) error {
28	if !o.CallerIsOwner() {
29		return ErrUnauthorized
30	}
31
32	if !newOwner.IsValid() {
33		return ErrInvalidAddress
34	}
35
36	prevOwner := o.owner
37	o.owner = newOwner
38	std.Emit(
39		OwnershipTransferEvent,
40		"from", prevOwner.String(),
41		"to", newOwner.String(),
42	)
43
44	return nil
45}
46
47// DropOwnership removes the owner, effectively disabling any owner-related actions
48// Top-level usage: disables all only-owner actions/functions,
49// Embedded usage: behaves like a burn functionality, removing the owner from the struct
50func (o *Ownable) DropOwnership() error {
51	if !o.CallerIsOwner() {
52		return ErrUnauthorized
53	}
54
55	prevOwner := o.owner
56	o.owner = ""
57
58	std.Emit(
59		OwnershipTransferEvent,
60		"from", prevOwner.String(),
61		"to", "",
62	)
63
64	return nil
65}
66
67// Owner returns the owner address from Ownable
68func (o *Ownable) Owner() std.Address {
69	if o == nil {
70		return std.Address("")
71	}
72	return o.owner
73}
74
75// CallerIsOwner checks if the caller of the function is the Realm's owner
76func (o *Ownable) CallerIsOwner() bool {
77	if o == nil {
78		return false
79	}
80	return std.PreviousRealm().Address() == o.owner
81}
82
83// AssertCallerIsOwner panics if the caller is not the owner
84func (o *Ownable) AssertCallerIsOwner() {
85	if o == nil {
86		panic(ErrUnauthorized)
87	}
88	caller := std.PreviousRealm().Address()
89	if caller != o.owner {
90		panic(ErrUnauthorized)
91	}
92}