From 0c529dfe8afd2a84d1e8af57c0baa18658618c5c Mon Sep 17 00:00:00 2001 From: leohhhn Date: Mon, 9 Oct 2023 13:10:20 +0200 Subject: [PATCH 01/19] add poll p & r --- examples/gno.land/voting/cmds.txt | 39 ++++++ examples/gno.land/voting/p/poll.gno | 69 ++++++++++ examples/gno.land/voting/r/pollFactory.gno | 139 +++++++++++++++++++++ 3 files changed, 247 insertions(+) create mode 100644 examples/gno.land/voting/cmds.txt create mode 100644 examples/gno.land/voting/p/poll.gno create mode 100644 examples/gno.land/voting/r/pollFactory.gno diff --git a/examples/gno.land/voting/cmds.txt b/examples/gno.land/voting/cmds.txt new file mode 100644 index 00000000000..86b232ae9c7 --- /dev/null +++ b/examples/gno.land/voting/cmds.txt @@ -0,0 +1,39 @@ +Poll cmds + +gnokey maketx addpkg \ +--pkgpath "gno.land/p/demo/poll" \ +--pkgdir "./p/" \ +--gas-fee 10000000ugnot \ +--gas-wanted 800000 \ +--broadcast \ +--chainid dev \ +--remote localhost:26657 \ +lol && gnokey maketx addpkg \ +--pkgpath "gno.land/r/demo/poll" \ +--pkgdir "./r/" \ +--gas-fee 10000000ugnot \ +--gas-wanted 800000 \ +--broadcast \ +--chainid dev \ +--remote localhost:26657 \ +lol && gnokey maketx call \ +--pkgpath "gno.land/r/demo/poll" \ +--func "NewPoll" \ +--args "Is Gno good?" \ +--args "vibe check" \ +--args 1000 \ +--gas-fee 10000000ugnot \ +--gas-wanted 800000 \ +--broadcast \ +--remote localhost:26657 \ +lol && gnokey maketx call \ +--pkgpath "gno.land/r/demo/poll" \ +--func "Vote" \ +--args 0 \ +--args true \ +--gas-fee 10000000ugnot \ +--gas-wanted 800000 \ +--broadcast \ +--remote localhost:26657 \ +lol + diff --git a/examples/gno.land/voting/p/poll.gno b/examples/gno.land/voting/p/poll.gno new file mode 100644 index 00000000000..fdafb024a7d --- /dev/null +++ b/examples/gno.land/voting/p/poll.gno @@ -0,0 +1,69 @@ +package poll + +import ( + "gno.land/p/demo/avl" + "std" +) + +type Poll struct { + title string + description string + deadline int64 // block height + voters *avl.Tree // addr -> yes / no (bool) +} + +func (p Poll) Title() string { + return p.title +} + +func (p Poll) Description() string { + return p.description +} + +func (p Poll) Deadline() int64 { + return p.deadline +} + +func (p Poll) Voters() *avl.Tree { + return p.voters +} + +func NewPoll(title, description string, deadline int64) *Poll { + return &Poll{ + title: title, + description: description, + deadline: deadline, + voters: avl.NewTree(), + } +} + +func (p *Poll) Vote(voter std.Address, vote bool) { + p.Voters().Set(string(voter), vote) +} + +// HasVoted vote: yes - true, no - false +func (p *Poll) HasVoted(address std.Address) (bool, bool) { + vote, exists := p.Voters().Get(string(address)) + if exists { + return true, vote.(bool) + } + return false, false +} + +func (p Poll) VoteCount() (int, int) { + var ( + yay int + nay int + ) + p.Voters().Iterate("", "", func(key string, value interface{}) bool { + vote := value.(bool) + + if vote == true { + yay = yay + 1 + } else { + nay = nay + 1 + } + }) + + return yay, nay +} diff --git a/examples/gno.land/voting/r/pollFactory.gno b/examples/gno.land/voting/r/pollFactory.gno new file mode 100644 index 00000000000..d056e709f51 --- /dev/null +++ b/examples/gno.land/voting/r/pollFactory.gno @@ -0,0 +1,139 @@ +package poll + +import ( + "bytes" + "gno.land/p/demo/avl" + "gno.land/p/demo/poll" + "gno.land/p/demo/ufmt" + "std" + + "strconv" +) + +// state variables +var ( + polls *avl.Tree // id -> Poll + pollIDCounter int +) + +func init() { + polls = avl.NewTree() + pollIDCounter = 0 +} + +func NewPoll(title, description string, deadline int64) string { + // Get block height + if deadline <= std.GetHeight() { + return "Error: Deadline has to be in the future." + } + + id := ufmt.Sprintf("%d", pollIDCounter) + p := poll.NewPoll(title, description, deadline) + + // set new poll in avl tree + polls.Set(id, p) + pollIDCounter = pollIDCounter + 1 + + return ufmt.Sprintf("Successfully created poll #%s!", id) +} + +func Vote(pollID int, vote bool) string { + txSender := std.GetOrigCaller() + + pollRaw, exists := polls.Get(strconv.Itoa(pollID)) + + if !exists { + return "Error: Poll with specified doesn't exist." + } + + poll, _ := pollRaw.(*poll.Poll) + + voted, _ := poll.HasVoted(txSender) + if voted { + return "Error: You've already voted!" + } + + if poll.Deadline() <= std.GetHeight() { + return "Error: Voting for this poll is closed." + } + + poll.Vote(txSender, vote) + polls.Set(strconv.Itoa(pollID), poll) + + if vote == true { + return ufmt.Sprintf("Successfully voted YAY for poll #%d!", pollID) + } + return ufmt.Sprintf("Successfully voted NAY for poll #%d!", pollID) + +} + +func Render(path string) string { + if path == "" { + return renderHome() + } + return "tf" +} + +func renderHome() string { + var b bytes.Buffer + + b.WriteString("# Polls!\n\n") + + if polls.Size() == 0 { + b.WriteString("### No active polls currently!") + return b.String() + } + polls.Iterate("", "", func(key string, value interface{}) bool { + + // cast raw data from tree into Whitelist struct + p := value.(*poll.Poll) + ddl := p.Deadline() + + yay, nay := p.VoteCount() + + b.WriteString( + ufmt.Sprintf( + "## Poll #%s: %s\n", + key, // poll ID + p.Title(), + ), + ) + + b.WriteString( + ufmt.Sprintf("Voting until block: %d, current vote count: %d\n\n", p.Deadline(), p.Voters().Size()), + ) + + b.WriteString( + ufmt.Sprintf("YAY votes: %d\n\n", yay), + ) + b.WriteString( + ufmt.Sprintf("NAY votes: %d\n\n", nay), + ) + + dropdown := "
\nVoter details
" + b.WriteString(dropdown) + + p.Voters().Iterate("", "", func(key string, value interface{}) bool { + + voter := key + vote := value.(bool) + + if vote == true { + b.WriteString( + ufmt.Sprintf("
1. Voter %s voted YAY!\n", voter), + ) + } else { + b.WriteString( + ufmt.Sprintf("
1. Voter %s voted NAY!\n", voter), + ) + } + + b.WriteString("
\n") + return false + }) + + return false + }) + + return b.String() +} From 2b8e027ae80b76e6f6d1cbaea793348f0378d4a2 Mon Sep 17 00:00:00 2001 From: leohhhn Date: Mon, 9 Oct 2023 14:02:38 +0200 Subject: [PATCH 02/19] render update --- examples/gno.land/voting/cmds.txt | 1 - examples/gno.land/voting/r/pollFactory.gno | 23 +++++++++++++++++----- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/examples/gno.land/voting/cmds.txt b/examples/gno.land/voting/cmds.txt index 86b232ae9c7..135fcd9d04d 100644 --- a/examples/gno.land/voting/cmds.txt +++ b/examples/gno.land/voting/cmds.txt @@ -36,4 +36,3 @@ lol && gnokey maketx call \ --broadcast \ --remote localhost:26657 \ lol - diff --git a/examples/gno.land/voting/r/pollFactory.gno b/examples/gno.land/voting/r/pollFactory.gno index d056e709f51..1733d983c37 100644 --- a/examples/gno.land/voting/r/pollFactory.gno +++ b/examples/gno.land/voting/r/pollFactory.gno @@ -90,6 +90,13 @@ func renderHome() string { ddl := p.Deadline() yay, nay := p.VoteCount() + yayPercent := 0 + nayPercent := 0 + + if yay+nay != 0 { + yayPercent = yay * 100 / (yay + nay) + nayPercent = nay * 100 / (yay + nay) + } b.WriteString( ufmt.Sprintf( @@ -99,18 +106,24 @@ func renderHome() string { ), ) + dropdown := "
\nPoll details
" + + b.WriteString(dropdown + "Description: " + p.Description()) + b.WriteString( - ufmt.Sprintf("Voting until block: %d, current vote count: %d\n\n", p.Deadline(), p.Voters().Size()), + ufmt.Sprintf("
Voting until block: %d
Current vote count: %d", + p.Deadline(), + p.Voters().Size()), ) b.WriteString( - ufmt.Sprintf("YAY votes: %d\n\n", yay), + ufmt.Sprintf("
YAY votes: %d (%d%%)", yay, yayPercent), ) b.WriteString( - ufmt.Sprintf("NAY votes: %d\n\n", nay), + ufmt.Sprintf("
NAY votes: %d (%d%%)
", nay, nayPercent), ) - dropdown := "
\nVoter details
" + dropdown = "
\nVote details" b.WriteString(dropdown) p.Voters().Iterate("", "", func(key string, value interface{}) bool { @@ -128,7 +141,7 @@ func renderHome() string { ) } - b.WriteString("
\n") + b.WriteString("
\n\n") return false }) From fb2ef6c2178a54becd9b03e9d94e576b4ff66ed1 Mon Sep 17 00:00:00 2001 From: leohhhn Date: Mon, 9 Oct 2023 14:44:06 +0200 Subject: [PATCH 03/19] optimized votecount --- examples/gno.land/voting/p/poll.gno | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/examples/gno.land/voting/p/poll.gno b/examples/gno.land/voting/p/poll.gno index fdafb024a7d..e35d340411c 100644 --- a/examples/gno.land/voting/p/poll.gno +++ b/examples/gno.land/voting/p/poll.gno @@ -5,6 +5,7 @@ import ( "std" ) +// Main struct type Poll struct { title string description string @@ -12,6 +13,7 @@ type Poll struct { voters *avl.Tree // addr -> yes / no (bool) } +// Getters func (p Poll) Title() string { return p.title } @@ -28,6 +30,7 @@ func (p Poll) Voters() *avl.Tree { return p.voters } +// Poll instance constructor func NewPoll(title, description string, deadline int64) *Poll { return &Poll{ title: title, @@ -37,6 +40,7 @@ func NewPoll(title, description string, deadline int64) *Poll { } } +// Vote Votes for a user func (p *Poll) Vote(voter std.Address, vote bool) { p.Voters().Set(string(voter), vote) } @@ -50,20 +54,16 @@ func (p *Poll) HasVoted(address std.Address) (bool, bool) { return false, false } +// VoteCount Returns number of yay & nay votes func (p Poll) VoteCount() (int, int) { - var ( - yay int - nay int - ) + var yay int + p.Voters().Iterate("", "", func(key string, value interface{}) bool { vote := value.(bool) - if vote == true { yay = yay + 1 - } else { - nay = nay + 1 } }) - return yay, nay + return yay, p.Voters().Size() - yay } From df6e9595daf0486434447cf64703a8e8d7a0c1f1 Mon Sep 17 00:00:00 2001 From: leohhhn Date: Mon, 9 Oct 2023 16:51:15 +0200 Subject: [PATCH 04/19] fix rendering --- examples/gno.land/voting/p/poll.gno | 1 - examples/gno.land/voting/r/pollFactory.gno | 26 +++++++++++----------- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/examples/gno.land/voting/p/poll.gno b/examples/gno.land/voting/p/poll.gno index e35d340411c..a00c575130f 100644 --- a/examples/gno.land/voting/p/poll.gno +++ b/examples/gno.land/voting/p/poll.gno @@ -64,6 +64,5 @@ func (p Poll) VoteCount() (int, int) { yay = yay + 1 } }) - return yay, p.Voters().Size() - yay } diff --git a/examples/gno.land/voting/r/pollFactory.gno b/examples/gno.land/voting/r/pollFactory.gno index 1733d983c37..5828c8de357 100644 --- a/examples/gno.land/voting/r/pollFactory.gno +++ b/examples/gno.land/voting/r/pollFactory.gno @@ -6,8 +6,6 @@ import ( "gno.land/p/demo/poll" "gno.land/p/demo/ufmt" "std" - - "strconv" ) // state variables @@ -22,16 +20,19 @@ func init() { } func NewPoll(title, description string, deadline int64) string { - // Get block height + // get block height if deadline <= std.GetHeight() { return "Error: Deadline has to be in the future." } + // convert int ID to string used in AVL tree id := ufmt.Sprintf("%d", pollIDCounter) p := poll.NewPoll(title, description, deadline) - // set new poll in avl tree + // add new poll in avl tree polls.Set(id, p) + + // increment ID counter pollIDCounter = pollIDCounter + 1 return ufmt.Sprintf("Successfully created poll #%s!", id) @@ -40,7 +41,8 @@ func NewPoll(title, description string, deadline int64) string { func Vote(pollID int, vote bool) string { txSender := std.GetOrigCaller() - pollRaw, exists := polls.Get(strconv.Itoa(pollID)) + id := ufmt.Sprintf("%d", pollID) + pollRaw, exists := polls.Get(id) if !exists { return "Error: Poll with specified doesn't exist." @@ -58,13 +60,12 @@ func Vote(pollID int, vote bool) string { } poll.Vote(txSender, vote) - polls.Set(strconv.Itoa(pollID), poll) + polls.Set(id, poll) if vote == true { - return ufmt.Sprintf("Successfully voted YAY for poll #%d!", pollID) + return ufmt.Sprintf("Successfully voted YAY for poll #%s!", id) } - return ufmt.Sprintf("Successfully voted NAY for poll #%d!", pollID) - + return ufmt.Sprintf("Successfully voted NAY for poll #%s!", id) } func Render(path string) string { @@ -133,20 +134,19 @@ func renderHome() string { if vote == true { b.WriteString( - ufmt.Sprintf("
1. Voter %s voted YAY!\n", voter), + ufmt.Sprintf("
%s voted YAY!", voter), ) } else { b.WriteString( - ufmt.Sprintf("
1. Voter %s voted NAY!\n", voter), + ufmt.Sprintf("
%s voted NAY!", voter), ) } - b.WriteString("\n\n") return false }) + b.WriteString("\n\n") return false }) - return b.String() } From 3337d5d9df7d95d0942390045546ccce61788717 Mon Sep 17 00:00:00 2001 From: leohhhn Date: Mon, 9 Oct 2023 16:56:29 +0200 Subject: [PATCH 05/19] replaced renderHome with Render --- examples/gno.land/voting/r/pollFactory.gno | 8 -------- 1 file changed, 8 deletions(-) diff --git a/examples/gno.land/voting/r/pollFactory.gno b/examples/gno.land/voting/r/pollFactory.gno index 5828c8de357..3eb1e2069ab 100644 --- a/examples/gno.land/voting/r/pollFactory.gno +++ b/examples/gno.land/voting/r/pollFactory.gno @@ -69,13 +69,6 @@ func Vote(pollID int, vote bool) string { } func Render(path string) string { - if path == "" { - return renderHome() - } - return "tf" -} - -func renderHome() string { var b bytes.Buffer b.WriteString("# Polls!\n\n") @@ -141,7 +134,6 @@ func renderHome() string { ufmt.Sprintf("
%s voted NAY!", voter), ) } - return false }) From 66d939585321c4b782bae590444faaf4b4cf2691 Mon Sep 17 00:00:00 2001 From: leohhhn Date: Wed, 25 Oct 2023 23:02:25 -0400 Subject: [PATCH 06/19] WIP add ownable --- examples/gno.land/p/demo/ownable/ownable.gno | 54 +++++++ .../gno.land/p/demo/ownable/ownable_test.gno | 23 +++ examples/gno.land/voting/cmds.txt | 38 ----- examples/gno.land/voting/p/poll.gno | 68 --------- examples/gno.land/voting/r/pollFactory.gno | 144 ------------------ 5 files changed, 77 insertions(+), 250 deletions(-) create mode 100644 examples/gno.land/p/demo/ownable/ownable.gno create mode 100644 examples/gno.land/p/demo/ownable/ownable_test.gno delete mode 100644 examples/gno.land/voting/cmds.txt delete mode 100644 examples/gno.land/voting/p/poll.gno delete mode 100644 examples/gno.land/voting/r/pollFactory.gno diff --git a/examples/gno.land/p/demo/ownable/ownable.gno b/examples/gno.land/p/demo/ownable/ownable.gno new file mode 100644 index 00000000000..c5ab267ac74 --- /dev/null +++ b/examples/gno.land/p/demo/ownable/ownable.gno @@ -0,0 +1,54 @@ +package ownable + +import ( + "github.com/gnolang/gno/examples/gno.land/p/demo/ufmt" + "std" +) + +type Ownable struct { + owner std.Address +} + +// CallerIsOwner checks if the caller of the function is the Realm's owner +func (o *Ownable) CallerIsOwner() bool { + if std.GetOrigCaller() == o.owner { + return true + } + return false +} + +// TransferOwnership transfers ownership to a new address +// It also checks that the new owner address conforms with the bech32 standard +func (o *Ownable) TransferOwnership(newOwner std.Address) string { + if !o.CallerIsOwner() { + return "unauthorized; caller is not owner" + } + + _, _, ok := std.DecodeBech32(newOwner) + + if !ok { + return "new owner address is not valid" + } + + o.setOwner(newOwner) + return ufmt.Sprintf("owner changed to %s\n", string(newOwner)) +} + +// RenounceOwnership Removes the owner from the Realm, +// Warning - Calling RenounceOwnership practically bricks only-owner functions +func (o *Ownable) RenounceOwnership() string { + if !o.CallerIsOwner() { + return "unauthorized; caller is not owner" + } + + o.owner = "" + return "renounced ownership successfully" +} + +func (o *Ownable) GetOwner() std.Address { + return o.owner +} + +func (o *Ownable) setOwner(newOwner std.Address) { + o.owner = newOwner +} diff --git a/examples/gno.land/p/demo/ownable/ownable_test.gno b/examples/gno.land/p/demo/ownable/ownable_test.gno new file mode 100644 index 00000000000..2abce6fcf99 --- /dev/null +++ b/examples/gno.land/p/demo/ownable/ownable_test.gno @@ -0,0 +1,23 @@ +package ownable + +import "github.com/gnolang/gno/gnovm/stdlibs/testing" + +func TestSetOwnerUponInit() { + +} + +func TestTransferOwnership(t *testing.T) { + +} + +func TestCallerIsOwner(t *testing.T) { + +} + +func TestRenounceOwnership(t *testing.T) { + +} + +func TestGetOwner(t *testing.T) { + +} diff --git a/examples/gno.land/voting/cmds.txt b/examples/gno.land/voting/cmds.txt deleted file mode 100644 index 135fcd9d04d..00000000000 --- a/examples/gno.land/voting/cmds.txt +++ /dev/null @@ -1,38 +0,0 @@ -Poll cmds - -gnokey maketx addpkg \ ---pkgpath "gno.land/p/demo/poll" \ ---pkgdir "./p/" \ ---gas-fee 10000000ugnot \ ---gas-wanted 800000 \ ---broadcast \ ---chainid dev \ ---remote localhost:26657 \ -lol && gnokey maketx addpkg \ ---pkgpath "gno.land/r/demo/poll" \ ---pkgdir "./r/" \ ---gas-fee 10000000ugnot \ ---gas-wanted 800000 \ ---broadcast \ ---chainid dev \ ---remote localhost:26657 \ -lol && gnokey maketx call \ ---pkgpath "gno.land/r/demo/poll" \ ---func "NewPoll" \ ---args "Is Gno good?" \ ---args "vibe check" \ ---args 1000 \ ---gas-fee 10000000ugnot \ ---gas-wanted 800000 \ ---broadcast \ ---remote localhost:26657 \ -lol && gnokey maketx call \ ---pkgpath "gno.land/r/demo/poll" \ ---func "Vote" \ ---args 0 \ ---args true \ ---gas-fee 10000000ugnot \ ---gas-wanted 800000 \ ---broadcast \ ---remote localhost:26657 \ -lol diff --git a/examples/gno.land/voting/p/poll.gno b/examples/gno.land/voting/p/poll.gno deleted file mode 100644 index a00c575130f..00000000000 --- a/examples/gno.land/voting/p/poll.gno +++ /dev/null @@ -1,68 +0,0 @@ -package poll - -import ( - "gno.land/p/demo/avl" - "std" -) - -// Main struct -type Poll struct { - title string - description string - deadline int64 // block height - voters *avl.Tree // addr -> yes / no (bool) -} - -// Getters -func (p Poll) Title() string { - return p.title -} - -func (p Poll) Description() string { - return p.description -} - -func (p Poll) Deadline() int64 { - return p.deadline -} - -func (p Poll) Voters() *avl.Tree { - return p.voters -} - -// Poll instance constructor -func NewPoll(title, description string, deadline int64) *Poll { - return &Poll{ - title: title, - description: description, - deadline: deadline, - voters: avl.NewTree(), - } -} - -// Vote Votes for a user -func (p *Poll) Vote(voter std.Address, vote bool) { - p.Voters().Set(string(voter), vote) -} - -// HasVoted vote: yes - true, no - false -func (p *Poll) HasVoted(address std.Address) (bool, bool) { - vote, exists := p.Voters().Get(string(address)) - if exists { - return true, vote.(bool) - } - return false, false -} - -// VoteCount Returns number of yay & nay votes -func (p Poll) VoteCount() (int, int) { - var yay int - - p.Voters().Iterate("", "", func(key string, value interface{}) bool { - vote := value.(bool) - if vote == true { - yay = yay + 1 - } - }) - return yay, p.Voters().Size() - yay -} diff --git a/examples/gno.land/voting/r/pollFactory.gno b/examples/gno.land/voting/r/pollFactory.gno deleted file mode 100644 index 3eb1e2069ab..00000000000 --- a/examples/gno.land/voting/r/pollFactory.gno +++ /dev/null @@ -1,144 +0,0 @@ -package poll - -import ( - "bytes" - "gno.land/p/demo/avl" - "gno.land/p/demo/poll" - "gno.land/p/demo/ufmt" - "std" -) - -// state variables -var ( - polls *avl.Tree // id -> Poll - pollIDCounter int -) - -func init() { - polls = avl.NewTree() - pollIDCounter = 0 -} - -func NewPoll(title, description string, deadline int64) string { - // get block height - if deadline <= std.GetHeight() { - return "Error: Deadline has to be in the future." - } - - // convert int ID to string used in AVL tree - id := ufmt.Sprintf("%d", pollIDCounter) - p := poll.NewPoll(title, description, deadline) - - // add new poll in avl tree - polls.Set(id, p) - - // increment ID counter - pollIDCounter = pollIDCounter + 1 - - return ufmt.Sprintf("Successfully created poll #%s!", id) -} - -func Vote(pollID int, vote bool) string { - txSender := std.GetOrigCaller() - - id := ufmt.Sprintf("%d", pollID) - pollRaw, exists := polls.Get(id) - - if !exists { - return "Error: Poll with specified doesn't exist." - } - - poll, _ := pollRaw.(*poll.Poll) - - voted, _ := poll.HasVoted(txSender) - if voted { - return "Error: You've already voted!" - } - - if poll.Deadline() <= std.GetHeight() { - return "Error: Voting for this poll is closed." - } - - poll.Vote(txSender, vote) - polls.Set(id, poll) - - if vote == true { - return ufmt.Sprintf("Successfully voted YAY for poll #%s!", id) - } - return ufmt.Sprintf("Successfully voted NAY for poll #%s!", id) -} - -func Render(path string) string { - var b bytes.Buffer - - b.WriteString("# Polls!\n\n") - - if polls.Size() == 0 { - b.WriteString("### No active polls currently!") - return b.String() - } - polls.Iterate("", "", func(key string, value interface{}) bool { - - // cast raw data from tree into Whitelist struct - p := value.(*poll.Poll) - ddl := p.Deadline() - - yay, nay := p.VoteCount() - yayPercent := 0 - nayPercent := 0 - - if yay+nay != 0 { - yayPercent = yay * 100 / (yay + nay) - nayPercent = nay * 100 / (yay + nay) - } - - b.WriteString( - ufmt.Sprintf( - "## Poll #%s: %s\n", - key, // poll ID - p.Title(), - ), - ) - - dropdown := "
\nPoll details
" - - b.WriteString(dropdown + "Description: " + p.Description()) - - b.WriteString( - ufmt.Sprintf("
Voting until block: %d
Current vote count: %d", - p.Deadline(), - p.Voters().Size()), - ) - - b.WriteString( - ufmt.Sprintf("
YAY votes: %d (%d%%)", yay, yayPercent), - ) - b.WriteString( - ufmt.Sprintf("
NAY votes: %d (%d%%)
", nay, nayPercent), - ) - - dropdown = "
\nVote details" - b.WriteString(dropdown) - - p.Voters().Iterate("", "", func(key string, value interface{}) bool { - - voter := key - vote := value.(bool) - - if vote == true { - b.WriteString( - ufmt.Sprintf("
%s voted YAY!", voter), - ) - } else { - b.WriteString( - ufmt.Sprintf("
%s voted NAY!", voter), - ) - } - return false - }) - - b.WriteString("
\n\n") - return false - }) - return b.String() -} From 3e9fdb2a734dfb18b4b65a45d8e56658c40665b5 Mon Sep 17 00:00:00 2001 From: leohhhn Date: Thu, 26 Oct 2023 13:56:34 -0400 Subject: [PATCH 07/19] change address check --- examples/gno.land/p/demo/ownable/ownable.gno | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/examples/gno.land/p/demo/ownable/ownable.gno b/examples/gno.land/p/demo/ownable/ownable.gno index c5ab267ac74..f98263c3072 100644 --- a/examples/gno.land/p/demo/ownable/ownable.gno +++ b/examples/gno.land/p/demo/ownable/ownable.gno @@ -24,9 +24,7 @@ func (o *Ownable) TransferOwnership(newOwner std.Address) string { return "unauthorized; caller is not owner" } - _, _, ok := std.DecodeBech32(newOwner) - - if !ok { + if !newOwner.Valid() { return "new owner address is not valid" } From e01d8269252f509a5aff3110172bcfc624ec29d9 Mon Sep 17 00:00:00 2001 From: leohhhn Date: Fri, 27 Oct 2023 19:10:26 -0400 Subject: [PATCH 08/19] wip added tests --- examples/gno.land/p/demo/ownable/errors.gno | 8 +++ examples/gno.land/p/demo/ownable/ownable.gno | 46 +++++++------ .../gno.land/p/demo/ownable/ownable_test.gno | 66 +++++++++++++++++-- 3 files changed, 97 insertions(+), 23 deletions(-) create mode 100644 examples/gno.land/p/demo/ownable/errors.gno diff --git a/examples/gno.land/p/demo/ownable/errors.gno b/examples/gno.land/p/demo/ownable/errors.gno new file mode 100644 index 00000000000..ffbf6ab3f6f --- /dev/null +++ b/examples/gno.land/p/demo/ownable/errors.gno @@ -0,0 +1,8 @@ +package ownable + +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/ownable/ownable.gno b/examples/gno.land/p/demo/ownable/ownable.gno index f98263c3072..74da0e94360 100644 --- a/examples/gno.land/p/demo/ownable/ownable.gno +++ b/examples/gno.land/p/demo/ownable/ownable.gno @@ -1,46 +1,54 @@ package ownable import ( - "github.com/gnolang/gno/examples/gno.land/p/demo/ufmt" "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 { owner std.Address } -// CallerIsOwner checks if the caller of the function is the Realm's owner -func (o *Ownable) CallerIsOwner() bool { - if std.GetOrigCaller() == o.owner { - return true - } - return false +func New() *Ownable { + o := Ownable{} + caller := std.GetOrigCaller() + o.setOwner(caller) + return &o } -// TransferOwnership transfers ownership to a new address -// It also checks that the new owner address conforms with the bech32 standard -func (o *Ownable) TransferOwnership(newOwner std.Address) string { +// TransferOwnership transfers ownership of the Ownable object to a new address +func (o *Ownable) TransferOwnership(newOwner std.Address) error { if !o.CallerIsOwner() { - return "unauthorized; caller is not owner" + return ErrUnauthorized } - if !newOwner.Valid() { - return "new owner address is not valid" + if len(string(newOwner)) != 40 { + return ErrInvalidAddress } o.setOwner(newOwner) - return ufmt.Sprintf("owner changed to %s\n", string(newOwner)) + return nil } -// RenounceOwnership Removes the owner from the Realm, -// Warning - Calling RenounceOwnership practically bricks only-owner functions -func (o *Ownable) RenounceOwnership() string { +// 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 { if !o.CallerIsOwner() { - return "unauthorized; caller is not owner" + return ErrUnauthorized } o.owner = "" - return "renounced ownership successfully" + return nil +} + +// CallerIsOwner checks if the caller of the function is the Realm's owner +func (o *Ownable) CallerIsOwner() bool { + if std.GetOrigCaller() == o.owner { + return true + } + return false } func (o *Ownable) GetOwner() std.Address { diff --git a/examples/gno.land/p/demo/ownable/ownable_test.gno b/examples/gno.land/p/demo/ownable/ownable_test.gno index 2abce6fcf99..c4795a8ba7a 100644 --- a/examples/gno.land/p/demo/ownable/ownable_test.gno +++ b/examples/gno.land/p/demo/ownable/ownable_test.gno @@ -1,23 +1,81 @@ package ownable -import "github.com/gnolang/gno/gnovm/stdlibs/testing" +import ( + "std" + "testing" +) -func TestSetOwnerUponInit() { +func TestNew(t *testing.T) { + std.TestSetOrigCaller("g1l9aypkr8xfvs82zeux486ddzec88ty69lue9de") + expected := Ownable{ + owner: "g1l9aypkr8xfvs82zeux486ddzec88ty69lue9de", + } + + result := New() + if expected.owner != result.owner { + t.Fatalf("Expected %s, got: %s\n", expected.owner.String(), result.owner.String()) + } +} + +func TestGetOwner(t *testing.T) { + std.TestSetOrigCaller("g1l9aypkr8xfvs82zeux486ddzec88ty69lue9de") + + result := New() + resultOwner := result.GetOwner() + + expected := "g1l9aypkr8xfvs82zeux486ddzec88ty69lue9de" + if resultOwner.String() != expected { + t.Fatalf("Expected %s, got: %s\n", expected, result) + } } func TestTransferOwnership(t *testing.T) { + std.TestSetOrigCaller("g1l9aypkr8xfvs82zeux486ddzec88ty69lue9de") + + o := New() + secondOwner := "g127jydsh6cms3lrtdenydxsckh23a8d6emqcvfa" + err := o.TransferOwnership(std.Address(secondOwner)) + if err != nil { + t.Fatalf("TransferOwnership failed, %v", err) + } + + result := o.GetOwner() + if secondOwner != result { + t.Fatalf("Expected: %s, got: %s\n", secondOwner, result) + } } func TestCallerIsOwner(t *testing.T) { + std.TestSetOrigCaller("g1l9aypkr8xfvs82zeux486ddzec88ty69lue9de") + + o := New() + unauthorizedCaller := "g127jydsh6cms3lrtdenydxsckh23a8d6emqcvfa" + + std.TestSetOrigCaller(std.Address(unauthorizedCaller)) + if o.CallerIsOwner() { + t.Fatalf("Expected: %s to not be owner\n", unauthorizedCaller) + } } -func TestRenounceOwnership(t *testing.T) { +func TestDropOwnership(t *testing.T) { + std.TestSetOrigCaller("g1l9aypkr8xfvs82zeux486ddzec88ty69lue9de") + o := New() + + err := o.DropOwnership() + if err != nil { + t.Fatalf("DropOwnership failed, %v", err) + } + + owner := o.GetOwner() + if owner != "" { + t.Fatalf("Expected owner to be empty, not %s\n", owner) + } } -func TestGetOwner(t *testing.T) { +func TestErrors(t *testing.T) { } From b6422d9b877f8a1db24c4652db5d3cbba3c08643 Mon Sep 17 00:00:00 2001 From: leohhhn Date: Sat, 28 Oct 2023 03:51:22 -0400 Subject: [PATCH 09/19] wip added more tests --- examples/gno.land/p/demo/ownable/ownable.gno | 2 +- .../gno.land/p/demo/ownable/ownable_test.gno | 72 ++++++++++++++----- 2 files changed, 56 insertions(+), 18 deletions(-) diff --git a/examples/gno.land/p/demo/ownable/ownable.gno b/examples/gno.land/p/demo/ownable/ownable.gno index 74da0e94360..3743ba2dcdd 100644 --- a/examples/gno.land/p/demo/ownable/ownable.gno +++ b/examples/gno.land/p/demo/ownable/ownable.gno @@ -46,7 +46,7 @@ func (o *Ownable) DropOwnership() error { // CallerIsOwner checks if the caller of the function is the Realm's owner func (o *Ownable) CallerIsOwner() bool { if std.GetOrigCaller() == o.owner { - return true + return true // TODO figure out why it panics if you switch bools } return false } diff --git a/examples/gno.land/p/demo/ownable/ownable_test.gno b/examples/gno.land/p/demo/ownable/ownable_test.gno index c4795a8ba7a..3a3d19bec63 100644 --- a/examples/gno.land/p/demo/ownable/ownable_test.gno +++ b/examples/gno.land/p/demo/ownable/ownable_test.gno @@ -5,55 +5,58 @@ import ( "testing" ) +var ( + firstCaller = std.Address("g1l9aypkr8xfvs82zeux486ddzec88ty69lue9de") + secondCaller = std.Address("g127jydsh6cms3lrtdenydxsckh23a8d6emqcvfa") +) + func TestNew(t *testing.T) { - std.TestSetOrigCaller("g1l9aypkr8xfvs82zeux486ddzec88ty69lue9de") + std.TestSetOrigCaller(firstCaller) expected := Ownable{ - owner: "g1l9aypkr8xfvs82zeux486ddzec88ty69lue9de", + owner: firstCaller, } result := New() if expected.owner != result.owner { - t.Fatalf("Expected %s, got: %s\n", expected.owner.String(), result.owner.String()) + t.Fatalf("Expected %s, got: %s\n", expected.owner, result.owner) } } func TestGetOwner(t *testing.T) { - std.TestSetOrigCaller("g1l9aypkr8xfvs82zeux486ddzec88ty69lue9de") + std.TestSetOrigCaller(firstCaller) result := New() resultOwner := result.GetOwner() - expected := "g1l9aypkr8xfvs82zeux486ddzec88ty69lue9de" - if resultOwner.String() != expected { + expected := firstCaller + if resultOwner != expected { t.Fatalf("Expected %s, got: %s\n", expected, result) } } func TestTransferOwnership(t *testing.T) { - std.TestSetOrigCaller("g1l9aypkr8xfvs82zeux486ddzec88ty69lue9de") - + std.TestSetOrigCaller(firstCaller) o := New() - secondOwner := "g127jydsh6cms3lrtdenydxsckh23a8d6emqcvfa" - err := o.TransferOwnership(std.Address(secondOwner)) + err := o.TransferOwnership(secondCaller) if err != nil { t.Fatalf("TransferOwnership failed, %v", err) } result := o.GetOwner() - if secondOwner != result { - t.Fatalf("Expected: %s, got: %s\n", secondOwner, result) + if secondCaller != result { + t.Fatalf("Expected: %s, got: %s\n", secondCaller, result) } } func TestCallerIsOwner(t *testing.T) { - std.TestSetOrigCaller("g1l9aypkr8xfvs82zeux486ddzec88ty69lue9de") + std.TestSetOrigCaller(firstCaller) o := New() - unauthorizedCaller := "g127jydsh6cms3lrtdenydxsckh23a8d6emqcvfa" + unauthorizedCaller := secondCaller - std.TestSetOrigCaller(std.Address(unauthorizedCaller)) + std.TestSetOrigCaller(unauthorizedCaller) if o.CallerIsOwner() { t.Fatalf("Expected: %s to not be owner\n", unauthorizedCaller) @@ -61,7 +64,7 @@ func TestCallerIsOwner(t *testing.T) { } func TestDropOwnership(t *testing.T) { - std.TestSetOrigCaller("g1l9aypkr8xfvs82zeux486ddzec88ty69lue9de") + std.TestSetOrigCaller(firstCaller) o := New() @@ -76,6 +79,41 @@ func TestDropOwnership(t *testing.T) { } } -func TestErrors(t *testing.T) { +// TODO add embedded Tests? + +// Errors + +func TestErrUnauthorized(t *testing.T) { + std.TestSetOrigCaller(firstCaller) + + o := New() + + std.TestSetOrigCaller(secondCaller) + + err := o.TransferOwnership(firstCaller) + if err != ErrUnauthorized { // TODO errors.Is doesnt work + t.Fatalf("Shoud've been ErrUnauthorized, was %v", err) + } + + err = o.DropOwnership() + if err != ErrUnauthorized { + t.Fatalf("Shoud've been ErrUnauthorized, was %v", err) + } +} + +func TestErrInvalidAddress(t *testing.T) { + std.TestSetOrigCaller(firstCaller) + + o := New() + + err := o.TransferOwnership("") + if err != ErrInvalidAddress { + t.Fatalf("Shoud've been ErrInvalidAddress, was %v", err) + } + + err = o.TransferOwnership("10000000001000000000100000000010000000001000000000") + if err != ErrInvalidAddress { + t.Fatalf("Shoud've been ErrInvalidAddress, was %v", err) + } } From 749272b81ca2dd38f053549ab6bf38ab302c10b1 Mon Sep 17 00:00:00 2001 From: leohhhn Date: Sat, 28 Oct 2023 11:23:59 +0200 Subject: [PATCH 10/19] remove comment --- 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 3743ba2dcdd..74da0e94360 100644 --- a/examples/gno.land/p/demo/ownable/ownable.gno +++ b/examples/gno.land/p/demo/ownable/ownable.gno @@ -46,7 +46,7 @@ func (o *Ownable) DropOwnership() error { // CallerIsOwner checks if the caller of the function is the Realm's owner func (o *Ownable) CallerIsOwner() bool { if std.GetOrigCaller() == o.owner { - return true // TODO figure out why it panics if you switch bools + return true } return false } From 814e4bdbc773f13d5cbd9c78ac29fff8c7d8e131 Mon Sep 17 00:00:00 2001 From: leohhhn Date: Sun, 29 Oct 2023 01:59:16 +0200 Subject: [PATCH 11/19] add address validity check --- 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 74da0e94360..040a3bd578d 100644 --- a/examples/gno.land/p/demo/ownable/ownable.gno +++ b/examples/gno.land/p/demo/ownable/ownable.gno @@ -23,7 +23,7 @@ func (o *Ownable) TransferOwnership(newOwner std.Address) error { return ErrUnauthorized } - if len(string(newOwner)) != 40 { + if !newOwner.IsValid() { return ErrInvalidAddress } From d6edf8f860080aaeea421f0220690271d8ccc4a8 Mon Sep 17 00:00:00 2001 From: leohhhn Date: Mon, 30 Oct 2023 15:33:44 +0100 Subject: [PATCH 12/19] minor test change --- examples/gno.land/p/demo/ownable/ownable.gno | 2 +- examples/gno.land/p/demo/ownable/ownable_test.gno | 8 ++------ 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/examples/gno.land/p/demo/ownable/ownable.gno b/examples/gno.land/p/demo/ownable/ownable.gno index 040a3bd578d..1450e931323 100644 --- a/examples/gno.land/p/demo/ownable/ownable.gno +++ b/examples/gno.land/p/demo/ownable/ownable.gno @@ -17,7 +17,7 @@ func New() *Ownable { return &o } -// TransferOwnership transfers ownership of the Ownable object to a new address +// TransferOwnership transfers ownership of the Ownable struct to a new address func (o *Ownable) TransferOwnership(newOwner std.Address) error { if !o.CallerIsOwner() { 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 3a3d19bec63..cf77f0bb37a 100644 --- a/examples/gno.land/p/demo/ownable/ownable_test.gno +++ b/examples/gno.land/p/demo/ownable/ownable_test.gno @@ -13,13 +13,9 @@ var ( func TestNew(t *testing.T) { std.TestSetOrigCaller(firstCaller) - expected := Ownable{ - owner: firstCaller, - } - result := New() - if expected.owner != result.owner { - t.Fatalf("Expected %s, got: %s\n", expected.owner, result.owner) + if firstCaller != result.owner { + t.Fatalf("Expected %s, got: %s\n", firstCaller, result.owner) } } From 7180d477b0cfdae5601be63eea7b74954ef529d8 Mon Sep 17 00:00:00 2001 From: leohhhn Date: Tue, 31 Oct 2023 12:28:46 +0100 Subject: [PATCH 13/19] minor changes --- examples/gno.land/p/demo/ownable/ownable.gno | 13 ++++--------- examples/gno.land/p/demo/ownable/ownable_test.gno | 2 -- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/examples/gno.land/p/demo/ownable/ownable.gno b/examples/gno.land/p/demo/ownable/ownable.gno index 1450e931323..5dce1d7bd52 100644 --- a/examples/gno.land/p/demo/ownable/ownable.gno +++ b/examples/gno.land/p/demo/ownable/ownable.gno @@ -11,10 +11,9 @@ type Ownable struct { } func New() *Ownable { - o := Ownable{} - caller := std.GetOrigCaller() - o.setOwner(caller) - return &o + return &Ownable{ + owner: std.GetOrigCaller(), + } } // TransferOwnership transfers ownership of the Ownable struct to a new address @@ -27,7 +26,7 @@ func (o *Ownable) TransferOwnership(newOwner std.Address) error { return ErrInvalidAddress } - o.setOwner(newOwner) + o.owner = newOwner return nil } @@ -54,7 +53,3 @@ func (o *Ownable) CallerIsOwner() bool { func (o *Ownable) GetOwner() std.Address { return o.owner } - -func (o *Ownable) setOwner(newOwner std.Address) { - o.owner = newOwner -} diff --git a/examples/gno.land/p/demo/ownable/ownable_test.gno b/examples/gno.land/p/demo/ownable/ownable_test.gno index cf77f0bb37a..69ddb611874 100644 --- a/examples/gno.land/p/demo/ownable/ownable_test.gno +++ b/examples/gno.land/p/demo/ownable/ownable_test.gno @@ -75,8 +75,6 @@ func TestDropOwnership(t *testing.T) { } } -// TODO add embedded Tests? - // Errors func TestErrUnauthorized(t *testing.T) { From d215384f6092dbe1e4fa1bbea9ceee6c73e04db2 Mon Sep 17 00:00:00 2001 From: leohhhn Date: Wed, 1 Nov 2023 00:11:58 +0100 Subject: [PATCH 14/19] minor refactor] --- examples/gno.land/p/demo/ownable/ownable.gno | 18 +++++++++++------- .../gno.land/p/demo/ownable/ownable_test.gno | 6 ++++-- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/examples/gno.land/p/demo/ownable/ownable.gno b/examples/gno.land/p/demo/ownable/ownable.gno index 5dce1d7bd52..1bf6af672f8 100644 --- a/examples/gno.land/p/demo/ownable/ownable.gno +++ b/examples/gno.land/p/demo/ownable/ownable.gno @@ -18,8 +18,10 @@ func New() *Ownable { // TransferOwnership transfers ownership of the Ownable struct to a new address func (o *Ownable) TransferOwnership(newOwner std.Address) error { - if !o.CallerIsOwner() { - return ErrUnauthorized + err := o.CallerIsOwner() + + if err != nil { + return err } if !newOwner.IsValid() { @@ -34,8 +36,10 @@ func (o *Ownable) 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 *Ownable) DropOwnership() error { - if !o.CallerIsOwner() { - return ErrUnauthorized + err := o.CallerIsOwner() + + if err != nil { + return err } o.owner = "" @@ -43,11 +47,11 @@ func (o *Ownable) DropOwnership() error { } // CallerIsOwner checks if the caller of the function is the Realm's owner -func (o *Ownable) CallerIsOwner() bool { +func (o *Ownable) CallerIsOwner() error { if std.GetOrigCaller() == o.owner { - return true + return nil } - return false + return ErrUnauthorized } func (o *Ownable) GetOwner() std.Address { diff --git a/examples/gno.land/p/demo/ownable/ownable_test.gno b/examples/gno.land/p/demo/ownable/ownable_test.gno index 69ddb611874..bc3ecbac779 100644 --- a/examples/gno.land/p/demo/ownable/ownable_test.gno +++ b/examples/gno.land/p/demo/ownable/ownable_test.gno @@ -54,8 +54,10 @@ func TestCallerIsOwner(t *testing.T) { std.TestSetOrigCaller(unauthorizedCaller) - if o.CallerIsOwner() { - t.Fatalf("Expected: %s to not be owner\n", unauthorizedCaller) + err := o.CallerIsOwner() + + if err == nil { + t.Fatalf("Expected %s to not be owner\n", unauthorizedCaller) } } From 1f67228ef5fe0b7c10c8bff0006df284bb111a2b Mon Sep 17 00:00:00 2001 From: leohhhn Date: Thu, 2 Nov 2023 10:14:15 +0100 Subject: [PATCH 15/19] run make fmt --- examples/gno.land/p/demo/ownable/ownable.gno | 2 -- 1 file changed, 2 deletions(-) diff --git a/examples/gno.land/p/demo/ownable/ownable.gno b/examples/gno.land/p/demo/ownable/ownable.gno index 1bf6af672f8..495662b854c 100644 --- a/examples/gno.land/p/demo/ownable/ownable.gno +++ b/examples/gno.land/p/demo/ownable/ownable.gno @@ -19,7 +19,6 @@ func New() *Ownable { // TransferOwnership transfers ownership of the Ownable struct to a new address func (o *Ownable) TransferOwnership(newOwner std.Address) error { err := o.CallerIsOwner() - if err != nil { return err } @@ -37,7 +36,6 @@ func (o *Ownable) TransferOwnership(newOwner std.Address) error { // Embedded usage: behaves like a burn functionality, removing the owner from the struct func (o *Ownable) DropOwnership() error { err := o.CallerIsOwner() - if err != nil { return err } From f24daacdde679fe20c2280d92c57567b7919e426 Mon Sep 17 00:00:00 2001 From: leohhhn Date: Thu, 2 Nov 2023 10:18:22 +0100 Subject: [PATCH 16/19] add gno.mod --- examples/gno.land/p/demo/ownable/gno.mod | 1 + 1 file changed, 1 insertion(+) create mode 100644 examples/gno.land/p/demo/ownable/gno.mod diff --git a/examples/gno.land/p/demo/ownable/gno.mod b/examples/gno.land/p/demo/ownable/gno.mod new file mode 100644 index 00000000000..9a9abb1e661 --- /dev/null +++ b/examples/gno.land/p/demo/ownable/gno.mod @@ -0,0 +1 @@ +module gno.land/p/demo/ownable From 1d1ca12e408d79412e7ceed226765d0e821810ca Mon Sep 17 00:00:00 2001 From: leohhhn Date: Thu, 2 Nov 2023 10:41:45 +0100 Subject: [PATCH 17/19] formatting --- examples/gno.land/p/demo/ownable/ownable_test.gno | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/examples/gno.land/p/demo/ownable/ownable_test.gno b/examples/gno.land/p/demo/ownable/ownable_test.gno index bc3ecbac779..3ee9e85531e 100644 --- a/examples/gno.land/p/demo/ownable/ownable_test.gno +++ b/examples/gno.land/p/demo/ownable/ownable_test.gno @@ -55,7 +55,6 @@ func TestCallerIsOwner(t *testing.T) { std.TestSetOrigCaller(unauthorizedCaller) err := o.CallerIsOwner() - if err == nil { t.Fatalf("Expected %s to not be owner\n", unauthorizedCaller) } @@ -87,7 +86,7 @@ func TestErrUnauthorized(t *testing.T) { std.TestSetOrigCaller(secondCaller) err := o.TransferOwnership(firstCaller) - if err != ErrUnauthorized { // TODO errors.Is doesnt work + if err != ErrUnauthorized { t.Fatalf("Shoud've been ErrUnauthorized, was %v", err) } @@ -103,7 +102,6 @@ func TestErrInvalidAddress(t *testing.T) { o := New() err := o.TransferOwnership("") - if err != ErrInvalidAddress { t.Fatalf("Shoud've been ErrInvalidAddress, was %v", err) } From fb51a9f84ffa2eb9866644c0c5e1b8ef895f6f57 Mon Sep 17 00:00:00 2001 From: leohhhn Date: Thu, 2 Nov 2023 11:46:14 +0100 Subject: [PATCH 18/19] updated getter function --- examples/gno.land/p/demo/ownable/ownable.gno | 2 +- examples/gno.land/p/demo/ownable/ownable_test.gno | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/gno.land/p/demo/ownable/ownable.gno b/examples/gno.land/p/demo/ownable/ownable.gno index 495662b854c..9fd526fb283 100644 --- a/examples/gno.land/p/demo/ownable/ownable.gno +++ b/examples/gno.land/p/demo/ownable/ownable.gno @@ -52,6 +52,6 @@ func (o *Ownable) CallerIsOwner() error { return ErrUnauthorized } -func (o *Ownable) GetOwner() std.Address { +func (o *Ownable) 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 3ee9e85531e..c7000ecd788 100644 --- a/examples/gno.land/p/demo/ownable/ownable_test.gno +++ b/examples/gno.land/p/demo/ownable/ownable_test.gno @@ -23,7 +23,7 @@ func TestGetOwner(t *testing.T) { std.TestSetOrigCaller(firstCaller) result := New() - resultOwner := result.GetOwner() + resultOwner := result.Owner() expected := firstCaller if resultOwner != expected { @@ -40,7 +40,7 @@ func TestTransferOwnership(t *testing.T) { t.Fatalf("TransferOwnership failed, %v", err) } - result := o.GetOwner() + result := o.Owner() if secondCaller != result { t.Fatalf("Expected: %s, got: %s\n", secondCaller, result) } @@ -70,7 +70,7 @@ func TestDropOwnership(t *testing.T) { t.Fatalf("DropOwnership failed, %v", err) } - owner := o.GetOwner() + owner := o.Owner() if owner != "" { t.Fatalf("Expected owner to be empty, not %s\n", owner) } From 534f96b8fbc7466ed58c84dae28341b3e960979a Mon Sep 17 00:00:00 2001 From: leohhhn Date: Thu, 2 Nov 2023 13:13:18 +0100 Subject: [PATCH 19/19] fix typos --- examples/gno.land/p/demo/ownable/ownable.gno | 2 +- examples/gno.land/p/demo/ownable/ownable_test.gno | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/gno.land/p/demo/ownable/ownable.gno b/examples/gno.land/p/demo/ownable/ownable.gno index 9fd526fb283..7f2eac008e1 100644 --- a/examples/gno.land/p/demo/ownable/ownable.gno +++ b/examples/gno.land/p/demo/ownable/ownable.gno @@ -31,7 +31,7 @@ func (o *Ownable) TransferOwnership(newOwner std.Address) error { return nil } -// DropOwnership Removes the owner, effectively disabling any owner-related actions +// 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 { diff --git a/examples/gno.land/p/demo/ownable/ownable_test.gno b/examples/gno.land/p/demo/ownable/ownable_test.gno index c7000ecd788..f725795fd47 100644 --- a/examples/gno.land/p/demo/ownable/ownable_test.gno +++ b/examples/gno.land/p/demo/ownable/ownable_test.gno @@ -19,7 +19,7 @@ func TestNew(t *testing.T) { } } -func TestGetOwner(t *testing.T) { +func TestOwner(t *testing.T) { std.TestSetOrigCaller(firstCaller) result := New() @@ -87,12 +87,12 @@ func TestErrUnauthorized(t *testing.T) { err := o.TransferOwnership(firstCaller) if err != ErrUnauthorized { - t.Fatalf("Shoud've been ErrUnauthorized, was %v", err) + t.Fatalf("Should've been ErrUnauthorized, was %v", err) } err = o.DropOwnership() if err != ErrUnauthorized { - t.Fatalf("Shoud've been ErrUnauthorized, was %v", err) + t.Fatalf("Should've been ErrUnauthorized, was %v", err) } } @@ -103,11 +103,11 @@ func TestErrInvalidAddress(t *testing.T) { err := o.TransferOwnership("") if err != ErrInvalidAddress { - t.Fatalf("Shoud've been ErrInvalidAddress, was %v", err) + t.Fatalf("Should've been ErrInvalidAddress, was %v", err) } err = o.TransferOwnership("10000000001000000000100000000010000000001000000000") if err != ErrInvalidAddress { - t.Fatalf("Shoud've been ErrInvalidAddress, was %v", err) + t.Fatalf("Should've been ErrInvalidAddress, was %v", err) } }