From c307de3534c11e9f01a944700391a02f2b61efb3 Mon Sep 17 00:00:00 2001 From: linhpn99 Date: Sun, 26 May 2024 16:12:38 +0700 Subject: [PATCH 01/30] define Ownable and Transferrable Interface for custom --- examples/gno.land/p/demo/ownable/ownable.gno | 31 ++++++++++++++------ 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/examples/gno.land/p/demo/ownable/ownable.gno b/examples/gno.land/p/demo/ownable/ownable.gno index 7f2eac008e1..b067410a41a 100644 --- a/examples/gno.land/p/demo/ownable/ownable.gno +++ b/examples/gno.land/p/demo/ownable/ownable.gno @@ -4,20 +4,33 @@ import ( "std" ) -// Ownable is meant to be used as a top-level object to make your contract ownable OR -// being embedded in a Gno object to manage per-object ownership. -type Ownable struct { +// Ownable defines an interface that requires a method to get the owner's address +type Ownable interface { + Owner() std.Address +} + +// Transferrable embeds Ownable, indicating that an object can transfer ownership +type Transferrable interface { + Ownable + + TransferOwnership(newOwner std.Address) error +} + +// DefaultOwnable provides a basic implementation of ownership functionality +// It can be used as a top-level object to make a contract ownable or embedded within +// another object to manage per-object ownership. +type DefaultOwnable struct { owner std.Address } -func New() *Ownable { - return &Ownable{ +func New() *DefaultOwnable { + return &DefaultOwnable{ owner: std.GetOrigCaller(), } } // TransferOwnership transfers ownership of the Ownable struct to a new address -func (o *Ownable) TransferOwnership(newOwner std.Address) error { +func (o *DefaultOwnable) TransferOwnership(newOwner std.Address) error { err := o.CallerIsOwner() if err != nil { return err @@ -34,7 +47,7 @@ func (o *Ownable) TransferOwnership(newOwner std.Address) error { // DropOwnership removes the owner, effectively disabling any owner-related actions // Top-level usage: disables all only-owner actions/functions, // Embedded usage: behaves like a burn functionality, removing the owner from the struct -func (o *Ownable) DropOwnership() error { +func (o *DefaultOwnable) DropOwnership() error { err := o.CallerIsOwner() if err != nil { return err @@ -45,13 +58,13 @@ func (o *Ownable) DropOwnership() error { } // CallerIsOwner checks if the caller of the function is the Realm's owner -func (o *Ownable) CallerIsOwner() error { +func (o *DefaultOwnable) CallerIsOwner() error { if std.GetOrigCaller() == o.owner { return nil } return ErrUnauthorized } -func (o *Ownable) Owner() std.Address { +func (o *DefaultOwnable) Owner() std.Address { return o.owner } From 085349164202cd62d90ef6126704b8036b1e9b05 Mon Sep 17 00:00:00 2001 From: linhpn99 Date: Sun, 26 May 2024 16:23:37 +0700 Subject: [PATCH 02/30] Update the affected packages --- examples/gno.land/p/demo/memeland/memeland.gno | 2 +- examples/gno.land/p/demo/pausable/pausable.gno | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/gno.land/p/demo/memeland/memeland.gno b/examples/gno.land/p/demo/memeland/memeland.gno index 9c302ca365b..186fb988c12 100644 --- a/examples/gno.land/p/demo/memeland/memeland.gno +++ b/examples/gno.land/p/demo/memeland/memeland.gno @@ -26,7 +26,7 @@ type Post struct { } type Memeland struct { - *ownable.Ownable + *ownable.DefaultOwnable Posts []*Post MemeCounter seqid.ID } diff --git a/examples/gno.land/p/demo/pausable/pausable.gno b/examples/gno.land/p/demo/pausable/pausable.gno index eae3456ba61..778e87fb3b2 100644 --- a/examples/gno.land/p/demo/pausable/pausable.gno +++ b/examples/gno.land/p/demo/pausable/pausable.gno @@ -3,7 +3,7 @@ package pausable import "gno.land/p/demo/ownable" type Pausable struct { - *ownable.Ownable + *ownable.DefaultOwnable paused bool } @@ -16,7 +16,7 @@ func New() *Pausable { } // NewFromOwnable is the same as New, but with a pre-existing top-level ownable -func NewFromOwnable(ownable *ownable.Ownable) *Pausable { +func NewFromOwnable(ownable *ownable.DefaultOwnable) *Pausable { return &Pausable{ Ownable: ownable, paused: false, From a2e5c69d4cb8e17403bbaf941bee3b312d3a42fb Mon Sep 17 00:00:00 2001 From: linhpn99 Date: Sun, 26 May 2024 16:29:20 +0700 Subject: [PATCH 03/30] rename fields --- examples/gno.land/p/demo/memeland/memeland.gno | 4 ++-- examples/gno.land/p/demo/pausable/pausable.gno | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/gno.land/p/demo/memeland/memeland.gno b/examples/gno.land/p/demo/memeland/memeland.gno index 186fb988c12..874ec21314b 100644 --- a/examples/gno.land/p/demo/memeland/memeland.gno +++ b/examples/gno.land/p/demo/memeland/memeland.gno @@ -33,8 +33,8 @@ type Memeland struct { func NewMemeland() *Memeland { return &Memeland{ - Ownable: ownable.New(), - Posts: make([]*Post, 0), + DefaultOwnable: ownable.New(), + Posts: make([]*Post, 0), } } diff --git a/examples/gno.land/p/demo/pausable/pausable.gno b/examples/gno.land/p/demo/pausable/pausable.gno index 778e87fb3b2..04a33c885e7 100644 --- a/examples/gno.land/p/demo/pausable/pausable.gno +++ b/examples/gno.land/p/demo/pausable/pausable.gno @@ -10,16 +10,16 @@ type Pausable struct { // New returns a new Pausable struct with non-paused state as default func New() *Pausable { return &Pausable{ - Ownable: ownable.New(), - paused: false, + DefaultOwnable: ownable.New(), + paused: false, } } // NewFromOwnable is the same as New, but with a pre-existing top-level ownable func NewFromOwnable(ownable *ownable.DefaultOwnable) *Pausable { return &Pausable{ - Ownable: ownable, - paused: false, + DefaultOwnable: ownable, + paused: false, } } From b206494583e6bcb6bc2efdf1ce7df76516833f93 Mon Sep 17 00:00:00 2001 From: linhpn99 Date: Sun, 26 May 2024 19:25:40 +0700 Subject: [PATCH 04/30] embed interface instead of implement --- examples/gno.land/p/demo/index/index.gno | 30 +++++++++++++++++++ .../gno.land/p/demo/memeland/memeland.gno | 6 ++-- .../gno.land/p/demo/pausable/pausable.gno | 12 ++++---- 3 files changed, 39 insertions(+), 9 deletions(-) create mode 100644 examples/gno.land/p/demo/index/index.gno diff --git a/examples/gno.land/p/demo/index/index.gno b/examples/gno.land/p/demo/index/index.gno new file mode 100644 index 00000000000..d36067821b6 --- /dev/null +++ b/examples/gno.land/p/demo/index/index.gno @@ -0,0 +1,30 @@ +package index + +import ( + "gno.land/p/demo/avl" +) + +type Indexer interface { + GetByIndex(string, string) + IterateByIndex(string) +} + +type LargeIndexer struct { + data *avl.Tree +} + +type SmallIndexer struct { + data []interface{} +} + +func String(db *avl.Tree, indexer func(entry interface{}) string) (*avl.Tree, Indexer) { + db.Iterate("", "", func(key string, value interface{}) bool { + indexManager.Set(indexer(key), value) + return false + }) +} + +func Int(db *avl.Tree, indexer func(entry interface{}) int) *avl.Tree { + // + return nil, nil +} diff --git a/examples/gno.land/p/demo/memeland/memeland.gno b/examples/gno.land/p/demo/memeland/memeland.gno index 874ec21314b..efe2379660d 100644 --- a/examples/gno.land/p/demo/memeland/memeland.gno +++ b/examples/gno.land/p/demo/memeland/memeland.gno @@ -26,15 +26,15 @@ type Post struct { } type Memeland struct { - *ownable.DefaultOwnable + ownable.Ownable Posts []*Post MemeCounter seqid.ID } func NewMemeland() *Memeland { return &Memeland{ - DefaultOwnable: ownable.New(), - Posts: make([]*Post, 0), + Ownable: ownable.New(), + Posts: make([]*Post, 0), } } diff --git a/examples/gno.land/p/demo/pausable/pausable.gno b/examples/gno.land/p/demo/pausable/pausable.gno index 04a33c885e7..f0fcc3d9ee6 100644 --- a/examples/gno.land/p/demo/pausable/pausable.gno +++ b/examples/gno.land/p/demo/pausable/pausable.gno @@ -3,23 +3,23 @@ package pausable import "gno.land/p/demo/ownable" type Pausable struct { - *ownable.DefaultOwnable + ownable.Ownable paused bool } // New returns a new Pausable struct with non-paused state as default func New() *Pausable { return &Pausable{ - DefaultOwnable: ownable.New(), - paused: false, + Ownable: ownable.New(), + paused: false, } } // NewFromOwnable is the same as New, but with a pre-existing top-level ownable -func NewFromOwnable(ownable *ownable.DefaultOwnable) *Pausable { +func NewFromOwnable(ownable ownable.Ownable) *Pausable { return &Pausable{ - DefaultOwnable: ownable, - paused: false, + Ownable: ownable, + paused: false, } } From fe82cab6003a246cef22c7a66ce74e309cae72de Mon Sep 17 00:00:00 2001 From: linhpn99 Date: Sun, 26 May 2024 19:53:22 +0700 Subject: [PATCH 05/30] update --- examples/gno.land/p/demo/helper/gno.mod | 1 + examples/gno.land/p/demo/helper/helper.gno | 10 +++++ examples/gno.land/p/demo/index/index.gno | 30 ------------- examples/gno.land/p/demo/memeland/errors.gno | 5 +++ .../gno.land/p/demo/memeland/memeland.gno | 5 ++- examples/gno.land/p/demo/ownable/ownable.gno | 43 +++++++++---------- .../gno.land/p/demo/ownable/ownable_test.gno | 5 ++- examples/gno.land/p/demo/pausable/errors.gno | 8 ++++ .../gno.land/p/demo/pausable/pausable.gno | 13 +++--- 9 files changed, 59 insertions(+), 61 deletions(-) create mode 100644 examples/gno.land/p/demo/helper/gno.mod create mode 100644 examples/gno.land/p/demo/helper/helper.gno delete mode 100644 examples/gno.land/p/demo/index/index.gno create mode 100644 examples/gno.land/p/demo/memeland/errors.gno create mode 100644 examples/gno.land/p/demo/pausable/errors.gno diff --git a/examples/gno.land/p/demo/helper/gno.mod b/examples/gno.land/p/demo/helper/gno.mod new file mode 100644 index 00000000000..7b49085db57 --- /dev/null +++ b/examples/gno.land/p/demo/helper/gno.mod @@ -0,0 +1 @@ +module gno.land/p/demo/helper \ No newline at end of file diff --git a/examples/gno.land/p/demo/helper/helper.gno b/examples/gno.land/p/demo/helper/helper.gno new file mode 100644 index 00000000000..8c4447c3282 --- /dev/null +++ b/examples/gno.land/p/demo/helper/helper.gno @@ -0,0 +1,10 @@ +package helper + +import ( + "std" +) + +// PrevRealmIsOwner checks if the caller of the function is the Realm's owner +func PrevRealmIsOwner(owner std.Address) bool { + return std.GetOrigCaller() == owner +} diff --git a/examples/gno.land/p/demo/index/index.gno b/examples/gno.land/p/demo/index/index.gno deleted file mode 100644 index d36067821b6..00000000000 --- a/examples/gno.land/p/demo/index/index.gno +++ /dev/null @@ -1,30 +0,0 @@ -package index - -import ( - "gno.land/p/demo/avl" -) - -type Indexer interface { - GetByIndex(string, string) - IterateByIndex(string) -} - -type LargeIndexer struct { - data *avl.Tree -} - -type SmallIndexer struct { - data []interface{} -} - -func String(db *avl.Tree, indexer func(entry interface{}) string) (*avl.Tree, Indexer) { - db.Iterate("", "", func(key string, value interface{}) bool { - indexManager.Set(indexer(key), value) - return false - }) -} - -func Int(db *avl.Tree, indexer func(entry interface{}) int) *avl.Tree { - // - return nil, nil -} diff --git a/examples/gno.land/p/demo/memeland/errors.gno b/examples/gno.land/p/demo/memeland/errors.gno new file mode 100644 index 00000000000..84e1dbdd1cb --- /dev/null +++ b/examples/gno.land/p/demo/memeland/errors.gno @@ -0,0 +1,5 @@ +package memeland + +import "errors" + +var ErrUnauthorized = errors.New("unauthorized; caller is not owner") diff --git a/examples/gno.land/p/demo/memeland/memeland.gno b/examples/gno.land/p/demo/memeland/memeland.gno index efe2379660d..b265d804d22 100644 --- a/examples/gno.land/p/demo/memeland/memeland.gno +++ b/examples/gno.land/p/demo/memeland/memeland.gno @@ -8,6 +8,7 @@ import ( "time" "gno.land/p/demo/avl" + "gno.land/p/demo/helper" "gno.land/p/demo/ownable" "gno.land/p/demo/seqid" ) @@ -160,8 +161,8 @@ func (m *Memeland) RemovePost(id string) string { panic("id cannot be empty") } - if err := m.CallerIsOwner(); err != nil { - panic(err) + if !helper.PrevRealmIsOwner(m.Owner()) { + panic(ErrUnauthorized) } for i, post := range m.Posts { diff --git a/examples/gno.land/p/demo/ownable/ownable.gno b/examples/gno.land/p/demo/ownable/ownable.gno index b067410a41a..9f67ffee8ec 100644 --- a/examples/gno.land/p/demo/ownable/ownable.gno +++ b/examples/gno.land/p/demo/ownable/ownable.gno @@ -2,6 +2,8 @@ package ownable import ( "std" + + "gno.land/p/demo/helper" ) // Ownable defines an interface that requires a method to get the owner's address @@ -9,31 +11,37 @@ type Ownable interface { Owner() std.Address } -// Transferrable embeds Ownable, indicating that an object can transfer ownership +// Transferrable embeds Ownable, indicating that an object can transfer and drop an ownership type Transferrable interface { Ownable TransferOwnership(newOwner std.Address) error + DropOwnership() error } -// DefaultOwnable provides a basic implementation of ownership functionality +// TransferrableOwnership provides a basic implementation of ownership functionality // It can be used as a top-level object to make a contract ownable or embedded within // another object to manage per-object ownership. -type DefaultOwnable struct { +type TransferrableOwnership struct { owner std.Address } -func New() *DefaultOwnable { - return &DefaultOwnable{ +// Ensure that TransferrableOwnership implements the Ownable and Transferrable interfaces +var ( + _ Ownable = (*TransferrableOwnership)(nil) + _ Transferrable = (*TransferrableOwnership)(nil) +) + +func New() *TransferrableOwnership { + return &TransferrableOwnership{ owner: std.GetOrigCaller(), } } // TransferOwnership transfers ownership of the Ownable struct to a new address -func (o *DefaultOwnable) TransferOwnership(newOwner std.Address) error { - err := o.CallerIsOwner() - if err != nil { - return err +func (o *TransferrableOwnership) TransferOwnership(newOwner std.Address) error { + if !helper.PrevRealmIsOwner(o.owner) { + return ErrUnauthorized } if !newOwner.IsValid() { @@ -47,24 +55,15 @@ func (o *DefaultOwnable) TransferOwnership(newOwner std.Address) error { // DropOwnership removes the owner, effectively disabling any owner-related actions // Top-level usage: disables all only-owner actions/functions, // Embedded usage: behaves like a burn functionality, removing the owner from the struct -func (o *DefaultOwnable) DropOwnership() error { - err := o.CallerIsOwner() - if err != nil { - return err +func (o *TransferrableOwnership) DropOwnership() error { + if !helper.PrevRealmIsOwner(o.owner) { + return ErrUnauthorized } o.owner = "" return nil } -// CallerIsOwner checks if the caller of the function is the Realm's owner -func (o *DefaultOwnable) CallerIsOwner() error { - if std.GetOrigCaller() == o.owner { - return nil - } - return ErrUnauthorized -} - -func (o *DefaultOwnable) Owner() std.Address { +func (o *TransferrableOwnership) Owner() std.Address { return o.owner } diff --git a/examples/gno.land/p/demo/ownable/ownable_test.gno b/examples/gno.land/p/demo/ownable/ownable_test.gno index f725795fd47..acbe1555b7b 100644 --- a/examples/gno.land/p/demo/ownable/ownable_test.gno +++ b/examples/gno.land/p/demo/ownable/ownable_test.gno @@ -3,6 +3,8 @@ package ownable import ( "std" "testing" + + "gno.land/p/demo/helper" ) var ( @@ -54,8 +56,7 @@ func TestCallerIsOwner(t *testing.T) { std.TestSetOrigCaller(unauthorizedCaller) - err := o.CallerIsOwner() - if err == nil { + if helper.PrevRealmIsOwner(o.owner) { t.Fatalf("Expected %s to not be owner\n", unauthorizedCaller) } } diff --git a/examples/gno.land/p/demo/pausable/errors.gno b/examples/gno.land/p/demo/pausable/errors.gno new file mode 100644 index 00000000000..3eb50ae37f6 --- /dev/null +++ b/examples/gno.land/p/demo/pausable/errors.gno @@ -0,0 +1,8 @@ +package pausable + +import "errors" + +var ( + ErrUnauthorized = errors.New("unauthorized; caller is not owner") + ErrInvalidAddress = errors.New("new owner address is invalid") +) diff --git a/examples/gno.land/p/demo/pausable/pausable.gno b/examples/gno.land/p/demo/pausable/pausable.gno index f0fcc3d9ee6..3edacf95653 100644 --- a/examples/gno.land/p/demo/pausable/pausable.gno +++ b/examples/gno.land/p/demo/pausable/pausable.gno @@ -1,6 +1,9 @@ package pausable -import "gno.land/p/demo/ownable" +import ( + "gno.land/p/demo/helper" + "gno.land/p/demo/ownable" +) type Pausable struct { ownable.Ownable @@ -30,8 +33,8 @@ func (p Pausable) IsPaused() bool { // Pause sets the state of Pausable to true, meaning all pausable functions are paused func (p *Pausable) Pause() error { - if err := p.CallerIsOwner(); err != nil { - return err + if !helper.PrevRealmIsOwner(p.Owner()) { + return ErrUnauthorized } p.paused = true @@ -40,8 +43,8 @@ func (p *Pausable) Pause() error { // Unpause sets the state of Pausable to false, meaning all pausable functions are resumed func (p *Pausable) Unpause() error { - if err := p.CallerIsOwner(); err != nil { - return err + if !helper.PrevRealmIsOwner(p.Owner()) { + return ErrUnauthorized } p.paused = false From e45723142234f0824869d0f22caaf044c2b2db3a Mon Sep 17 00:00:00 2001 From: linhpn99 Date: Sun, 26 May 2024 19:59:44 +0700 Subject: [PATCH 06/30] update --- examples/gno.land/p/demo/memeland/memeland.gno | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/gno.land/p/demo/memeland/memeland.gno b/examples/gno.land/p/demo/memeland/memeland.gno index b265d804d22..965b68417bd 100644 --- a/examples/gno.land/p/demo/memeland/memeland.gno +++ b/examples/gno.land/p/demo/memeland/memeland.gno @@ -27,15 +27,15 @@ type Post struct { } type Memeland struct { - ownable.Ownable + ownable.TransferrableOwnership Posts []*Post MemeCounter seqid.ID } func NewMemeland() *Memeland { return &Memeland{ - Ownable: ownable.New(), - Posts: make([]*Post, 0), + TransferrableOwnership: ownable.New(), + Posts: make([]*Post, 0), } } From d0c12d84eb9dfd9b9c736b64df01d952db49673f Mon Sep 17 00:00:00 2001 From: linhpn99 Date: Sun, 26 May 2024 20:02:52 +0700 Subject: [PATCH 07/30] wrong name --- examples/gno.land/p/demo/memeland/memeland.gno | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/gno.land/p/demo/memeland/memeland.gno b/examples/gno.land/p/demo/memeland/memeland.gno index 965b68417bd..7c93f69153c 100644 --- a/examples/gno.land/p/demo/memeland/memeland.gno +++ b/examples/gno.land/p/demo/memeland/memeland.gno @@ -27,15 +27,15 @@ type Post struct { } type Memeland struct { - ownable.TransferrableOwnership + ownable.Transferrable Posts []*Post MemeCounter seqid.ID } func NewMemeland() *Memeland { return &Memeland{ - TransferrableOwnership: ownable.New(), - Posts: make([]*Post, 0), + Transferrable: ownable.New(), + Posts: make([]*Post, 0), } } From 00f4ef0ba159af0ee3ecf9af8dff8ca5e8792fa5 Mon Sep 17 00:00:00 2001 From: linhpn99 Date: Sun, 26 May 2024 20:10:55 +0700 Subject: [PATCH 08/30] unused error --- examples/gno.land/p/demo/pausable/errors.gno | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/examples/gno.land/p/demo/pausable/errors.gno b/examples/gno.land/p/demo/pausable/errors.gno index 3eb50ae37f6..acab739cc5b 100644 --- a/examples/gno.land/p/demo/pausable/errors.gno +++ b/examples/gno.land/p/demo/pausable/errors.gno @@ -2,7 +2,4 @@ package pausable import "errors" -var ( - ErrUnauthorized = errors.New("unauthorized; caller is not owner") - ErrInvalidAddress = errors.New("new owner address is invalid") -) +var ErrUnauthorized = errors.New("unauthorized; caller is not owner") From 0163f8d4a02803f1949de335609df530ccea154d Mon Sep 17 00:00:00 2001 From: linhpn99 Date: Sun, 26 May 2024 20:19:11 +0700 Subject: [PATCH 09/30] make tidy --- examples/gno.land/p/demo/helper/gno.mod | 2 +- examples/gno.land/p/demo/memeland/gno.mod | 1 + examples/gno.land/p/demo/ownable/gno.mod | 2 ++ examples/gno.land/p/demo/pausable/gno.mod | 5 ++++- 4 files changed, 8 insertions(+), 2 deletions(-) diff --git a/examples/gno.land/p/demo/helper/gno.mod b/examples/gno.land/p/demo/helper/gno.mod index 7b49085db57..5a9cd727cf6 100644 --- a/examples/gno.land/p/demo/helper/gno.mod +++ b/examples/gno.land/p/demo/helper/gno.mod @@ -1 +1 @@ -module gno.land/p/demo/helper \ No newline at end of file +module gno.land/p/demo/helper diff --git a/examples/gno.land/p/demo/memeland/gno.mod b/examples/gno.land/p/demo/memeland/gno.mod index b1409c7db6d..2c36af432e2 100644 --- a/examples/gno.land/p/demo/memeland/gno.mod +++ b/examples/gno.land/p/demo/memeland/gno.mod @@ -2,6 +2,7 @@ module gno.land/p/demo/memeland require ( gno.land/p/demo/avl v0.0.0-latest + gno.land/p/demo/helper v0.0.0-latest gno.land/p/demo/ownable v0.0.0-latest gno.land/p/demo/seqid v0.0.0-latest gno.land/p/demo/testutils v0.0.0-latest diff --git a/examples/gno.land/p/demo/ownable/gno.mod b/examples/gno.land/p/demo/ownable/gno.mod index 9a9abb1e661..a8cca29b7f6 100644 --- a/examples/gno.land/p/demo/ownable/gno.mod +++ b/examples/gno.land/p/demo/ownable/gno.mod @@ -1 +1,3 @@ module gno.land/p/demo/ownable + +require gno.land/p/demo/helper v0.0.0-latest diff --git a/examples/gno.land/p/demo/pausable/gno.mod b/examples/gno.land/p/demo/pausable/gno.mod index 08c7a4f7e5f..3f4801ba2a8 100644 --- a/examples/gno.land/p/demo/pausable/gno.mod +++ b/examples/gno.land/p/demo/pausable/gno.mod @@ -1,3 +1,6 @@ module gno.land/p/demo/pausable -require gno.land/p/demo/ownable v0.0.0-latest +require ( + gno.land/p/demo/helper v0.0.0-latest + gno.land/p/demo/ownable v0.0.0-latest +) From 22b8e27281adb15b00ffbb2111bc4f2fee928236 Mon Sep 17 00:00:00 2001 From: linhpn99 Date: Sun, 26 May 2024 20:23:16 +0700 Subject: [PATCH 10/30] make tidy again --- examples/gno.land/p/demo/pausable/gno.mod | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/gno.land/p/demo/pausable/gno.mod b/examples/gno.land/p/demo/pausable/gno.mod index 3f4801ba2a8..b96c8358797 100644 --- a/examples/gno.land/p/demo/pausable/gno.mod +++ b/examples/gno.land/p/demo/pausable/gno.mod @@ -1,6 +1,6 @@ module gno.land/p/demo/pausable require ( - gno.land/p/demo/helper v0.0.0-latest - gno.land/p/demo/ownable v0.0.0-latest + gno.land/p/demo/helper v0.0.0-latest + gno.land/p/demo/ownable v0.0.0-latest ) From c6ef1202fe8acc948b8ca911da93020a1cc24bbb Mon Sep 17 00:00:00 2001 From: linhpn99 Date: Mon, 27 May 2024 22:42:39 +0700 Subject: [PATCH 11/30] remove helper pkg --- examples/gno.land/p/demo/memeland/errors.gno | 5 ----- examples/gno.land/p/demo/memeland/gno.mod | 1 - examples/gno.land/p/demo/memeland/helper.gno | 9 +++++++++ examples/gno.land/p/demo/memeland/memeland.gno | 11 +++++------ examples/gno.land/p/demo/memeland/memeland_test.gno | 10 +++++----- 5 files changed, 19 insertions(+), 17 deletions(-) delete mode 100644 examples/gno.land/p/demo/memeland/errors.gno create mode 100644 examples/gno.land/p/demo/memeland/helper.gno diff --git a/examples/gno.land/p/demo/memeland/errors.gno b/examples/gno.land/p/demo/memeland/errors.gno deleted file mode 100644 index 84e1dbdd1cb..00000000000 --- a/examples/gno.land/p/demo/memeland/errors.gno +++ /dev/null @@ -1,5 +0,0 @@ -package memeland - -import "errors" - -var ErrUnauthorized = errors.New("unauthorized; caller is not owner") diff --git a/examples/gno.land/p/demo/memeland/gno.mod b/examples/gno.land/p/demo/memeland/gno.mod index 2c36af432e2..b1409c7db6d 100644 --- a/examples/gno.land/p/demo/memeland/gno.mod +++ b/examples/gno.land/p/demo/memeland/gno.mod @@ -2,7 +2,6 @@ module gno.land/p/demo/memeland require ( gno.land/p/demo/avl v0.0.0-latest - gno.land/p/demo/helper v0.0.0-latest gno.land/p/demo/ownable v0.0.0-latest gno.land/p/demo/seqid v0.0.0-latest gno.land/p/demo/testutils v0.0.0-latest diff --git a/examples/gno.land/p/demo/memeland/helper.gno b/examples/gno.land/p/demo/memeland/helper.gno new file mode 100644 index 00000000000..1cf00452f35 --- /dev/null +++ b/examples/gno.land/p/demo/memeland/helper.gno @@ -0,0 +1,9 @@ +package memeland + +import ( + "std" +) + +func prevRealmIsOwner(addr std.Address) bool { + return std.PrevRealm().Addr() == addr +} diff --git a/examples/gno.land/p/demo/memeland/memeland.gno b/examples/gno.land/p/demo/memeland/memeland.gno index 7c93f69153c..a3314acd3e5 100644 --- a/examples/gno.land/p/demo/memeland/memeland.gno +++ b/examples/gno.land/p/demo/memeland/memeland.gno @@ -8,7 +8,6 @@ import ( "time" "gno.land/p/demo/avl" - "gno.land/p/demo/helper" "gno.land/p/demo/ownable" "gno.land/p/demo/seqid" ) @@ -27,15 +26,15 @@ type Post struct { } type Memeland struct { - ownable.Transferrable + ownable.Ownable Posts []*Post MemeCounter seqid.ID } func NewMemeland() *Memeland { return &Memeland{ - Transferrable: ownable.New(), - Posts: make([]*Post, 0), + Ownable: ownable.New(), + Posts: make([]*Post, 0), } } @@ -161,8 +160,8 @@ func (m *Memeland) RemovePost(id string) string { panic("id cannot be empty") } - if !helper.PrevRealmIsOwner(m.Owner()) { - panic(ErrUnauthorized) + if !prevRealmIsOwner(m.Owner()) { + panic("unauthorized; address is not owner") } for i, post := range m.Posts { diff --git a/examples/gno.land/p/demo/memeland/memeland_test.gno b/examples/gno.land/p/demo/memeland/memeland_test.gno index 76c44327993..f8a1cdcdc8b 100644 --- a/examples/gno.land/p/demo/memeland/memeland_test.gno +++ b/examples/gno.land/p/demo/memeland/memeland_test.gno @@ -130,8 +130,8 @@ func TestGetPostsInRangeByUpvote(t *testing.T) { m.Upvote(id1) m.Upvote(id2) - // Change caller so avoid double upvote panic - std.TestSetOrigCaller(testutils.TestAddress("alice")) + // Change prevAddr so avoid double upvote panic + std.TestSetPrevAddr(testutils.TestAddress("alice")) m.Upvote(id1) // Final upvote count: @@ -260,21 +260,21 @@ func TestUpvote(t *testing.T) { func TestDelete(t *testing.T) { alice := testutils.TestAddress("alice") - std.TestSetOrigCaller(alice) + std.TestSetPrevAddr(alice) // Alice is admin m := NewMemeland() // Set caller to Bob bob := testutils.TestAddress("bob") - std.TestSetOrigCaller(bob) + std.TestSetPrevAddr(bob) // Bob adds post to Memeland now := time.Now() postID := m.PostMeme("Meme #1", now.Unix()) // Alice removes Bob's post - std.TestSetOrigCaller(alice) + std.TestSetPrevAddr(alice) id := m.RemovePost(postID) if id != postID { From b04aadcb8562d9488649ac38156ce64cf862351d Mon Sep 17 00:00:00 2001 From: linhpn99 Date: Mon, 27 May 2024 22:47:57 +0700 Subject: [PATCH 12/30] owner to transferrable --- examples/gno.land/p/demo/memeland/memeland.gno | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/gno.land/p/demo/memeland/memeland.gno b/examples/gno.land/p/demo/memeland/memeland.gno index a3314acd3e5..b348a464af8 100644 --- a/examples/gno.land/p/demo/memeland/memeland.gno +++ b/examples/gno.land/p/demo/memeland/memeland.gno @@ -26,15 +26,15 @@ type Post struct { } type Memeland struct { - ownable.Ownable + ownable.Transferrable Posts []*Post MemeCounter seqid.ID } func NewMemeland() *Memeland { return &Memeland{ - Ownable: ownable.New(), - Posts: make([]*Post, 0), + Transferrable: ownable.New(), + Posts: make([]*Post, 0), } } From 3b0a77caa391c37fc1055c40c44e3a6d12f4ed3d Mon Sep 17 00:00:00 2001 From: linhpn99 Date: Mon, 27 May 2024 22:57:38 +0700 Subject: [PATCH 13/30] tmp --- examples/gno.land/p/demo/helper/gno.mod | 1 - examples/gno.land/p/demo/helper/helper.gno | 10 ----- examples/gno.land/p/demo/ownable/errors.gno | 2 +- examples/gno.land/p/demo/ownable/gno.mod | 2 - examples/gno.land/p/demo/ownable/helper.gno | 9 ++++ examples/gno.land/p/demo/ownable/ownable.gno | 8 ++-- .../gno.land/p/demo/ownable/ownable_test.gno | 42 +++++++++---------- examples/gno.land/p/demo/pausable/errors.gno | 2 +- examples/gno.land/p/demo/pausable/gno.mod | 5 +-- examples/gno.land/p/demo/pausable/helper.gno | 9 ++++ .../gno.land/p/demo/pausable/pausable.gno | 5 +-- .../p/demo/pausable/pausable_test.gno | 24 +++++------ 12 files changed, 58 insertions(+), 61 deletions(-) delete mode 100644 examples/gno.land/p/demo/helper/gno.mod delete mode 100644 examples/gno.land/p/demo/helper/helper.gno create mode 100644 examples/gno.land/p/demo/ownable/helper.gno create mode 100644 examples/gno.land/p/demo/pausable/helper.gno diff --git a/examples/gno.land/p/demo/helper/gno.mod b/examples/gno.land/p/demo/helper/gno.mod deleted file mode 100644 index 5a9cd727cf6..00000000000 --- a/examples/gno.land/p/demo/helper/gno.mod +++ /dev/null @@ -1 +0,0 @@ -module gno.land/p/demo/helper diff --git a/examples/gno.land/p/demo/helper/helper.gno b/examples/gno.land/p/demo/helper/helper.gno deleted file mode 100644 index 8c4447c3282..00000000000 --- a/examples/gno.land/p/demo/helper/helper.gno +++ /dev/null @@ -1,10 +0,0 @@ -package helper - -import ( - "std" -) - -// PrevRealmIsOwner checks if the caller of the function is the Realm's owner -func PrevRealmIsOwner(owner std.Address) bool { - return std.GetOrigCaller() == owner -} diff --git a/examples/gno.land/p/demo/ownable/errors.gno b/examples/gno.land/p/demo/ownable/errors.gno index ffbf6ab3f6f..406fef15a0a 100644 --- a/examples/gno.land/p/demo/ownable/errors.gno +++ b/examples/gno.land/p/demo/ownable/errors.gno @@ -3,6 +3,6 @@ package ownable import "errors" var ( - ErrUnauthorized = errors.New("unauthorized; caller is not owner") + ErrUnauthorized = errors.New("unauthorized; address is not owner") ErrInvalidAddress = errors.New("new owner address is invalid") ) diff --git a/examples/gno.land/p/demo/ownable/gno.mod b/examples/gno.land/p/demo/ownable/gno.mod index a8cca29b7f6..9a9abb1e661 100644 --- a/examples/gno.land/p/demo/ownable/gno.mod +++ b/examples/gno.land/p/demo/ownable/gno.mod @@ -1,3 +1 @@ module gno.land/p/demo/ownable - -require gno.land/p/demo/helper v0.0.0-latest diff --git a/examples/gno.land/p/demo/ownable/helper.gno b/examples/gno.land/p/demo/ownable/helper.gno new file mode 100644 index 00000000000..00f9e0da5af --- /dev/null +++ b/examples/gno.land/p/demo/ownable/helper.gno @@ -0,0 +1,9 @@ +package ownable + +import ( + "std" +) + +func prevRealmIsOwner(addr std.Address) bool { + return std.PrevRealm().Addr() == addr +} diff --git a/examples/gno.land/p/demo/ownable/ownable.gno b/examples/gno.land/p/demo/ownable/ownable.gno index 9f67ffee8ec..da1d6b8b07d 100644 --- a/examples/gno.land/p/demo/ownable/ownable.gno +++ b/examples/gno.land/p/demo/ownable/ownable.gno @@ -2,8 +2,6 @@ package ownable import ( "std" - - "gno.land/p/demo/helper" ) // Ownable defines an interface that requires a method to get the owner's address @@ -34,13 +32,13 @@ var ( func New() *TransferrableOwnership { return &TransferrableOwnership{ - owner: std.GetOrigCaller(), + owner: std.PrevRealm().Addr(), } } // TransferOwnership transfers ownership of the Ownable struct to a new address func (o *TransferrableOwnership) TransferOwnership(newOwner std.Address) error { - if !helper.PrevRealmIsOwner(o.owner) { + if !prevRealmIsOwner(o.owner) { return ErrUnauthorized } @@ -56,7 +54,7 @@ func (o *TransferrableOwnership) TransferOwnership(newOwner std.Address) error { // Top-level usage: disables all only-owner actions/functions, // Embedded usage: behaves like a burn functionality, removing the owner from the struct func (o *TransferrableOwnership) DropOwnership() error { - if !helper.PrevRealmIsOwner(o.owner) { + if !prevRealmIsOwner(o.owner) { return ErrUnauthorized } diff --git a/examples/gno.land/p/demo/ownable/ownable_test.gno b/examples/gno.land/p/demo/ownable/ownable_test.gno index acbe1555b7b..197009232ec 100644 --- a/examples/gno.land/p/demo/ownable/ownable_test.gno +++ b/examples/gno.land/p/demo/ownable/ownable_test.gno @@ -3,66 +3,64 @@ package ownable import ( "std" "testing" - - "gno.land/p/demo/helper" ) var ( - firstCaller = std.Address("g1l9aypkr8xfvs82zeux486ddzec88ty69lue9de") - secondCaller = std.Address("g127jydsh6cms3lrtdenydxsckh23a8d6emqcvfa") + firstAddr = std.Address("g1l9aypkr8xfvs82zeux486ddzec88ty69lue9de") + secondAddr = std.Address("g127jydsh6cms3lrtdenydxsckh23a8d6emqcvfa") ) func TestNew(t *testing.T) { - std.TestSetOrigCaller(firstCaller) + std.TestSetPrevAddr(firstAddr) result := New() - if firstCaller != result.owner { - t.Fatalf("Expected %s, got: %s\n", firstCaller, result.owner) + if firstAddr != result.owner { + t.Fatalf("Expected %s, got: %s\n", firstAddr, result.owner) } } func TestOwner(t *testing.T) { - std.TestSetOrigCaller(firstCaller) + std.TestSetPrevAddr(firstAddr) result := New() resultOwner := result.Owner() - expected := firstCaller + expected := firstAddr if resultOwner != expected { t.Fatalf("Expected %s, got: %s\n", expected, result) } } func TestTransferOwnership(t *testing.T) { - std.TestSetOrigCaller(firstCaller) + std.TestSetPrevAddr(firstAddr) o := New() - err := o.TransferOwnership(secondCaller) + err := o.TransferOwnership(secondAddr) if err != nil { t.Fatalf("TransferOwnership failed, %v", err) } result := o.Owner() - if secondCaller != result { - t.Fatalf("Expected: %s, got: %s\n", secondCaller, result) + if secondAddr != result { + t.Fatalf("Expected: %s, got: %s\n", secondAddr, result) } } func TestCallerIsOwner(t *testing.T) { - std.TestSetOrigCaller(firstCaller) + std.TestSetPrevAddr(firstAddr) o := New() - unauthorizedCaller := secondCaller + unauthorizedCaller := secondAddr - std.TestSetOrigCaller(unauthorizedCaller) + std.TestSetPrevAddr(unauthorizedCaller) - if helper.PrevRealmIsOwner(o.owner) { + if prevRealmIsOwner(o.owner) { t.Fatalf("Expected %s to not be owner\n", unauthorizedCaller) } } func TestDropOwnership(t *testing.T) { - std.TestSetOrigCaller(firstCaller) + std.TestSetPrevAddr(firstAddr) o := New() @@ -80,13 +78,13 @@ func TestDropOwnership(t *testing.T) { // Errors func TestErrUnauthorized(t *testing.T) { - std.TestSetOrigCaller(firstCaller) + std.TestSetPrevAddr(firstAddr) o := New() - std.TestSetOrigCaller(secondCaller) + std.TestSetPrevAddr(secondAddr) - err := o.TransferOwnership(firstCaller) + err := o.TransferOwnership(firstAddr) if err != ErrUnauthorized { t.Fatalf("Should've been ErrUnauthorized, was %v", err) } @@ -98,7 +96,7 @@ func TestErrUnauthorized(t *testing.T) { } func TestErrInvalidAddress(t *testing.T) { - std.TestSetOrigCaller(firstCaller) + std.TestSetPrevAddr(firstAddr) o := New() diff --git a/examples/gno.land/p/demo/pausable/errors.gno b/examples/gno.land/p/demo/pausable/errors.gno index acab739cc5b..bcb7a6875d8 100644 --- a/examples/gno.land/p/demo/pausable/errors.gno +++ b/examples/gno.land/p/demo/pausable/errors.gno @@ -2,4 +2,4 @@ package pausable import "errors" -var ErrUnauthorized = errors.New("unauthorized; caller is not owner") +var ErrUnauthorized = errors.New("unauthorized; address is not owner") diff --git a/examples/gno.land/p/demo/pausable/gno.mod b/examples/gno.land/p/demo/pausable/gno.mod index b96c8358797..08c7a4f7e5f 100644 --- a/examples/gno.land/p/demo/pausable/gno.mod +++ b/examples/gno.land/p/demo/pausable/gno.mod @@ -1,6 +1,3 @@ module gno.land/p/demo/pausable -require ( - gno.land/p/demo/helper v0.0.0-latest - gno.land/p/demo/ownable v0.0.0-latest -) +require gno.land/p/demo/ownable v0.0.0-latest diff --git a/examples/gno.land/p/demo/pausable/helper.gno b/examples/gno.land/p/demo/pausable/helper.gno new file mode 100644 index 00000000000..c6173bcfbb5 --- /dev/null +++ b/examples/gno.land/p/demo/pausable/helper.gno @@ -0,0 +1,9 @@ +package pausable + +import ( + "std" +) + +func prevRealmIsOwner(addr std.Address) bool { + return std.PrevRealm().Addr() == addr +} diff --git a/examples/gno.land/p/demo/pausable/pausable.gno b/examples/gno.land/p/demo/pausable/pausable.gno index 3edacf95653..85a35e897cc 100644 --- a/examples/gno.land/p/demo/pausable/pausable.gno +++ b/examples/gno.land/p/demo/pausable/pausable.gno @@ -1,7 +1,6 @@ package pausable import ( - "gno.land/p/demo/helper" "gno.land/p/demo/ownable" ) @@ -33,7 +32,7 @@ func (p Pausable) IsPaused() bool { // Pause sets the state of Pausable to true, meaning all pausable functions are paused func (p *Pausable) Pause() error { - if !helper.PrevRealmIsOwner(p.Owner()) { + if !prevRealmIsOwner(p.Owner()) { return ErrUnauthorized } @@ -43,7 +42,7 @@ func (p *Pausable) Pause() error { // Unpause sets the state of Pausable to false, meaning all pausable functions are resumed func (p *Pausable) Unpause() error { - if !helper.PrevRealmIsOwner(p.Owner()) { + if !prevRealmIsOwner(p.Owner()) { return ErrUnauthorized } diff --git a/examples/gno.land/p/demo/pausable/pausable_test.gno b/examples/gno.land/p/demo/pausable/pausable_test.gno index cc95c457573..59db7d5fa5b 100644 --- a/examples/gno.land/p/demo/pausable/pausable_test.gno +++ b/examples/gno.land/p/demo/pausable/pausable_test.gno @@ -8,12 +8,12 @@ import ( ) var ( - firstCaller = std.Address("g1l9aypkr8xfvs82zeux486ddzec88ty69lue9de") - secondCaller = std.Address("g127jydsh6cms3lrtdenydxsckh23a8d6emqcvfa") + firstAddr = std.Address("g1l9aypkr8xfvs82zeux486ddzec88ty69lue9de") + secondAddr = std.Address("g127jydsh6cms3lrtdenydxsckh23a8d6emqcvfa") ) func TestNew(t *testing.T) { - std.TestSetOrigCaller(firstCaller) + std.TestSetOrigCaller(firstAddr) result := New() @@ -21,25 +21,25 @@ func TestNew(t *testing.T) { t.Fatalf("Expected result to be unpaused, got %t\n", result.paused) } - if result.Owner() != firstCaller { - t.Fatalf("Expected %s, got %s\n", firstCaller, result.Owner()) + if result.Owner() != firstAddr { + t.Fatalf("Expected %s, got %s\n", firstAddr, result.Owner()) } } func TestNewFromOwnable(t *testing.T) { - std.TestSetOrigCaller(firstCaller) + std.TestSetOrigCaller(firstAddr) o := ownable.New() - std.TestSetOrigCaller(secondCaller) + std.TestSetOrigCaller(secondAddr) result := NewFromOwnable(o) - if result.Owner() != firstCaller { - t.Fatalf("Expected %s, got %s\n", firstCaller, result.Owner()) + if result.Owner() != firstAddr { + t.Fatalf("Expected %s, got %s\n", firstAddr, result.Owner()) } } func TestSetUnpaused(t *testing.T) { - std.TestSetOrigCaller(firstCaller) + std.TestSetOrigCaller(firstAddr) result := New() result.Unpause() @@ -50,7 +50,7 @@ func TestSetUnpaused(t *testing.T) { } func TestSetPaused(t *testing.T) { - std.TestSetOrigCaller(firstCaller) + std.TestSetOrigCaller(firstAddr) result := New() result.Pause() @@ -61,7 +61,7 @@ func TestSetPaused(t *testing.T) { } func TestIsPaused(t *testing.T) { - std.TestSetOrigCaller(firstCaller) + std.TestSetOrigCaller(firstAddr) result := New() From 8bd5ec9f5b49d4522bed9fff802c5c62328d1e95 Mon Sep 17 00:00:00 2001 From: linhpn99 Date: Mon, 27 May 2024 22:59:36 +0700 Subject: [PATCH 14/30] tmp --- examples/gno.land/p/demo/memeland/memeland_test.gno | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/gno.land/p/demo/memeland/memeland_test.gno b/examples/gno.land/p/demo/memeland/memeland_test.gno index f8a1cdcdc8b..c58c76cc7f8 100644 --- a/examples/gno.land/p/demo/memeland/memeland_test.gno +++ b/examples/gno.land/p/demo/memeland/memeland_test.gno @@ -130,7 +130,7 @@ func TestGetPostsInRangeByUpvote(t *testing.T) { m.Upvote(id1) m.Upvote(id2) - // Change prevAddr so avoid double upvote panic + // Change caller so avoid double upvote panic std.TestSetPrevAddr(testutils.TestAddress("alice")) m.Upvote(id1) From 2249f42a616a7acd0c179227afbf6ba9a4eb7f04 Mon Sep 17 00:00:00 2001 From: linhpn99 Date: Mon, 27 May 2024 23:07:51 +0700 Subject: [PATCH 15/30] change to TestSetOrigCaller --- examples/gno.land/p/demo/memeland/memeland_test.gno | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/gno.land/p/demo/memeland/memeland_test.gno b/examples/gno.land/p/demo/memeland/memeland_test.gno index c58c76cc7f8..76c44327993 100644 --- a/examples/gno.land/p/demo/memeland/memeland_test.gno +++ b/examples/gno.land/p/demo/memeland/memeland_test.gno @@ -131,7 +131,7 @@ func TestGetPostsInRangeByUpvote(t *testing.T) { m.Upvote(id2) // Change caller so avoid double upvote panic - std.TestSetPrevAddr(testutils.TestAddress("alice")) + std.TestSetOrigCaller(testutils.TestAddress("alice")) m.Upvote(id1) // Final upvote count: @@ -260,21 +260,21 @@ func TestUpvote(t *testing.T) { func TestDelete(t *testing.T) { alice := testutils.TestAddress("alice") - std.TestSetPrevAddr(alice) + std.TestSetOrigCaller(alice) // Alice is admin m := NewMemeland() // Set caller to Bob bob := testutils.TestAddress("bob") - std.TestSetPrevAddr(bob) + std.TestSetOrigCaller(bob) // Bob adds post to Memeland now := time.Now() postID := m.PostMeme("Meme #1", now.Unix()) // Alice removes Bob's post - std.TestSetPrevAddr(alice) + std.TestSetOrigCaller(alice) id := m.RemovePost(postID) if id != postID { From ce717f68757bed6bde5cd9d00be2890e10c71857 Mon Sep 17 00:00:00 2001 From: linhpn99 Date: Thu, 30 May 2024 14:54:17 +0700 Subject: [PATCH 16/30] use TestSetRealm instead --- .../gno.land/p/demo/ownable/ownable_test.gno | 23 ++++++++++--------- .../p/demo/pausable/pausable_test.gno | 16 ++++++------- 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/examples/gno.land/p/demo/ownable/ownable_test.gno b/examples/gno.land/p/demo/ownable/ownable_test.gno index 197009232ec..0a9a7d3e551 100644 --- a/examples/gno.land/p/demo/ownable/ownable_test.gno +++ b/examples/gno.land/p/demo/ownable/ownable_test.gno @@ -6,12 +6,12 @@ import ( ) var ( - firstAddr = std.Address("g1l9aypkr8xfvs82zeux486ddzec88ty69lue9de") - secondAddr = std.Address("g127jydsh6cms3lrtdenydxsckh23a8d6emqcvfa") + firstAddr = std.Address("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm") + secondAddr = std.Address("g1r0mlnkc05z0fv49km99z60qnp95tengyqfdr02") ) func TestNew(t *testing.T) { - std.TestSetPrevAddr(firstAddr) + std.TestSetRealm(std.NewUserRealm(firstAddr)) result := New() if firstAddr != result.owner { @@ -20,7 +20,7 @@ func TestNew(t *testing.T) { } func TestOwner(t *testing.T) { - std.TestSetPrevAddr(firstAddr) + std.TestSetRealm(std.NewUserRealm(firstAddr)) result := New() resultOwner := result.Owner() @@ -32,7 +32,7 @@ func TestOwner(t *testing.T) { } func TestTransferOwnership(t *testing.T) { - std.TestSetPrevAddr(firstAddr) + std.TestSetRealm(std.NewUserRealm(firstAddr)) o := New() err := o.TransferOwnership(secondAddr) @@ -47,12 +47,13 @@ func TestTransferOwnership(t *testing.T) { } func TestCallerIsOwner(t *testing.T) { - std.TestSetPrevAddr(firstAddr) + std.TestSetOrigCaller(firstAddr) o := New() + unauthorizedCaller := secondAddr - std.TestSetPrevAddr(unauthorizedCaller) + std.TestSetOrigCaller(unauthorizedCaller) if prevRealmIsOwner(o.owner) { t.Fatalf("Expected %s to not be owner\n", unauthorizedCaller) @@ -60,7 +61,7 @@ func TestCallerIsOwner(t *testing.T) { } func TestDropOwnership(t *testing.T) { - std.TestSetPrevAddr(firstAddr) + std.TestSetRealm(std.NewUserRealm(firstAddr)) o := New() @@ -78,11 +79,11 @@ func TestDropOwnership(t *testing.T) { // Errors func TestErrUnauthorized(t *testing.T) { - std.TestSetPrevAddr(firstAddr) + std.TestSetOrigCaller(firstAddr) o := New() - std.TestSetPrevAddr(secondAddr) + std.TestSetOrigCaller(secondAddr) err := o.TransferOwnership(firstAddr) if err != ErrUnauthorized { @@ -96,7 +97,7 @@ func TestErrUnauthorized(t *testing.T) { } func TestErrInvalidAddress(t *testing.T) { - std.TestSetPrevAddr(firstAddr) + std.TestSetRealm(std.NewUserRealm(firstAddr)) o := New() diff --git a/examples/gno.land/p/demo/pausable/pausable_test.gno b/examples/gno.land/p/demo/pausable/pausable_test.gno index 59db7d5fa5b..943b0a61e7f 100644 --- a/examples/gno.land/p/demo/pausable/pausable_test.gno +++ b/examples/gno.land/p/demo/pausable/pausable_test.gno @@ -8,12 +8,12 @@ import ( ) var ( - firstAddr = std.Address("g1l9aypkr8xfvs82zeux486ddzec88ty69lue9de") - secondAddr = std.Address("g127jydsh6cms3lrtdenydxsckh23a8d6emqcvfa") + firstAddr = std.Address("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm") + secondAddr = std.Address("g1r0mlnkc05z0fv49km99z60qnp95tengyqfdr02") ) func TestNew(t *testing.T) { - std.TestSetOrigCaller(firstAddr) + std.TestSetRealm(std.NewUserRealm(firstAddr)) result := New() @@ -27,10 +27,10 @@ func TestNew(t *testing.T) { } func TestNewFromOwnable(t *testing.T) { - std.TestSetOrigCaller(firstAddr) + std.TestSetRealm(std.NewUserRealm(firstAddr)) o := ownable.New() - std.TestSetOrigCaller(secondAddr) + std.TestSetRealm(std.NewUserRealm(secondAddr)) result := NewFromOwnable(o) if result.Owner() != firstAddr { @@ -39,7 +39,7 @@ func TestNewFromOwnable(t *testing.T) { } func TestSetUnpaused(t *testing.T) { - std.TestSetOrigCaller(firstAddr) + std.TestSetRealm(std.NewUserRealm(firstAddr)) result := New() result.Unpause() @@ -50,7 +50,7 @@ func TestSetUnpaused(t *testing.T) { } func TestSetPaused(t *testing.T) { - std.TestSetOrigCaller(firstAddr) + std.TestSetRealm(std.NewUserRealm(firstAddr)) result := New() result.Pause() @@ -61,7 +61,7 @@ func TestSetPaused(t *testing.T) { } func TestIsPaused(t *testing.T) { - std.TestSetOrigCaller(firstAddr) + std.TestSetRealm(std.NewUserRealm(firstAddr)) result := New() From 3c459fcb02ccf3d637042a9c684e55c700438eea Mon Sep 17 00:00:00 2001 From: linhpn99 Date: Wed, 12 Jun 2024 02:10:00 +0700 Subject: [PATCH 17/30] refactor code after manfred's review --- examples/gno.land/p/demo/memeland/helper.gno | 9 ----- .../gno.land/p/demo/memeland/memeland.gno | 14 ++++--- examples/gno.land/p/demo/ownable/errors.gno | 2 +- examples/gno.land/p/demo/ownable/helper.gno | 9 ----- examples/gno.land/p/demo/ownable/ownable.gno | 33 +++++++++------- .../gno.land/p/demo/ownable/ownable_test.gno | 38 +++++++++---------- 6 files changed, 48 insertions(+), 57 deletions(-) delete mode 100644 examples/gno.land/p/demo/memeland/helper.gno delete mode 100644 examples/gno.land/p/demo/ownable/helper.gno diff --git a/examples/gno.land/p/demo/memeland/helper.gno b/examples/gno.land/p/demo/memeland/helper.gno deleted file mode 100644 index 1cf00452f35..00000000000 --- a/examples/gno.land/p/demo/memeland/helper.gno +++ /dev/null @@ -1,9 +0,0 @@ -package memeland - -import ( - "std" -) - -func prevRealmIsOwner(addr std.Address) bool { - return std.PrevRealm().Addr() == addr -} diff --git a/examples/gno.land/p/demo/memeland/memeland.gno b/examples/gno.land/p/demo/memeland/memeland.gno index b348a464af8..db78a86a756 100644 --- a/examples/gno.land/p/demo/memeland/memeland.gno +++ b/examples/gno.land/p/demo/memeland/memeland.gno @@ -26,15 +26,15 @@ type Post struct { } type Memeland struct { - ownable.Transferrable + ownable.Ownable Posts []*Post MemeCounter seqid.ID } func NewMemeland() *Memeland { return &Memeland{ - Transferrable: ownable.New(), - Posts: make([]*Post, 0), + Ownable: ownable.New(), + Posts: make([]*Post, 0), } } @@ -160,8 +160,8 @@ func (m *Memeland) RemovePost(id string) string { panic("id cannot be empty") } - if !prevRealmIsOwner(m.Owner()) { - panic("unauthorized; address is not owner") + if !callerIsOwner(m.Owner()) { + panic("unauthorized; caller is not owner") } for i, post := range m.Posts { @@ -238,3 +238,7 @@ func (p PostSorter) Swap(i, j int) { func (p PostSorter) Less(i, j int) bool { return p.LessF(i, j) } + +func callerIsOwner(addr std.Address) bool { + return std.PrevRealm().Addr() == addr +} diff --git a/examples/gno.land/p/demo/ownable/errors.gno b/examples/gno.land/p/demo/ownable/errors.gno index 406fef15a0a..ffbf6ab3f6f 100644 --- a/examples/gno.land/p/demo/ownable/errors.gno +++ b/examples/gno.land/p/demo/ownable/errors.gno @@ -3,6 +3,6 @@ package ownable import "errors" var ( - ErrUnauthorized = errors.New("unauthorized; address is not owner") + ErrUnauthorized = errors.New("unauthorized; caller is not owner") ErrInvalidAddress = errors.New("new owner address is invalid") ) diff --git a/examples/gno.land/p/demo/ownable/helper.gno b/examples/gno.land/p/demo/ownable/helper.gno deleted file mode 100644 index 00f9e0da5af..00000000000 --- a/examples/gno.land/p/demo/ownable/helper.gno +++ /dev/null @@ -1,9 +0,0 @@ -package ownable - -import ( - "std" -) - -func prevRealmIsOwner(addr std.Address) bool { - return std.PrevRealm().Addr() == addr -} diff --git a/examples/gno.land/p/demo/ownable/ownable.gno b/examples/gno.land/p/demo/ownable/ownable.gno index da1d6b8b07d..de188a338bc 100644 --- a/examples/gno.land/p/demo/ownable/ownable.gno +++ b/examples/gno.land/p/demo/ownable/ownable.gno @@ -4,12 +4,13 @@ import ( "std" ) -// Ownable defines an interface that requires a method to get the owner's address +// Ownable is meant to be used as a top-level object to make your contract ownable OR +// being embedded in a Gno object to manage per-object ownership. type Ownable interface { Owner() std.Address } -// Transferrable embeds Ownable, indicating that an object can transfer and drop an ownership +// Transferrable embeds Ownable, indicating that the owner has the ability to transfer or drop ownership. type Transferrable interface { Ownable @@ -17,28 +18,28 @@ type Transferrable interface { DropOwnership() error } -// TransferrableOwnership provides a basic implementation of ownership functionality +// transferrableOwnership provides a basic implementation of ownership functionality // It can be used as a top-level object to make a contract ownable or embedded within // another object to manage per-object ownership. -type TransferrableOwnership struct { +type transferrableOwnership struct { owner std.Address } -// Ensure that TransferrableOwnership implements the Ownable and Transferrable interfaces +// Ensure that transferrableOwnership implements the Ownable and Transferrable interfaces var ( - _ Ownable = (*TransferrableOwnership)(nil) - _ Transferrable = (*TransferrableOwnership)(nil) + _ Ownable = (*transferrableOwnership)(nil) + _ Transferrable = (*transferrableOwnership)(nil) ) -func New() *TransferrableOwnership { - return &TransferrableOwnership{ +func New() *transferrableOwnership { + return &transferrableOwnership{ owner: std.PrevRealm().Addr(), } } // TransferOwnership transfers ownership of the Ownable struct to a new address -func (o *TransferrableOwnership) TransferOwnership(newOwner std.Address) error { - if !prevRealmIsOwner(o.owner) { +func (o *transferrableOwnership) TransferOwnership(newOwner std.Address) error { + if !callerIsOwner(o.owner) { return ErrUnauthorized } @@ -53,8 +54,8 @@ func (o *TransferrableOwnership) TransferOwnership(newOwner std.Address) error { // DropOwnership removes the owner, effectively disabling any owner-related actions // Top-level usage: disables all only-owner actions/functions, // Embedded usage: behaves like a burn functionality, removing the owner from the struct -func (o *TransferrableOwnership) DropOwnership() error { - if !prevRealmIsOwner(o.owner) { +func (o *transferrableOwnership) DropOwnership() error { + if !callerIsOwner(o.owner) { return ErrUnauthorized } @@ -62,6 +63,10 @@ func (o *TransferrableOwnership) DropOwnership() error { return nil } -func (o *TransferrableOwnership) Owner() std.Address { +func (o *transferrableOwnership) Owner() std.Address { return o.owner } + +func callerIsOwner(addr std.Address) bool { + return std.PrevRealm().Addr() == addr +} diff --git a/examples/gno.land/p/demo/ownable/ownable_test.gno b/examples/gno.land/p/demo/ownable/ownable_test.gno index 0a9a7d3e551..c9d5c86b2c0 100644 --- a/examples/gno.land/p/demo/ownable/ownable_test.gno +++ b/examples/gno.land/p/demo/ownable/ownable_test.gno @@ -6,62 +6,62 @@ import ( ) var ( - firstAddr = std.Address("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm") - secondAddr = std.Address("g1r0mlnkc05z0fv49km99z60qnp95tengyqfdr02") + firstCaller = std.Address("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm") + secondCaller = std.Address("g1r0mlnkc05z0fv49km99z60qnp95tengyqfdr02") ) func TestNew(t *testing.T) { - std.TestSetRealm(std.NewUserRealm(firstAddr)) + std.TestSetRealm(std.NewUserRealm(firstCaller)) result := New() - if firstAddr != result.owner { - t.Fatalf("Expected %s, got: %s\n", firstAddr, result.owner) + if firstCaller != result.owner { + t.Fatalf("Expected %s, got: %s\n", firstCaller, result.owner) } } func TestOwner(t *testing.T) { - std.TestSetRealm(std.NewUserRealm(firstAddr)) + std.TestSetRealm(std.NewUserRealm(firstCaller)) result := New() resultOwner := result.Owner() - expected := firstAddr + expected := firstCaller if resultOwner != expected { t.Fatalf("Expected %s, got: %s\n", expected, result) } } func TestTransferOwnership(t *testing.T) { - std.TestSetRealm(std.NewUserRealm(firstAddr)) + std.TestSetRealm(std.NewUserRealm(firstCaller)) o := New() - err := o.TransferOwnership(secondAddr) + err := o.TransferOwnership(secondCaller) if err != nil { t.Fatalf("TransferOwnership failed, %v", err) } result := o.Owner() - if secondAddr != result { - t.Fatalf("Expected: %s, got: %s\n", secondAddr, result) + if secondCaller != result { + t.Fatalf("Expected: %s, got: %s\n", secondCaller, result) } } func TestCallerIsOwner(t *testing.T) { - std.TestSetOrigCaller(firstAddr) + std.TestSetOrigCaller(firstCaller) o := New() - unauthorizedCaller := secondAddr + unauthorizedCaller := secondCaller std.TestSetOrigCaller(unauthorizedCaller) - if prevRealmIsOwner(o.owner) { + if callerIsOwner(o.owner) { t.Fatalf("Expected %s to not be owner\n", unauthorizedCaller) } } func TestDropOwnership(t *testing.T) { - std.TestSetRealm(std.NewUserRealm(firstAddr)) + std.TestSetRealm(std.NewUserRealm(firstCaller)) o := New() @@ -79,13 +79,13 @@ func TestDropOwnership(t *testing.T) { // Errors func TestErrUnauthorized(t *testing.T) { - std.TestSetOrigCaller(firstAddr) + std.TestSetOrigCaller(firstCaller) o := New() - std.TestSetOrigCaller(secondAddr) + std.TestSetOrigCaller(secondCaller) - err := o.TransferOwnership(firstAddr) + err := o.TransferOwnership(firstCaller) if err != ErrUnauthorized { t.Fatalf("Should've been ErrUnauthorized, was %v", err) } @@ -97,7 +97,7 @@ func TestErrUnauthorized(t *testing.T) { } func TestErrInvalidAddress(t *testing.T) { - std.TestSetRealm(std.NewUserRealm(firstAddr)) + std.TestSetRealm(std.NewUserRealm(firstCaller)) o := New() From 4e51027890807bd937e97f8ebdd7d41478563625 Mon Sep 17 00:00:00 2001 From: linhpn99 Date: Wed, 12 Jun 2024 02:12:25 +0700 Subject: [PATCH 18/30] missing changes --- examples/gno.land/p/demo/pausable/helper.gno | 9 ------- .../gno.land/p/demo/pausable/pausable.gno | 10 ++++++-- .../p/demo/pausable/pausable_test.gno | 24 +++++++++---------- 3 files changed, 20 insertions(+), 23 deletions(-) delete mode 100644 examples/gno.land/p/demo/pausable/helper.gno diff --git a/examples/gno.land/p/demo/pausable/helper.gno b/examples/gno.land/p/demo/pausable/helper.gno deleted file mode 100644 index c6173bcfbb5..00000000000 --- a/examples/gno.land/p/demo/pausable/helper.gno +++ /dev/null @@ -1,9 +0,0 @@ -package pausable - -import ( - "std" -) - -func prevRealmIsOwner(addr std.Address) bool { - return std.PrevRealm().Addr() == addr -} diff --git a/examples/gno.land/p/demo/pausable/pausable.gno b/examples/gno.land/p/demo/pausable/pausable.gno index 85a35e897cc..bf8253120e4 100644 --- a/examples/gno.land/p/demo/pausable/pausable.gno +++ b/examples/gno.land/p/demo/pausable/pausable.gno @@ -1,6 +1,8 @@ package pausable import ( + "std" + "gno.land/p/demo/ownable" ) @@ -32,7 +34,7 @@ func (p Pausable) IsPaused() bool { // Pause sets the state of Pausable to true, meaning all pausable functions are paused func (p *Pausable) Pause() error { - if !prevRealmIsOwner(p.Owner()) { + if !callerIsOwner(p.Owner()) { return ErrUnauthorized } @@ -42,10 +44,14 @@ func (p *Pausable) Pause() error { // Unpause sets the state of Pausable to false, meaning all pausable functions are resumed func (p *Pausable) Unpause() error { - if !prevRealmIsOwner(p.Owner()) { + if !callerIsOwner(p.Owner()) { return ErrUnauthorized } p.paused = false return nil } + +func callerIsOwner(addr std.Address) bool { + return std.PrevRealm().Addr() == addr +} diff --git a/examples/gno.land/p/demo/pausable/pausable_test.gno b/examples/gno.land/p/demo/pausable/pausable_test.gno index 943b0a61e7f..883b82975e9 100644 --- a/examples/gno.land/p/demo/pausable/pausable_test.gno +++ b/examples/gno.land/p/demo/pausable/pausable_test.gno @@ -8,12 +8,12 @@ import ( ) var ( - firstAddr = std.Address("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm") - secondAddr = std.Address("g1r0mlnkc05z0fv49km99z60qnp95tengyqfdr02") + firstCaller = std.Address("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm") + secondCaller = std.Address("g1r0mlnkc05z0fv49km99z60qnp95tengyqfdr02") ) func TestNew(t *testing.T) { - std.TestSetRealm(std.NewUserRealm(firstAddr)) + std.TestSetRealm(std.NewUserRealm(firstCaller)) result := New() @@ -21,25 +21,25 @@ func TestNew(t *testing.T) { t.Fatalf("Expected result to be unpaused, got %t\n", result.paused) } - if result.Owner() != firstAddr { - t.Fatalf("Expected %s, got %s\n", firstAddr, result.Owner()) + if result.Owner() != firstCaller { + t.Fatalf("Expected %s, got %s\n", firstCaller, result.Owner()) } } func TestNewFromOwnable(t *testing.T) { - std.TestSetRealm(std.NewUserRealm(firstAddr)) + std.TestSetRealm(std.NewUserRealm(firstCaller)) o := ownable.New() - std.TestSetRealm(std.NewUserRealm(secondAddr)) + std.TestSetRealm(std.NewUserRealm(secondCaller)) result := NewFromOwnable(o) - if result.Owner() != firstAddr { - t.Fatalf("Expected %s, got %s\n", firstAddr, result.Owner()) + if result.Owner() != firstCaller { + t.Fatalf("Expected %s, got %s\n", firstCaller, result.Owner()) } } func TestSetUnpaused(t *testing.T) { - std.TestSetRealm(std.NewUserRealm(firstAddr)) + std.TestSetRealm(std.NewUserRealm(firstCaller)) result := New() result.Unpause() @@ -50,7 +50,7 @@ func TestSetUnpaused(t *testing.T) { } func TestSetPaused(t *testing.T) { - std.TestSetRealm(std.NewUserRealm(firstAddr)) + std.TestSetRealm(std.NewUserRealm(firstCaller)) result := New() result.Pause() @@ -61,7 +61,7 @@ func TestSetPaused(t *testing.T) { } func TestIsPaused(t *testing.T) { - std.TestSetRealm(std.NewUserRealm(firstAddr)) + std.TestSetRealm(std.NewUserRealm(firstCaller)) result := New() From 6f97dfeb95b6b158093385a24f2ebcd8fd9b11dd Mon Sep 17 00:00:00 2001 From: linhpn99 Date: Wed, 12 Jun 2024 02:17:00 +0700 Subject: [PATCH 19/30] return interface --- examples/gno.land/p/demo/ownable/ownable.gno | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/gno.land/p/demo/ownable/ownable.gno b/examples/gno.land/p/demo/ownable/ownable.gno index de188a338bc..27f1dedf62e 100644 --- a/examples/gno.land/p/demo/ownable/ownable.gno +++ b/examples/gno.land/p/demo/ownable/ownable.gno @@ -31,7 +31,7 @@ var ( _ Transferrable = (*transferrableOwnership)(nil) ) -func New() *transferrableOwnership { +func New() Ownable { return &transferrableOwnership{ owner: std.PrevRealm().Addr(), } From a6ca8bc28e70032adce0968601e7a0dc5120ba2e Mon Sep 17 00:00:00 2001 From: linhpn99 Date: Wed, 12 Jun 2024 02:20:02 +0700 Subject: [PATCH 20/30] return interface --- examples/gno.land/p/demo/ownable/ownable.gno | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/examples/gno.land/p/demo/ownable/ownable.gno b/examples/gno.land/p/demo/ownable/ownable.gno index 27f1dedf62e..e2a2653430e 100644 --- a/examples/gno.land/p/demo/ownable/ownable.gno +++ b/examples/gno.land/p/demo/ownable/ownable.gno @@ -18,27 +18,27 @@ type Transferrable interface { DropOwnership() error } -// transferrableOwnership provides a basic implementation of ownership functionality +// TransferrableOwnership provides a basic implementation of ownership functionality // It can be used as a top-level object to make a contract ownable or embedded within // another object to manage per-object ownership. -type transferrableOwnership struct { +type TransferrableOwnership struct { owner std.Address } -// Ensure that transferrableOwnership implements the Ownable and Transferrable interfaces +// Ensure that TransferrableOwnership implements the Ownable and Transferrable interfaces var ( - _ Ownable = (*transferrableOwnership)(nil) - _ Transferrable = (*transferrableOwnership)(nil) + _ Ownable = (*TransferrableOwnership)(nil) + _ Transferrable = (*TransferrableOwnership)(nil) ) -func New() Ownable { - return &transferrableOwnership{ +func New() *TransferrableOwnership { + return &TransferrableOwnership{ owner: std.PrevRealm().Addr(), } } // TransferOwnership transfers ownership of the Ownable struct to a new address -func (o *transferrableOwnership) TransferOwnership(newOwner std.Address) error { +func (o *TransferrableOwnership) TransferOwnership(newOwner std.Address) error { if !callerIsOwner(o.owner) { return ErrUnauthorized } @@ -54,7 +54,7 @@ func (o *transferrableOwnership) TransferOwnership(newOwner std.Address) error { // DropOwnership removes the owner, effectively disabling any owner-related actions // Top-level usage: disables all only-owner actions/functions, // Embedded usage: behaves like a burn functionality, removing the owner from the struct -func (o *transferrableOwnership) DropOwnership() error { +func (o *TransferrableOwnership) DropOwnership() error { if !callerIsOwner(o.owner) { return ErrUnauthorized } @@ -63,7 +63,7 @@ func (o *transferrableOwnership) DropOwnership() error { return nil } -func (o *transferrableOwnership) Owner() std.Address { +func (o *TransferrableOwnership) Owner() std.Address { return o.owner } From 4765f371b9ccd11f43d6bc7146d67257b9616675 Mon Sep 17 00:00:00 2001 From: linhpn99 Date: Wed, 12 Jun 2024 02:23:24 +0700 Subject: [PATCH 21/30] update --- examples/gno.land/p/demo/ownable/ownable.gno | 22 ++++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/examples/gno.land/p/demo/ownable/ownable.gno b/examples/gno.land/p/demo/ownable/ownable.gno index e2a2653430e..f2a35bdfdb4 100644 --- a/examples/gno.land/p/demo/ownable/ownable.gno +++ b/examples/gno.land/p/demo/ownable/ownable.gno @@ -10,7 +10,7 @@ type Ownable interface { Owner() std.Address } -// Transferrable embeds Ownable, indicating that the owner has the ability to transfer or drop ownership. +// Transferrable embeds Ownable, indicating that the owner can transfer ownership and drop ownership type Transferrable interface { Ownable @@ -18,27 +18,27 @@ type Transferrable interface { DropOwnership() error } -// TransferrableOwnership provides a basic implementation of ownership functionality +// transferrableOwnership provides a basic implementation of ownership functionality // It can be used as a top-level object to make a contract ownable or embedded within // another object to manage per-object ownership. -type TransferrableOwnership struct { +type transferrableOwnership struct { owner std.Address } -// Ensure that TransferrableOwnership implements the Ownable and Transferrable interfaces +// Ensure that transferrableOwnership implements the Ownable and Transferrable interfaces var ( - _ Ownable = (*TransferrableOwnership)(nil) - _ Transferrable = (*TransferrableOwnership)(nil) + _ Ownable = (*transferrableOwnership)(nil) + _ Transferrable = (*transferrableOwnership)(nil) ) -func New() *TransferrableOwnership { - return &TransferrableOwnership{ +func New() *transferrableOwnership { + return &transferrableOwnership{ owner: std.PrevRealm().Addr(), } } // TransferOwnership transfers ownership of the Ownable struct to a new address -func (o *TransferrableOwnership) TransferOwnership(newOwner std.Address) error { +func (o *transferrableOwnership) TransferOwnership(newOwner std.Address) error { if !callerIsOwner(o.owner) { return ErrUnauthorized } @@ -54,7 +54,7 @@ func (o *TransferrableOwnership) TransferOwnership(newOwner std.Address) error { // DropOwnership removes the owner, effectively disabling any owner-related actions // Top-level usage: disables all only-owner actions/functions, // Embedded usage: behaves like a burn functionality, removing the owner from the struct -func (o *TransferrableOwnership) DropOwnership() error { +func (o *transferrableOwnership) DropOwnership() error { if !callerIsOwner(o.owner) { return ErrUnauthorized } @@ -63,7 +63,7 @@ func (o *TransferrableOwnership) DropOwnership() error { return nil } -func (o *TransferrableOwnership) Owner() std.Address { +func (o *transferrableOwnership) Owner() std.Address { return o.owner } From 3d1962347e5b3a27a2420e7b660d06d3ed3a81ed Mon Sep 17 00:00:00 2001 From: linhpn99 Date: Wed, 12 Jun 2024 02:27:51 +0700 Subject: [PATCH 22/30] update --- examples/gno.land/p/demo/memeland/memeland.gno | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/gno.land/p/demo/memeland/memeland.gno b/examples/gno.land/p/demo/memeland/memeland.gno index db78a86a756..df68b286e04 100644 --- a/examples/gno.land/p/demo/memeland/memeland.gno +++ b/examples/gno.land/p/demo/memeland/memeland.gno @@ -26,15 +26,15 @@ type Post struct { } type Memeland struct { - ownable.Ownable + ownable.Transferrable Posts []*Post MemeCounter seqid.ID } func NewMemeland() *Memeland { return &Memeland{ - Ownable: ownable.New(), - Posts: make([]*Post, 0), + Transferrable: ownable.New(), + Posts: make([]*Post, 0), } } From f5fe77eacf1c3528574c0ed422ba9ef2ca91a1b2 Mon Sep 17 00:00:00 2001 From: linhpn99 Date: Wed, 12 Jun 2024 02:28:45 +0700 Subject: [PATCH 23/30] rename --- examples/gno.land/p/demo/ownable/ownable.gno | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/examples/gno.land/p/demo/ownable/ownable.gno b/examples/gno.land/p/demo/ownable/ownable.gno index f2a35bdfdb4..e5dc213567b 100644 --- a/examples/gno.land/p/demo/ownable/ownable.gno +++ b/examples/gno.land/p/demo/ownable/ownable.gno @@ -18,27 +18,27 @@ type Transferrable interface { DropOwnership() error } -// transferrableOwnership provides a basic implementation of ownership functionality +// transferrable provides a basic implementation of ownership functionality // It can be used as a top-level object to make a contract ownable or embedded within // another object to manage per-object ownership. -type transferrableOwnership struct { +type transferrable struct { owner std.Address } -// Ensure that transferrableOwnership implements the Ownable and Transferrable interfaces +// Ensure that transferrable implements the Ownable and Transferrable interfaces var ( - _ Ownable = (*transferrableOwnership)(nil) - _ Transferrable = (*transferrableOwnership)(nil) + _ Ownable = (*transferrable)(nil) + _ Transferrable = (*transferrable)(nil) ) -func New() *transferrableOwnership { - return &transferrableOwnership{ +func New() *transferrable { + return &transferrable{ owner: std.PrevRealm().Addr(), } } // TransferOwnership transfers ownership of the Ownable struct to a new address -func (o *transferrableOwnership) TransferOwnership(newOwner std.Address) error { +func (o *transferrable) TransferOwnership(newOwner std.Address) error { if !callerIsOwner(o.owner) { return ErrUnauthorized } @@ -54,7 +54,7 @@ func (o *transferrableOwnership) TransferOwnership(newOwner std.Address) error { // DropOwnership removes the owner, effectively disabling any owner-related actions // Top-level usage: disables all only-owner actions/functions, // Embedded usage: behaves like a burn functionality, removing the owner from the struct -func (o *transferrableOwnership) DropOwnership() error { +func (o *transferrable) DropOwnership() error { if !callerIsOwner(o.owner) { return ErrUnauthorized } @@ -63,7 +63,7 @@ func (o *transferrableOwnership) DropOwnership() error { return nil } -func (o *transferrableOwnership) Owner() std.Address { +func (o *transferrable) Owner() std.Address { return o.owner } From 8bd3ac0bd411c9f2adee3bbc466e57ed6f33ac5b Mon Sep 17 00:00:00 2001 From: linhpn99 Date: Wed, 12 Jun 2024 08:24:31 +0700 Subject: [PATCH 24/30] fixed all --- .../gno.land/p/demo/memeland/memeland.gno | 21 +++++----- .../p/demo/memeland/memeland_test.gno | 21 +++++++--- examples/gno.land/p/demo/ownable/ownable.gno | 29 ++++++++++--- .../gno.land/p/demo/ownable/ownable_test.gno | 41 ++++++++++++------- .../gno.land/p/demo/pausable/pausable.gno | 17 +++++--- 5 files changed, 88 insertions(+), 41 deletions(-) diff --git a/examples/gno.land/p/demo/memeland/memeland.gno b/examples/gno.land/p/demo/memeland/memeland.gno index df68b286e04..d53179fb900 100644 --- a/examples/gno.land/p/demo/memeland/memeland.gno +++ b/examples/gno.land/p/demo/memeland/memeland.gno @@ -26,15 +26,15 @@ type Post struct { } type Memeland struct { - ownable.Transferrable + ownable.Ownable Posts []*Post MemeCounter seqid.ID } func NewMemeland() *Memeland { return &Memeland{ - Transferrable: ownable.New(), - Posts: make([]*Post, 0), + Ownable: ownable.New(), + Posts: make([]*Post, 0), } } @@ -160,9 +160,7 @@ func (m *Memeland) RemovePost(id string) string { panic("id cannot be empty") } - if !callerIsOwner(m.Owner()) { - panic("unauthorized; caller is not owner") - } + m.AssertCallerIsOwner() for i, post := range m.Posts { if post.ID == id { @@ -174,6 +172,13 @@ func (m *Memeland) RemovePost(id string) string { panic("post with specified id does not exist") } +// AssertCallerIsOwner panics if the caller is not the Realm's owner +func (m *Memeland) AssertCallerIsOwner() { + if std.PrevRealm().Addr() != m.Owner() { + panic("unauthorized; caller is not owner") + } +} + // PostsToJSONString converts a slice of Post structs into a JSON string func PostsToJSONString(posts []*Post) string { var sb strings.Builder @@ -238,7 +243,3 @@ func (p PostSorter) Swap(i, j int) { func (p PostSorter) Less(i, j int) bool { return p.LessF(i, j) } - -func callerIsOwner(addr std.Address) bool { - return std.PrevRealm().Addr() == addr -} diff --git a/examples/gno.land/p/demo/memeland/memeland_test.gno b/examples/gno.land/p/demo/memeland/memeland_test.gno index 76c44327993..072da42f4a9 100644 --- a/examples/gno.land/p/demo/memeland/memeland_test.gno +++ b/examples/gno.land/p/demo/memeland/memeland_test.gno @@ -117,6 +117,8 @@ func TestGetPostsInRangeByTimestamp(t *testing.T) { } func TestGetPostsInRangeByUpvote(t *testing.T) { + alice := testutils.TestAddress("alice") + m := NewMemeland() now := time.Now() @@ -131,7 +133,8 @@ func TestGetPostsInRangeByUpvote(t *testing.T) { m.Upvote(id2) // Change caller so avoid double upvote panic - std.TestSetOrigCaller(testutils.TestAddress("alice")) + std.TestSetRealm(std.NewUserRealm(alice)) + std.TestSetOrigCaller(alice) // TODO(bug): should not be needed m.Upvote(id1) // Final upvote count: @@ -260,14 +263,18 @@ func TestUpvote(t *testing.T) { func TestDelete(t *testing.T) { alice := testutils.TestAddress("alice") - std.TestSetOrigCaller(alice) + + std.TestSetRealm(std.NewUserRealm(alice)) + std.TestSetOrigCaller(alice) // TODO(bug): should not be needed // Alice is admin m := NewMemeland() // Set caller to Bob bob := testutils.TestAddress("bob") - std.TestSetOrigCaller(bob) + + std.TestSetRealm(std.NewUserRealm(bob)) + std.TestSetOrigCaller(bob) // TODO(bug): should not be needed // Bob adds post to Memeland now := time.Now() @@ -288,7 +295,9 @@ func TestDelete(t *testing.T) { func TestDeleteByNonAdmin(t *testing.T) { alice := testutils.TestAddress("alice") - std.TestSetOrigCaller(alice) + + std.TestSetRealm(std.NewUserRealm(alice)) + std.TestSetOrigCaller(alice) // TODO(bug): should not be needed m := NewMemeland() @@ -298,7 +307,9 @@ func TestDeleteByNonAdmin(t *testing.T) { // Bob will try to delete meme posted by Alice, which should fail bob := testutils.TestAddress("bob") - std.TestSetOrigCaller(bob) + + std.TestSetRealm(std.NewUserRealm(bob)) + std.TestSetOrigCaller(bob) // TODO(bug): should not be needed defer func() { if r := recover(); r == nil { diff --git a/examples/gno.land/p/demo/ownable/ownable.gno b/examples/gno.land/p/demo/ownable/ownable.gno index e5dc213567b..e18ae2b6ee8 100644 --- a/examples/gno.land/p/demo/ownable/ownable.gno +++ b/examples/gno.land/p/demo/ownable/ownable.gno @@ -37,9 +37,15 @@ func New() *transferrable { } } +func NewWithAddress(addr std.Address) *transferrable { + return &transferrable{ + owner: addr, + } +} + // TransferOwnership transfers ownership of the Ownable struct to a new address func (o *transferrable) TransferOwnership(newOwner std.Address) error { - if !callerIsOwner(o.owner) { + if err := o.CallerIsOwner(); err != nil { return ErrUnauthorized } @@ -55,18 +61,29 @@ func (o *transferrable) TransferOwnership(newOwner std.Address) error { // Top-level usage: disables all only-owner actions/functions, // Embedded usage: behaves like a burn functionality, removing the owner from the struct func (o *transferrable) DropOwnership() error { - if !callerIsOwner(o.owner) { - return ErrUnauthorized + if err := o.CallerIsOwner(); err != nil { + return err } o.owner = "" return nil } -func (o *transferrable) Owner() std.Address { +func (o transferrable) Owner() std.Address { return o.owner } -func callerIsOwner(addr std.Address) bool { - return std.PrevRealm().Addr() == addr +// CallerIsOwner checks if the caller of the function is the Realm's owner +func (o transferrable) CallerIsOwner() error { + if std.PrevRealm().Addr() == o.owner { + return nil + } + + return ErrUnauthorized +} + +func (o transferrable) AssertCallerIsOwner() { + if std.PrevRealm().Addr() != o.owner { + panic(ErrUnauthorized) + } } diff --git a/examples/gno.land/p/demo/ownable/ownable_test.gno b/examples/gno.land/p/demo/ownable/ownable_test.gno index c9d5c86b2c0..d175afa20d8 100644 --- a/examples/gno.land/p/demo/ownable/ownable_test.gno +++ b/examples/gno.land/p/demo/ownable/ownable_test.gno @@ -6,12 +6,13 @@ import ( ) var ( - firstCaller = std.Address("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm") - secondCaller = std.Address("g1r0mlnkc05z0fv49km99z60qnp95tengyqfdr02") + firstCaller = std.Address("g1l9aypkr8xfvs82zeux486ddzec88ty69lue9de") + secondCaller = std.Address("g127jydsh6cms3lrtdenydxsckh23a8d6emqcvfa") ) func TestNew(t *testing.T) { std.TestSetRealm(std.NewUserRealm(firstCaller)) + std.TestSetOrigCaller(firstCaller) // TODO(bug): should not be needed result := New() if firstCaller != result.owner { @@ -19,15 +20,24 @@ func TestNew(t *testing.T) { } } +func TestNewWithAddress(t *testing.T) { + o := NewWithAddress(firstCaller) + + got := o.Owner() + if firstCaller != got { + t.Fatalf("Expected %s, got: %s", firstCaller, got) + } +} + func TestOwner(t *testing.T) { std.TestSetRealm(std.NewUserRealm(firstCaller)) - result := New() - resultOwner := result.Owner() + o := New() + got := o.Owner() expected := firstCaller - if resultOwner != expected { - t.Fatalf("Expected %s, got: %s\n", expected, result) + if got != expected { + t.Fatalf("Expected %s, got: %s", expected, got) } } @@ -40,9 +50,9 @@ func TestTransferOwnership(t *testing.T) { t.Fatalf("TransferOwnership failed, %v", err) } - result := o.Owner() - if secondCaller != result { - t.Fatalf("Expected: %s, got: %s\n", secondCaller, result) + got := o.Owner() + if secondCaller != got { + t.Fatalf("Expected: %s, got: %s", secondCaller, got) } } @@ -53,10 +63,11 @@ func TestCallerIsOwner(t *testing.T) { unauthorizedCaller := secondCaller - std.TestSetOrigCaller(unauthorizedCaller) + std.TestSetRealm(std.NewUserRealm(unauthorizedCaller)) + std.TestSetOrigCaller(unauthorizedCaller) // TODO(bug): should not be needed - if callerIsOwner(o.owner) { - t.Fatalf("Expected %s to not be owner\n", unauthorizedCaller) + if err := o.CallerIsOwner(); err == nil { + t.Fatalf("Expected %s to not be owner", unauthorizedCaller) } } @@ -72,18 +83,20 @@ func TestDropOwnership(t *testing.T) { owner := o.Owner() if owner != "" { - t.Fatalf("Expected owner to be empty, not %s\n", owner) + t.Fatalf("Expected owner to be empty, not %s", owner) } } // Errors func TestErrUnauthorized(t *testing.T) { - std.TestSetOrigCaller(firstCaller) + std.TestSetRealm(std.NewUserRealm(firstCaller)) + std.TestSetOrigCaller(firstCaller) // TODO(bug): should not be needed o := New() std.TestSetOrigCaller(secondCaller) + std.TestSetOrigCaller(secondCaller) // TODO(bug): should not be needed err := o.TransferOwnership(firstCaller) if err != ErrUnauthorized { diff --git a/examples/gno.land/p/demo/pausable/pausable.gno b/examples/gno.land/p/demo/pausable/pausable.gno index bf8253120e4..55105ad7559 100644 --- a/examples/gno.land/p/demo/pausable/pausable.gno +++ b/examples/gno.land/p/demo/pausable/pausable.gno @@ -34,8 +34,8 @@ func (p Pausable) IsPaused() bool { // Pause sets the state of Pausable to true, meaning all pausable functions are paused func (p *Pausable) Pause() error { - if !callerIsOwner(p.Owner()) { - return ErrUnauthorized + if err := p.CallerIsOwner(); err != nil { + return err } p.paused = true @@ -44,14 +44,19 @@ func (p *Pausable) Pause() error { // Unpause sets the state of Pausable to false, meaning all pausable functions are resumed func (p *Pausable) Unpause() error { - if !callerIsOwner(p.Owner()) { - return ErrUnauthorized + if err := p.CallerIsOwner(); err != nil { + return err } p.paused = false return nil } -func callerIsOwner(addr std.Address) bool { - return std.PrevRealm().Addr() == addr +// CallerIsOwner checks if the caller of the function is the Realm's owner +func (p Pausable) CallerIsOwner() error { + if std.PrevRealm().Addr() == p.Owner() { + return nil + } + + return ErrUnauthorized } From a3dad4c2c399009cc88455dee6a3bdc11cf21028 Mon Sep 17 00:00:00 2001 From: linhpn99 Date: Wed, 12 Jun 2024 08:31:48 +0700 Subject: [PATCH 25/30] fixed all --- examples/gno.land/p/demo/memeland/memeland.gno | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/gno.land/p/demo/memeland/memeland.gno b/examples/gno.land/p/demo/memeland/memeland.gno index d53179fb900..efa50c0bc3a 100644 --- a/examples/gno.land/p/demo/memeland/memeland.gno +++ b/examples/gno.land/p/demo/memeland/memeland.gno @@ -26,15 +26,15 @@ type Post struct { } type Memeland struct { - ownable.Ownable + ownable.Transferrable Posts []*Post MemeCounter seqid.ID } func NewMemeland() *Memeland { return &Memeland{ - Ownable: ownable.New(), - Posts: make([]*Post, 0), + Transferrable: ownable.New(), + Posts: make([]*Post, 0), } } From 0e7f9d5cc8c4298b704941727e7232c4bf6a17dd Mon Sep 17 00:00:00 2001 From: linhpn99 Date: Wed, 12 Jun 2024 13:13:24 +0700 Subject: [PATCH 26/30] fix pausable --- examples/gno.land/p/demo/pausable/pausable_test.gno | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/examples/gno.land/p/demo/pausable/pausable_test.gno b/examples/gno.land/p/demo/pausable/pausable_test.gno index 883b82975e9..172264a36ef 100644 --- a/examples/gno.land/p/demo/pausable/pausable_test.gno +++ b/examples/gno.land/p/demo/pausable/pausable_test.gno @@ -8,12 +8,13 @@ import ( ) var ( - firstCaller = std.Address("g1wymu47drhr0kuq2098m792lytgtj2nyx77yrsm") - secondCaller = std.Address("g1r0mlnkc05z0fv49km99z60qnp95tengyqfdr02") + firstCaller = std.Address("g1l9aypkr8xfvs82zeux486ddzec88ty69lue9de") + secondCaller = std.Address("g127jydsh6cms3lrtdenydxsckh23a8d6emqcvfa") ) func TestNew(t *testing.T) { std.TestSetRealm(std.NewUserRealm(firstCaller)) + std.TestSetOrigCaller(firstCaller) // TODO(bug): should not be needed result := New() @@ -28,9 +29,13 @@ func TestNew(t *testing.T) { func TestNewFromOwnable(t *testing.T) { std.TestSetRealm(std.NewUserRealm(firstCaller)) + std.TestSetOrigCaller(firstCaller) // TODO(bug): should not be needed + o := ownable.New() std.TestSetRealm(std.NewUserRealm(secondCaller)) + std.TestSetOrigCaller(secondCaller) // TODO(bug): should not be needed + result := NewFromOwnable(o) if result.Owner() != firstCaller { @@ -40,6 +45,7 @@ func TestNewFromOwnable(t *testing.T) { func TestSetUnpaused(t *testing.T) { std.TestSetRealm(std.NewUserRealm(firstCaller)) + std.TestSetOrigCaller(firstCaller) // TODO(bug): should not be needed result := New() result.Unpause() @@ -51,6 +57,7 @@ func TestSetUnpaused(t *testing.T) { func TestSetPaused(t *testing.T) { std.TestSetRealm(std.NewUserRealm(firstCaller)) + std.TestSetOrigCaller(firstCaller) // TODO(bug): should not be needed result := New() result.Pause() @@ -62,6 +69,7 @@ func TestSetPaused(t *testing.T) { func TestIsPaused(t *testing.T) { std.TestSetRealm(std.NewUserRealm(firstCaller)) + std.TestSetOrigCaller(firstCaller) // TODO(bug): should not be needed result := New() From 6fd4c2b64511074b1213365d5ba73db5d58921bb Mon Sep 17 00:00:00 2001 From: linhpn99 Date: Thu, 13 Jun 2024 18:23:29 +0700 Subject: [PATCH 27/30] wrong delete --- examples/gno.land/p/demo/ownable/ownable_test.gno | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/examples/gno.land/p/demo/ownable/ownable_test.gno b/examples/gno.land/p/demo/ownable/ownable_test.gno index abd60840e60..e145ed38ac8 100644 --- a/examples/gno.land/p/demo/ownable/ownable_test.gno +++ b/examples/gno.land/p/demo/ownable/ownable_test.gno @@ -21,6 +21,15 @@ func TestNew(t *testing.T) { } } +func TestNewWithAddress(t *testing.T) { + o := NewWithAddress(firstCaller) + + got := o.Owner() + if firstCaller != got { + t.Fatalf("Expected %s, got: %s", firstCaller, got) + } +} + func TestOwner(t *testing.T) { std.TestSetRealm(std.NewUserRealm(firstCaller)) From 0cc00c4aec3e347f75a620643e920cea52a0b291 Mon Sep 17 00:00:00 2001 From: linhpn99 Date: Fri, 14 Jun 2024 09:05:16 +0700 Subject: [PATCH 28/30] update from master --- examples/gno.land/p/demo/ownable/ownable.gno | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/gno.land/p/demo/ownable/ownable.gno b/examples/gno.land/p/demo/ownable/ownable.gno index 046b7888472..e4c23293a5e 100644 --- a/examples/gno.land/p/demo/ownable/ownable.gno +++ b/examples/gno.land/p/demo/ownable/ownable.gno @@ -48,7 +48,7 @@ func NewWithAddress(addr std.Address) *transferrable { // TransferOwnership transfers ownership of the Ownable struct to a new address func (o *transferrable) TransferOwnership(newOwner std.Address) error { if err := o.CallerIsOwner(); err != nil { - return ErrUnauthorized + return err } if !newOwner.IsValid() { From 88b7481d3a831fbf1e6374bdc9f1557282a24712 Mon Sep 17 00:00:00 2001 From: linhpn99 Date: Thu, 4 Jul 2024 14:35:33 +0700 Subject: [PATCH 29/30] fix CI --- examples/gno.land/r/gnoland/home/home_filetest.gno | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/gno.land/r/gnoland/home/home_filetest.gno b/examples/gno.land/r/gnoland/home/home_filetest.gno index 919f8dd4fbc..2f2ac26f2fe 100644 --- a/examples/gno.land/r/gnoland/home/home_filetest.gno +++ b/examples/gno.land/r/gnoland/home/home_filetest.gno @@ -133,7 +133,8 @@ func main() { // - [r/demo/microblog](r/demo/microblog) // - [r/demo/nft](r/demo/nft) // - [r/demo/types](r/demo/types) -// - [r/demo/art](r/demo/art) +// - [r/demo/art/gnoface](r/demo/art/gnoface) +// - [r/demo/art/millipede](r/demo/art/millipede) // - [r/demo/groups](r/demo/groups) // - ... // From efafea782dfbbd8538bd4b522eb1fac817dfb5ae Mon Sep 17 00:00:00 2001 From: linhpn99 Date: Mon, 8 Jul 2024 21:14:35 +0700 Subject: [PATCH 30/30] use interface instead --- examples/gno.land/p/demo/ownable/ownable.gno | 1 + examples/gno.land/r/demo/foo20/foo20.gno | 2 +- examples/gno.land/r/demo/grc20factory/grc20factory.gno | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/gno.land/p/demo/ownable/ownable.gno b/examples/gno.land/p/demo/ownable/ownable.gno index e4c23293a5e..c9ccb4cf5ec 100644 --- a/examples/gno.land/p/demo/ownable/ownable.gno +++ b/examples/gno.land/p/demo/ownable/ownable.gno @@ -10,6 +10,7 @@ const OwnershipTransferEvent = "OwnershipTransfer" // being embedded in a Gno object to manage per-object ownership. type Ownable interface { Owner() std.Address + AssertCallerIsOwner() } // Transferrable embeds Ownable, indicating that the owner can transfer ownership and drop ownership diff --git a/examples/gno.land/r/demo/foo20/foo20.gno b/examples/gno.land/r/demo/foo20/foo20.gno index 9d4e5d40193..bc237eb33f3 100644 --- a/examples/gno.land/r/demo/foo20/foo20.gno +++ b/examples/gno.land/r/demo/foo20/foo20.gno @@ -15,7 +15,7 @@ import ( var ( banker *grc20.Banker - admin *ownable.Ownable + admin ownable.Ownable token grc20.Token ) diff --git a/examples/gno.land/r/demo/grc20factory/grc20factory.gno b/examples/gno.land/r/demo/grc20factory/grc20factory.gno index f37a9370a9e..6f19bafc28b 100644 --- a/examples/gno.land/r/demo/grc20factory/grc20factory.gno +++ b/examples/gno.land/r/demo/grc20factory/grc20factory.gno @@ -39,7 +39,7 @@ func NewWithAdmin(name, symbol string, decimals uint, initialMint, faucet uint64 type instance struct { banker *grc20.Banker - admin *ownable.Ownable + admin ownable.Ownable faucet uint64 // per-request amount. disabled if 0. }