From b840b9e970c804934673999af2c582cd296bf7d3 Mon Sep 17 00:00:00 2001 From: Manfred Touron <94029+moul@users.noreply.github.com> Date: Thu, 4 Aug 2022 21:27:31 +0200 Subject: [PATCH] chore: refactor gno.land/p/grc structure (#309) * chore: refactor gno.land/p/grc structure Signed-off-by: Manfred Touron <94029+moul@users.noreply.github.com> --- cmd/gnoland/main.go | 2 +- examples/gno.land/p/grc/README.md | 14 + .../gno.land/p/grc/exts/token-metadata.gno | 12 + examples/gno.land/p/grc/grc20/grc20.gno | 262 ++++++++++++++---- examples/gno.land/p/grc/grc20/igrc20.gno | 72 +++++ examples/gno.land/p/grc/grc20/impl/impl.gno | 208 -------------- .../p/grc/grc721/{grc721.gno => igrc721.gno} | 2 +- .../gno.land/r/foo20/{foo.gno => foo20.gno} | 2 +- .../foo20/{foo200_test.gno => foo20_test.gno} | 2 - examples/gno.land/r/nft/nft.gno | 38 +-- examples/gno.land/r/nft/z_0_filetest.gno | 2 +- examples/gno.land/r/nft/z_1_filetest.gno | 2 +- examples/gno.land/r/nft/z_2_filetest.gno | 2 +- examples/gno.land/r/nft/z_3_filetest.gno | 2 +- examples/gno.land/r/nft/z_4_filetest.gno | 2 +- 15 files changed, 327 insertions(+), 297 deletions(-) create mode 100644 examples/gno.land/p/grc/README.md create mode 100644 examples/gno.land/p/grc/exts/token-metadata.gno create mode 100644 examples/gno.land/p/grc/grc20/igrc20.gno delete mode 100644 examples/gno.land/p/grc/grc20/impl/impl.gno rename examples/gno.land/p/grc/grc721/{grc721.gno => igrc721.gno} (96%) rename examples/gno.land/r/foo20/{foo.gno => foo20.gno} (98%) rename examples/gno.land/r/foo20/{foo200_test.gno => foo20_test.gno} (99%) diff --git a/cmd/gnoland/main.go b/cmd/gnoland/main.go index 1887e59a21c..80503ef6a98 100644 --- a/cmd/gnoland/main.go +++ b/cmd/gnoland/main.go @@ -134,8 +134,8 @@ func makeGenesisDoc(pvPub crypto.PubKey) *bft.GenesisDoc { for _, path := range []string{ "p/ufmt", "p/avl", + "p/grc/exts", "p/grc/grc20", - "p/grc/grc20/impl", "p/grc/grc721", "p/maths", "r/users", diff --git a/examples/gno.land/p/grc/README.md b/examples/gno.land/p/grc/README.md new file mode 100644 index 00000000000..c21e5b7a66a --- /dev/null +++ b/examples/gno.land/p/grc/README.md @@ -0,0 +1,14 @@ +# GRC: Gnoland Request for Comments + +GRCs are the Gnoland's equivalent of Ethereum's ERCs and EIPs, or Bitcoin's BIPs. + +This folder contains interfaces, examples, and implementations of standard smart-contracts and patterns. + +## Acknowledgment + +Based and adapted from the work and discussions with people from: + +* https://ethereum.org/en/developers/docs/standards/ +* https://www.openzeppelin.com/ +* https://github.com/transmissions11/solmate +* https://github.com/bitcoin/bips diff --git a/examples/gno.land/p/grc/exts/token-metadata.gno b/examples/gno.land/p/grc/exts/token-metadata.gno new file mode 100644 index 00000000000..c1d7a463300 --- /dev/null +++ b/examples/gno.land/p/grc/exts/token-metadata.gno @@ -0,0 +1,12 @@ +package exts + +type TokenMetadata interface { + // Returns the name of the token. + Name() string + + // Returns the symbol of the token. + Symbol() string + + // Returns the decimals places of the token. + Decimals() uint +} diff --git a/examples/gno.land/p/grc/grc20/grc20.gno b/examples/gno.land/p/grc/grc20/grc20.gno index ba6013a1272..a1cf30da4ce 100644 --- a/examples/gno.land/p/grc/grc20/grc20.gno +++ b/examples/gno.land/p/grc/grc20/grc20.gno @@ -1,64 +1,206 @@ package grc20 -import "std" - -type GRC20 interface { - // Returns the amount of tokens in existence. - TotalSupply() uint64 - - // Returns the amount of tokens owned by `account`. - BalanceOf(address std.Address) uint64 - - // Moves `amount` tokens from the caller's account to `to`. - // - // Returns a boolean value indicating whether the operation succeeded. - // - // Emits a {EventTransfer} event. - Transfer(to std.Address, amount uint64) bool - - // Returns the remaining number of tokens that `spender` will be - // allowed to spend on behalf of `owner` through {transferFrom}. This is - // zero by default. - // - // This value changes when {approve} or {transferFrom} are called. - Allowance(owner, spender std.Address) uint64 - - // Sets `amount` as the allowance of `spender` over the caller's tokens. - // Returns a boolean value indicating whether the operation succeeded. - // - // IMPORTANT: Beware that changing an allowance with this method brings the risk - // that someone may use both the old and the new allowance by unfortunate - // transaction ordering. One possible solution to mitigate this race - // condition is to first reduce the spender's allowance to 0 and set the - // desired value afterwards: - // https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 - // - // Emits an {EventApproval} event. - Approve(spender std.Address, amount uint64) bool - - // Moves `amount` tokens from `from` to `to` using the - // allowance mechanism. `amount` is then deducted from the caller's - // allowance. - // - // Returns a boolean value indicating whether the operation succeeded. - // - // Emits a {EventTransfer} event. - TransferFrom(from, to std.Address, amount uint64) bool -} - -// Emitted when `value` tokens are moved from one account (`from`) to another (`to`). +import ( + "std" + + "gno.land/p/avl" + "gno.land/p/ufmt" +) + +// FIXME: helper that creates a Permissionless instance of the token (without mint, and with caller as address). + +type Token struct { + IGRC20 // implements the GRC20 interface + + name string + symbol string + decimals uint + totalSupply uint64 + balances *avl.MutTree // std.Address(owner) -> uint64 + allowances *avl.MutTree // string(owner+":"+spender) -> uint64 +} + +func NewToken(name, symbol string, decimals uint) *Token { + // FIXME: check for limits + + return &Token{ + name: name, + symbol: symbol, + decimals: decimals, + + balances: avl.NewMutTree(), + allowances: avl.NewMutTree(), + } +} + +const zeroAddress = std.Address("") + +// GRC20 implementation. // -// Note that `value` may be zero. -type TransferEvent struct { - From std.Address - To std.Address - Value uint64 -} - -// Emitted when the allowance of a `spender` for an `owner` is set by -// a call to {approve}. `value` is the new allowance. -type ApprovalEvent struct { - Owner std.Address - Spender std.Address - Value uint64 + +// TODO: create a reusable interface with optional hooks. +// TODO: simplify the API and try to use events when available. +// TODO: useful Render() method. +// TODO: add a lot of unit tests, really a lot. + +func (t *Token) GetName() string { return t.name } +func (t *Token) GetSymbol() string { return t.symbol } +func (t *Token) GetDecimals() uint { return t.decimals } +func (t *Token) TotalSupply() uint64 { return t.totalSupply } + +func (t *Token) BalanceOf(owner std.Address) uint64 { + return t.balanceOf(owner) +} + +func (t *Token) Transfer(owner, to std.Address, amount uint64) { + t.transfer(owner, to, amount) +} + +func (t *Token) Allowance(owner, spender std.Address) uint64 { + return t.allowance(owner, spender) +} + +func (t *Token) Approve(owner, spender std.Address, amount uint64) { + t.approve(owner, spender, amount) +} + +func (t *Token) TransferFrom(spender, from, to std.Address, amount uint64) { + t.spendAllowance(from, spender, amount) + t.transfer(from, to, amount) +} + +// Administration helpers implementation. +// + +func (t *Token) Mint(to std.Address, amount uint64) { + t.mint(to, amount) +} + +func (t *Token) Burn(from std.Address, amount uint64) { + t.burn(from, amount) +} + +// private helpers +// + +func (t *Token) mint(address std.Address, amount uint64) { + checkIsValidAddress(address) + // TODO: check for overflow + + t.totalSupply += amount + currentBalance := t.balanceOf(address) + newBalance := currentBalance + amount + + t.balances.Set(string(address), newBalance) + + event := TransferEvent{zeroAddress, address, amount} + emit(&event) +} + +func (t *Token) burn(address std.Address, amount uint64) { + checkIsValidAddress(address) + // TODO: check for overflow + + currentBalance := t.balanceOf(address) + if currentBalance < amount { + panic("insufficient balance") + } + + t.totalSupply -= amount + newBalance := currentBalance - amount + + t.balances.Set(string(address), newBalance) + + event := TransferEvent{address, zeroAddress, amount} + emit(&event) +} + +func (t *Token) balanceOf(address std.Address) uint64 { + checkIsValidAddress(address) + + balance, found := t.balances.Get(address.String()) + if !found { + return 0 + } + return balance.(uint64) +} + +func (t *Token) spendAllowance(owner, spender std.Address, amount uint64) { + checkIsValidAddress(owner) + checkIsValidAddress(spender) + + currentAllowance := t.allowance(owner, spender) + if currentAllowance < amount { + panic("insufficient allowance") + } +} + +func (t *Token) transfer(from, to std.Address, amount uint64) { + checkIsValidAddress(from) + checkIsValidAddress(to) + + if from == to { + panic("cannot send transfer to self") + } + + toBalance := t.balanceOf(to) + fromBalance := t.balanceOf(from) + + if fromBalance < amount { + panic("insufficient balance") + } + + newToBalance := toBalance + amount + newFromBalance := fromBalance - amount + + t.balances.Set(string(to), newToBalance) + t.balances.Set(string(from), newFromBalance) + + event := TransferEvent{from, to, amount} + emit(&event) +} + +func (t *Token) allowance(owner, spender std.Address) uint64 { + checkIsValidAddress(owner) + checkIsValidAddress(spender) + + key := owner.String() + ":" + spender.String() + + allowance, found := t.allowances.Get(key) + if !found { + return 0 + } + + return allowance.(uint64) +} + +func (t *Token) approve(owner, spender std.Address, amount uint64) { + checkIsValidAddress(owner) + checkIsValidAddress(spender) + + key := owner.String() + ":" + spender.String() + t.allowances.Set(key, amount) + + event := ApprovalEvent{owner, spender, amount} + emit(&event) +} + +func checkIsValidAddress(addr std.Address) { + if addr.String() == "" { + panic("invalid address") + } +} + +func (t *Token) RenderHome() string { + str := "" + str += ufmt.Sprintf("# %s ($%s)\n\n", t.name, t.symbol) + str += ufmt.Sprintf("* **Decimals**: %d\n", t.decimals) + str += ufmt.Sprintf("* **Total supply**: %d\n", t.totalSupply) + str += ufmt.Sprintf("* **Known accounts**: %d\n", t.balances.Size()) + return str +} + +func emit(event interface{}) { + // TODO: should we do something there? + // noop } diff --git a/examples/gno.land/p/grc/grc20/igrc20.gno b/examples/gno.land/p/grc/grc20/igrc20.gno new file mode 100644 index 00000000000..f98dd0c6090 --- /dev/null +++ b/examples/gno.land/p/grc/grc20/igrc20.gno @@ -0,0 +1,72 @@ +package grc20 + +import ( + "std" + + "gno.land/p/grc/exts" +) + +// TODO: use big.Int or a custom uint256 instead of uint64? + +type IGRC20 interface { + exts.TokenMetadata + + // Returns the amount of tokens in existence. + TotalSupply() uint64 + + // Returns the amount of tokens owned by `account`. + BalanceOf(account std.Address) uint64 + + // Moves `amount` tokens from the caller's account to `to`. + // + // Returns a boolean value indicating whether the operation succeeded. + // + // Emits a {EventTransfer} event. + Transfer(to std.Address, amount uint64) bool + + // Returns the remaining number of tokens that `spender` will be + // allowed to spend on behalf of `owner` through {transferFrom}. This is + // zero by default. + // + // This value changes when {approve} or {transferFrom} are called. + Allowance(owner, spender std.Address) uint64 + + // Sets `amount` as the allowance of `spender` over the caller's tokens. + // Returns a boolean value indicating whether the operation succeeded. + // + // IMPORTANT: Beware that changing an allowance with this method brings the risk + // that someone may use both the old and the new allowance by unfortunate + // transaction ordering. One possible solution to mitigate this race + // condition is to first reduce the spender's allowance to 0 and set the + // desired value afterwards: + // https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 + // + // Emits an {EventApproval} event. + Approve(spender std.Address, amount uint64) bool + + // Moves `amount` tokens from `from` to `to` using the + // allowance mechanism. `amount` is then deducted from the caller's + // allowance. + // + // Returns a boolean value indicating whether the operation succeeded. + // + // Emits a {EventTransfer} event. + TransferFrom(from, to std.Address, amount uint64) bool +} + +// Emitted when `value` tokens are moved from one account (`from`) to another (`to`). +// +// Note that `value` may be zero. +type TransferEvent struct { + From std.Address + To std.Address + Value uint64 +} + +// Emitted when the allowance of a `spender` for an `owner` is set by +// a call to {approve}. `value` is the new allowance. +type ApprovalEvent struct { + Owner std.Address + Spender std.Address + Value uint64 +} diff --git a/examples/gno.land/p/grc/grc20/impl/impl.gno b/examples/gno.land/p/grc/grc20/impl/impl.gno deleted file mode 100644 index 08f0e8d0c8f..00000000000 --- a/examples/gno.land/p/grc/grc20/impl/impl.gno +++ /dev/null @@ -1,208 +0,0 @@ -package grc20impl - -import ( - "std" - - "gno.land/p/avl" - "gno.land/p/grc/grc20" - "gno.land/p/ufmt" -) - -type Token struct { - // TODO: use big.Int or a custom uint256 instead of uint64? - - grc20.GRC20 // implements the GRC20 interface - - name string - symbol string - decimals uint - totalSupply uint64 - - balances *avl.MutTree // std.Address(owner) -> uint64 - allowances *avl.MutTree // string(owner+":"+spender) -> uint64 -} - -func NewToken(name, symbol string, decimals uint) *Token { - // FIXME: check for limits - - return &Token{ - name: name, - symbol: symbol, - decimals: decimals, - - balances: avl.NewMutTree(), - allowances: avl.NewMutTree(), - } -} - -const zeroAddress = std.Address("") - -// GRC20 implementation. -// - -// TODO: create a reusable interface with optional hooks. -// TODO: simplify the API and try to use events when available. -// TODO: useful Render() method. -// TODO: add a lot of unit tests, really a lot. - -func (t *Token) GetName() string { return t.name } -func (t *Token) GetSymbol() string { return t.symbol } -func (t *Token) GetDecimals() uint { return t.decimals } -func (t *Token) TotalSupply() uint64 { return t.totalSupply } - -func (t *Token) BalanceOf(owner std.Address) uint64 { - return t.balanceOf(owner) -} - -func (t *Token) Transfer(owner, to std.Address, amount uint64) { - t.transfer(owner, to, amount) -} - -func (t *Token) Allowance(owner, spender std.Address) uint64 { - return t.allowance(owner, spender) -} - -func (t *Token) Approve(owner, spender std.Address, amount uint64) { - t.approve(owner, spender, amount) -} - -func (t *Token) TransferFrom(spender, from, to std.Address, amount uint64) { - t.spendAllowance(from, spender, amount) - t.transfer(from, to, amount) -} - -// Administration helpers implementation. -// - -func (t *Token) Mint(to std.Address, amount uint64) { - t.mint(to, amount) -} - -func (t *Token) Burn(from std.Address, amount uint64) { - t.burn(from, amount) -} - -// private helpers -// - -func (t *Token) mint(address std.Address, amount uint64) { - checkIsValidAddress(address) - // TODO: check for overflow - - t.totalSupply += amount - currentBalance := t.balanceOf(address) - newBalance := currentBalance + amount - - t.balances.Set(string(address), newBalance) - - event := grc20.TransferEvent{zeroAddress, address, amount} - emit(&event) -} - -func (t *Token) burn(address std.Address, amount uint64) { - checkIsValidAddress(address) - // TODO: check for overflow - - currentBalance := t.balanceOf(address) - if currentBalance < amount { - panic("insufficient balance") - } - - t.totalSupply -= amount - newBalance := currentBalance - amount - - t.balances.Set(string(address), newBalance) - - event := grc20.TransferEvent{address, zeroAddress, amount} - emit(&event) -} - -func (t *Token) balanceOf(address std.Address) uint64 { - checkIsValidAddress(address) - - balance, found := t.balances.Get(address.String()) - if !found { - return 0 - } - return balance.(uint64) -} - -func (t *Token) spendAllowance(owner, spender std.Address, amount uint64) { - checkIsValidAddress(owner) - checkIsValidAddress(spender) - - currentAllowance := t.allowance(owner, spender) - if currentAllowance < amount { - panic("insufficient allowance") - } -} - -func (t *Token) transfer(from, to std.Address, amount uint64) { - checkIsValidAddress(from) - checkIsValidAddress(to) - - if from == to { - panic("cannot send transfer to self") - } - - toBalance := t.balanceOf(to) - fromBalance := t.balanceOf(from) - - if fromBalance < amount { - panic("insufficient balance") - } - - newToBalance := toBalance + amount - newFromBalance := fromBalance - amount - - t.balances.Set(string(to), newToBalance) - t.balances.Set(string(from), newFromBalance) - - event := grc20.TransferEvent{from, to, amount} - emit(&event) -} - -func (t *Token) allowance(owner, spender std.Address) uint64 { - checkIsValidAddress(owner) - checkIsValidAddress(spender) - - key := owner.String() + ":" + spender.String() - - allowance, found := t.allowances.Get(key) - if !found { - return 0 - } - - return allowance.(uint64) -} - -func (t *Token) approve(owner, spender std.Address, amount uint64) { - checkIsValidAddress(owner) - checkIsValidAddress(spender) - - key := owner.String() + ":" + spender.String() - t.allowances.Set(key, amount) - - event := grc20.ApprovalEvent{owner, spender, amount} - emit(&event) -} - -func checkIsValidAddress(addr std.Address) { - if addr.String() == "" { - panic("invalid address") - } -} - -func (t *Token) RenderHome() string { - str := "" - str += ufmt.Sprintf("# %s ($%s)\n\n", t.name, t.symbol) - str += ufmt.Sprintf("* **Decimals**: %d\n", t.decimals) - str += ufmt.Sprintf("* **Total supply**: %d\n", t.totalSupply) - str += ufmt.Sprintf("* **Known accounts**: %d\n", t.balances.Size()) - return str -} - -func emit(event interface{}) { - // TODO: should we do something there? - // noop -} diff --git a/examples/gno.land/p/grc/grc721/grc721.gno b/examples/gno.land/p/grc/grc721/igrc721.gno similarity index 96% rename from examples/gno.land/p/grc/grc721/grc721.gno rename to examples/gno.land/p/grc/grc721/igrc721.gno index 5d8e16ca564..0e82a0e4878 100644 --- a/examples/gno.land/p/grc/grc721/grc721.gno +++ b/examples/gno.land/p/grc/grc721/igrc721.gno @@ -2,7 +2,7 @@ package grc721 import "std" -type GRC721 interface { +type IGRC721 interface { BalanceOf(owner std.Address) (count int64) OwnerOf(tid TokenID) std.Address SafeTransferFrom(from, to std.Address, tid TokenID) diff --git a/examples/gno.land/r/foo20/foo.gno b/examples/gno.land/r/foo20/foo20.gno similarity index 98% rename from examples/gno.land/r/foo20/foo.gno rename to examples/gno.land/r/foo20/foo20.gno index 2c32b0481f9..5f12c83e425 100644 --- a/examples/gno.land/r/foo20/foo.gno +++ b/examples/gno.land/r/foo20/foo20.gno @@ -4,7 +4,7 @@ import ( "std" "strings" - grc20 "gno.land/p/grc/grc20/impl" + "gno.land/p/grc/grc20" "gno.land/p/ufmt" "gno.land/r/users" ) diff --git a/examples/gno.land/r/foo20/foo200_test.gno b/examples/gno.land/r/foo20/foo20_test.gno similarity index 99% rename from examples/gno.land/r/foo20/foo200_test.gno rename to examples/gno.land/r/foo20/foo20_test.gno index 0a96bfc7c79..eba2df260a5 100644 --- a/examples/gno.land/r/foo20/foo200_test.gno +++ b/examples/gno.land/r/foo20/foo20_test.gno @@ -6,7 +6,6 @@ import ( "gno.land/r/users" ) -/* func TestReadOnlyPublicMethods(t *testing.T) { var admin = users.AddressOrName("g1us8428u2a5satrlxzagqqa5m6vmuze025anjlj") var manfred = users.AddressOrName("g1u7y667z64x2h7vc6fmpcprgey4ck233jaww9zq") @@ -47,4 +46,3 @@ func TestReadOnlyPublicMethods(t *testing.T) { } } } -*/ diff --git a/examples/gno.land/r/nft/nft.gno b/examples/gno.land/r/nft/nft.gno index e38430b62cd..19ae729800a 100644 --- a/examples/gno.land/r/nft/nft.gno +++ b/examples/gno.land/r/nft/nft.gno @@ -5,35 +5,35 @@ import ( "strconv" "gno.land/p/avl" - igrc721 "gno.land/p/grc/grc721" + "gno.land/p/grc/grc721" ) -type grc721 struct { - igrc721.GRC721 // implements the GRC721 interface +type token struct { + grc721.IGRC721 // implements the GRC721 interface tokenCounter int - tokens *avl.Tree // igrc721.TokenID -> *NFToken{} + tokens *avl.Tree // grc721.TokenID -> *NFToken{} operators *avl.Tree // owner std.Address -> operator std.Address } type NFToken struct { owner std.Address approved std.Address - tokenID igrc721.TokenID + tokenID grc721.TokenID data string } -var gGRC721 = &grc721{} +var gToken = &token{} -func GetGRC721() *grc721 { return gGRC721 } +func GetToken() *token { return gToken } -func (grc *grc721) nextTokenID() igrc721.TokenID { +func (grc *token) nextTokenID() grc721.TokenID { grc.tokenCounter++ s := strconv.Itoa(grc.tokenCounter) - return igrc721.TokenID(s) + return grc721.TokenID(s) } -func (grc *grc721) getToken(tid igrc721.TokenID) (*NFToken, bool) { +func (grc *token) getToken(tid grc721.TokenID) (*NFToken, bool) { _, token, ok := grc.tokens.Get(string(tid)) if !ok { return nil, false @@ -41,7 +41,7 @@ func (grc *grc721) getToken(tid igrc721.TokenID) (*NFToken, bool) { return token.(*NFToken), true } -func (grc *grc721) Mint(to std.Address, data string) igrc721.TokenID { +func (grc *token) Mint(to std.Address, data string) grc721.TokenID { tid := grc.nextTokenID() newTokens, _ := grc.tokens.Set(string(tid), &NFToken{ owner: to, @@ -52,11 +52,11 @@ func (grc *grc721) Mint(to std.Address, data string) igrc721.TokenID { return tid } -func (grc *grc721) BalanceOf(owner std.Address) (count int64) { +func (grc *token) BalanceOf(owner std.Address) (count int64) { panic("not yet implemented") } -func (grc *grc721) OwnerOf(tid igrc721.TokenID) std.Address { +func (grc *token) OwnerOf(tid grc721.TokenID) std.Address { token, ok := grc.getToken(tid) if !ok { panic("token does not exist") @@ -65,7 +65,7 @@ func (grc *grc721) OwnerOf(tid igrc721.TokenID) std.Address { } // XXX not fully implemented yet. -func (grc *grc721) SafeTransferFrom(from, to std.Address, tid igrc721.TokenID) { +func (grc *token) SafeTransferFrom(from, to std.Address, tid grc721.TokenID) { grc.TransferFrom(from, to, tid) // When transfer is complete, this function checks if `_to` is a smart // contract (code size > 0). If so, it calls `onERC721Received` on @@ -74,7 +74,7 @@ func (grc *grc721) SafeTransferFrom(from, to std.Address, tid igrc721.TokenID) { // XXX ensure "to" is a realm with onERC721Received() signature. } -func (grc *grc721) TransferFrom(from, to std.Address, tid igrc721.TokenID) { +func (grc *token) TransferFrom(from, to std.Address, tid grc721.TokenID) { caller := std.GetCallerAt(2) token, ok := grc.getToken(tid) // Throws if `_tokenId` is not a valid NFT. @@ -101,7 +101,7 @@ func (grc *grc721) TransferFrom(from, to std.Address, tid igrc721.TokenID) { token.owner = to } -func (grc *grc721) Approve(approved std.Address, tid igrc721.TokenID) { +func (grc *token) Approve(approved std.Address, tid grc721.TokenID) { caller := std.GetCallerAt(2) token, ok := grc.getToken(tid) // Throws if `_tokenId` is not a valid NFT. @@ -121,13 +121,13 @@ func (grc *grc721) Approve(approved std.Address, tid igrc721.TokenID) { } // XXX make it work for set of operators. -func (grc *grc721) SetApprovalForAll(operator std.Address, approved bool) { +func (grc *token) SetApprovalForAll(operator std.Address, approved bool) { caller := std.GetCallerAt(2) newOperators, _ := grc.operators.Set(caller.String(), operator) grc.operators = newOperators } -func (grc *grc721) GetApproved(tid igrc721.TokenID) std.Address { +func (grc *token) GetApproved(tid grc721.TokenID) std.Address { token, ok := grc.getToken(tid) // Throws if `_tokenId` is not a valid NFT. if !ok { @@ -137,7 +137,7 @@ func (grc *grc721) GetApproved(tid igrc721.TokenID) std.Address { } // XXX make it work for set of operators -func (grc *grc721) IsApprovedForAll(owner, operator std.Address) bool { +func (grc *token) IsApprovedForAll(owner, operator std.Address) bool { _, operator2, ok := grc.operators.Get(owner.String()) if !ok { return false diff --git a/examples/gno.land/r/nft/z_0_filetest.gno b/examples/gno.land/r/nft/z_0_filetest.gno index 16b376bfd95..568e1e50c38 100644 --- a/examples/gno.land/r/nft/z_0_filetest.gno +++ b/examples/gno.land/r/nft/z_0_filetest.gno @@ -9,7 +9,7 @@ import ( func main() { addr1 := testutils.TestAddress("addr1") // addr2 := testutils.TestAddress("addr2") - grc721 := nft.GetGRC721() + grc721 := nft.GetToken() tid := grc721.Mint(addr1, "NFT#1") println(grc721.OwnerOf(tid)) println(addr1) diff --git a/examples/gno.land/r/nft/z_1_filetest.gno b/examples/gno.land/r/nft/z_1_filetest.gno index f1873ba5031..c8266c27a79 100644 --- a/examples/gno.land/r/nft/z_1_filetest.gno +++ b/examples/gno.land/r/nft/z_1_filetest.gno @@ -9,7 +9,7 @@ import ( func main() { addr1 := testutils.TestAddress("addr1") addr2 := testutils.TestAddress("addr2") - grc721 := nft.GetGRC721() + grc721 := nft.GetToken() tid := grc721.Mint(addr1, "NFT#1") println(grc721.OwnerOf(tid)) println(addr1) diff --git a/examples/gno.land/r/nft/z_2_filetest.gno b/examples/gno.land/r/nft/z_2_filetest.gno index f78a609a772..174d71cbada 100644 --- a/examples/gno.land/r/nft/z_2_filetest.gno +++ b/examples/gno.land/r/nft/z_2_filetest.gno @@ -12,7 +12,7 @@ func main() { caller := std.GetCallerAt(1) addr1 := testutils.TestAddress("addr1") // addr2 := testutils.TestAddress("addr2") - grc721 := nft.GetGRC721() + grc721 := nft.GetToken() tid := grc721.Mint(caller, "NFT#1") println(grc721.OwnerOf(tid)) println(addr1) diff --git a/examples/gno.land/r/nft/z_3_filetest.gno b/examples/gno.land/r/nft/z_3_filetest.gno index 81a78183264..bd5badf05ac 100644 --- a/examples/gno.land/r/nft/z_3_filetest.gno +++ b/examples/gno.land/r/nft/z_3_filetest.gno @@ -12,7 +12,7 @@ func main() { caller := std.GetCallerAt(1) addr1 := testutils.TestAddress("addr1") addr2 := testutils.TestAddress("addr2") - grc721 := nft.GetGRC721() + grc721 := nft.GetToken() tid := grc721.Mint(caller, "NFT#1") println(grc721.OwnerOf(tid)) println(addr1) diff --git a/examples/gno.land/r/nft/z_4_filetest.gno b/examples/gno.land/r/nft/z_4_filetest.gno index 51fd7efb977..4f1e6d63558 100644 --- a/examples/gno.land/r/nft/z_4_filetest.gno +++ b/examples/gno.land/r/nft/z_4_filetest.gno @@ -12,7 +12,7 @@ func main() { caller := std.GetCallerAt(1) addr1 := testutils.TestAddress("addr1") addr2 := testutils.TestAddress("addr2") - grc721 := nft.GetGRC721() + grc721 := nft.GetToken() tid := grc721.Mint(caller, "NFT#1") println(grc721.OwnerOf(tid)) println(addr1)