diff --git a/x/nft/keeper/genesis.go b/x/nft/keeper/genesis.go index 3c8d1b59bb..20631dbbf6 100644 --- a/x/nft/keeper/genesis.go +++ b/x/nft/keeper/genesis.go @@ -38,11 +38,15 @@ func (k Keeper) ExportGenesis(ctx sdk.Context) *nft.GenesisState { nfts := k.GetNFTsOfClass(ctx, class.Id) for i, n := range nfts { owner := k.GetOwner(ctx, n.ClassId, n.Id) - nftArr, ok := nftMap[owner.String()] + ownerStr, err := k.ac.BytesToString(owner.Bytes()) + if err != nil { + panic(err) + } + nftArr, ok := nftMap[ownerStr] if !ok { nftArr = make([]*nft.NFT, 0) } - nftMap[owner.String()] = append(nftArr, &nfts[i]) + nftMap[ownerStr] = append(nftArr, &nfts[i]) } } diff --git a/x/nft/keeper/grpc_query.go b/x/nft/keeper/grpc_query.go index 2742382881..e4ccb1cc31 100644 --- a/x/nft/keeper/grpc_query.go +++ b/x/nft/keeper/grpc_query.go @@ -50,7 +50,14 @@ func (k Keeper) Owner(goCtx context.Context, r *nft.QueryOwnerRequest) (*nft.Que ctx := sdk.UnwrapSDKContext(goCtx) owner := k.GetOwner(ctx, r.ClassId, r.Id) - return &nft.QueryOwnerResponse{Owner: owner.String()}, nil + if owner.Empty() { + return &nft.QueryOwnerResponse{Owner: ""}, nil + } + ownerstr, err := k.ac.BytesToString(owner.Bytes()) + if err != nil { + return nil, err + } + return &nft.QueryOwnerResponse{Owner: ownerstr}, nil } // Supply return the number of NFTs from the given class, same as totalSupply of ERC721. diff --git a/x/nft/keeper/grpc_query_test.go b/x/nft/keeper/grpc_query_test.go index bd1bec6b54..42e5c56586 100644 --- a/x/nft/keeper/grpc_query_test.go +++ b/x/nft/keeper/grpc_query_test.go @@ -54,7 +54,7 @@ func (s *TestSuite) TestBalance() { s.TestMint() req = &nft.QueryBalanceRequest{ ClassId: testClassID, - Owner: s.addrs[0].String(), + Owner: s.encodedAddrs[0], } }, "", @@ -145,7 +145,7 @@ func (s *TestSuite) TestOwner() { ClassId: testClassID, Id: testID, } - owner = s.addrs[0].String() + owner = s.encodedAddrs[0] }, "", func(index int, require *require.Assertions, res *nft.QueryOwnerResponse) { @@ -275,7 +275,7 @@ func (s *TestSuite) TestNFTs() { "success,empty ClassId and no nft", func(index int, require *require.Assertions) { req = &nft.QueryNFTsRequest{ - Owner: s.addrs[1].String(), + Owner: s.encodedAddrs[1], } s.TestSaveClass() }, @@ -323,7 +323,7 @@ func (s *TestSuite) TestNFTs() { } req = &nft.QueryNFTsRequest{ - Owner: s.addrs[2].String(), + Owner: s.encodedAddrs[2], } }, "", @@ -348,7 +348,7 @@ func (s *TestSuite) TestNFTs() { func(index int, require *require.Assertions) { req = &nft.QueryNFTsRequest{ ClassId: testClassID, - Owner: s.addrs[0].String(), + Owner: s.encodedAddrs[0], } nfts = []*nft.NFT{ { diff --git a/x/nft/keeper/keeper_test.go b/x/nft/keeper/keeper_test.go index 45be0db297..58fe41d307 100644 --- a/x/nft/keeper/keeper_test.go +++ b/x/nft/keeper/keeper_test.go @@ -40,6 +40,7 @@ type TestSuite struct { ctx sdk.Context addrs []sdk.AccAddress + encodedAddrs []string queryClient nft.QueryClient nftKeeper keeper.Keeper accountKeeper *nfttestutil.MockAccountKeeper @@ -64,6 +65,12 @@ func (s *TestSuite) SetupTest() { accountKeeper.EXPECT().GetModuleAddress("nft").Return(s.addrs[0]).AnyTimes() accountKeeper.EXPECT().AddressCodec().Return(address.NewBech32Codec("cosmos")).AnyTimes() + for _, addr := range s.addrs { + st, err := accountKeeper.AddressCodec().BytesToString(addr.Bytes()) + s.Require().NoError(err) + s.encodedAddrs = append(s.encodedAddrs, st) + } + s.accountKeeper = accountKeeper nftKeeper := keeper.NewKeeper(storeService, s.encCfg.Codec, accountKeeper, bankKeeper) @@ -348,7 +355,7 @@ func (s *TestSuite) TestExportGenesis() { expGenesis := &nft.GenesisState{ Classes: []*nft.Class{&class}, Entries: []*nft.Entry{{ - Owner: s.addrs[0].String(), + Owner: s.encodedAddrs[0], Nfts: []*nft.NFT{&expNFT}, }}, } @@ -373,7 +380,7 @@ func (s *TestSuite) TestInitGenesis() { expGenesis := &nft.GenesisState{ Classes: []*nft.Class{&expClass}, Entries: []*nft.Entry{{ - Owner: s.addrs[0].String(), + Owner: s.encodedAddrs[0], Nfts: []*nft.NFT{&expNFT}, }}, } diff --git a/x/nft/keeper/msg_server_test.go b/x/nft/keeper/msg_server_test.go index fc044a5f99..ae70d60b52 100644 --- a/x/nft/keeper/msg_server_test.go +++ b/x/nft/keeper/msg_server_test.go @@ -37,7 +37,7 @@ func (s *TestSuite) TestSend() { expGenesis := &nft.GenesisState{ Classes: []*nft.Class{&ExpClass}, Entries: []*nft.Entry{{ - Owner: s.addrs[0].String(), + Owner: s.encodedAddrs[0], Nfts: []*nft.NFT{&ExpNFT}, }}, } @@ -55,8 +55,8 @@ func (s *TestSuite) TestSend() { req: &nft.MsgSend{ ClassId: testClassID, Id: "", - Sender: s.addrs[0].String(), - Receiver: s.addrs[1].String(), + Sender: s.encodedAddrs[0], + Receiver: s.encodedAddrs[1], }, expErr: true, errMsg: "empty nft id", @@ -66,8 +66,8 @@ func (s *TestSuite) TestSend() { req: &nft.MsgSend{ ClassId: "", Id: testID, - Sender: s.addrs[0].String(), - Receiver: s.addrs[1].String(), + Sender: s.encodedAddrs[0], + Receiver: s.encodedAddrs[1], }, expErr: true, errMsg: "empty class id", @@ -77,8 +77,8 @@ func (s *TestSuite) TestSend() { req: &nft.MsgSend{ ClassId: "invalid ClassId", Id: testID, - Sender: s.addrs[0].String(), - Receiver: s.addrs[1].String(), + Sender: s.encodedAddrs[0], + Receiver: s.encodedAddrs[1], }, expErr: true, errMsg: "unauthorized", @@ -88,8 +88,8 @@ func (s *TestSuite) TestSend() { req: &nft.MsgSend{ ClassId: testClassID, Id: "invalid Id", - Sender: s.addrs[0].String(), - Receiver: s.addrs[1].String(), + Sender: s.encodedAddrs[0], + Receiver: s.encodedAddrs[1], }, expErr: true, errMsg: "unauthorized", @@ -99,19 +99,19 @@ func (s *TestSuite) TestSend() { req: &nft.MsgSend{ ClassId: testClassID, Id: testID, - Sender: s.addrs[1].String(), - Receiver: s.addrs[2].String(), + Sender: s.encodedAddrs[1], + Receiver: s.encodedAddrs[2], }, expErr: true, - errMsg: fmt.Sprintf("%s is not the owner of nft %s", s.addrs[1].String(), testID), + errMsg: fmt.Sprintf("%s is not the owner of nft %s", s.encodedAddrs[1], testID), }, { name: "valid transaction", req: &nft.MsgSend{ ClassId: testClassID, Id: testID, - Sender: s.addrs[0].String(), - Receiver: s.addrs[1].String(), + Sender: s.encodedAddrs[0], + Receiver: s.encodedAddrs[1], }, expErr: false, errMsg: "", diff --git a/x/nft/keeper/nft.go b/x/nft/keeper/nft.go index 5f0d21bf8e..15a4c7ce18 100644 --- a/x/nft/keeper/nft.go +++ b/x/nft/keeper/nft.go @@ -21,26 +21,26 @@ func (k Keeper) Mint(ctx context.Context, token nft.NFT, receiver sdk.AccAddress return errors.Wrap(nft.ErrNFTExists, token.Id) } - k.mintWithNoCheck(ctx, token, receiver) - return nil + return k.mintWithNoCheck(ctx, token, receiver) } // mintWithNoCheck defines a method for minting a new nft // Note: this method does not check whether the class already exists in nft. // The upper-layer application needs to check it when it needs to use it. -func (k Keeper) mintWithNoCheck(ctx context.Context, token nft.NFT, receiver sdk.AccAddress) { +func (k Keeper) mintWithNoCheck(ctx context.Context, token nft.NFT, receiver sdk.AccAddress) error { k.setNFT(ctx, token) k.setOwner(ctx, token.ClassId, token.Id, receiver) k.incrTotalSupply(ctx, token.ClassId) - err := sdk.UnwrapSDKContext(ctx).EventManager().EmitTypedEvent(&nft.EventMint{ + recStr, err := k.ac.BytesToString(receiver.Bytes()) + if err != nil { + return err + } + return sdk.UnwrapSDKContext(ctx).EventManager().EmitTypedEvent(&nft.EventMint{ ClassId: token.ClassId, Id: token.Id, - Owner: receiver.String(), + Owner: recStr, }) - if err != nil { - panic(err) - } } // Burn defines a method for burning a nft from a specific account. @@ -71,15 +71,16 @@ func (k Keeper) burnWithNoCheck(ctx context.Context, classID, nftID string) erro k.deleteOwner(ctx, classID, nftID, owner) k.decrTotalSupply(ctx, classID) - err := sdk.UnwrapSDKContext(ctx).EventManager().EmitTypedEvent(&nft.EventBurn{ - ClassId: classID, - Id: nftID, - Owner: owner.String(), - }) + ownerStr, err := k.ac.BytesToString(owner.Bytes()) if err != nil { return err } - return nil + + return sdk.UnwrapSDKContext(ctx).EventManager().EmitTypedEvent(&nft.EventBurn{ + ClassId: classID, + Id: nftID, + Owner: ownerStr, + }) } // Update defines a method for updating an exist nft diff --git a/x/nft/keeper/nft_batch.go b/x/nft/keeper/nft_batch.go index 474842869f..889e67fe33 100644 --- a/x/nft/keeper/nft_batch.go +++ b/x/nft/keeper/nft_batch.go @@ -25,7 +25,9 @@ func (k Keeper) BatchMint(ctx context.Context, } checked[token.ClassId] = true - k.mintWithNoCheck(ctx, token, receiver) + if err := k.mintWithNoCheck(ctx, token, receiver); err != nil { + return err + } } return nil } diff --git a/x/nft/module/module.go b/x/nft/module/module.go index 9338870b0d..c1254756f7 100644 --- a/x/nft/module/module.go +++ b/x/nft/module/module.go @@ -141,8 +141,8 @@ func (AppModule) ConsensusVersion() uint64 { return 1 } // AppModuleSimulation functions // GenerateGenesisState creates a randomized GenState of the nft module. -func (AppModule) GenerateGenesisState(simState *module.SimulationState) { - simulation.RandomizedGenState(simState) +func (am AppModule) GenerateGenesisState(simState *module.SimulationState) { + simulation.RandomizedGenState(simState, am.accountKeeper.AddressCodec()) } // RegisterStoreDecoder registers a decoder for nft module's types diff --git a/x/nft/simulation/genesis.go b/x/nft/simulation/genesis.go index b40f07f045..ec115681f7 100644 --- a/x/nft/simulation/genesis.go +++ b/x/nft/simulation/genesis.go @@ -3,6 +3,7 @@ package simulation import ( "math/rand" + "cosmossdk.io/core/address" "cosmossdk.io/x/nft" "github.com/cosmos/cosmos-sdk/types/module" @@ -25,12 +26,16 @@ func genClasses(r *rand.Rand, accounts []simtypes.Account) []*nft.Class { } // genNFT returns a slice of nft. -func genNFT(r *rand.Rand, classID string, accounts []simtypes.Account) []*nft.Entry { +func genNFT(r *rand.Rand, classID string, accounts []simtypes.Account, ac address.Codec) []*nft.Entry { entries := make([]*nft.Entry, len(accounts)-1) for i := 0; i < len(accounts)-1; i++ { owner := accounts[i] + oast, err := ac.BytesToString(owner.Address.Bytes()) + if err != nil { + panic(err) + } entries[i] = &nft.Entry{ - Owner: owner.Address.String(), + Owner: oast, Nfts: []*nft.NFT{ { ClassId: classID, @@ -44,7 +49,7 @@ func genNFT(r *rand.Rand, classID string, accounts []simtypes.Account) []*nft.En } // RandomizedGenState generates a random GenesisState for nft. -func RandomizedGenState(simState *module.SimulationState) { +func RandomizedGenState(simState *module.SimulationState, ac address.Codec) { var classes []*nft.Class simState.AppParams.GetOrGenerate( "nft", &classes, simState.Rand, @@ -56,7 +61,7 @@ func RandomizedGenState(simState *module.SimulationState) { "nft", &entries, simState.Rand, func(r *rand.Rand) { class := classes[r.Int63n(int64(len(classes)))] - entries = genNFT(r, class.Id, simState.Accounts) + entries = genNFT(r, class.Id, simState.Accounts, ac) }, ) diff --git a/x/nft/simulation/genesis_test.go b/x/nft/simulation/genesis_test.go index 02f69fc7ae..a04511ed15 100644 --- a/x/nft/simulation/genesis_test.go +++ b/x/nft/simulation/genesis_test.go @@ -12,6 +12,7 @@ import ( nftmodule "cosmossdk.io/x/nft/module" "cosmossdk.io/x/nft/simulation" + addresscodec "github.com/cosmos/cosmos-sdk/codec/address" "github.com/cosmos/cosmos-sdk/types/module" moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" simtypes "github.com/cosmos/cosmos-sdk/types/simulation" @@ -33,7 +34,7 @@ func TestRandomizedGenState(t *testing.T) { GenState: make(map[string]json.RawMessage), } - simulation.RandomizedGenState(&simState) + simulation.RandomizedGenState(&simState, addresscodec.NewBech32Codec("cosmos")) var nftGenesis nft.GenesisState simState.Cdc.MustUnmarshalJSON(simState.GenState[nft.ModuleName], &nftGenesis) diff --git a/x/nft/simulation/operations.go b/x/nft/simulation/operations.go index 6c992a4ab3..82163ae009 100644 --- a/x/nft/simulation/operations.go +++ b/x/nft/simulation/operations.go @@ -87,11 +87,21 @@ func SimulateMsgSend( return simtypes.NoOpMsg(nft.ModuleName, TypeMsgSend, err.Error()), nil, err } + senderStr, err := ak.AddressCodec().BytesToString(senderAcc.GetAddress().Bytes()) + if err != nil { + return simtypes.NoOpMsg(nft.ModuleName, TypeMsgSend, err.Error()), nil, err + } + + recieverStr, err := ak.AddressCodec().BytesToString(receiver.Address.Bytes()) + if err != nil { + return simtypes.NoOpMsg(nft.ModuleName, TypeMsgSend, err.Error()), nil, err + } + msg := &nft.MsgSend{ ClassId: n.ClassId, Id: n.Id, - Sender: senderAcc.GetAddress().String(), - Receiver: receiver.Address.String(), + Sender: senderStr, + Receiver: recieverStr, } tx, err := simtestutil.GenSignedMockTx(