diff --git a/modules/nft/client/cli/cli_test.go b/modules/nft/client/cli/cli_test.go index d68b0401..9646fa4a 100644 --- a/modules/nft/client/cli/cli_test.go +++ b/modules/nft/client/cli/cli_test.go @@ -57,8 +57,10 @@ func (s *IntegrationTestSuite) TestNft() { from := val.Address tokenName := "Kitty Token" - tokenURI := "uri" - tokenData := "data" + uri := "uri" + uriHash := "uriHash" + description := "description" + data := "data" tokenID := "kitty" //owner := "owner" denomName := "name" @@ -73,6 +75,10 @@ func (s *IntegrationTestSuite) TestNft() { fmt.Sprintf("--%s=%s", nftcli.FlagDenomName, denomName), fmt.Sprintf("--%s=%s", nftcli.FlagSchema, schema), fmt.Sprintf("--%s=%s", nftcli.FlagSymbol, symbol), + fmt.Sprintf("--%s=%s", nftcli.FlagURI, uri), + fmt.Sprintf("--%s=%s", nftcli.FlagURIHash, uriHash), + fmt.Sprintf("--%s=%s", nftcli.FlagDescription, description), + fmt.Sprintf("--%s=%s", nftcli.FlagData, data), fmt.Sprintf("--%s=%t", nftcli.FlagMintRestricted, mintRestricted), fmt.Sprintf("--%s=%t", nftcli.FlagUpdateRestricted, updateRestricted), @@ -101,6 +107,10 @@ func (s *IntegrationTestSuite) TestNft() { s.Require().Equal(denomName, denomItem.Name) s.Require().Equal(schema, denomItem.Schema) s.Require().Equal(symbol, denomItem.Symbol) + s.Require().Equal(uri, denomItem.Uri) + s.Require().Equal(uriHash, denomItem.UriHash) + s.Require().Equal(description, denomItem.Description) + s.Require().Equal(data, denomItem.Data) s.Require().Equal(mintRestricted, denomItem.MintRestricted) s.Require().Equal(updateRestricted, denomItem.UpdateRestricted) @@ -115,9 +125,10 @@ func (s *IntegrationTestSuite) TestNft() { //------test GetCmdMintNFT()------------- args = []string{ - fmt.Sprintf("--%s=%s", nftcli.FlagTokenData, tokenData), + fmt.Sprintf("--%s=%s", nftcli.FlagData, data), fmt.Sprintf("--%s=%s", nftcli.FlagRecipient, from.String()), - fmt.Sprintf("--%s=%s", nftcli.FlagTokenURI, tokenURI), + fmt.Sprintf("--%s=%s", nftcli.FlagURI, uri), + fmt.Sprintf("--%s=%s", nftcli.FlagURIHash, uriHash), fmt.Sprintf("--%s=%s", nftcli.FlagTokenName, tokenName), fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), @@ -149,8 +160,9 @@ func (s *IntegrationTestSuite) TestNft() { nftItem := respType.(*nfttypes.BaseNFT) s.Require().Equal(tokenID, nftItem.Id) s.Require().Equal(tokenName, nftItem.Name) - s.Require().Equal(tokenURI, nftItem.URI) - s.Require().Equal(tokenData, nftItem.Data) + s.Require().Equal(uri, nftItem.URI) + s.Require().Equal(uriHash, nftItem.UriHash) + s.Require().Equal(data, nftItem.Data) s.Require().Equal(from.String(), nftItem.Owner) //------test GetCmdQueryOwner()------------- @@ -174,10 +186,12 @@ func (s *IntegrationTestSuite) TestNft() { //------test GetCmdEditNFT()------------- newTokenDate := "newdata" newTokenURI := "newuri" + newTokenURIHash := "newuriHash" newTokenName := "new Kitty Token" args = []string{ - fmt.Sprintf("--%s=%s", nftcli.FlagTokenData, newTokenDate), - fmt.Sprintf("--%s=%s", nftcli.FlagTokenURI, newTokenURI), + fmt.Sprintf("--%s=%s", nftcli.FlagData, newTokenDate), + fmt.Sprintf("--%s=%s", nftcli.FlagURI, newTokenURI), + fmt.Sprintf("--%s=%s", nftcli.FlagURIHash, newTokenURIHash), fmt.Sprintf("--%s=%s", nftcli.FlagTokenName, newTokenName), fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), @@ -200,14 +214,16 @@ func (s *IntegrationTestSuite) TestNft() { newNftItem := respType.(*nfttypes.BaseNFT) s.Require().Equal(newTokenName, newNftItem.Name) s.Require().Equal(newTokenURI, newNftItem.URI) + s.Require().Equal(newTokenURIHash, newNftItem.UriHash) s.Require().Equal(newTokenDate, newNftItem.Data) //------test GetCmdTransferNFT()------------- recipient := sdk.AccAddress(crypto.AddressHash([]byte("dgsbl"))) args = []string{ - fmt.Sprintf("--%s=%s", nftcli.FlagTokenData, tokenData), - fmt.Sprintf("--%s=%s", nftcli.FlagTokenURI, tokenURI), + fmt.Sprintf("--%s=%s", nftcli.FlagData, data), + fmt.Sprintf("--%s=%s", nftcli.FlagURI, uri), + fmt.Sprintf("--%s=%s", nftcli.FlagURIHash, uriHash), fmt.Sprintf("--%s=%s", nftcli.FlagTokenName, tokenName), fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), @@ -230,16 +246,17 @@ func (s *IntegrationTestSuite) TestNft() { nftItem = respType.(*nfttypes.BaseNFT) s.Require().Equal(tokenID, nftItem.Id) s.Require().Equal(tokenName, nftItem.Name) - s.Require().Equal(tokenURI, nftItem.URI) - s.Require().Equal(tokenData, nftItem.Data) + s.Require().Equal(uri, nftItem.URI) + s.Require().Equal(uriHash, nftItem.UriHash) + s.Require().Equal(data, nftItem.Data) s.Require().Equal(recipient.String(), nftItem.Owner) //------test GetCmdBurnNFT()------------- newTokenID := "dgsbl" args = []string{ - fmt.Sprintf("--%s=%s", nftcli.FlagTokenData, newTokenDate), + fmt.Sprintf("--%s=%s", nftcli.FlagData, newTokenDate), fmt.Sprintf("--%s=%s", nftcli.FlagRecipient, from.String()), - fmt.Sprintf("--%s=%s", nftcli.FlagTokenURI, newTokenURI), + fmt.Sprintf("--%s=%s", nftcli.FlagURI, newTokenURI), fmt.Sprintf("--%s=%s", nftcli.FlagTokenName, newTokenName), fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), diff --git a/modules/nft/client/cli/flags.go b/modules/nft/client/cli/flags.go index 65645c53..f7657394 100644 --- a/modules/nft/client/cli/flags.go +++ b/modules/nft/client/cli/flags.go @@ -5,11 +5,13 @@ import ( ) const ( - FlagTokenName = "name" - FlagTokenURI = "uri" - FlagTokenData = "data" - FlagRecipient = "recipient" - FlagOwner = "owner" + FlagTokenName = "name" + FlagURI = "uri" + FlagURIHash = "uri-hash" + FlagDescription = "description" + FlagRecipient = "recipient" + FlagOwner = "owner" + FlagData = "data" FlagDenomName = "name" FlagDenomID = "denom-id" @@ -31,22 +33,29 @@ var ( func init() { FsIssueDenom.String(FlagSchema, "", "Denom data structure definition") + FsIssueDenom.String(FlagURI, "", "The uri for the class metadata stored off chain. It can define schema for Class and NFT `Data` attributes. Optional") + FsIssueDenom.String(FlagURIHash, "", "The uri-hash is a hash of the document pointed by uri. Optional") + FsIssueDenom.String(FlagDescription, "", "The description is a brief description of nft classification. Optional") FsIssueDenom.String(FlagDenomName, "", "The name of the denom") FsIssueDenom.String(FlagSymbol, "", "The symbol of the denom") + FsIssueDenom.String(FlagData, "", "The data is the app specific metadata of the NFT class. Optional") FsIssueDenom.Bool(FlagMintRestricted, false, "mint restricted of nft under denom") FsIssueDenom.Bool(FlagUpdateRestricted, false, "update restricted of nft under denom") - FsMintNFT.String(FlagTokenURI, "", "URI for supplemental off-chain tokenData (should return a JSON object)") - FsMintNFT.String(FlagRecipient, "", "Receiver of the nft, if not filled, the default is the sender of the transaction") - FsMintNFT.String(FlagTokenData, "", "The origin data of the nft") + FsMintNFT.String(FlagURI, "", "The uri for supplemental off-chain tokenData (should return a JSON object)") + FsMintNFT.String(FlagURIHash, "", "The uri_hash is a hash of the document pointed by uri. Optional") + FsMintNFT.String(FlagRecipient, "", "The receiver of the nft, if not filled, the default is the sender of the transaction") + FsMintNFT.String(FlagData, "", "The origin data of the nft") FsMintNFT.String(FlagTokenName, "", "The name of the nft") - FsEditNFT.String(FlagTokenURI, "[do-not-modify]", "URI for the supplemental off-chain token data (should return a JSON object)") - FsEditNFT.String(FlagTokenData, "[do-not-modify]", "The token data of the nft") + FsEditNFT.String(FlagURI, "[do-not-modify]", "URI for the supplemental off-chain token data (should return a JSON object)") + FsEditNFT.String(FlagURIHash, "[do-not-modify]", "The uri_hash is a hash of the document pointed by uri. Optional") + FsEditNFT.String(FlagData, "[do-not-modify]", "The token data of the nft") FsEditNFT.String(FlagTokenName, "[do-not-modify]", "The name of the nft") - FsTransferNFT.String(FlagTokenURI, "[do-not-modify]", "URI for the supplemental off-chain token data (should return a JSON object)") - FsTransferNFT.String(FlagTokenData, "[do-not-modify]", "The token data of the nft") + FsTransferNFT.String(FlagURI, "[do-not-modify]", "URI for the supplemental off-chain token data (should return a JSON object)") + FsTransferNFT.String(FlagURIHash, "[do-not-modify]", "The uri_hash is a hash of the document pointed by uri. Optional") + FsTransferNFT.String(FlagData, "[do-not-modify]", "The token data of the nft") FsTransferNFT.String(FlagTokenName, "[do-not-modify]", "The name of the nft") FsQuerySupply.String(FlagOwner, "", "The owner of the nft") diff --git a/modules/nft/client/cli/tx.go b/modules/nft/client/cli/tx.go index 29958bd0..70d7bd54 100644 --- a/modules/nft/client/cli/tx.go +++ b/modules/nft/client/cli/tx.go @@ -51,6 +51,10 @@ func GetCmdIssueDenom() *cobra.Command { "--mint-restricted= "+ "--update-restricted= "+ "--schema= "+ + "--description= "+ + "--uri= "+ + "--uri-hash= "+ + "--data= "+ "--chain-id= "+ "--fees=", version.AppName, @@ -82,6 +86,22 @@ func GetCmdIssueDenom() *cobra.Command { if err != nil { return err } + uri, err := cmd.Flags().GetString(FlagURI) + if err != nil { + return err + } + uriHash, err := cmd.Flags().GetString(FlagURIHash) + if err != nil { + return err + } + description, err := cmd.Flags().GetString(FlagDescription) + if err != nil { + return err + } + data, err := cmd.Flags().GetString(FlagData) + if err != nil { + return err + } optionsContent, err := ioutil.ReadFile(schema) if err == nil { schema = string(optionsContent) @@ -95,6 +115,10 @@ func GetCmdIssueDenom() *cobra.Command { symbol, mintRestricted, updateRestricted, + description, + uri, + uriHash, + data, ) if err := msg.ValidateBasic(); err != nil { return err @@ -118,6 +142,7 @@ func GetCmdMintNFT() *cobra.Command { Example: fmt.Sprintf( "$ %s tx nft mint "+ "--uri= "+ + "--uri-hash= "+ "--recipient= "+ "--from= "+ "--chain-id= "+ @@ -151,11 +176,15 @@ func GetCmdMintNFT() *cobra.Command { if err != nil { return err } - tokenURI, err := cmd.Flags().GetString(FlagTokenURI) + tokenURI, err := cmd.Flags().GetString(FlagURI) + if err != nil { + return err + } + tokenURIHash, err := cmd.Flags().GetString(FlagURIHash) if err != nil { return err } - tokenData, err := cmd.Flags().GetString(FlagTokenData) + tokenData, err := cmd.Flags().GetString(FlagData) if err != nil { return err } @@ -165,6 +194,7 @@ func GetCmdMintNFT() *cobra.Command { args[0], tokenName, tokenURI, + tokenURIHash, tokenData, sender, recipient, @@ -189,6 +219,7 @@ func GetCmdEditNFT() *cobra.Command { Example: fmt.Sprintf( "$ %s tx nft edit "+ "--uri= "+ + "--uri-hash= "+ "--from= "+ "--chain-id= "+ "--fees=", @@ -205,11 +236,15 @@ func GetCmdEditNFT() *cobra.Command { if err != nil { return err } - tokenURI, err := cmd.Flags().GetString(FlagTokenURI) + tokenURI, err := cmd.Flags().GetString(FlagURI) if err != nil { return err } - tokenData, err := cmd.Flags().GetString(FlagTokenData) + tokenURIHash, err := cmd.Flags().GetString(FlagURIHash) + if err != nil { + return err + } + tokenData, err := cmd.Flags().GetString(FlagData) if err != nil { return err } @@ -218,6 +253,7 @@ func GetCmdEditNFT() *cobra.Command { args[0], tokenName, tokenURI, + tokenURIHash, tokenData, clientCtx.GetFromAddress().String(), ) @@ -241,6 +277,7 @@ func GetCmdTransferNFT() *cobra.Command { Example: fmt.Sprintf( "$ %s tx nft transfer "+ "--uri= "+ + "--uri-hash= "+ "--from= "+ "--chain-id= "+ "--fees=", @@ -261,11 +298,15 @@ func GetCmdTransferNFT() *cobra.Command { if err != nil { return err } - tokenURI, err := cmd.Flags().GetString(FlagTokenURI) + tokenURI, err := cmd.Flags().GetString(FlagURI) + if err != nil { + return err + } + tokenURIHash, err := cmd.Flags().GetString(FlagURIHash) if err != nil { return err } - tokenData, err := cmd.Flags().GetString(FlagTokenData) + tokenData, err := cmd.Flags().GetString(FlagData) if err != nil { return err } @@ -274,6 +315,7 @@ func GetCmdTransferNFT() *cobra.Command { args[1], tokenName, tokenURI, + tokenURIHash, tokenData, clientCtx.GetFromAddress().String(), args[0], diff --git a/modules/nft/client/rest/grpc_query_test.go b/modules/nft/client/rest/grpc_query_test.go index 261e7c92..706c3267 100644 --- a/modules/nft/client/rest/grpc_query_test.go +++ b/modules/nft/client/rest/grpc_query_test.go @@ -57,8 +57,10 @@ func (s *IntegrationTestSuite) TestNft() { from := val.Address tokenName := "Kitty Token" - tokenURI := "uri" - tokenData := "data" + uri := "uri" + uriHash := "uriHash" + description := "description" + data := "data" tokenID := "kitty" //owner := "owner" denomName := "name" @@ -74,6 +76,10 @@ func (s *IntegrationTestSuite) TestNft() { fmt.Sprintf("--%s=%s", nftcli.FlagDenomName, denomName), fmt.Sprintf("--%s=%s", nftcli.FlagSymbol, symbol), fmt.Sprintf("--%s=%s", nftcli.FlagSchema, schema), + fmt.Sprintf("--%s=%s", nftcli.FlagURI, uri), + fmt.Sprintf("--%s=%s", nftcli.FlagURIHash, uriHash), + fmt.Sprintf("--%s=%s", nftcli.FlagDescription, description), + fmt.Sprintf("--%s=%s", nftcli.FlagData, data), fmt.Sprintf("--%s=%t", nftcli.FlagMintRestricted, mintRestricted), fmt.Sprintf("--%s=%t", nftcli.FlagUpdateRestricted, updateRestricted), @@ -103,6 +109,10 @@ func (s *IntegrationTestSuite) TestNft() { s.Require().Equal(denomName, denomItem.Denom.Name) s.Require().Equal(schema, denomItem.Denom.Schema) s.Require().Equal(symbol, denomItem.Denom.Symbol) + s.Require().Equal(uri, denomItem.Denom.Uri) + s.Require().Equal(uriHash, denomItem.Denom.UriHash) + s.Require().Equal(description, denomItem.Denom.Description) + s.Require().Equal(data, denomItem.Denom.Data) s.Require().Equal(mintRestricted, denomItem.Denom.MintRestricted) s.Require().Equal(updateRestricted, denomItem.Denom.UpdateRestricted) @@ -118,9 +128,10 @@ func (s *IntegrationTestSuite) TestNft() { //------test GetCmdMintNFT()------------- args = []string{ - fmt.Sprintf("--%s=%s", nftcli.FlagTokenData, tokenData), + fmt.Sprintf("--%s=%s", nftcli.FlagData, data), fmt.Sprintf("--%s=%s", nftcli.FlagRecipient, from.String()), - fmt.Sprintf("--%s=%s", nftcli.FlagTokenURI, tokenURI), + fmt.Sprintf("--%s=%s", nftcli.FlagURI, uri), + fmt.Sprintf("--%s=%s", nftcli.FlagURIHash, uriHash), fmt.Sprintf("--%s=%s", nftcli.FlagTokenName, tokenName), fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), @@ -154,8 +165,9 @@ func (s *IntegrationTestSuite) TestNft() { nftItem := respType.(*nfttypes.QueryNFTResponse) s.Require().Equal(tokenID, nftItem.NFT.Id) s.Require().Equal(tokenName, nftItem.NFT.Name) - s.Require().Equal(tokenURI, nftItem.NFT.URI) - s.Require().Equal(tokenData, nftItem.NFT.Data) + s.Require().Equal(uri, nftItem.NFT.URI) + s.Require().Equal(uriHash, nftItem.NFT.UriHash) + s.Require().Equal(data, nftItem.NFT.Data) s.Require().Equal(from.String(), nftItem.NFT.Owner) //------test GetCmdQueryOwner()------------- diff --git a/modules/nft/client/rest/rest.go b/modules/nft/client/rest/rest.go index 383113c7..45d6f05c 100644 --- a/modules/nft/client/rest/rest.go +++ b/modules/nft/client/rest/rest.go @@ -28,6 +28,10 @@ type issueDenomReq struct { Symbol string `json:"symbol"` MintRestricted bool `json:"mint_restricted"` UpdateRestricted bool `json:"update_restricted"` + Description string `json:"description"` + Uri string `json:"uri"` + UriHash string `json:"uri_hash"` + Data string `json:"data"` } type mintNFTReq struct { @@ -38,6 +42,7 @@ type mintNFTReq struct { ID string `json:"id"` Name string `json:"name"` URI string `json:"uri"` + UriHash string `json:"uri_hash"` Data string `json:"data"` } @@ -46,6 +51,7 @@ type editNFTReq struct { Owner string `json:"owner"` Name string `json:"name"` URI string `json:"uri"` + UriHash string `json:"uri_hash"` Data string `json:"data"` } @@ -55,6 +61,7 @@ type transferNFTReq struct { Recipient string `json:"recipient"` Name string `json:"name"` URI string `json:"uri"` + UriHash string `json:"uri_hash"` Data string `json:"data"` } diff --git a/modules/nft/client/rest/tx.go b/modules/nft/client/rest/tx.go index 4476ebfd..2dc99d7a 100644 --- a/modules/nft/client/rest/tx.go +++ b/modules/nft/client/rest/tx.go @@ -40,7 +40,10 @@ func issueDenomHandlerFn(cliCtx client.Context) http.HandlerFunc { } // create the message - msg := types.NewMsgIssueDenom(req.ID, req.Name, req.Schema, req.Owner, req.Symbol, req.MintRestricted, req.UpdateRestricted) + msg := types.NewMsgIssueDenom(req.ID, req.Name, req.Schema, req.Owner, req.Symbol, + req.MintRestricted, req.UpdateRestricted, + req.Description, req.Uri, req.UriHash, req.Data, + ) if err := msg.ValidateBasic(); err != nil { rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) return @@ -70,6 +73,7 @@ func mintNFTHandlerFn(cliCtx client.Context) http.HandlerFunc { req.DenomID, req.Name, req.URI, + req.UriHash, req.Data, req.Owner, req.Recipient, @@ -101,6 +105,7 @@ func editNFTHandlerFn(cliCtx client.Context) http.HandlerFunc { vars[RestParamDenomID], req.Name, req.URI, + req.UriHash, req.Data, req.Owner, ) if err := msg.ValidateBasic(); err != nil { @@ -134,6 +139,7 @@ func transferNFTHandlerFn(cliCtx client.Context) http.HandlerFunc { vars[RestParamDenomID], req.Name, req.URI, + req.UriHash, req.Data, req.Owner, req.Recipient, diff --git a/modules/nft/client/testutil/test_helpers.go b/modules/nft/client/testutil/test_helpers.go index b47f639d..db6f57a8 100644 --- a/modules/nft/client/testutil/test_helpers.go +++ b/modules/nft/client/testutil/test_helpers.go @@ -13,7 +13,7 @@ import ( nftcli "github.com/irisnet/irismod/modules/nft/client/cli" ) -// MsgRedelegateExec creates a redelegate message. +// IssueDenomExec creates a redelegate message. func IssueDenomExec(clientCtx client.Context, from string, denom string, extraArgs ...string) (testutil.BufferWriter, error) { args := []string{ denom, diff --git a/modules/nft/exported/nft.go b/modules/nft/exported/nft.go index 383149db..e26994f4 100644 --- a/modules/nft/exported/nft.go +++ b/modules/nft/exported/nft.go @@ -10,5 +10,6 @@ type NFT interface { GetName() string GetOwner() sdk.AccAddress GetURI() string + GetURIHash() string GetData() string } diff --git a/modules/nft/keeper/collection.go b/modules/nft/keeper/collection.go index 2d693327..bdff27d5 100644 --- a/modules/nft/keeper/collection.go +++ b/modules/nft/keeper/collection.go @@ -22,6 +22,7 @@ func (k Keeper) SetCollection(ctx sdk.Context, collection types.Collection) erro nft.GetID(), nft.GetName(), nft.GetURI(), + nft.GetURIHash(), nft.GetData(), nft.GetOwner(), ); err != nil { diff --git a/modules/nft/keeper/collection_test.go b/modules/nft/keeper/collection_test.go index 03339944..de2ca5e0 100644 --- a/modules/nft/keeper/collection_test.go +++ b/modules/nft/keeper/collection_test.go @@ -6,9 +6,9 @@ import ( ) func (suite *KeeperSuite) TestSetCollection() { - nft := types.NewBaseNFT(tokenID, tokenNm, address, tokenURI, tokenData) + nft := types.NewBaseNFT(tokenID, tokenNm, address, tokenURI, tokenURIHash, tokenData) // create a new NFT and add it to the collection created with the NFT mint - nft2 := types.NewBaseNFT(tokenID2, tokenNm, address, tokenURI, tokenData) + nft2 := types.NewBaseNFT(tokenID2, tokenNm, address, tokenURI, tokenURIHash2, tokenData) denomE := types.Denom{ Id: denomID, @@ -38,7 +38,7 @@ func (suite *KeeperSuite) TestSetCollection() { func (suite *KeeperSuite) TestGetCollection() { // MintNFT shouldn't fail when collection does not exist - err := suite.keeper.MintNFT(suite.ctx, denomID, tokenID, tokenNm, tokenURI, tokenData, address) + err := suite.keeper.MintNFT(suite.ctx, denomID, tokenID, tokenNm, tokenURI, tokenURIHash, tokenData, address) suite.NoError(err) // collection should exist @@ -53,7 +53,7 @@ func (suite *KeeperSuite) TestGetCollection() { func (suite *KeeperSuite) TestGetCollections() { // MintNFT shouldn't fail when collection does not exist - err := suite.keeper.MintNFT(suite.ctx, denomID, tokenID, tokenNm, tokenURI, tokenData, address) + err := suite.keeper.MintNFT(suite.ctx, denomID, tokenID, tokenNm, tokenURI, tokenURIHash, tokenData, address) suite.NoError(err) msg, fail := keeper.SupplyInvariant(suite.keeper)(suite.ctx) @@ -62,15 +62,15 @@ func (suite *KeeperSuite) TestGetCollections() { func (suite *KeeperSuite) TestGetSupply() { // MintNFT shouldn't fail when collection does not exist - err := suite.keeper.MintNFT(suite.ctx, denomID, tokenID, tokenNm, tokenURI, tokenData, address) + err := suite.keeper.MintNFT(suite.ctx, denomID, tokenID, tokenNm, tokenURI, tokenURIHash, tokenData, address) suite.NoError(err) // MintNFT shouldn't fail when collection does not exist - err = suite.keeper.MintNFT(suite.ctx, denomID, tokenID2, tokenNm2, tokenURI, tokenData, address2) + err = suite.keeper.MintNFT(suite.ctx, denomID, tokenID2, tokenNm2, tokenURI, tokenURIHash, tokenData, address2) suite.NoError(err) // MintNFT shouldn't fail when collection does not exist - err = suite.keeper.MintNFT(suite.ctx, denomID2, tokenID, tokenNm2, tokenURI, tokenData, address2) + err = suite.keeper.MintNFT(suite.ctx, denomID2, tokenID, tokenNm2, tokenURI, tokenURIHash, tokenData, address2) suite.NoError(err) supply := suite.keeper.GetTotalSupply(suite.ctx, denomID) diff --git a/modules/nft/keeper/grpc_query_test.go b/modules/nft/keeper/grpc_query_test.go index 88fec55f..f9bb549f 100644 --- a/modules/nft/keeper/grpc_query_test.go +++ b/modules/nft/keeper/grpc_query_test.go @@ -7,7 +7,7 @@ import ( ) func (suite *KeeperSuite) TestSupply() { - err := suite.keeper.MintNFT(suite.ctx, denomID, tokenID, tokenNm, tokenURI, tokenData, address) + err := suite.keeper.MintNFT(suite.ctx, denomID, tokenID, tokenNm, tokenURI, tokenURIHash, tokenData, address) suite.NoError(err) response, err := suite.queryClient.Supply(gocontext.Background(), &types.QuerySupplyRequest{ @@ -20,7 +20,7 @@ func (suite *KeeperSuite) TestSupply() { } func (suite *KeeperSuite) TestOwner() { - err := suite.keeper.MintNFT(suite.ctx, denomID, tokenID, tokenNm, tokenURI, tokenData, address) + err := suite.keeper.MintNFT(suite.ctx, denomID, tokenID, tokenNm, tokenURI, tokenURIHash, tokenData, address) suite.NoError(err) response, err := suite.queryClient.Owner(gocontext.Background(), &types.QueryOwnerRequest{ @@ -34,7 +34,7 @@ func (suite *KeeperSuite) TestOwner() { } func (suite *KeeperSuite) TestCollection() { - err := suite.keeper.MintNFT(suite.ctx, denomID, tokenID, tokenNm, tokenURI, tokenData, address) + err := suite.keeper.MintNFT(suite.ctx, denomID, tokenID, tokenNm, tokenURI, tokenURIHash, tokenData, address) suite.NoError(err) response, err := suite.queryClient.Collection(gocontext.Background(), &types.QueryCollectionRequest{ @@ -48,7 +48,7 @@ func (suite *KeeperSuite) TestCollection() { } func (suite *KeeperSuite) TestDenom() { - err := suite.keeper.MintNFT(suite.ctx, denomID, tokenID, tokenNm, tokenURI, tokenData, address) + err := suite.keeper.MintNFT(suite.ctx, denomID, tokenID, tokenNm, tokenURI, tokenURIHash, tokenData, address) suite.NoError(err) response, err := suite.queryClient.Denom(gocontext.Background(), &types.QueryDenomRequest{ @@ -61,7 +61,7 @@ func (suite *KeeperSuite) TestDenom() { } func (suite *KeeperSuite) TestDenoms() { - err := suite.keeper.MintNFT(suite.ctx, denomID, tokenID, tokenNm, tokenURI, tokenData, address) + err := suite.keeper.MintNFT(suite.ctx, denomID, tokenID, tokenNm, tokenURI, tokenURIHash, tokenData, address) suite.NoError(err) response, err := suite.queryClient.Denoms(gocontext.Background(), &types.QueryDenomsRequest{}) @@ -72,7 +72,7 @@ func (suite *KeeperSuite) TestDenoms() { } func (suite *KeeperSuite) TestNFT() { - err := suite.keeper.MintNFT(suite.ctx, denomID, tokenID, tokenNm, tokenURI, tokenData, address) + err := suite.keeper.MintNFT(suite.ctx, denomID, tokenID, tokenNm, tokenURI, tokenURIHash, tokenData, address) suite.NoError(err) response, err := suite.queryClient.NFT(gocontext.Background(), &types.QueryNFTRequest{ diff --git a/modules/nft/keeper/keeper.go b/modules/nft/keeper/keeper.go index 54ddbd98..0bbc749d 100644 --- a/modules/nft/keeper/keeper.go +++ b/modules/nft/keeper/keeper.go @@ -6,6 +6,7 @@ import ( "github.com/tendermint/tendermint/libs/log" "github.com/cosmos/cosmos-sdk/codec" + storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" @@ -14,12 +15,12 @@ import ( // Keeper maintains the link to data storage and exposes getter/setter methods for the various parts of the state machine type Keeper struct { - storeKey sdk.StoreKey // Unexposed key to access store from sdk.Context + storeKey storetypes.StoreKey // Unexposed key to access store from sdk.Context cdc codec.Codec } // NewKeeper creates a new instance of the NFT Keeper -func NewKeeper(cdc codec.Codec, storeKey sdk.StoreKey) Keeper { +func NewKeeper(cdc codec.Codec, storeKey storetypes.StoreKey) Keeper { return Keeper{ storeKey: storeKey, cdc: cdc, @@ -36,14 +37,27 @@ func (k Keeper) IssueDenom(ctx sdk.Context, id, name, schema, symbol string, creator sdk.AccAddress, mintRestricted, updateRestricted bool, + description, uri, uriHash, data string, ) error { - return k.SetDenom(ctx, types.NewDenom(id, name, schema, symbol, creator, mintRestricted, updateRestricted)) + return k.SetDenom(ctx, types.Denom{ + Id: id, + Name: name, + Schema: schema, + Creator: creator.String(), + Symbol: symbol, + MintRestricted: mintRestricted, + UpdateRestricted: updateRestricted, + Description: description, + Uri: uri, + UriHash: uriHash, + Data: data, + }) } // MintNFT mints an NFT and manages the NFT's existence within Collections and Owners func (k Keeper) MintNFT( ctx sdk.Context, denomID, tokenID, tokenNm, - tokenURI, tokenData string, owner sdk.AccAddress, + tokenURI, uriHash, tokenData string, owner sdk.AccAddress, ) error { if k.HasNFT(ctx, denomID, tokenID) { return sdkerrors.Wrapf(types.ErrNFTAlreadyExists, "NFT %s already exists in collection %s", tokenID, denomID) @@ -56,6 +70,7 @@ func (k Keeper) MintNFT( tokenNm, owner, tokenURI, + uriHash, tokenData, ), ) @@ -68,7 +83,7 @@ func (k Keeper) MintNFT( // EditNFT updates an already existing NFT func (k Keeper) EditNFT( ctx sdk.Context, denomID, tokenID, tokenNm, - tokenURI, tokenData string, owner sdk.AccAddress, + tokenURI, tokenURIHash, tokenData string, owner sdk.AccAddress, ) error { denom, found := k.GetDenom(ctx, denomID) if !found { @@ -94,6 +109,10 @@ func (k Keeper) EditNFT( nft.URI = tokenURI } + if types.Modified(tokenURIHash) { + nft.UriHash = tokenURIHash + } + if types.Modified(tokenData) { nft.Data = tokenData } @@ -105,7 +124,7 @@ func (k Keeper) EditNFT( // TransferOwner transfers the ownership of the given NFT to the new owner func (k Keeper) TransferOwner( - ctx sdk.Context, denomID, tokenID, tokenNm, tokenURI, + ctx sdk.Context, denomID, tokenID, tokenNm, tokenURI, tokenURIHash, tokenData string, srcOwner, dstOwner sdk.AccAddress, ) error { denom, found := k.GetDenom(ctx, denomID) @@ -130,6 +149,9 @@ func (k Keeper) TransferOwner( if types.Modified(tokenURI) { nft.URI = tokenURI } + if types.Modified(tokenURIHash) { + nft.UriHash = tokenURIHash + } if types.Modified(tokenData) { nft.Data = tokenData } diff --git a/modules/nft/keeper/keeper_test.go b/modules/nft/keeper/keeper_test.go index de58c8a5..6352a5e0 100644 --- a/modules/nft/keeper/keeper_test.go +++ b/modules/nft/keeper/keeper_test.go @@ -40,14 +40,19 @@ var ( denomNm3 = "denom3nm" denomSymbol3 = "denomSymbol3" - address = CreateTestAddrs(1)[0] - address2 = CreateTestAddrs(2)[1] - address3 = CreateTestAddrs(3)[2] - tokenURI = "https://google.com/token-1.json" - tokenURI2 = "https://google.com/token-2.json" - tokenData = "{a:a,b:b}" - - isCheckTx = false + address = CreateTestAddrs(1)[0] + address2 = CreateTestAddrs(2)[1] + address3 = CreateTestAddrs(3)[2] + tokenURI = "https://google.com/token-1.json" + tokenURIHash = "tokenURIHash" + tokenURI2 = "https://google.com/token-2.json" + tokenURIHash2 = "tokenURIHash2" + tokenData = "{a:a,b:b}" + denomDescription = "this is a class name of a nft" + denomUri = "denom uri" + denomUriHash = "denom uri hash" + denomData = "denom data" + isCheckTx = false ) type KeeperSuite struct { @@ -74,14 +79,14 @@ func (suite *KeeperSuite) SetupTest() { types.RegisterQueryServer(queryHelper, app.NFTKeeper) suite.queryClient = types.NewQueryClient(queryHelper) - err := suite.keeper.IssueDenom(suite.ctx, denomID, denomNm, schema, denomSymbol, address, false, false) + err := suite.keeper.IssueDenom(suite.ctx, denomID, denomNm, schema, denomSymbol, address, false, false, denomDescription, denomUri, denomUriHash, denomData) suite.NoError(err) // MintNFT shouldn't fail when collection does not exist - err = suite.keeper.IssueDenom(suite.ctx, denomID2, denomNm2, schema, denomSymbol2, address, false, false) + err = suite.keeper.IssueDenom(suite.ctx, denomID2, denomNm2, schema, denomSymbol2, address, false, false, denomDescription, denomUri, denomUriHash, denomData) suite.NoError(err) - err = suite.keeper.IssueDenom(suite.ctx, denomID3, denomNm3, schema, denomSymbol3, address3, true, true) + err = suite.keeper.IssueDenom(suite.ctx, denomID3, denomNm3, schema, denomSymbol3, address3, true, true, denomDescription, denomUri, denomUriHash, denomData) suite.NoError(err) // collections should equal 3 @@ -96,34 +101,34 @@ func TestKeeperSuite(t *testing.T) { func (suite *KeeperSuite) TestMintNFT() { // MintNFT shouldn't fail when collection does not exist - err := suite.keeper.MintNFT(suite.ctx, denomID, tokenID, tokenNm, tokenURI, tokenData, address) + err := suite.keeper.MintNFT(suite.ctx, denomID, tokenID, tokenNm, tokenURI, tokenURIHash, tokenData, address) suite.NoError(err) // MintNFT shouldn't fail when collection exists - err = suite.keeper.MintNFT(suite.ctx, denomID, tokenID2, tokenNm2, tokenURI, tokenData, address) + err = suite.keeper.MintNFT(suite.ctx, denomID, tokenID2, tokenNm2, tokenURI, tokenURIHash, tokenData, address) suite.NoError(err) } func (suite *KeeperSuite) TestUpdateNFT() { // EditNFT should fail when NFT doesn't exists - err := suite.keeper.EditNFT(suite.ctx, denomID, tokenID, tokenNm3, tokenURI, tokenData, address) + err := suite.keeper.EditNFT(suite.ctx, denomID, tokenID, tokenNm3, tokenURI, tokenURIHash, tokenData, address) suite.Error(err) // MintNFT shouldn't fail when collection does not exist - err = suite.keeper.MintNFT(suite.ctx, denomID, tokenID, tokenNm, tokenURI, tokenData, address) + err = suite.keeper.MintNFT(suite.ctx, denomID, tokenID, tokenNm, tokenURI, tokenURIHash, tokenData, address) suite.NoError(err) // EditNFT should fail when NFT doesn't exists - err = suite.keeper.EditNFT(suite.ctx, denomID, tokenID2, tokenNm2, tokenURI, tokenData, address) + err = suite.keeper.EditNFT(suite.ctx, denomID, tokenID2, tokenNm2, tokenURI, tokenURIHash, tokenData, address) suite.Error(err) // EditNFT shouldn't fail when NFT exists - err = suite.keeper.EditNFT(suite.ctx, denomID, tokenID, tokenNm, tokenURI2, tokenData, address) + err = suite.keeper.EditNFT(suite.ctx, denomID, tokenID, tokenNm, tokenURI2, tokenURIHash2, tokenData, address) suite.NoError(err) // EditNFT should fail when NFT failed to authorize - err = suite.keeper.EditNFT(suite.ctx, denomID, tokenID, tokenNm, tokenURI2, tokenData, address2) + err = suite.keeper.EditNFT(suite.ctx, denomID, tokenID, tokenNm, tokenURI2, tokenURIHash2, tokenData, address2) suite.Error(err) // GetNFT should get the NFT with new tokenURI @@ -132,29 +137,29 @@ func (suite *KeeperSuite) TestUpdateNFT() { suite.Equal(receivedNFT.GetURI(), tokenURI2) // EditNFT shouldn't fail when NFT exists - err = suite.keeper.EditNFT(suite.ctx, denomID, tokenID, tokenNm, tokenURI2, tokenData, address2) + err = suite.keeper.EditNFT(suite.ctx, denomID, tokenID, tokenNm, tokenURI2, tokenURIHash2, tokenData, address2) suite.Error(err) - err = suite.keeper.MintNFT(suite.ctx, denomID3, denomID3, tokenID3, tokenURI, tokenData, address3) + err = suite.keeper.MintNFT(suite.ctx, denomID3, denomID3, tokenID3, tokenURI, tokenURIHash, tokenData, address3) suite.NoError(err) // EditNFT should fail if updateRestricted equal to true, nobody can update the NFT under this denom - err = suite.keeper.EditNFT(suite.ctx, denomID3, denomID3, tokenID3, tokenURI, tokenData, address3) + err = suite.keeper.EditNFT(suite.ctx, denomID3, denomID3, tokenID3, tokenURI, tokenURIHash, tokenData, address3) suite.Error(err) } func (suite *KeeperSuite) TestTransferOwner() { // MintNFT shouldn't fail when collection does not exist - err := suite.keeper.MintNFT(suite.ctx, denomID, tokenID, tokenNm, tokenURI, tokenData, address) + err := suite.keeper.MintNFT(suite.ctx, denomID, tokenID, tokenNm, tokenURI, tokenURIHash, tokenData, address) suite.NoError(err) // invalid owner - err = suite.keeper.TransferOwner(suite.ctx, denomID, tokenID, tokenNm, tokenURI, tokenData, address2, address3) + err = suite.keeper.TransferOwner(suite.ctx, denomID, tokenID, tokenNm, tokenURI, tokenURIHash, tokenData, address2, address3) suite.Error(err) // right - err = suite.keeper.TransferOwner(suite.ctx, denomID, tokenID, tokenNm2, tokenURI2, tokenData, address, address2) + err = suite.keeper.TransferOwner(suite.ctx, denomID, tokenID, tokenNm2, tokenURI2, tokenURIHash2, tokenData, address, address2) suite.NoError(err) nft, err := suite.keeper.GetNFT(suite.ctx, denomID, tokenID) @@ -180,7 +185,7 @@ func (suite *KeeperSuite) TestTransferDenom() { func (suite *KeeperSuite) TestBurnNFT() { // MintNFT should not fail when collection does not exist - err := suite.keeper.MintNFT(suite.ctx, denomID, tokenID, tokenNm, tokenURI, tokenData, address) + err := suite.keeper.MintNFT(suite.ctx, denomID, tokenID, tokenNm, tokenURI, tokenURIHash, tokenData, address) suite.NoError(err) // BurnNFT should fail when NFT doesn't exist but collection does exist diff --git a/modules/nft/keeper/msg_server.go b/modules/nft/keeper/msg_server.go index 3f15e8ac..710535f4 100644 --- a/modules/nft/keeper/msg_server.go +++ b/modules/nft/keeper/msg_server.go @@ -29,7 +29,10 @@ func (m msgServer) IssueDenom(goCtx context.Context, msg *types.MsgIssueDenom) ( } ctx := sdk.UnwrapSDKContext(goCtx) - if err := m.Keeper.IssueDenom(ctx, msg.Id, msg.Name, msg.Schema, msg.Symbol, sender, msg.MintRestricted, msg.UpdateRestricted); err != nil { + if err := m.Keeper.IssueDenom(ctx, msg.Id, msg.Name, msg.Schema, msg.Symbol, sender, + msg.MintRestricted, msg.UpdateRestricted, + msg.Description, msg.Uri, msg.UriHash, msg.Data, + ); err != nil { return nil, err } @@ -75,6 +78,7 @@ func (m msgServer) MintNFT(goCtx context.Context, msg *types.MsgMintNFT) (*types if err := m.Keeper.MintNFT(ctx, msg.DenomId, msg.Id, msg.Name, msg.URI, + msg.UriHash, msg.Data, recipient, ); err != nil { @@ -109,6 +113,7 @@ func (m msgServer) EditNFT(goCtx context.Context, msg *types.MsgEditNFT) (*types if err := m.Keeper.EditNFT(ctx, msg.DenomId, msg.Id, msg.Name, msg.URI, + msg.UriHash, msg.Data, sender, ); err != nil { @@ -148,6 +153,7 @@ func (m msgServer) TransferNFT(goCtx context.Context, msg *types.MsgTransferNFT) if err := m.Keeper.TransferOwner(ctx, msg.DenomId, msg.Id, msg.Name, msg.URI, + msg.UriHash, msg.Data, sender, recipient, diff --git a/modules/nft/keeper/nft_test.go b/modules/nft/keeper/nft_test.go index 4576be65..07f67011 100644 --- a/modules/nft/keeper/nft_test.go +++ b/modules/nft/keeper/nft_test.go @@ -6,7 +6,7 @@ import ( func (suite *KeeperSuite) TestGetNFT() { // MintNFT shouldn't fail when collection does not exist - err := suite.keeper.MintNFT(suite.ctx, denomID, tokenID, tokenNm, tokenURI, tokenData, address) + err := suite.keeper.MintNFT(suite.ctx, denomID, tokenID, tokenNm, tokenURI, tokenURIHash, tokenData, address) suite.NoError(err) // GetNFT should get the NFT @@ -17,7 +17,7 @@ func (suite *KeeperSuite) TestGetNFT() { suite.Equal(receivedNFT.GetURI(), tokenURI) // MintNFT shouldn't fail when collection exists - err = suite.keeper.MintNFT(suite.ctx, denomID, tokenID2, tokenNm2, tokenURI, tokenData, address) + err = suite.keeper.MintNFT(suite.ctx, denomID, tokenID2, tokenNm2, tokenURI, tokenURIHash, tokenData, address) suite.NoError(err) // GetNFT should get the NFT when collection exists @@ -32,16 +32,16 @@ func (suite *KeeperSuite) TestGetNFT() { } func (suite *KeeperSuite) TestGetNFTs() { - err := suite.keeper.MintNFT(suite.ctx, denomID2, tokenID, tokenNm, tokenURI, tokenData, address) + err := suite.keeper.MintNFT(suite.ctx, denomID2, tokenID, tokenNm, tokenURI, tokenURIHash, tokenData, address) suite.NoError(err) - err = suite.keeper.MintNFT(suite.ctx, denomID2, tokenID2, tokenNm2, tokenURI, tokenData, address) + err = suite.keeper.MintNFT(suite.ctx, denomID2, tokenID2, tokenNm2, tokenURI, tokenURIHash, tokenData, address) suite.NoError(err) - err = suite.keeper.MintNFT(suite.ctx, denomID2, tokenID3, tokenNm3, tokenURI, tokenData, address) + err = suite.keeper.MintNFT(suite.ctx, denomID2, tokenID3, tokenNm3, tokenURI, tokenURIHash, tokenData, address) suite.NoError(err) - err = suite.keeper.MintNFT(suite.ctx, denomID, tokenID3, tokenNm3, tokenURI, tokenData, address) + err = suite.keeper.MintNFT(suite.ctx, denomID, tokenID3, tokenNm3, tokenURI, tokenURIHash, tokenData, address) suite.NoError(err) nfts := suite.keeper.GetNFTs(suite.ctx, denomID2) @@ -49,7 +49,7 @@ func (suite *KeeperSuite) TestGetNFTs() { } func (suite *KeeperSuite) TestAuthorize() { - err := suite.keeper.MintNFT(suite.ctx, denomID, tokenID, tokenNm, tokenURI, tokenData, address) + err := suite.keeper.MintNFT(suite.ctx, denomID, tokenID, tokenNm, tokenURI, tokenURIHash, tokenData, address) suite.NoError(err) _, err = suite.keeper.Authorize(suite.ctx, denomID, tokenID, address2) @@ -65,7 +65,7 @@ func (suite *KeeperSuite) TestHasNFT() { suite.False(isNFT) // MintNFT shouldn't fail when collection does not exist - err := suite.keeper.MintNFT(suite.ctx, denomID, tokenID, tokenNm, tokenURI, tokenData, address) + err := suite.keeper.MintNFT(suite.ctx, denomID, tokenID, tokenNm, tokenURI, tokenURIHash, tokenData, address) suite.NoError(err) // IsNFT should return true diff --git a/modules/nft/keeper/owners_test.go b/modules/nft/keeper/owners_test.go index 2bc69c40..a57db0b0 100644 --- a/modules/nft/keeper/owners_test.go +++ b/modules/nft/keeper/owners_test.go @@ -6,25 +6,25 @@ import ( func (suite *KeeperSuite) TestGetOwners() { - err := suite.keeper.MintNFT(suite.ctx, denomID, tokenID, tokenNm, tokenURI, tokenData, address) + err := suite.keeper.MintNFT(suite.ctx, denomID, tokenID, tokenNm, tokenURI, tokenURIHash, tokenData, address) suite.NoError(err) - err = suite.keeper.MintNFT(suite.ctx, denomID, tokenID2, tokenNm2, tokenURI, tokenData, address2) + err = suite.keeper.MintNFT(suite.ctx, denomID, tokenID2, tokenNm2, tokenURI, tokenURIHash, tokenData, address2) suite.NoError(err) - err = suite.keeper.MintNFT(suite.ctx, denomID, tokenID3, tokenNm3, tokenURI, tokenData, address3) + err = suite.keeper.MintNFT(suite.ctx, denomID, tokenID3, tokenNm3, tokenURI, tokenURIHash, tokenData, address3) suite.NoError(err) owners := suite.keeper.GetOwners(suite.ctx) suite.Equal(3, len(owners)) - err = suite.keeper.MintNFT(suite.ctx, denomID2, tokenID, tokenNm, tokenURI, tokenData, address) + err = suite.keeper.MintNFT(suite.ctx, denomID2, tokenID, tokenNm, tokenURI, tokenURIHash, tokenData, address) suite.NoError(err) - err = suite.keeper.MintNFT(suite.ctx, denomID2, tokenID2, tokenNm2, tokenURI, tokenData, address2) + err = suite.keeper.MintNFT(suite.ctx, denomID2, tokenID2, tokenNm2, tokenURI, tokenURIHash, tokenData, address2) suite.NoError(err) - err = suite.keeper.MintNFT(suite.ctx, denomID2, tokenID3, tokenNm3, tokenURI, tokenData, address3) + err = suite.keeper.MintNFT(suite.ctx, denomID2, tokenID3, tokenNm3, tokenURI, tokenURIHash, tokenData, address3) suite.NoError(err) owners = suite.keeper.GetOwners(suite.ctx) diff --git a/modules/nft/keeper/querier_test.go b/modules/nft/keeper/querier_test.go index caecdeca..39b5d907 100644 --- a/modules/nft/keeper/querier_test.go +++ b/modules/nft/keeper/querier_test.go @@ -22,7 +22,7 @@ func (suite *KeeperSuite) TestNewQuerier() { func (suite *KeeperSuite) TestQuerySupply() { // MintNFT shouldn't fail when collection does not exist - err := suite.keeper.MintNFT(suite.ctx, denomID, tokenID, tokenNm, tokenURI, tokenData, address) + err := suite.keeper.MintNFT(suite.ctx, denomID, tokenID, tokenNm, tokenURI, tokenURIHash, tokenData, address) suite.NoError(err) querier := keep.NewQuerier(suite.keeper, suite.legacyAmino) @@ -63,7 +63,7 @@ func (suite *KeeperSuite) TestQuerySupply() { func (suite *KeeperSuite) TestQueryCollection() { // MintNFT shouldn't fail when collection does not exist - err := suite.keeper.MintNFT(suite.ctx, denomID, tokenID, tokenNm, tokenURI, tokenData, address) + err := suite.keeper.MintNFT(suite.ctx, denomID, tokenID, tokenNm, tokenURI, tokenURIHash, tokenData, address) suite.NoError(err) querier := keep.NewQuerier(suite.keeper, suite.legacyAmino) @@ -104,10 +104,10 @@ func (suite *KeeperSuite) TestQueryCollection() { func (suite *KeeperSuite) TestQueryOwner() { // MintNFT shouldn't fail when collection does not exist - err := suite.keeper.MintNFT(suite.ctx, denomID, tokenID, tokenNm, tokenURI, tokenData, address) + err := suite.keeper.MintNFT(suite.ctx, denomID, tokenID, tokenNm, tokenURI, tokenURIHash, tokenData, address) suite.NoError(err) - err = suite.keeper.MintNFT(suite.ctx, denomID2, tokenID, tokenNm, tokenURI, tokenData, address) + err = suite.keeper.MintNFT(suite.ctx, denomID2, tokenID, tokenNm, tokenURI, tokenURIHash, tokenData, address) suite.NoError(err) querier := keep.NewQuerier(suite.keeper, suite.legacyAmino) @@ -143,7 +143,7 @@ func (suite *KeeperSuite) TestQueryOwner() { func (suite *KeeperSuite) TestQueryNFT() { // MintNFT shouldn't fail when collection does not exist - err := suite.keeper.MintNFT(suite.ctx, denomID, tokenID, tokenNm, tokenURI, tokenData, address) + err := suite.keeper.MintNFT(suite.ctx, denomID, tokenID, tokenNm, tokenURI, tokenURIHash, tokenData, address) suite.NoError(err) querier := keep.NewQuerier(suite.keeper, suite.legacyAmino) @@ -188,10 +188,10 @@ func (suite *KeeperSuite) TestQueryNFT() { func (suite *KeeperSuite) TestQueryDenoms() { // MintNFT shouldn't fail when collection does not exist - err := suite.keeper.MintNFT(suite.ctx, denomID, tokenID, tokenNm, tokenURI, tokenData, address) + err := suite.keeper.MintNFT(suite.ctx, denomID, tokenID, tokenNm, tokenURI, tokenURIHash, tokenData, address) suite.NoError(err) - err = suite.keeper.MintNFT(suite.ctx, denomID2, tokenID, tokenNm, tokenURI, tokenData, address) + err = suite.keeper.MintNFT(suite.ctx, denomID2, tokenID, tokenNm, tokenURI, tokenURIHash, tokenData, address) suite.NoError(err) querier := keep.NewQuerier(suite.keeper, suite.legacyAmino) diff --git a/modules/nft/module.go b/modules/nft/module.go index cfb41b63..8adb3d5f 100644 --- a/modules/nft/module.go +++ b/modules/nft/module.go @@ -20,7 +20,6 @@ import ( simtypes "github.com/cosmos/cosmos-sdk/types/simulation" "github.com/irisnet/irismod/modules/nft/client/cli" - "github.com/irisnet/irismod/modules/nft/client/rest" "github.com/irisnet/irismod/modules/nft/keeper" "github.com/irisnet/irismod/modules/nft/simulation" "github.com/irisnet/irismod/modules/nft/types" @@ -62,7 +61,6 @@ func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncod // RegisterRESTRoutes registers the REST routes for the NFT module. func (AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Router) { - rest.RegisterHandlers(clientCtx, rtr, types.RouterKey) } // RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the NFT module. diff --git a/modules/nft/simulation/genesis.go b/modules/nft/simulation/genesis.go index 0ee1864c..1565dd55 100644 --- a/modules/nft/simulation/genesis.go +++ b/modules/nft/simulation/genesis.go @@ -48,6 +48,7 @@ func RandomizedGenState(simState *module.SimulationState) { simtypes.RandStringOfLength(simState.Rand, 10), acc.Address, simtypes.RandStringOfLength(simState.Rand, 45), // tokenURI + simtypes.RandStringOfLength(simState.Rand, 32), // tokenURIHash simtypes.RandStringOfLength(simState.Rand, 10), ) diff --git a/modules/nft/simulation/operations.go b/modules/nft/simulation/operations.go index b1ed26f3..3e8389f3 100644 --- a/modules/nft/simulation/operations.go +++ b/modules/nft/simulation/operations.go @@ -125,6 +125,7 @@ func SimulateMsgTransferNFT(k keeper.Keeper, ak types.AccountKeeper, bk types.Ba denom, "", "", + "", simtypes.RandStringOfLength(r, 10), // tokenData ownerAddr.String(), // sender recipientAccount.Address.String(), // recipient @@ -184,6 +185,7 @@ func SimulateMsgEditNFT(k keeper.Keeper, ak types.AccountKeeper, bk types.BankKe denom, "", simtypes.RandStringOfLength(r, 45), // tokenURI + simtypes.RandStringOfLength(r, 32), // tokenURI simtypes.RandStringOfLength(r, 10), // tokenData ownerAddr.String(), ) @@ -239,6 +241,7 @@ func SimulateMsgMintNFT(k keeper.Keeper, ak types.AccountKeeper, bk types.BankKe getRandomDenom(ctx, k, r), // denom "", simtypes.RandStringOfLength(r, 45), // tokenURI + simtypes.RandStringOfLength(r, 32), // uriHash simtypes.RandStringOfLength(r, 10), // tokenData randomSender.Address.String(), // sender randomRecipient.Address.String(), // recipient @@ -405,6 +408,10 @@ func SimulateMsgIssueDenom(k keeper.Keeper, ak types.AccountKeeper, bk types.Ban sender, _ := simtypes.RandomAcc(r, accs) mintRestricted := genRandomBool(r) updateRestricted := genRandomBool(r) + description := simtypes.RandStringOfLength(r, 10) + uri := simtypes.RandStringOfLength(r, 10) + uriHash := simtypes.RandStringOfLength(r, 32) + data := simtypes.RandStringOfLength(r, 20) if err := types.ValidateDenomID(denomId); err != nil { return simtypes.NoOpMsg(types.ModuleName, types.TypeMsgTransferDenom, "invalid denom"), nil, nil @@ -423,6 +430,8 @@ func SimulateMsgIssueDenom(k keeper.Keeper, ak types.AccountKeeper, bk types.Ban symbol, mintRestricted, updateRestricted, + description, + uri, uriHash, data, ) account := ak.GetAccount(ctx, sender.Address) spendable := bk.SpendableCoins(ctx, account.GetAddress()) diff --git a/modules/nft/spec/01_state.md b/modules/nft/spec/01_state.md index 021274f7..27f5a35b 100644 --- a/modules/nft/spec/01_state.md +++ b/modules/nft/spec/01_state.md @@ -11,6 +11,7 @@ type NFT interface { GetName() string // return the name of BaseNFT GetOwner() sdk.AccAddress // gets owner account of the NFT GetURI() string // tokenData field: URI to retrieve the of chain tokenData of the NFT + GetURIHash() string GetData() string // return the Data of BaseNFT } ``` diff --git a/modules/nft/spec/02_messages.md b/modules/nft/spec/02_messages.md index 2c607124..a0ed4a78 100644 --- a/modules/nft/spec/02_messages.md +++ b/modules/nft/spec/02_messages.md @@ -4,25 +4,33 @@ This message defines a type of nft, there can be multiple nft of the same type -| **Field** | **Type** | **Description** | -| :-------- | :------- | :------------------------------------------------------------------------------------------------------------------------------- | -| Id | `string` | The denomination ID of the NFT, necessary as multiple denominations are able to be represented on each chain. | -| Name | `string` | The denomination name of the NFT, necessary as multiple denominations are able to be represented on each chain. | -| Sender | `string` | The account address of the user sending the NFT. By default it is __not__ required that the sender is also the owner of the NFT. | -| Schema | `string` | NFT specifications defined under this category | -| Symbol | `string` | The abbreviated name of a specific NFT type | -| MintRestricted | `bool` | MintRestricted is true means that only Denom owners can issue NFTs under this category, false means anyone can | | -| UpdateRestricted | `bool` | UpdateRestricted is true means that no one in this category can update the NFT, false means that only the owner of this NFT can update | | +| **Field** | **Type** | **Description** | +|:-----------------|:---------|:---------------------------------------------------------------------------------------------------------------------------------------| +| Id | `string` | The denomination ID of the NFT, necessary as multiple denominations are able to be represented on each chain. | +| Name | `string` | The denomination name of the NFT, necessary as multiple denominations are able to be represented on each chain. | +| Sender | `string` | The account address of the user sending the NFT. By default it is __not__ required that the sender is also the owner of the NFT. | +| Schema | `string` | NFT specifications defined under this category | +| Symbol | `string` | The abbreviated name of a specific NFT type | +| MintRestricted | `bool` | MintRestricted is true means that only Denom owners can issue NFTs under this category, false means anyone can | | +| UpdateRestricted | `bool` | UpdateRestricted is true means that no one in this category can update the NFT, false means that only the owner of this NFT can update | | +| Description | `string` | Description is a brief description of nft classification. Optional | | +| URI | `string` | The uri_hash is a hash of the document pointed by uri. Optional | | +| UriHash | `string` | UriHash is true means that no one in this category can update the NFT, false means that only the owner of this NFT can update | | +| Data | `string` | data is the app specific metadata of the NFT class. Optional | | ```go type MsgIssueDenom struct { - Id string - Name string - Schema string - Sender string - Symbol string - MintRestricted bool + Id string + Name string + Schema string + Sender string + Symbol string + MintRestricted bool UpdateRestricted bool + Description string + Uri string + UriHash string + Data string } ``` @@ -31,11 +39,12 @@ type MsgIssueDenom struct { This is the most commonly expected MsgType to be supported across chains. While each application specific blockchain will have very different adoption of the `MsgMintNFT`, `MsgBurnNFT` and `MsgEditNFT` it should be expected that most chains support the ability to transfer ownership of the NFT asset. The exception to this would be non-transferable NFTs that might be attached to reputation or some asset which should not be transferable. It still makes sense for this to be represented as an NFT because there are common queriers which will remain relevant to the NFT type even if non-transferable. This Message will fail if the NFT does not exist. By default it will not fail if the transfer is executed by someone beside the owner. **It is highly recommended that a custom handler is made to restrict use of this Message type to prevent unintended use.** | **Field** | **Type** | **Description** | -| :-------- | :------- | :------------------------------------------------------------------------------------------------------------------------------- | +|:----------|:---------|:---------------------------------------------------------------------------------------------------------------------------------| | ID | `string` | The unique ID of the NFT being transferred. | | DenomId | `string` | The unique ID of the denomination, necessary as multiple denominations are able to be represented on each chain. | | Name | `string` | The name of the NFT being transferred. | | URI | `string` | The URI pointing to a JSON object that contains subsequent tokenData information off-chain | +| UriHash | `string` | The uri_hash is a hash of the document pointed by uri. Optional | | | Data | `string` | The data of the NFT | | Sender | `string` | The account address of the user sending the NFT. By default it is __not__ required that the sender is also the owner of the NFT. | | Recipient | `string` | The account address who will receive the NFT as a result of the transfer transaction. | @@ -47,6 +56,7 @@ type MsgTransferNFT struct { DenomId string Name string URI string + UriHash string Data string Sender string Recipient string @@ -58,11 +68,12 @@ type MsgTransferNFT struct { This message type allows the `TokenURI` to be updated. By default anyone can execute this Message type. **It is highly recommended that a custom handler is made to restrict use of this Message type to prevent unintended use.** | **Field** | **Type** | **Description** | -| :-------- | :------- | :--------------------------------------------------------------------------------------------------------------- | +|:----------|:---------|:-----------------------------------------------------------------------------------------------------------------| | Id | `string` | The unique ID of the NFT being edited. | | DenomId | `string` | The unique ID of the denomination, necessary as multiple denominations are able to be represented on each chain. | | Name | `string` | The name of the NFT being edited. | | URI | `string` | The URI pointing to a JSON object that contains subsequent tokenData information off-chain | +| UriHash | `string` | The uri_hash is a hash of the document pointed by uri. Optional | | | Data | `string` | The data of the NFT | | Sender | `string` | The creator of the message | @@ -73,6 +84,7 @@ type MsgEditNFT struct { DenomId string Name string URI string + UriHash string Data string Sender string } @@ -83,11 +95,12 @@ type MsgEditNFT struct { This message type is used for minting new tokens. If a new `NFT` is minted under a new `Denom`, a new `Collection` will also be created, otherwise the `NFT` is added to the existing `Collection`. If a new `NFT` is minted by a new account, a new `Owner` is created, otherwise the `NFT` `ID` is added to the existing `Owner`'s `IDCollection`. By default anyone can execute this Message type. **It is highly recommended that a custom handler is made to restrict use of this Message type to prevent unintended use.** | **Field** | **Type** | **Description** | -| :-------- | :------- | :----------------------------------------------------------------------------------------- | +|:----------|:---------|:-------------------------------------------------------------------------------------------| | Id | `string` | The unique ID of the NFT being minted | | DenomId | `string` | The unique ID of the denomination. | | Name | `string` | The name of the NFT being minted. | | URI | `string` | The URI pointing to a JSON object that contains subsequent tokenData information off-chain | +| UriHash | `string` | The uri_hash is a hash of the document pointed by uri. Optional | | | Data | `string` | The data of the NFT. | | Sender | `string` | The sender of the Message | | Recipient | `string` | The recipiet of the new NFT | @@ -99,6 +112,7 @@ type MsgMintNFT struct { DenomId string Name string URI string + UriHash string Data string Sender string Recipient string @@ -110,7 +124,7 @@ type MsgMintNFT struct { This message type is used for burning tokens which destroys and deletes them. By default anyone can execute this Message type. **It is highly recommended that a custom handler is made to restrict use of this Message type to prevent unintended use.** | **Field** | **Type** | **Description** | -| :-------- | :------- | :------------------------------------------------- | +|:----------|:---------|:---------------------------------------------------| | Id | `string` | The ID of the Token. | | DenomId | `string` | The Denom ID of the Token. | | Sender | `string` | The account address of the user burning the token. | @@ -127,11 +141,11 @@ type MsgBurnNFT struct { ## MsgTransferDenom This message is used by the owner of the NFT classification to transfer the ownership of the NFT classification to others -| **Field** | **Type** | **Description** | -| :-------- | :------- | :------------------------------------------------------------------------------------------------------------------------------- | -| ID | `string` | The unique ID of the Denom being transferred. | -| Sender | `string` | The account address of the user sending the Denom. | -| Recipient | `string` | The account address who will receive the Denom as a result of the transfer transaction. | +| **Field** | **Type** | **Description** | +|:----------|:---------|:----------------------------------------------------------------------------------------| +| ID | `string` | The unique ID of the Denom being transferred. | +| Sender | `string` | The account address of the user sending the Denom. | +| Recipient | `string` | The account address who will receive the Denom as a result of the transfer transaction. | ```go // MsgTransferDenom defines an SDK message for transferring an Denom to recipient. diff --git a/modules/nft/spec/03_events.md b/modules/nft/spec/03_events.md index 1aba9f12..c6dbec62 100644 --- a/modules/nft/spec/03_events.md +++ b/modules/nft/spec/03_events.md @@ -7,7 +7,7 @@ The nft module emits the following events: ### MsgIssueDenom | Type | Attribute Key | Attribute Value | -| :---------- | :------------ | :--------------- | +|:------------|:--------------|:-----------------| | issue_denom | denom_id | {nftDenomID} | | issue_denom | denom_name | {nftDenomName} | | issue_denom | creator | {creatorAddress} | @@ -17,7 +17,7 @@ The nft module emits the following events: ### MsgTransferNFT | Type | Attribute Key | Attribute Value | -| :----------- | :------------ | :----------------- | +|:-------------|:--------------|:-------------------| | transfer_nft | token_id | {tokenID} | | transfer_nft | denom_id | {nftDenomID} | | transfer_nft | sender | {senderAddress} | @@ -28,7 +28,7 @@ The nft module emits the following events: ### MsgEditNFT | Type | Attribute Key | Attribute Value | -| :------- | :------------ | :-------------- | +|:---------|:--------------|:----------------| | edit_nft | token_id | {tokenID} | | edit_nft | denom_id | {nftDenomID} | | edit_nft | token_uri | {tokenURI} | @@ -39,7 +39,7 @@ The nft module emits the following events: ### MsgMintNFT | Type | Attribute Key | Attribute Value | -| :------- | :------------ | :----------------- | +|:---------|:--------------|:-------------------| | mint_nft | token_id | {tokenID} | | mint_nft | denom_id | {nftDenomID} | | mint_nft | token_uri | {tokenURI} | @@ -50,7 +50,7 @@ The nft module emits the following events: ### MsgBurnNFTs | Type | Attribute Key | Attribute Value | -| :------- | :------------ | :-------------- | +|:---------|:--------------|:----------------| | burn_nft | denom_id | {nftDenomID} | | burn_nft | token_id | {tokenID} | | burn_nft | owner | {ownerAddress} | @@ -59,10 +59,10 @@ The nft module emits the following events: ### MsgTransferDenom -| Type | Attribute Key | Attribute Value | -| :----------- | :------------ | :----------------- | +| Type | Attribute Key | Attribute Value | +|:---------------|:--------------|:-------------------| | transfer_denom | denom_id | {nftDenomID} | | transfer_denom | sender | {senderAddress} | | transfer_denom | recipient | {recipientAddress} | -| message | module | nft | -| message | sender | {senderAddress} | \ No newline at end of file +| message | module | nft | +| message | sender | {senderAddress} | \ No newline at end of file diff --git a/modules/nft/types/common_test.go b/modules/nft/types/common_test.go index f8e78b77..debd6347 100644 --- a/modules/nft/types/common_test.go +++ b/modules/nft/types/common_test.go @@ -16,6 +16,7 @@ var ( address = CreateTestAddrs(1)[0] address2 = CreateTestAddrs(2)[1] tokenURI = "https://google.com/token-1.json" + uriHash = "uriHash" tokenData = "https://google.com/token-1.json" ) diff --git a/modules/nft/types/denom.go b/modules/nft/types/denom.go index ca39c00f..3b6b0eea 100644 --- a/modules/nft/types/denom.go +++ b/modules/nft/types/denom.go @@ -5,7 +5,11 @@ import ( ) // NewDenom return a new denom -func NewDenom(id, name, schema, symbol string, creator sdk.AccAddress, mintRestricted, updateRestricted bool) Denom { +func NewDenom( + id, name, schema, symbol, description, uri, uriHash, data string, + creator sdk.AccAddress, + mintRestricted, updateRestricted bool, +) Denom { return Denom{ Id: id, Name: name, @@ -14,5 +18,9 @@ func NewDenom(id, name, schema, symbol string, creator sdk.AccAddress, mintRestr Symbol: symbol, MintRestricted: mintRestricted, UpdateRestricted: updateRestricted, + Description: description, + Uri: uri, + UriHash: uriHash, + Data: data, } } diff --git a/modules/nft/types/msgs.go b/modules/nft/types/msgs.go index 9b7ab8a0..12e47593 100644 --- a/modules/nft/types/msgs.go +++ b/modules/nft/types/msgs.go @@ -25,15 +25,22 @@ var ( ) // NewMsgIssueDenom is a constructor function for MsgSetName -func NewMsgIssueDenom(denomID, denomName, schema, sender, symbol string, mintRestricted, updateRestricted bool) *MsgIssueDenom { +func NewMsgIssueDenom(denomID, denomName, schema, sender, symbol string, + mintRestricted, updateRestricted bool, + description, uri, uriHash, data string, +) *MsgIssueDenom { return &MsgIssueDenom{ - Sender: sender, Id: denomID, Name: denomName, Schema: schema, + Sender: sender, Symbol: symbol, MintRestricted: mintRestricted, UpdateRestricted: updateRestricted, + Description: description, + Uri: uri, + UriHash: uriHash, + Data: data, } } @@ -72,13 +79,14 @@ func (msg MsgIssueDenom) GetSigners() []sdk.AccAddress { // NewMsgTransferNFT is a constructor function for MsgSetName func NewMsgTransferNFT( - tokenID, denomID, tokenName, tokenURI, tokenData, sender, recipient string, + tokenID, denomID, tokenName, tokenURI, tokenURIHash, tokenData, sender, recipient string, ) *MsgTransferNFT { return &MsgTransferNFT{ Id: tokenID, DenomId: denomID, Name: tokenName, URI: tokenURI, + UriHash: tokenURIHash, Data: tokenData, Sender: sender, Recipient: recipient, @@ -124,13 +132,14 @@ func (msg MsgTransferNFT) GetSigners() []sdk.AccAddress { // NewMsgEditNFT is a constructor function for MsgSetName func NewMsgEditNFT( - tokenID, denomID, tokenName, tokenURI, tokenData, sender string, + tokenID, denomID, tokenName, tokenURI, tokenURIHash, tokenData, sender string, ) *MsgEditNFT { return &MsgEditNFT{ Id: tokenID, DenomId: denomID, Name: tokenName, URI: tokenURI, + UriHash: tokenURIHash, Data: tokenData, Sender: sender, } @@ -175,13 +184,14 @@ func (msg MsgEditNFT) GetSigners() []sdk.AccAddress { // NewMsgMintNFT is a constructor function for MsgMintNFT func NewMsgMintNFT( - tokenID, denomID, tokenName, tokenURI, tokenData, sender, recipient string, + tokenID, denomID, tokenName, tokenURI, tokenURIHash, tokenData, sender, recipient string, ) *MsgMintNFT { return &MsgMintNFT{ Id: tokenID, DenomId: denomID, Name: tokenName, URI: tokenURI, + UriHash: tokenURIHash, Data: tokenData, Sender: sender, Recipient: recipient, diff --git a/modules/nft/types/msgs_test.go b/modules/nft/types/msgs_test.go index 07fe5092..f7c4f58b 100644 --- a/modules/nft/types/msgs_test.go +++ b/modules/nft/types/msgs_test.go @@ -11,92 +11,92 @@ import ( // ---------------------------------------- Msgs -------------------------------------------------- func TestMsgTransferNFTValidateBasicMethod(t *testing.T) { - newMsgTransferNFT := types.NewMsgTransferNFT(denomID, "", id, tokenURI, tokenData, address.String(), address2.String()) + newMsgTransferNFT := types.NewMsgTransferNFT(denomID, "", id, tokenURI, uriHash, tokenData, address.String(), address2.String()) err := newMsgTransferNFT.ValidateBasic() require.Error(t, err) - newMsgTransferNFT = types.NewMsgTransferNFT(denomID, denom, "", tokenURI, tokenData, "", address2.String()) + newMsgTransferNFT = types.NewMsgTransferNFT(denomID, denom, "", tokenURI, uriHash, tokenData, "", address2.String()) err = newMsgTransferNFT.ValidateBasic() require.Error(t, err) - newMsgTransferNFT = types.NewMsgTransferNFT(denomID, denom, "", tokenURI, tokenData, address.String(), "") + newMsgTransferNFT = types.NewMsgTransferNFT(denomID, denom, "", tokenURI, uriHash, tokenData, address.String(), "") err = newMsgTransferNFT.ValidateBasic() require.Error(t, err) - newMsgTransferNFT = types.NewMsgTransferNFT(denomID, denom, id, tokenURI, tokenData, address.String(), address2.String()) + newMsgTransferNFT = types.NewMsgTransferNFT(denomID, denom, id, tokenURI, uriHash, tokenData, address.String(), address2.String()) err = newMsgTransferNFT.ValidateBasic() require.NoError(t, err) } func TestMsgTransferNFTGetSignBytesMethod(t *testing.T) { - newMsgTransferNFT := types.NewMsgTransferNFT(denomID, denom, id, tokenURI, tokenData, address.String(), address2.String()) + newMsgTransferNFT := types.NewMsgTransferNFT(denomID, denom, id, tokenURI, uriHash, tokenData, address.String(), address2.String()) sortedBytes := newMsgTransferNFT.GetSignBytes() - expected := `{"type":"irismod/nft/MsgTransferNFT","value":{"data":"https://google.com/token-1.json","denom_id":"denom","id":"denom","name":"id1","recipient":"cosmos15ky9du8a2wlstz6fpx3p4mqpjyrm5cgp0ctjdj","sender":"cosmos15ky9du8a2wlstz6fpx3p4mqpjyrm5cgqjwl8sq","uri":"https://google.com/token-1.json"}}` + expected := `{"type":"irismod/nft/MsgTransferNFT","value":{"data":"https://google.com/token-1.json","denom_id":"denom","id":"denom","name":"id1","recipient":"cosmos15ky9du8a2wlstz6fpx3p4mqpjyrm5cgp0ctjdj","sender":"cosmos15ky9du8a2wlstz6fpx3p4mqpjyrm5cgqjwl8sq","uri":"https://google.com/token-1.json","uri_hash":"uriHash"}}` require.Equal(t, expected, string(sortedBytes)) } func TestMsgTransferNFTGetSignersMethod(t *testing.T) { - newMsgTransferNFT := types.NewMsgTransferNFT(denomID, denom, id, tokenURI, tokenData, address.String(), address2.String()) + newMsgTransferNFT := types.NewMsgTransferNFT(denomID, denom, id, tokenURI, uriHash, tokenData, address.String(), address2.String()) signers := newMsgTransferNFT.GetSigners() require.Equal(t, 1, len(signers)) require.Equal(t, address.String(), signers[0].String()) } func TestMsgEditNFTValidateBasicMethod(t *testing.T) { - newMsgEditNFT := types.NewMsgEditNFT(id, denom, nftName, tokenURI, tokenData, "") + newMsgEditNFT := types.NewMsgEditNFT(id, denom, nftName, tokenURI, uriHash, tokenData, "") err := newMsgEditNFT.ValidateBasic() require.Error(t, err) - newMsgEditNFT = types.NewMsgEditNFT("", denom, nftName, tokenURI, tokenData, address.String()) + newMsgEditNFT = types.NewMsgEditNFT("", denom, nftName, tokenURI, uriHash, tokenData, address.String()) err = newMsgEditNFT.ValidateBasic() require.Error(t, err) - newMsgEditNFT = types.NewMsgEditNFT(id, "", nftName, tokenURI, tokenData, address.String()) + newMsgEditNFT = types.NewMsgEditNFT(id, "", nftName, tokenURI, uriHash, tokenData, address.String()) err = newMsgEditNFT.ValidateBasic() require.Error(t, err) - newMsgEditNFT = types.NewMsgEditNFT(id, denom, nftName, tokenURI, tokenData, address.String()) + newMsgEditNFT = types.NewMsgEditNFT(id, denom, nftName, tokenURI, uriHash, tokenData, address.String()) err = newMsgEditNFT.ValidateBasic() require.NoError(t, err) } func TestMsgEditNFTGetSignBytesMethod(t *testing.T) { - newMsgEditNFT := types.NewMsgEditNFT(id, denom, nftName, tokenURI, tokenData, address.String()) + newMsgEditNFT := types.NewMsgEditNFT(id, denom, nftName, tokenURI, uriHash, tokenData, address.String()) sortedBytes := newMsgEditNFT.GetSignBytes() - expected := `{"type":"irismod/nft/MsgEditNFT","value":{"data":"https://google.com/token-1.json","denom_id":"denom","id":"id1","name":"report","sender":"cosmos15ky9du8a2wlstz6fpx3p4mqpjyrm5cgqjwl8sq","uri":"https://google.com/token-1.json"}}` + expected := `{"type":"irismod/nft/MsgEditNFT","value":{"data":"https://google.com/token-1.json","denom_id":"denom","id":"id1","name":"report","sender":"cosmos15ky9du8a2wlstz6fpx3p4mqpjyrm5cgqjwl8sq","uri":"https://google.com/token-1.json","uri_hash":"uriHash"}}` require.Equal(t, expected, string(sortedBytes)) } func TestMsgEditNFTGetSignersMethod(t *testing.T) { - newMsgEditNFT := types.NewMsgEditNFT(id, denom, nftName, tokenURI, tokenData, address.String()) + newMsgEditNFT := types.NewMsgEditNFT(id, denom, nftName, tokenURI, uriHash, tokenData, address.String()) signers := newMsgEditNFT.GetSigners() require.Equal(t, 1, len(signers)) require.Equal(t, address.String(), signers[0].String()) } func TestMsgMsgMintNFTValidateBasicMethod(t *testing.T) { - newMsgMintNFT := types.NewMsgMintNFT(id, denom, nftName, tokenURI, tokenData, "", address2.String()) + newMsgMintNFT := types.NewMsgMintNFT(id, denom, nftName, tokenURI, uriHash, tokenData, "", address2.String()) err := newMsgMintNFT.ValidateBasic() require.Error(t, err) - newMsgMintNFT = types.NewMsgMintNFT("", denom, nftName, tokenURI, tokenData, address.String(), address2.String()) + newMsgMintNFT = types.NewMsgMintNFT("", denom, nftName, tokenURI, uriHash, tokenData, address.String(), address2.String()) err = newMsgMintNFT.ValidateBasic() require.Error(t, err) - newMsgMintNFT = types.NewMsgMintNFT(id, "", nftName, tokenURI, tokenData, address.String(), address2.String()) + newMsgMintNFT = types.NewMsgMintNFT(id, "", nftName, tokenURI, uriHash, tokenData, address.String(), address2.String()) err = newMsgMintNFT.ValidateBasic() require.Error(t, err) - newMsgMintNFT = types.NewMsgMintNFT(id, denom, nftName, tokenURI, tokenData, address.String(), address2.String()) + newMsgMintNFT = types.NewMsgMintNFT(id, denom, nftName, tokenURI, uriHash, tokenData, address.String(), address2.String()) err = newMsgMintNFT.ValidateBasic() require.NoError(t, err) } func TestMsgMintNFTGetSignBytesMethod(t *testing.T) { - newMsgMintNFT := types.NewMsgMintNFT(id, denom, nftName, tokenURI, tokenData, address.String(), address2.String()) + newMsgMintNFT := types.NewMsgMintNFT(id, denom, nftName, tokenURI, uriHash, tokenData, address.String(), address2.String()) sortedBytes := newMsgMintNFT.GetSignBytes() - expected := `{"type":"irismod/nft/MsgMintNFT","value":{"data":"https://google.com/token-1.json","denom_id":"denom","id":"id1","name":"report","recipient":"cosmos15ky9du8a2wlstz6fpx3p4mqpjyrm5cgp0ctjdj","sender":"cosmos15ky9du8a2wlstz6fpx3p4mqpjyrm5cgqjwl8sq","uri":"https://google.com/token-1.json"}}` + expected := `{"type":"irismod/nft/MsgMintNFT","value":{"data":"https://google.com/token-1.json","denom_id":"denom","id":"id1","name":"report","recipient":"cosmos15ky9du8a2wlstz6fpx3p4mqpjyrm5cgp0ctjdj","sender":"cosmos15ky9du8a2wlstz6fpx3p4mqpjyrm5cgqjwl8sq","uri":"https://google.com/token-1.json","uri_hash":"uriHash"}}` require.Equal(t, expected, string(sortedBytes)) } diff --git a/modules/nft/types/nft.go b/modules/nft/types/nft.go index 001f286d..17aa88c6 100644 --- a/modules/nft/types/nft.go +++ b/modules/nft/types/nft.go @@ -9,13 +9,14 @@ import ( var _ exported.NFT = BaseNFT{} // NewBaseNFT creates a new NFT instance -func NewBaseNFT(id, name string, owner sdk.AccAddress, uri, data string) BaseNFT { +func NewBaseNFT(id, name string, owner sdk.AccAddress, uri, uriHash, data string) BaseNFT { return BaseNFT{ - Id: id, - Name: name, - Owner: owner.String(), - URI: uri, - Data: data, + Id: id, + Name: name, + Owner: owner.String(), + URI: uri, + UriHash: uriHash, + Data: data, } } @@ -40,6 +41,11 @@ func (bnft BaseNFT) GetURI() string { return bnft.URI } +// GetURIHash return the UriHash of BaseNFT +func (bnft BaseNFT) GetURIHash() string { + return bnft.UriHash +} + // GetData return the Data of BaseNFT func (bnft BaseNFT) GetData() string { return bnft.Data diff --git a/modules/nft/types/nft.pb.go b/modules/nft/types/nft.pb.go index 85aae8c1..50e22c75 100644 --- a/modules/nft/types/nft.pb.go +++ b/modules/nft/types/nft.pb.go @@ -25,11 +25,12 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // BaseNFT defines a non-fungible token type BaseNFT struct { - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - URI string `protobuf:"bytes,3,opt,name=uri,proto3" json:"uri,omitempty"` - Data string `protobuf:"bytes,4,opt,name=data,proto3" json:"data,omitempty"` - Owner string `protobuf:"bytes,5,opt,name=owner,proto3" json:"owner,omitempty"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + URI string `protobuf:"bytes,3,opt,name=uri,proto3" json:"uri,omitempty"` + Data string `protobuf:"bytes,4,opt,name=data,proto3" json:"data,omitempty"` + Owner string `protobuf:"bytes,5,opt,name=owner,proto3" json:"owner,omitempty"` + UriHash string `protobuf:"bytes,6,opt,name=uri_hash,json=uriHash,proto3" json:"uri_hash,omitempty"` } func (m *BaseNFT) Reset() { *m = BaseNFT{} } @@ -74,6 +75,10 @@ type Denom struct { Symbol string `protobuf:"bytes,5,opt,name=symbol,proto3" json:"symbol,omitempty"` MintRestricted bool `protobuf:"varint,6,opt,name=mint_restricted,json=mintRestricted,proto3" json:"mint_restricted,omitempty"` UpdateRestricted bool `protobuf:"varint,7,opt,name=update_restricted,json=updateRestricted,proto3" json:"update_restricted,omitempty"` + Description string `protobuf:"bytes,8,opt,name=description,proto3" json:"description,omitempty"` + Uri string `protobuf:"bytes,9,opt,name=uri,proto3" json:"uri,omitempty"` + UriHash string `protobuf:"bytes,10,opt,name=uri_hash,json=uriHash,proto3" json:"uri_hash,omitempty"` + Data string `protobuf:"bytes,11,opt,name=data,proto3" json:"data,omitempty"` } func (m *Denom) Reset() { *m = Denom{} } @@ -237,40 +242,43 @@ func init() { func init() { proto.RegisterFile("nft/nft.proto", fileDescriptor_fe8ab7e15b7f0646) } var fileDescriptor_fe8ab7e15b7f0646 = []byte{ - // 522 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x53, 0xcd, 0x8e, 0xd3, 0x30, - 0x18, 0x6c, 0xda, 0xf4, 0xcf, 0xdd, 0x76, 0x17, 0x53, 0xa1, 0x2c, 0x87, 0xa4, 0x8a, 0x90, 0xa8, - 0x04, 0x4a, 0xc4, 0x22, 0x71, 0xd8, 0x63, 0x58, 0xad, 0x54, 0x0e, 0x8b, 0x64, 0x2d, 0x17, 0x2e, - 0x55, 0x1a, 0xbb, 0x5d, 0x8b, 0xc6, 0xae, 0x62, 0x57, 0x4b, 0x79, 0x09, 0x78, 0x04, 0x1e, 0xa7, - 0xc7, 0xe5, 0xc6, 0x29, 0x82, 0xf6, 0xc2, 0xb9, 0x4f, 0x80, 0xec, 0xb8, 0x25, 0xbd, 0x71, 0xfb, - 0x66, 0xbe, 0xb1, 0x67, 0xbe, 0x4f, 0x36, 0xe8, 0xb2, 0xa9, 0x0c, 0xd9, 0x54, 0x06, 0x8b, 0x8c, - 0x4b, 0x0e, 0x3b, 0x34, 0xa3, 0x22, 0xe5, 0x38, 0x60, 0x53, 0xf9, 0xb4, 0x3f, 0xe3, 0x33, 0xae, - 0xf9, 0x50, 0x55, 0x85, 0xc4, 0xff, 0x0c, 0x9a, 0x51, 0x2c, 0xc8, 0xcd, 0xf5, 0x2d, 0xec, 0x81, - 0x2a, 0xc5, 0x8e, 0x35, 0xb0, 0x86, 0x6d, 0x54, 0xa5, 0x18, 0x42, 0x60, 0xb3, 0x38, 0x25, 0x4e, - 0x55, 0x33, 0xba, 0x86, 0xe7, 0xa0, 0xb6, 0xcc, 0xa8, 0x53, 0x53, 0x54, 0xd4, 0xdc, 0xe4, 0x5e, - 0xed, 0x03, 0x1a, 0x21, 0xc5, 0x29, 0x39, 0x8e, 0x65, 0xec, 0xd8, 0x85, 0x5c, 0xd5, 0xb0, 0x0f, - 0xea, 0xfc, 0x9e, 0x91, 0xcc, 0xa9, 0x6b, 0xb2, 0x00, 0x97, 0xf6, 0x9f, 0xef, 0x9e, 0xe5, 0xff, - 0xb0, 0x40, 0xfd, 0x8a, 0x30, 0x9e, 0xfe, 0x97, 0xf1, 0x13, 0xd0, 0x10, 0xc9, 0x1d, 0x49, 0xe3, - 0xc2, 0x1b, 0x19, 0x04, 0x1d, 0xd0, 0x4c, 0x32, 0x12, 0x4b, 0x9e, 0x19, 0xe3, 0x3d, 0xd4, 0x27, - 0x56, 0xe9, 0x84, 0xcf, 0x8d, 0xb9, 0x41, 0xf0, 0x39, 0x38, 0x4d, 0x29, 0x93, 0xe3, 0x8c, 0x08, - 0x99, 0xd1, 0x44, 0x12, 0xec, 0x34, 0x06, 0xd6, 0xb0, 0x85, 0x7a, 0x8a, 0x46, 0x07, 0x16, 0xbe, - 0x00, 0x8f, 0x96, 0x0b, 0x1c, 0x4b, 0x52, 0x96, 0x36, 0xb5, 0xf4, 0xac, 0x68, 0xfc, 0x13, 0x9b, - 0x99, 0xee, 0xc1, 0xc9, 0xe8, 0xea, 0x2d, 0x9f, 0xcf, 0x49, 0x22, 0x29, 0x67, 0x30, 0x00, 0x2d, - 0xac, 0x46, 0x1c, 0xef, 0xe7, 0x8b, 0x1e, 0xef, 0x72, 0xef, 0x74, 0x15, 0xa7, 0xf3, 0x4b, 0x7f, - 0xdf, 0xf1, 0x51, 0x53, 0x97, 0x23, 0x0c, 0x5f, 0x81, 0xb6, 0xe4, 0x9f, 0x08, 0x1b, 0x53, 0x2c, - 0x9c, 0xea, 0xa0, 0x36, 0x6c, 0x47, 0xfd, 0x5d, 0xee, 0x9d, 0x15, 0x07, 0x0e, 0x2d, 0x1f, 0xb5, - 0x74, 0x3d, 0xc2, 0xc2, 0x18, 0x7f, 0xb5, 0x40, 0xfd, 0xbd, 0x5a, 0xae, 0x5a, 0x48, 0x8c, 0x71, - 0x46, 0x84, 0x30, 0x1b, 0xdd, 0x43, 0x38, 0x05, 0x3d, 0x8a, 0xc7, 0xc9, 0x21, 0x5d, 0xe1, 0xd0, - 0xb9, 0x38, 0x0f, 0x4a, 0xcf, 0x24, 0x28, 0xe7, 0x8f, 0x9e, 0xad, 0x73, 0xaf, 0xb2, 0xc9, 0xbd, - 0x6e, 0x99, 0x15, 0xbb, 0xdc, 0xeb, 0x14, 0x89, 0x28, 0x4e, 0x84, 0x8f, 0xba, 0x14, 0x97, 0xba, - 0x26, 0xd1, 0x17, 0x00, 0x8e, 0x16, 0x51, 0xd7, 0x33, 0xea, 0x4c, 0x9d, 0x0b, 0x78, 0x64, 0xa9, - 0x5f, 0x41, 0x64, 0x2b, 0x2f, 0x54, 0xc8, 0xe0, 0x1b, 0x60, 0xb3, 0xa9, 0xdc, 0x27, 0xec, 0x1f, - 0xc9, 0xcd, 0x7b, 0x8d, 0x4e, 0x4c, 0x38, 0xfb, 0xe6, 0xfa, 0x56, 0x20, 0xad, 0x2f, 0xbc, 0xa3, - 0x77, 0xeb, 0xdf, 0x6e, 0x65, 0xbd, 0x71, 0xad, 0x87, 0x8d, 0x6b, 0xfd, 0xda, 0xb8, 0xd6, 0xb7, - 0xad, 0x5b, 0x79, 0xd8, 0xba, 0x95, 0x9f, 0x5b, 0xb7, 0xf2, 0xf1, 0xe5, 0x8c, 0xca, 0xbb, 0xe5, - 0x24, 0x48, 0x78, 0x1a, 0xaa, 0x7b, 0x19, 0x91, 0xa1, 0xb9, 0x3f, 0x4c, 0x39, 0x5e, 0xce, 0x89, - 0x50, 0x7f, 0x28, 0x94, 0xab, 0x05, 0x11, 0x93, 0x86, 0xfe, 0x27, 0xaf, 0xff, 0x06, 0x00, 0x00, - 0xff, 0xff, 0xcd, 0xca, 0x3c, 0x53, 0x5b, 0x03, 0x00, 0x00, + // 576 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x53, 0xbd, 0x8e, 0xd3, 0x4c, + 0x14, 0x8d, 0x13, 0x67, 0x9d, 0x5c, 0xef, 0xdf, 0x37, 0x5f, 0x84, 0x1c, 0x0a, 0x3b, 0xb2, 0x90, + 0x58, 0x09, 0x64, 0x8b, 0x45, 0xa2, 0xd8, 0xd2, 0xac, 0x56, 0x84, 0x62, 0x91, 0xac, 0xa5, 0xa1, + 0x89, 0x1c, 0xcf, 0x24, 0x19, 0x11, 0x7b, 0xa2, 0x99, 0xb1, 0x56, 0xe1, 0x25, 0x40, 0xe2, 0x05, + 0x78, 0x08, 0x1e, 0x22, 0xe5, 0x96, 0x54, 0x16, 0x24, 0x0d, 0x75, 0x9e, 0x00, 0x79, 0xec, 0x04, + 0xa7, 0xa3, 0xbb, 0xf7, 0xdc, 0xe3, 0x39, 0xc7, 0x67, 0xe6, 0xc2, 0x49, 0x3a, 0x91, 0x7e, 0x3a, + 0x91, 0xde, 0x82, 0x33, 0xc9, 0x90, 0x49, 0x39, 0x15, 0x09, 0xc3, 0x5e, 0x3a, 0x91, 0x8f, 0x7b, + 0x53, 0x36, 0x65, 0x0a, 0xf7, 0x8b, 0xaa, 0xa4, 0xb8, 0x5f, 0x35, 0x30, 0x82, 0x48, 0x90, 0xdb, + 0x9b, 0x3b, 0x74, 0x0a, 0x4d, 0x8a, 0x2d, 0x6d, 0xa0, 0x5d, 0x74, 0xc3, 0x26, 0xc5, 0x08, 0x81, + 0x9e, 0x46, 0x09, 0xb1, 0x9a, 0x0a, 0x51, 0x35, 0xea, 0x43, 0x2b, 0xe3, 0xd4, 0x6a, 0x15, 0x50, + 0x60, 0xac, 0x73, 0xa7, 0xf5, 0x3e, 0x1c, 0x86, 0x05, 0x56, 0xd0, 0x71, 0x24, 0x23, 0x4b, 0x2f, + 0xe9, 0x45, 0x8d, 0x7a, 0xd0, 0x66, 0xf7, 0x29, 0xe1, 0x56, 0x5b, 0x81, 0x65, 0x83, 0xfa, 0xd0, + 0xc9, 0x38, 0x1d, 0xcd, 0x22, 0x31, 0xb3, 0x8e, 0xd4, 0xc0, 0xc8, 0x38, 0x7d, 0x13, 0x89, 0xd9, + 0x95, 0xfe, 0xfb, 0x9b, 0xa3, 0xb9, 0xdf, 0x9b, 0xd0, 0xbe, 0x26, 0x29, 0x4b, 0xfe, 0xc9, 0xd3, + 0x23, 0x38, 0x12, 0xf1, 0x8c, 0x24, 0x51, 0x69, 0x2b, 0xac, 0x3a, 0x64, 0x81, 0x11, 0x73, 0x12, + 0x49, 0xc6, 0x2b, 0x4f, 0xbb, 0x56, 0x7d, 0xb1, 0x4c, 0xc6, 0x6c, 0x5e, 0xf9, 0xaa, 0x3a, 0xf4, + 0x14, 0xce, 0x12, 0x9a, 0xca, 0x11, 0x27, 0x42, 0x72, 0x1a, 0x4b, 0x82, 0x95, 0xbf, 0x4e, 0x78, + 0x5a, 0xc0, 0xe1, 0x1e, 0x45, 0xcf, 0xe0, 0xbf, 0x6c, 0x81, 0x23, 0x49, 0xea, 0x54, 0x43, 0x51, + 0xcf, 0xcb, 0x41, 0x8d, 0x3c, 0x00, 0x13, 0x13, 0x11, 0x73, 0xba, 0x90, 0x94, 0xa5, 0x56, 0x47, + 0x49, 0xd6, 0x21, 0x74, 0x5e, 0xa6, 0xda, 0x55, 0x13, 0x15, 0x66, 0x3d, 0x22, 0x38, 0x88, 0x68, + 0x9f, 0xb3, 0xf9, 0x37, 0xe7, 0x2a, 0xb6, 0x7b, 0x38, 0x1e, 0x5e, 0xbf, 0x66, 0xf3, 0x39, 0x89, + 0xd5, 0xb1, 0x1e, 0x74, 0x70, 0x91, 0xe2, 0x68, 0x17, 0x61, 0xf0, 0xff, 0x36, 0x77, 0xce, 0x96, + 0x51, 0x32, 0xbf, 0x72, 0x77, 0x13, 0x37, 0x34, 0x54, 0x39, 0xc4, 0xe8, 0x05, 0x74, 0x25, 0xfb, + 0x48, 0xd2, 0x11, 0xc5, 0xc2, 0x6a, 0x0e, 0x5a, 0x17, 0xdd, 0xa0, 0xb7, 0xcd, 0x9d, 0xf3, 0xf2, + 0x83, 0xfd, 0xc8, 0x0d, 0x3b, 0xaa, 0x1e, 0x62, 0x51, 0x09, 0x7f, 0xd6, 0xa0, 0xfd, 0x4e, 0x5d, + 0xad, 0x05, 0x46, 0x84, 0x31, 0x27, 0x42, 0x54, 0x97, 0xb6, 0x6b, 0xd1, 0x04, 0x4e, 0x29, 0x1e, + 0xc5, 0x7b, 0x77, 0xa5, 0x82, 0x79, 0xd9, 0xf7, 0x6a, 0xaf, 0xd4, 0xab, 0xfb, 0x0f, 0x9e, 0xac, + 0x72, 0xa7, 0xb1, 0xce, 0x9d, 0x93, 0x3a, 0x2a, 0xb6, 0xb9, 0x63, 0x96, 0x8e, 0x28, 0x8e, 0x85, + 0x1b, 0x9e, 0x50, 0x5c, 0x9b, 0x56, 0x8e, 0x3e, 0x01, 0x1c, 0x04, 0xd1, 0x56, 0xff, 0xa8, 0x3c, + 0x99, 0x97, 0xe8, 0x40, 0x52, 0x3d, 0xb4, 0x40, 0x2f, 0xb4, 0xc2, 0x92, 0x86, 0x5e, 0x81, 0x9e, + 0x4e, 0xe4, 0xce, 0x61, 0xef, 0x80, 0x5e, 0x6d, 0x4b, 0x70, 0x5c, 0x99, 0xd3, 0x6f, 0x6f, 0xee, + 0x44, 0xa8, 0xf8, 0xa5, 0x76, 0xf0, 0x76, 0xf5, 0xcb, 0x6e, 0xac, 0xd6, 0xb6, 0xf6, 0xb0, 0xb6, + 0xb5, 0x9f, 0x6b, 0x5b, 0xfb, 0xb2, 0xb1, 0x1b, 0x0f, 0x1b, 0xbb, 0xf1, 0x63, 0x63, 0x37, 0x3e, + 0x3c, 0x9f, 0x52, 0x39, 0xcb, 0xc6, 0x5e, 0xcc, 0x12, 0xbf, 0x38, 0x37, 0x25, 0xd2, 0xaf, 0xce, + 0xf7, 0x13, 0x86, 0xb3, 0x39, 0x11, 0xc5, 0x0a, 0xfb, 0x72, 0xb9, 0x20, 0x62, 0x7c, 0xa4, 0xd6, + 0xf4, 0xe5, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x64, 0x01, 0xda, 0xf2, 0xda, 0x03, 0x00, 0x00, } func (this *BaseNFT) Equal(that interface{}) bool { @@ -307,6 +315,9 @@ func (this *BaseNFT) Equal(that interface{}) bool { if this.Owner != that1.Owner { return false } + if this.UriHash != that1.UriHash { + return false + } return true } func (this *Denom) Equal(that interface{}) bool { @@ -349,6 +360,18 @@ func (this *Denom) Equal(that interface{}) bool { if this.UpdateRestricted != that1.UpdateRestricted { return false } + if this.Description != that1.Description { + return false + } + if this.Uri != that1.Uri { + return false + } + if this.UriHash != that1.UriHash { + return false + } + if this.Data != that1.Data { + return false + } return true } func (this *IDCollection) Equal(that interface{}) bool { @@ -467,6 +490,13 @@ func (m *BaseNFT) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.UriHash) > 0 { + i -= len(m.UriHash) + copy(dAtA[i:], m.UriHash) + i = encodeVarintNft(dAtA, i, uint64(len(m.UriHash))) + i-- + dAtA[i] = 0x32 + } if len(m.Owner) > 0 { i -= len(m.Owner) copy(dAtA[i:], m.Owner) @@ -525,6 +555,34 @@ func (m *Denom) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.Data) > 0 { + i -= len(m.Data) + copy(dAtA[i:], m.Data) + i = encodeVarintNft(dAtA, i, uint64(len(m.Data))) + i-- + dAtA[i] = 0x5a + } + if len(m.UriHash) > 0 { + i -= len(m.UriHash) + copy(dAtA[i:], m.UriHash) + i = encodeVarintNft(dAtA, i, uint64(len(m.UriHash))) + i-- + dAtA[i] = 0x52 + } + if len(m.Uri) > 0 { + i -= len(m.Uri) + copy(dAtA[i:], m.Uri) + i = encodeVarintNft(dAtA, i, uint64(len(m.Uri))) + i-- + dAtA[i] = 0x4a + } + if len(m.Description) > 0 { + i -= len(m.Description) + copy(dAtA[i:], m.Description) + i = encodeVarintNft(dAtA, i, uint64(len(m.Description))) + i-- + dAtA[i] = 0x42 + } if m.UpdateRestricted { i-- if m.UpdateRestricted { @@ -750,6 +808,10 @@ func (m *BaseNFT) Size() (n int) { if l > 0 { n += 1 + l + sovNft(uint64(l)) } + l = len(m.UriHash) + if l > 0 { + n += 1 + l + sovNft(uint64(l)) + } return n } @@ -785,6 +847,22 @@ func (m *Denom) Size() (n int) { if m.UpdateRestricted { n += 2 } + l = len(m.Description) + if l > 0 { + n += 1 + l + sovNft(uint64(l)) + } + l = len(m.Uri) + if l > 0 { + n += 1 + l + sovNft(uint64(l)) + } + l = len(m.UriHash) + if l > 0 { + n += 1 + l + sovNft(uint64(l)) + } + l = len(m.Data) + if l > 0 { + n += 1 + l + sovNft(uint64(l)) + } return n } @@ -1038,6 +1116,38 @@ func (m *BaseNFT) Unmarshal(dAtA []byte) error { } m.Owner = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UriHash", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowNft + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthNft + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthNft + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.UriHash = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipNft(dAtA[iNdEx:]) @@ -1288,6 +1398,134 @@ func (m *Denom) Unmarshal(dAtA []byte) error { } } m.UpdateRestricted = bool(v != 0) + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowNft + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthNft + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthNft + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Description = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 9: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Uri", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowNft + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthNft + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthNft + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Uri = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 10: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UriHash", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowNft + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthNft + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthNft + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.UriHash = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 11: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowNft + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthNft + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthNft + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Data = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipNft(dAtA[iNdEx:]) diff --git a/modules/nft/types/tx.pb.go b/modules/nft/types/tx.pb.go index d01b36b8..87688518 100644 --- a/modules/nft/types/tx.pb.go +++ b/modules/nft/types/tx.pb.go @@ -37,6 +37,10 @@ type MsgIssueDenom struct { Symbol string `protobuf:"bytes,5,opt,name=symbol,proto3" json:"symbol,omitempty"` MintRestricted bool `protobuf:"varint,6,opt,name=mint_restricted,json=mintRestricted,proto3" json:"mint_restricted,omitempty"` UpdateRestricted bool `protobuf:"varint,7,opt,name=update_restricted,json=updateRestricted,proto3" json:"update_restricted,omitempty"` + Description string `protobuf:"bytes,8,opt,name=description,proto3" json:"description,omitempty"` + Uri string `protobuf:"bytes,9,opt,name=uri,proto3" json:"uri,omitempty"` + UriHash string `protobuf:"bytes,10,opt,name=uri_hash,json=uriHash,proto3" json:"uri_hash,omitempty"` + Data string `protobuf:"bytes,11,opt,name=data,proto3" json:"data,omitempty"` } func (m *MsgIssueDenom) Reset() { *m = MsgIssueDenom{} } @@ -118,6 +122,7 @@ type MsgTransferNFT struct { Data string `protobuf:"bytes,5,opt,name=data,proto3" json:"data,omitempty"` Sender string `protobuf:"bytes,6,opt,name=sender,proto3" json:"sender,omitempty"` Recipient string `protobuf:"bytes,7,opt,name=recipient,proto3" json:"recipient,omitempty"` + UriHash string `protobuf:"bytes,8,opt,name=uri_hash,json=uriHash,proto3" json:"uri_hash,omitempty"` } func (m *MsgTransferNFT) Reset() { *m = MsgTransferNFT{} } @@ -198,6 +203,7 @@ type MsgEditNFT struct { URI string `protobuf:"bytes,4,opt,name=uri,proto3" json:"uri,omitempty"` Data string `protobuf:"bytes,5,opt,name=data,proto3" json:"data,omitempty"` Sender string `protobuf:"bytes,6,opt,name=sender,proto3" json:"sender,omitempty"` + UriHash string `protobuf:"bytes,7,opt,name=uri_hash,json=uriHash,proto3" json:"uri_hash,omitempty"` } func (m *MsgEditNFT) Reset() { *m = MsgEditNFT{} } @@ -279,6 +285,7 @@ type MsgMintNFT struct { Data string `protobuf:"bytes,5,opt,name=data,proto3" json:"data,omitempty"` Sender string `protobuf:"bytes,6,opt,name=sender,proto3" json:"sender,omitempty"` Recipient string `protobuf:"bytes,7,opt,name=recipient,proto3" json:"recipient,omitempty"` + UriHash string `protobuf:"bytes,8,opt,name=uri_hash,json=uriHash,proto3" json:"uri_hash,omitempty"` } func (m *MsgMintNFT) Reset() { *m = MsgMintNFT{} } @@ -523,44 +530,48 @@ func init() { func init() { proto.RegisterFile("nft/tx.proto", fileDescriptor_09d30374d974e015) } var fileDescriptor_09d30374d974e015 = []byte{ - // 591 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x95, 0x4f, 0x6f, 0xd3, 0x30, - 0x18, 0xc6, 0x9b, 0x66, 0xb4, 0xdb, 0x3b, 0xd6, 0x0d, 0x33, 0xb6, 0x10, 0x20, 0x9d, 0x82, 0x10, - 0x93, 0x40, 0x89, 0x04, 0xb7, 0x1d, 0xcb, 0x1f, 0xa9, 0x88, 0x82, 0x14, 0x6d, 0x17, 0x0e, 0x4c, - 0x69, 0xed, 0x66, 0x46, 0x8d, 0x53, 0xc5, 0x8e, 0x44, 0xbf, 0x05, 0x1f, 0x81, 0x2f, 0xc0, 0xf7, - 0x98, 0xe0, 0xc0, 0x6e, 0x70, 0x9a, 0xa0, 0xbd, 0x70, 0xe6, 0x13, 0xa0, 0x38, 0x4e, 0x93, 0xb6, - 0xeb, 0x4e, 0x1c, 0x10, 0x37, 0xfb, 0x79, 0xde, 0xbc, 0x7e, 0x7f, 0xaf, 0x1d, 0x1b, 0xae, 0xb2, - 0xbe, 0x70, 0xc5, 0x7b, 0x67, 0x18, 0x47, 0x22, 0x42, 0xeb, 0x34, 0xa6, 0x3c, 0x8c, 0xb0, 0xc3, - 0xfa, 0xc2, 0xdc, 0x0e, 0xa2, 0x20, 0x92, 0xba, 0x9b, 0x8e, 0xb2, 0x10, 0xfb, 0x9b, 0x06, 0x1b, - 0x1d, 0x1e, 0xb4, 0x39, 0x4f, 0xc8, 0x53, 0xc2, 0xa2, 0x10, 0x35, 0xa0, 0x4a, 0xb1, 0xa1, 0xed, - 0x69, 0xfb, 0x6b, 0x5e, 0x95, 0x62, 0x84, 0x60, 0x85, 0xf9, 0x21, 0x31, 0xaa, 0x52, 0x91, 0x63, - 0xb4, 0x03, 0x35, 0xde, 0x3b, 0x21, 0xa1, 0x6f, 0xe8, 0x52, 0x55, 0x33, 0xa9, 0x13, 0x86, 0x49, - 0x6c, 0xac, 0x28, 0x5d, 0xce, 0xa4, 0x3e, 0x0a, 0xbb, 0xd1, 0xc0, 0xb8, 0xa2, 0x74, 0x39, 0x43, - 0xf7, 0x61, 0x33, 0xa4, 0x4c, 0x1c, 0xc7, 0x84, 0x8b, 0x98, 0xf6, 0x04, 0xc1, 0x46, 0x6d, 0x4f, - 0xdb, 0x5f, 0xf5, 0x1a, 0xa9, 0xec, 0x4d, 0x55, 0xf4, 0x00, 0xae, 0x25, 0x43, 0xec, 0x0b, 0x52, - 0x0e, 0xad, 0xcb, 0xd0, 0xad, 0xcc, 0x28, 0x82, 0x0f, 0x56, 0x7e, 0x7d, 0x6c, 0x6a, 0xf6, 0x2e, - 0xdc, 0x98, 0x01, 0xf3, 0x08, 0x1f, 0x46, 0x8c, 0x13, 0xfb, 0xab, 0x06, 0x8d, 0x0e, 0x0f, 0x0e, - 0x63, 0x9f, 0xf1, 0x3e, 0x89, 0x5f, 0x3d, 0x3f, 0x5c, 0x60, 0x76, 0x60, 0x15, 0xa7, 0xdf, 0x1c, - 0x53, 0x9c, 0x71, 0xb7, 0xae, 0xff, 0x3e, 0x6f, 0x6e, 0x8e, 0xfc, 0x70, 0x70, 0x60, 0xe7, 0x8e, - 0xed, 0xd5, 0xe5, 0xb0, 0x5d, 0xf4, 0x48, 0x2f, 0xf5, 0xe8, 0x26, 0xe8, 0x49, 0x4c, 0xb3, 0x46, - 0xb4, 0xea, 0xe3, 0xf3, 0xa6, 0x7e, 0xe4, 0xb5, 0xbd, 0x54, 0x4b, 0xc3, 0xb1, 0x2f, 0x7c, 0xd5, - 0x0c, 0x39, 0x2e, 0xb5, 0xae, 0x36, 0xd3, 0xba, 0xdb, 0xb0, 0x16, 0x93, 0x1e, 0x1d, 0x52, 0xc2, - 0x84, 0x24, 0x5e, 0xf3, 0x0a, 0x41, 0xa1, 0x1a, 0xb0, 0x33, 0x0b, 0x34, 0x65, 0xfd, 0xa4, 0x01, - 0x74, 0x78, 0xf0, 0x0c, 0x53, 0xf1, 0x6f, 0x73, 0x2a, 0x92, 0x6d, 0x40, 0x45, 0xb9, 0x53, 0x8a, - 0x2f, 0x19, 0x45, 0x87, 0x32, 0xf1, 0x1f, 0xec, 0x56, 0xc6, 0xa8, 0x60, 0xa6, 0x8c, 0xef, 0x24, - 0x62, 0x2b, 0x89, 0xd9, 0xdf, 0x40, 0x2c, 0xea, 0xd3, 0x97, 0x76, 0x59, 0xad, 0x35, 0xad, 0xe0, - 0x2d, 0x6c, 0x95, 0x4e, 0xd1, 0xc5, 0x97, 0x41, 0x91, 0xb7, 0xba, 0x9c, 0x5b, 0xbf, 0x98, 0xdb, - 0x04, 0x63, 0x3e, 0x7f, 0xbe, 0xf6, 0xa3, 0xcf, 0x3a, 0xe8, 0x1d, 0x1e, 0xa0, 0x97, 0x00, 0xa5, - 0xab, 0xc8, 0x74, 0x4a, 0x17, 0x98, 0x33, 0xf3, 0x37, 0x9b, 0xf6, 0x72, 0x2f, 0xcf, 0x8a, 0x9e, - 0x40, 0x3d, 0x3f, 0x33, 0xbb, 0xf3, 0xe1, 0xca, 0x30, 0x9b, 0x4b, 0x8c, 0x72, 0x92, 0xfc, 0xf7, - 0x59, 0x48, 0xa2, 0x8c, 0xc5, 0x24, 0x73, 0x27, 0x18, 0xbd, 0x86, 0xf5, 0xf2, 0x7d, 0x73, 0x6b, - 0x3e, 0xbe, 0x64, 0x9a, 0x77, 0x2f, 0x31, 0xcb, 0x55, 0xe5, 0x67, 0x65, 0xa1, 0x2a, 0x65, 0x2c, - 0x56, 0x35, 0xb7, 0xe3, 0xe8, 0x08, 0x36, 0x66, 0xb7, 0xfb, 0xce, 0xb2, 0xa5, 0xb3, 0x9e, 0xdf, - 0xbb, 0xd4, 0xce, 0xd3, 0xb6, 0x5e, 0x9c, 0xfe, 0xb4, 0x2a, 0xa7, 0x63, 0x4b, 0x3b, 0x1b, 0x5b, - 0xda, 0x8f, 0xb1, 0xa5, 0x7d, 0x98, 0x58, 0x95, 0xb3, 0x89, 0x55, 0xf9, 0x3e, 0xb1, 0x2a, 0x6f, - 0x1e, 0x06, 0x54, 0x9c, 0x24, 0x5d, 0xa7, 0x17, 0x85, 0x6e, 0x9a, 0x8e, 0x11, 0xe1, 0xaa, 0xb4, - 0x6e, 0x18, 0xe1, 0x64, 0x40, 0xb8, 0x2b, 0x5f, 0xb1, 0xd1, 0x90, 0xf0, 0x6e, 0x4d, 0x3e, 0x53, - 0x8f, 0xff, 0x04, 0x00, 0x00, 0xff, 0xff, 0x20, 0xba, 0xca, 0xd5, 0xd9, 0x06, 0x00, 0x00, + // 653 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x55, 0xcd, 0x6e, 0xd3, 0x40, + 0x10, 0x8e, 0xe3, 0x36, 0x3f, 0x13, 0xfa, 0xc3, 0x52, 0xda, 0x6d, 0x00, 0xa7, 0x0a, 0x42, 0x54, + 0x02, 0x25, 0x12, 0xdc, 0x7a, 0x0c, 0x3f, 0xa2, 0x88, 0x80, 0x64, 0xb5, 0x17, 0x0e, 0x54, 0x6e, + 0x76, 0xeb, 0x2c, 0xaa, 0xd7, 0xd1, 0xee, 0x5a, 0xa2, 0x6f, 0xc1, 0x23, 0xf0, 0x1c, 0x3c, 0x41, + 0xc5, 0xa9, 0x47, 0x4e, 0x15, 0xa4, 0x12, 0x42, 0x1c, 0x79, 0x02, 0xe4, 0xb5, 0x9d, 0xac, 0x9d, + 0xa6, 0x27, 0x0e, 0x88, 0xdb, 0xee, 0xf7, 0x4d, 0x66, 0xe6, 0xfb, 0x66, 0x33, 0x86, 0x6b, 0xfc, + 0x48, 0x75, 0xd5, 0x87, 0xce, 0x48, 0x84, 0x2a, 0x44, 0x0d, 0x26, 0x98, 0x0c, 0x42, 0xd2, 0xe1, + 0x47, 0xaa, 0xb9, 0xe6, 0x87, 0x7e, 0xa8, 0xf1, 0x6e, 0x7c, 0x4a, 0x42, 0xda, 0x9f, 0xcb, 0xb0, + 0xd4, 0x97, 0xfe, 0xae, 0x94, 0x11, 0x7d, 0x4a, 0x79, 0x18, 0xa0, 0x65, 0x28, 0x33, 0x82, 0xad, + 0x2d, 0x6b, 0xbb, 0xee, 0x96, 0x19, 0x41, 0x08, 0x16, 0xb8, 0x17, 0x50, 0x5c, 0xd6, 0x88, 0x3e, + 0xa3, 0x75, 0xa8, 0xc8, 0xc1, 0x90, 0x06, 0x1e, 0xb6, 0x35, 0x9a, 0xde, 0x34, 0x4e, 0x39, 0xa1, + 0x02, 0x2f, 0xa4, 0xb8, 0xbe, 0x69, 0xfc, 0x24, 0x38, 0x0c, 0x8f, 0xf1, 0x62, 0x8a, 0xeb, 0x1b, + 0xba, 0x0f, 0x2b, 0x01, 0xe3, 0xea, 0x40, 0x50, 0xa9, 0x04, 0x1b, 0x28, 0x4a, 0x70, 0x65, 0xcb, + 0xda, 0xae, 0xb9, 0xcb, 0x31, 0xec, 0x4e, 0x50, 0xf4, 0x00, 0xae, 0x47, 0x23, 0xe2, 0x29, 0x6a, + 0x86, 0x56, 0x75, 0xe8, 0x6a, 0x42, 0x18, 0xc1, 0x5b, 0xd0, 0x20, 0x54, 0x0e, 0x04, 0x1b, 0x29, + 0x16, 0x72, 0x5c, 0xd3, 0x25, 0x4d, 0x08, 0xad, 0x82, 0x1d, 0x09, 0x86, 0xeb, 0x9a, 0x89, 0x8f, + 0x68, 0x13, 0x6a, 0x91, 0x60, 0x07, 0x43, 0x4f, 0x0e, 0x31, 0x68, 0xb8, 0x1a, 0x09, 0xf6, 0xc2, + 0x93, 0xc3, 0xd8, 0x00, 0xe2, 0x29, 0x0f, 0x37, 0x12, 0x03, 0xe2, 0xf3, 0xce, 0xc2, 0xcf, 0x4f, + 0x2d, 0xab, 0xbd, 0x01, 0x37, 0x73, 0xde, 0xb9, 0x54, 0x8e, 0x42, 0x2e, 0x69, 0xfb, 0x97, 0x05, + 0xcb, 0x7d, 0xe9, 0xef, 0x09, 0x8f, 0xcb, 0x23, 0x2a, 0x5e, 0x3f, 0xdf, 0x9b, 0xb1, 0xb5, 0x03, + 0x35, 0x12, 0xff, 0xe6, 0x80, 0x91, 0xc4, 0xda, 0xde, 0x8d, 0xdf, 0xe7, 0xad, 0x95, 0x13, 0x2f, + 0x38, 0xde, 0x69, 0x67, 0x4c, 0xdb, 0xad, 0xea, 0xe3, 0xee, 0x74, 0x0c, 0xb6, 0x31, 0x86, 0xcd, + 0x44, 0x86, 0xf6, 0xba, 0x57, 0x1d, 0x9f, 0xb7, 0xec, 0x7d, 0x77, 0x37, 0xd1, 0x93, 0x35, 0xbd, + 0x38, 0x6d, 0xda, 0x98, 0x4e, 0x25, 0x37, 0x9d, 0xdb, 0x50, 0x17, 0x74, 0xc0, 0x46, 0x8c, 0x72, + 0xa5, 0x4d, 0xad, 0xbb, 0x53, 0x20, 0xe7, 0x4c, 0x2d, 0xe7, 0x4c, 0xea, 0x02, 0x86, 0xf5, 0xbc, + 0xd6, 0x89, 0x0d, 0xa7, 0x16, 0x40, 0x5f, 0xfa, 0xcf, 0x08, 0x53, 0xff, 0xb8, 0x05, 0xa6, 0xc8, + 0xea, 0x65, 0x22, 0xd7, 0x00, 0x4d, 0x95, 0x4c, 0x04, 0xfe, 0x48, 0x04, 0xf6, 0x19, 0x57, 0xff, + 0xf7, 0x8c, 0x13, 0xf9, 0xa9, 0xce, 0x89, 0xfc, 0xf7, 0x5a, 0x7d, 0x2f, 0x12, 0xfc, 0x6f, 0xa8, + 0x9f, 0xb6, 0x6e, 0x9b, 0xad, 0xe7, 0x3a, 0x48, 0x6b, 0x4d, 0x3a, 0x78, 0x07, 0xab, 0xc6, 0xdb, + 0xbb, 0x7c, 0x81, 0x4d, 0xf3, 0x96, 0xe7, 0x5b, 0x62, 0x17, 0x2c, 0x49, 0xab, 0x36, 0x01, 0x17, + 0xf3, 0x67, 0xb5, 0x1f, 0x7d, 0xb1, 0xc1, 0xee, 0x4b, 0x1f, 0xbd, 0x02, 0x30, 0xd6, 0x67, 0xb3, + 0x63, 0x2c, 0xdd, 0x4e, 0x6e, 0x3d, 0x34, 0xdb, 0xf3, 0xb9, 0x2c, 0x2b, 0x7a, 0x02, 0xd5, 0xec, + 0x39, 0x6d, 0x14, 0xc3, 0x53, 0xa2, 0xd9, 0x9a, 0x43, 0x98, 0x49, 0xb2, 0x3f, 0xdd, 0x4c, 0x92, + 0x94, 0x98, 0x4d, 0x52, 0x78, 0xdc, 0xe8, 0x0d, 0x34, 0xcc, 0x05, 0x76, 0xab, 0x18, 0x6f, 0x90, + 0xcd, 0xbb, 0x57, 0x90, 0x66, 0x57, 0xd9, 0x5b, 0x99, 0xe9, 0x2a, 0x25, 0x66, 0xbb, 0x2a, 0x4c, + 0x1c, 0xed, 0xc3, 0x52, 0x7e, 0xdc, 0x77, 0xe6, 0x95, 0x4e, 0x3c, 0xbf, 0x77, 0x25, 0x9d, 0xa5, + 0xed, 0xbd, 0x3c, 0xfd, 0xee, 0x94, 0x4e, 0xc7, 0x8e, 0x75, 0x36, 0x76, 0xac, 0x6f, 0x63, 0xc7, + 0xfa, 0x78, 0xe1, 0x94, 0xce, 0x2e, 0x9c, 0xd2, 0xd7, 0x0b, 0xa7, 0xf4, 0xf6, 0xa1, 0xcf, 0xd4, + 0x30, 0x3a, 0xec, 0x0c, 0xc2, 0xa0, 0x1b, 0xa7, 0xe3, 0x54, 0x75, 0xd3, 0xb4, 0xdd, 0x20, 0x24, + 0xd1, 0x31, 0x95, 0x5d, 0xfd, 0xe5, 0x3d, 0x19, 0x51, 0x79, 0x58, 0xd1, 0x9f, 0xd6, 0xc7, 0x7f, + 0x02, 0x00, 0x00, 0xff, 0xff, 0x8e, 0x33, 0x0c, 0x0e, 0x8d, 0x07, 0x00, 0x00, } func (this *MsgIssueDenom) Equal(that interface{}) bool { @@ -603,6 +614,18 @@ func (this *MsgIssueDenom) Equal(that interface{}) bool { if this.UpdateRestricted != that1.UpdateRestricted { return false } + if this.Description != that1.Description { + return false + } + if this.Uri != that1.Uri { + return false + } + if this.UriHash != that1.UriHash { + return false + } + if this.Data != that1.Data { + return false + } return true } func (this *MsgTransferNFT) Equal(that interface{}) bool { @@ -645,6 +668,9 @@ func (this *MsgTransferNFT) Equal(that interface{}) bool { if this.Recipient != that1.Recipient { return false } + if this.UriHash != that1.UriHash { + return false + } return true } func (this *MsgEditNFT) Equal(that interface{}) bool { @@ -684,6 +710,9 @@ func (this *MsgEditNFT) Equal(that interface{}) bool { if this.Sender != that1.Sender { return false } + if this.UriHash != that1.UriHash { + return false + } return true } func (this *MsgMintNFT) Equal(that interface{}) bool { @@ -726,6 +755,9 @@ func (this *MsgMintNFT) Equal(that interface{}) bool { if this.Recipient != that1.Recipient { return false } + if this.UriHash != that1.UriHash { + return false + } return true } func (this *MsgBurnNFT) Equal(that interface{}) bool { @@ -1081,6 +1113,34 @@ func (m *MsgIssueDenom) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.Data) > 0 { + i -= len(m.Data) + copy(dAtA[i:], m.Data) + i = encodeVarintTx(dAtA, i, uint64(len(m.Data))) + i-- + dAtA[i] = 0x5a + } + if len(m.UriHash) > 0 { + i -= len(m.UriHash) + copy(dAtA[i:], m.UriHash) + i = encodeVarintTx(dAtA, i, uint64(len(m.UriHash))) + i-- + dAtA[i] = 0x52 + } + if len(m.Uri) > 0 { + i -= len(m.Uri) + copy(dAtA[i:], m.Uri) + i = encodeVarintTx(dAtA, i, uint64(len(m.Uri))) + i-- + dAtA[i] = 0x4a + } + if len(m.Description) > 0 { + i -= len(m.Description) + copy(dAtA[i:], m.Description) + i = encodeVarintTx(dAtA, i, uint64(len(m.Description))) + i-- + dAtA[i] = 0x42 + } if m.UpdateRestricted { i-- if m.UpdateRestricted { @@ -1182,6 +1242,13 @@ func (m *MsgTransferNFT) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.UriHash) > 0 { + i -= len(m.UriHash) + copy(dAtA[i:], m.UriHash) + i = encodeVarintTx(dAtA, i, uint64(len(m.UriHash))) + i-- + dAtA[i] = 0x42 + } if len(m.Recipient) > 0 { i -= len(m.Recipient) copy(dAtA[i:], m.Recipient) @@ -1277,6 +1344,13 @@ func (m *MsgEditNFT) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.UriHash) > 0 { + i -= len(m.UriHash) + copy(dAtA[i:], m.UriHash) + i = encodeVarintTx(dAtA, i, uint64(len(m.UriHash))) + i-- + dAtA[i] = 0x3a + } if len(m.Sender) > 0 { i -= len(m.Sender) copy(dAtA[i:], m.Sender) @@ -1365,6 +1439,13 @@ func (m *MsgMintNFT) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.UriHash) > 0 { + i -= len(m.UriHash) + copy(dAtA[i:], m.UriHash) + i = encodeVarintTx(dAtA, i, uint64(len(m.UriHash))) + i-- + dAtA[i] = 0x42 + } if len(m.Recipient) > 0 { i -= len(m.Recipient) copy(dAtA[i:], m.Recipient) @@ -1617,6 +1698,22 @@ func (m *MsgIssueDenom) Size() (n int) { if m.UpdateRestricted { n += 2 } + l = len(m.Description) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.Uri) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.UriHash) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.Data) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } return n } @@ -1663,6 +1760,10 @@ func (m *MsgTransferNFT) Size() (n int) { if l > 0 { n += 1 + l + sovTx(uint64(l)) } + l = len(m.UriHash) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } return n } @@ -1705,6 +1806,10 @@ func (m *MsgEditNFT) Size() (n int) { if l > 0 { n += 1 + l + sovTx(uint64(l)) } + l = len(m.UriHash) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } return n } @@ -1751,6 +1856,10 @@ func (m *MsgMintNFT) Size() (n int) { if l > 0 { n += 1 + l + sovTx(uint64(l)) } + l = len(m.UriHash) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } return n } @@ -2058,6 +2167,134 @@ func (m *MsgIssueDenom) Unmarshal(dAtA []byte) error { } } m.UpdateRestricted = bool(v != 0) + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Description = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 9: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Uri", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Uri = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 10: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UriHash", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.UriHash = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 11: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Data = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTx(dAtA[iNdEx:]) @@ -2382,6 +2619,38 @@ func (m *MsgTransferNFT) Unmarshal(dAtA []byte) error { } m.Recipient = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UriHash", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.UriHash = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTx(dAtA[iNdEx:]) @@ -2674,6 +2943,38 @@ func (m *MsgEditNFT) Unmarshal(dAtA []byte) error { } m.Sender = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UriHash", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.UriHash = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTx(dAtA[iNdEx:]) @@ -2998,6 +3299,38 @@ func (m *MsgMintNFT) Unmarshal(dAtA []byte) error { } m.Recipient = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UriHash", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.UriHash = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipTx(dAtA[iNdEx:]) diff --git a/modules/nft/types/validation.go b/modules/nft/types/validation.go index 09c1a1d7..b033bc80 100644 --- a/modules/nft/types/validation.go +++ b/modules/nft/types/validation.go @@ -39,9 +39,9 @@ func ValidateDenomID(denomID string) error { if len(denomID) < MinDenomLen || len(denomID) > MaxDenomLen { return sdkerrors.Wrapf(ErrInvalidDenom, "the length of denom(%s) only accepts value [%d, %d]", denomID, MinDenomLen, MaxDenomLen) } - boolPrifix := strings.HasPrefix(denomID,"tibc-") + boolPrifix := strings.HasPrefix(denomID, "tibc-") if !IsBeginWithAlpha(denomID) || !IsAlphaNumeric(denomID) && !boolPrifix { - return sdkerrors.Wrapf(ErrInvalidDenom, "the denom(%s) only accepts alphanumeric characters, and begin with an english letter", denomID) + return sdkerrors.Wrapf(ErrInvalidDenom, "the denom(%s) only accepts alphanumeric characters, and begin with an english letter", denomID) } return nil } diff --git a/proto/nft/nft.proto b/proto/nft/nft.proto index d16f0e51..982900cf 100644 --- a/proto/nft/nft.proto +++ b/proto/nft/nft.proto @@ -15,6 +15,7 @@ message BaseNFT { string uri = 3 [ (gogoproto.customname) = "URI" ]; string data = 4; string owner = 5; + string uri_hash = 6; } // Denom defines a type of NFT @@ -28,6 +29,10 @@ message Denom { string symbol = 5; bool mint_restricted = 6 ; bool update_restricted = 7 ; + string description = 8; + string uri = 9; + string uri_hash = 10; + string data = 11; } // IDCollection defines a type of collection with specified ID diff --git a/proto/nft/tx.proto b/proto/nft/tx.proto index b6d3364c..d2d8f5b5 100644 --- a/proto/nft/tx.proto +++ b/proto/nft/tx.proto @@ -38,6 +38,10 @@ message MsgIssueDenom { string symbol = 5; bool mint_restricted = 6 ; bool update_restricted = 7 ; + string description = 8; + string uri = 9; + string uri_hash = 10; + string data = 11; } // MsgIssueDenomResponse defines the Msg/IssueDenom response type. @@ -54,6 +58,7 @@ message MsgTransferNFT { string data = 5; string sender = 6; string recipient = 7; + string uri_hash = 8; } // MsgTransferNFTResponse defines the Msg/TransferNFT response type. @@ -69,6 +74,7 @@ message MsgEditNFT { string uri = 4 [ (gogoproto.customname) = "URI" ]; string data = 5; string sender = 6; + string uri_hash = 7; } // MsgEditNFTResponse defines the Msg/EditNFT response type. @@ -85,6 +91,7 @@ message MsgMintNFT { string data = 5; string sender = 6; string recipient = 7; + string uri_hash = 8; } // MsgMintNFTResponse defines the Msg/MintNFT response type.