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}