Search Apps Documentation Source Content File Folder Download Copy Actions Download

ownable.gno

2.96 Kb ยท 128 lines
  1package ownable
  2
  3import (
  4	"chain"
  5	"chain/runtime"
  6)
  7
  8const OwnershipTransferEvent = "OwnershipTransfer"
  9
 10// Ownable is meant to be used as a top-level object to make your contract ownable OR
 11// being embedded in a Gno object to manage per-object ownership.
 12// Ownable is safe to export as a top-level object
 13type Ownable struct {
 14	owner address
 15}
 16
 17func New() *Ownable {
 18	return &Ownable{
 19		owner: runtime.CurrentRealm().Address(),
 20	}
 21}
 22
 23func NewWithOrigin() *Ownable {
 24	origin := runtime.OriginCaller()
 25	previous := runtime.PreviousRealm()
 26	if origin != previous.Address() {
 27		panic("NewWithOrigin() should be called from init() where std.PreviousRealm() is origin")
 28	}
 29	return &Ownable{
 30		owner: origin,
 31	}
 32}
 33
 34func NewWithAddress(addr address) *Ownable {
 35	return &Ownable{
 36		owner: addr,
 37	}
 38}
 39
 40// TransferOwnership transfers ownership of the Ownable struct to a new address
 41func (o *Ownable) TransferOwnership(newOwner address) error {
 42	if !o.OwnedByCurrent() {
 43		return ErrUnauthorized
 44	}
 45
 46	if !newOwner.IsValid() {
 47		return ErrInvalidAddress
 48	}
 49
 50	prevOwner := o.owner
 51	o.owner = newOwner
 52	chain.Emit(
 53		OwnershipTransferEvent,
 54		"from", prevOwner.String(),
 55		"to", newOwner.String(),
 56	)
 57
 58	return nil
 59}
 60
 61// DropOwnershipByCurrent removes the owner, effectively disabling any owner-related actions
 62// Top-level usage: disables all only-owner actions/functions,
 63// Embedded usage: behaves like a burn functionality, removing the owner from the struct
 64func (o *Ownable) DropOwnershipByCurrent() error {
 65	if !o.OwnedByCurrent() {
 66		return ErrUnauthorized
 67	}
 68	o.dropOwnership(o.owner)
 69	return nil
 70}
 71
 72// DropOwnershipByPrevious removes the owner, effectively disabling any owner-related actions
 73// Top-level usage: disables all only-owner actions/functions,
 74// Embedded usage: behaves like a burn functionality, removing the owner from the struct
 75func (o *Ownable) DropOwnershipByPrevious() error {
 76	if !o.OwnedByPrevious() {
 77		return ErrUnauthorized
 78	}
 79	o.dropOwnership(o.owner)
 80	return nil
 81}
 82
 83func (o *Ownable) dropOwnership(prevOwner address) {
 84	o.owner = ""
 85	chain.Emit(
 86		OwnershipTransferEvent,
 87		"from", prevOwner.String(),
 88		"to", "",
 89	)
 90}
 91
 92// Owner returns the owner address from Ownable
 93func (o *Ownable) Owner() address {
 94	if o == nil {
 95		return address("")
 96	}
 97	return o.owner
 98}
 99
100// OwnedByCurrent checks if the caller of the function is the Realm's owner
101func (o *Ownable) OwnedByCurrent() bool {
102	if o == nil {
103		return false
104	}
105	return runtime.CurrentRealm().Address() == o.owner
106}
107
108// AssertOwnedByCurrent panics if the caller is not the owner
109func (o *Ownable) AssertOwnedByCurrent() {
110	if !o.OwnedByCurrent() {
111		panic(ErrUnauthorized)
112	}
113}
114
115// OwnedByPrevious checks if the caller of the function is the Realm's owner
116func (o *Ownable) OwnedByPrevious() bool {
117	if o == nil {
118		return false
119	}
120	return runtime.PreviousRealm().Address() == o.owner
121}
122
123// AssertOwnedByPrevious panics if the caller is not the owner
124func (o *Ownable) AssertOwnedByPrevious() {
125	if !o.OwnedByPrevious() {
126		panic(ErrUnauthorized)
127	}
128}