From 0bcc2691a287c27622acb548f541e1d781369fd4 Mon Sep 17 00:00:00 2001 From: yihuang Date: Wed, 31 Jul 2024 12:21:19 +0800 Subject: [PATCH 1/8] Problem: minor security issue in github workflow (#1072) * Problem: minor security issue in github workflow * fix PR_PUSHED_AT --- .github/workflows/build.yml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8568ad1f2..2510abcfa 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -70,12 +70,17 @@ jobs: if: github.event_name == 'issue_comment' env: COMMENT_BODY: ${{ github.event.comment.body }} + COMMENT_DATE: ${{ github.event.comment.created_at }} run: | - echo "repo_name=${{ fromJson(steps.request.outputs.data).head.repo.full_name }}" >> $GITHUB_OUTPUT + PR_PUSHED_AT="${{ fromJson(steps.request.outputs.data).pushed_at }}" comment_hash=`echo "$COMMENT_BODY" | cut -d' ' -f2` # get commit hash if any if [[ "${comment_hash}" == "/runsim" ]]; then - # use default head ref - echo "ref=${{ fromJson(steps.request.outputs.data).head.ref }}" >> $GITHUB_OUTPUT + # use default head ref, if the PR hasn't changed since the comment + if [[ $(date -d "$PR_PUSHED_AT" +%s) -gt $(date -d "$COMMENT_AT" +%s) ]]; then + echo "The PR has changed since the comment, and is therefore not safe to use. Exiting." + exit 1 + fi + echo "ref=${{ fromJson(steps.request.outputs.data).head.sha }}" >> $GITHUB_OUTPUT else # use comment provided ref echo "ref=${comment_hash}" >> $GITHUB_OUTPUT @@ -90,7 +95,6 @@ jobs: with: submodules: true token: ${{ secrets.GITHUB_TOKEN }} - repository: ${{ steps.pr_data.outputs.repo_name }} ref: ${{ steps.pr_data.outputs.ref }} - name: Normal check out code uses: actions/checkout@v3 @@ -210,7 +214,6 @@ jobs: with: submodules: true token: ${{ secrets.GITHUB_TOKEN }} - repository: ${{ needs.build.outputs.repo_name }} ref: ${{ needs.build.outputs.ref }} - name: Normal check out code uses: actions/checkout@v3 @@ -257,7 +260,6 @@ jobs: with: submodules: true token: ${{ secrets.GITHUB_TOKEN }} - repository: ${{ needs.build.outputs.repo_name }} ref: ${{ needs.build.outputs.ref }} - name: Normal check out code uses: actions/checkout@v3 @@ -304,7 +306,6 @@ jobs: with: submodules: true token: ${{ secrets.GITHUB_TOKEN }} - repository: ${{ needs.build.outputs.repo_name }} ref: ${{ needs.build.outputs.ref }} - name: Normal check out code uses: actions/checkout@v3 From 9054a2d9bb9af0ae3938c0b50a95381bc0027a51 Mon Sep 17 00:00:00 2001 From: kaz-CDC Date: Wed, 31 Jul 2024 05:36:48 +0100 Subject: [PATCH 2/8] Changed all Crypto.org => Cronos POS & Cronos.org (#1071) * Update readme.md 1st Crypto.org to Cronos edit Signed-off-by: kaz-CDC * Update readme.md Crypto.org to Cronos Signed-off-by: kaz-CDC * Update CODE_OF_CONDUCT.md Update CODE_OF_CONDUCT.md changes Signed-off-by: kaz-CDC * Update CONTRIBUTING.md CONTRIBUTING.md Signed-off-by: kaz-CDC * Update readme.md Cronos POS - changes Signed-off-by: kaz-CDC * Update CODE_OF_CONDUCT.md Cronos.org & Cronos POS changes Signed-off-by: kaz-CDC * Update CONTRIBUTING.md Cronos POS changes Signed-off-by: kaz-CDC * Update LICENSE Cronos.org Signed-off-by: kaz-CDC * Update readme.md https://docs.cronos-pos.org/ Signed-off-by: kaz-CDC * Update readme.md Changes made Signed-off-by: kaz-CDC * Update logo.svg Changed Logo Signed-off-by: kaz-CDC * Update readme.md Cronos POS logo Signed-off-by: kaz-CDC * Update logo.svg logo change Signed-off-by: kaz-CDC * Update readme.md update discord label Signed-off-by: kaz-CDC --------- Signed-off-by: kaz-CDC --- CODE_OF_CONDUCT.md | 10 +++++----- CONTRIBUTING.md | 4 ++-- LICENSE | 4 ++-- assets/logo.svg | 42 +----------------------------------------- readme.md | 20 ++++++++++---------- 5 files changed, 20 insertions(+), 60 deletions(-) diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 3a9c77b53..6c2d1ae9b 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -1,7 +1,7 @@ # Code of Conduct ## Conduct -### Contact: chain@crypto.org +### Contact: contact@cronoslabs.org * We are committed to providing a friendly, safe and welcoming environment for all, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, nationality, or other similar characteristic. @@ -26,7 +26,7 @@ ## Moderation These are the policies for upholding our community’s standards of conduct. If you feel that a thread needs moderation, please contact the above mentioned person. -1. Remarks that violate the Crypto.org Chain standards of conduct, including hateful, hurtful, oppressive, or exclusionary remarks, are not allowed. (Cursing is allowed, but never targeting another user, and never in a hateful manner.) +1. Remarks that violate the Cronos.org standards of conduct, including hateful, hurtful, oppressive, or exclusionary remarks, are not allowed. (Cursing is allowed, but never targeting another user, and never in a hateful manner.) 2. Remarks that moderators find inappropriate, whether listed in the code of conduct or not, are also not allowed. @@ -42,10 +42,10 @@ These are the policies for upholding our community’s standards of conduct. If 8. Moderators are held to a higher standard than other community members. If a moderator creates an inappropriate situation, they should expect less leeway than others. -In the Crypto.org Chain developer community we strive to go the extra step to look out for each other. Don’t just aim to be technically unimpeachable, try to be your best self. In particular, avoid flirting with offensive or sensitive issues, particularly if they’re off-topic; this all too often leads to unnecessary fights, hurt feelings, and damaged trust; worse, it can drive people away from the community entirely. +In the Cronos POS Chain developer community we strive to go the extra step to look out for each other. Don’t just aim to be technically unimpeachable, try to be your best self. In particular, avoid flirting with offensive or sensitive issues, particularly if they’re off-topic; this all too often leads to unnecessary fights, hurt feelings, and damaged trust; worse, it can drive people away from the community entirely. -And if someone takes issue with something you said or did, resist the urge to be defensive. Just stop doing what it was they complained about and apologize. Even if you feel you were misinterpreted or unfairly accused, chances are good there was something you could’ve communicated better — remember that it’s your responsibility to make your fellow Crypto.org Chain developer community members comfortable. Everyone wants to get along and we are all here first and foremost because we want to talk about cool technology. You will find that people will be eager to assume good intent and forgive as long as you earn their trust. +And if someone takes issue with something you said or did, resist the urge to be defensive. Just stop doing what it was they complained about and apologize. Even if you feel you were misinterpreted or unfairly accused, chances are good there was something you could’ve communicated better — remember that it’s your responsibility to make your fellow Cronos POS Chain developer community members comfortable. Everyone wants to get along and we are all here first and foremost because we want to talk about cool technology. You will find that people will be eager to assume good intent and forgive as long as you earn their trust. -The enforcement policies listed above apply to all official Crypto.org Chain venues. For other projects adopting the Crypto.org Chain Code of Conduct, please contact the maintainers of those projects for enforcement. If you wish to use this code of conduct for your own project, consider explicitly mentioning your moderation policy or making a copy with your own moderation policy so as to avoid confusion. +The enforcement policies listed above apply to all official Cronos.org venues. For other projects adopting the Cronos.org Code of Conduct, please contact the maintainers of those projects for enforcement. If you wish to use this code of conduct for your own project, consider explicitly mentioning your moderation policy or making a copy with your own moderation policy so as to avoid confusion. * Adapted from the [Rust Code of Conduct](https://www.rust-lang.org/en-US/conduct.html), the [Node.js Policy on Trolling](http://blog.izs.me/post/30036893703/policy-on-trolling) as well as the [Contributor Covenant v1.3.0](http://contributor-covenant.org/version/1/3/0/). diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index cd81765ec..ffcf86669 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,7 +1,7 @@ # Contributing -Thank you for your interest in contributing to Chain! The goal of the chain-main repository is to develop the implementation -of Crypto.org Chain to best power its network use cases in payments, finance and digital assets. +Thank you for your interest in contributing to the Cronos POS Chain! The goal of the chain-main repository is to develop the implementation +of Cronos POS Chain to best power its network use cases in payments, finance and digital assets. Good places to start are this document and [the official documentation](https://github.com/crypto-org-chain/chain-docs). If you have any questions, feel free to ask on [Discord](https://discord.gg/pahqHz26q4). All work on the code base tries to adhere to the "Development Process" described in [The Collective Code Construction Contract (C4)](https://rfc.zeromq.org/spec/42/#24-development-process). diff --git a/LICENSE b/LICENSE index 26e20c933..ccfd89509 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ - Copyright 2018-present Crypto.org + Copyright 2018-present Cronos.org Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -10,4 +10,4 @@ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file + limitations under the License. diff --git a/assets/logo.svg b/assets/logo.svg index 042372c59..eb84b10e2 100644 --- a/assets/logo.svg +++ b/assets/logo.svg @@ -1,41 +1 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/readme.md b/readme.md index d7eb90bf4..2612c7c68 100644 --- a/readme.md +++ b/readme.md @@ -1,13 +1,13 @@

- Crypto.org Chain + Cronos POS Chain


- +

## Table of Contents @@ -35,8 +35,8 @@ ## 1. Description -**Crypto.org Chain** is a blockchain application built using Cosmos SDK and Tendermint, -intended as a backbone for some of the existing and future Crypto.org ecosystem. +**Cronos POS Chain** is a blockchain application built using Cosmos SDK and Tendermint, +intended as a backbone for some of the existing and future Cronos ecosystem. @@ -55,7 +55,7 @@ and the [contributing guidelines](CONTRIBUTING.md) when submitting code. ## 4. Documentation -Technical documentation can be found in this [Github repository](https://github.com/crypto-org-chain/chain-docs) (you can read it in [this hosted version](https://crypto.org/docs)). +Technical documentation can be found in this [Github repository](https://github.com/crypto-org-chain/chain-docs) (you can read it in [this hosted version](https://docs.cronos-pos.org/)). @@ -106,13 +106,13 @@ $ cachix use crypto-org-chain ## 6. Start a local Development Network and Node -Please follow this [documentation](https://crypto.org/docs/getting-started/local-devnet.html#devnet-running-latest-development-node) to run a local devnet. +Please follow this [documentation](https://docs.cronos-pos.org/for-node-hosts/getting-started) to run a local devnet. ## 7. Send Your First Transaction -After setting the local devnet, you may interact with your local blockchain by following this [documentation](https://crypto.org/docs/getting-started/local-devnet.html#interact-with-the-chain). +After setting the local devnet, you may interact with your local blockchain by following this [documentation](https://docs.cronos-pos.org/for-node-hosts/getting-started/local-devnet#interact-with-the-chain). @@ -185,9 +185,9 @@ pystarport supervisorctl stop all ## 10. Useful links -- [Project Website](http://crypto.org/) -- [Technical Documentation](http://crypto.org/docs) -- Community chatrooms (non-technical): [Discord](https://discord.gg/nsp9JTC) [Telegram](https://t.me/CryptoComOfficial) +- [Project Website](https://cronos-pos.org/) +- [Technical Documentation](https://docs.cronos-pos.org/) +- Community chatrooms (non-technical): [Discord](https://discord.gg/MkvPzvP5) [Telegram](**Update Telegram Link**) - Developer community channel (technical): [![Support Server](https://img.shields.io/discord/783264383978569728.svg?color=7289da&label=Crypto.org%20Chain&logo=discord&style=flat-square)](https://discord.gg/pahqHz26q4) - [Cosmos SDK documentation](https://docs.cosmos.network) From f7224d00a549b9f0036af520b4dd6a9215695dea Mon Sep 17 00:00:00 2001 From: cuiweiyuan Date: Thu, 15 Aug 2024 14:18:47 +0800 Subject: [PATCH 3/8] chore: fix some comments (#1075) Signed-off-by: cuiweiyuan --- app/docs/swagger_legacy.yaml | 4 ++-- app/types.go | 4 ++-- integration_tests/test_basic.py | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/docs/swagger_legacy.yaml b/app/docs/swagger_legacy.yaml index 48f5021d5..ec9cd030b 100644 --- a/app/docs/swagger_legacy.yaml +++ b/app/docs/swagger_legacy.yaml @@ -301,7 +301,7 @@ paths: parameters: - in: body name: txBroadcast - description: The tx must be a signed StdTx. The supported broadcast modes include `"block"`(return after tx commit), `"sync"`(return afer CheckTx) and `"async"`(return right away). + description: The tx must be a signed StdTx. The supported broadcast modes include `"block"`(return after tx commit), `"sync"`(return after CheckTx) and `"async"`(return right away). required: true schema: type: object @@ -524,7 +524,7 @@ paths: sequence: type: string 500: - description: Server internel error + description: Server internal error /staking/delegators/{delegatorAddr}/delegations: parameters: - in: path diff --git a/app/types.go b/app/types.go index 00cb0b05b..02b13e057 100644 --- a/app/types.go +++ b/app/types.go @@ -16,7 +16,7 @@ type App interface { Name() string // The application types codec. - // NOTE: This shoult be sealed before being returned. + // NOTE: This should be sealed before being returned. LegacyAmino() *codec.LegacyAmino // Application updates every begin block. @@ -36,6 +36,6 @@ type App interface { forZeroHeight bool, jailAllowedAddrs []string, modulesToExport []string, ) (servertypes.ExportedApp, error) - // All the registered module account addreses. + // All the registered module account addresses. ModuleAccountAddrs() map[string]bool } diff --git a/integration_tests/test_basic.py b/integration_tests/test_basic.py index 4b679b40f..79eacf33f 100644 --- a/integration_tests/test_basic.py +++ b/integration_tests/test_basic.py @@ -103,4 +103,4 @@ def test_statesync(cluster): # discovery_time is set to 5 seconds, add extra seconds for processing wait_for_block(cluster.cosmos_cli(i), 10) - print("succesfully syncing") + print("successfully syncing") From c26a336b8a85cf35818a5911bc7d1384e21229c1 Mon Sep 17 00:00:00 2001 From: mmsqe Date: Thu, 15 Aug 2024 16:24:42 +0800 Subject: [PATCH 4/8] Problem: no space left on device in upgrade test (#1076) --- .github/workflows/nix.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/nix.yml b/.github/workflows/nix.yml index 05194711c..0d1c8f9e3 100644 --- a/.github/workflows/nix.yml +++ b/.github/workflows/nix.yml @@ -95,6 +95,8 @@ jobs: test-upgrade: runs-on: ubuntu-latest steps: + - name: Create more disk space + run: sudo rm -rf /usr/share/dotnet && sudo rm -rf /opt/ghc && sudo rm -rf "/usr/local/share/boost" && sudo rm -rf "$AGENT_TOOLSDIRECTORY" - uses: actions/checkout@v3 with: submodules: true From f26b2cc5b11ced07f5adff9469574d8baeb72d80 Mon Sep 17 00:00:00 2001 From: mmsqe Date: Thu, 15 Aug 2024 17:25:52 +0800 Subject: [PATCH 5/8] Problem: update voting_period is not tested (#1017) * Problem: update voting_period is not tested * Apply suggestions from code review Signed-off-by: yihuang * fix test --------- Signed-off-by: mmsqe Signed-off-by: yihuang Co-authored-by: yihuang --- integration_tests/test_gov.py | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/integration_tests/test_gov.py b/integration_tests/test_gov.py index edebc944a..e9b8e1248 100644 --- a/integration_tests/test_gov.py +++ b/integration_tests/test_gov.py @@ -222,7 +222,7 @@ def test_inherit_vote(cluster, tmp_path): def test_host_enabled(cluster, tmp_path): cli = cluster.cosmos_cli() - p = cluster.cosmos_cli().query_host_params() + p = cli.query_host_params() assert p["host_enabled"] p["host_enabled"] = False proposal = tmp_path / "proposal.json" @@ -247,3 +247,35 @@ def test_host_enabled(cluster, tmp_path): approve_proposal(cluster, rsp, msg=msg) p = cli.query_host_params() assert not p["host_enabled"] + + +def test_gov_voting(cluster, tmp_path): + """ + - change voting_period from default 10s to 3m36s + """ + cli = cluster.cosmos_cli() + p = cli.query_params("gov") + assert p["params"]["voting_period"] == "10s" + updated = "3m36s" + p["params"]["voting_period"] = updated + proposal = tmp_path / "proposal.json" + authority = module_address("gov") + type = "/cosmos.gov.v1.MsgUpdateParams" + proposal_src = { + "messages": [ + { + "@type": type, + "authority": authority, + "params": p["params"], + } + ], + "deposit": "10000000basecro", + "title": "title", + "summary": "summary", + } + proposal.write_text(json.dumps(proposal_src)) + rsp = cluster.submit_gov_proposal(proposal, from_="community") + assert rsp["code"] == 0, rsp["raw_log"] + approve_proposal(cluster, rsp, msg=f",{type}") + p = cli.query_params("gov") + assert p["params"]["voting_period"] == updated From 57a34d6882de95114b40b70962a97fb4dda8f0dc Mon Sep 17 00:00:00 2001 From: pengbanban Date: Mon, 19 Aug 2024 10:22:22 +0900 Subject: [PATCH 6/8] chore: fix some comments (#1074) Signed-off-by: pengbanban Co-authored-by: mmsqe --- app/app.go | 2 +- nix/build_overlay.nix | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/app.go b/app/app.go index d42337b9a..ee43ee0f4 100644 --- a/app/app.go +++ b/app/app.go @@ -782,7 +782,7 @@ func New( v1 := app.qms.LatestVersion() v2 := app.LastBlockHeight() if v1 > 0 && v1 != v2 { - tmos.Exit(fmt.Sprintf("versiondb lastest version %d don't match iavl latest version %d", v1, v2)) + tmos.Exit(fmt.Sprintf("versiondb latest version %d don't match iavl latest version %d", v1, v2)) } } } diff --git a/nix/build_overlay.nix b/nix/build_overlay.nix index 476654e66..2870eae80 100644 --- a/nix/build_overlay.nix +++ b/nix/build_overlay.nix @@ -1,4 +1,4 @@ -# some basic overlays nessesary for the build +# some basic overlays necessary for the build final: super: { rocksdb = final.callPackage ./rocksdb.nix { }; } From 632d9defcf691b001eebd4be3007b55690fc4078 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Sep 2024 09:56:27 +0800 Subject: [PATCH 7/8] Bump actions/download-artifact from 1 to 4.1.7 in /.github/workflows (#1080) Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 1 to 4.1.7. - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](https://github.com/actions/download-artifact/compare/v1...v4.1.7) --- updated-dependencies: - dependency-name: actions/download-artifact dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2510abcfa..6aa1fea27 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -347,27 +347,27 @@ jobs: if: always() && github.event_name == 'issue_comment' && needs.member.outputs.valid == 'true' steps: - name: Download artifact pass_status_build - uses: actions/download-artifact@v1 + uses: actions/download-artifact@v4.1.7 continue-on-error: true with: name: pass_status_build - name: Download artifact pass_status_install - uses: actions/download-artifact@v1 + uses: actions/download-artifact@v4.1.7 continue-on-error: true with: name: pass_status_install - name: Download artifact pass_status_sim1 - uses: actions/download-artifact@v1 + uses: actions/download-artifact@v4.1.7 continue-on-error: true with: name: pass_status_sim1 - name: Download artifact pass_status_sim2 - uses: actions/download-artifact@v1 + uses: actions/download-artifact@v4.1.7 continue-on-error: true with: name: pass_status_sim2 - name: Download artifact pass_status_sim3 - uses: actions/download-artifact@v1 + uses: actions/download-artifact@v4.1.7 continue-on-error: true with: name: pass_status_sim3 From d548017c62eecb053fd2738a0bf00ffe5deba823 Mon Sep 17 00:00:00 2001 From: longhutianjie Date: Wed, 4 Sep 2024 18:07:11 +0800 Subject: [PATCH 8/8] chore: remove repetitive words (#1079) Signed-off-by: longhutianjie Co-authored-by: mmsqe --- x/nft-transfer/client/cli/query.go | 2 +- x/nft-transfer/keeper/relay.go | 2 +- x/nft/keeper/nft.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/x/nft-transfer/client/cli/query.go b/x/nft-transfer/client/cli/query.go index a8347c3c7..6c2fc3c8c 100644 --- a/x/nft-transfer/client/cli/query.go +++ b/x/nft-transfer/client/cli/query.go @@ -11,7 +11,7 @@ import ( "github.com/crypto-org-chain/chain-main/v4/x/nft-transfer/types" ) -// GetCmdQueryClassTrace defines the command to query a a class trace from a given trace hash or ibc class. +// GetCmdQueryClassTrace defines the command to query a class trace from a given trace hash or ibc class. func GetCmdQueryClassTrace() *cobra.Command { cmd := &cobra.Command{ Use: "class-trace [hash/class]", diff --git a/x/nft-transfer/keeper/relay.go b/x/nft-transfer/keeper/relay.go index 0b8163a15..4139d0686 100644 --- a/x/nft-transfer/keeper/relay.go +++ b/x/nft-transfer/keeper/relay.go @@ -131,7 +131,7 @@ func (k Keeper) OnRecvPacket(ctx sdk.Context, packet channeltypes.Packet, return k.processReceivedPacket(ctx, packet, data) } -// OnAcknowledgementPacket responds to the the success or failure of a packet +// OnAcknowledgementPacket responds to the success or failure of a packet // acknowledgement written on the receiving chain. If the acknowledgement // was a success then nothing occurs. If the acknowledgement failed, then // the sender is refunded their tokens using the refundPacketToken function. diff --git a/x/nft/keeper/nft.go b/x/nft/keeper/nft.go index df01ee60b..e86989247 100644 --- a/x/nft/keeper/nft.go +++ b/x/nft/keeper/nft.go @@ -10,7 +10,7 @@ import ( "github.com/crypto-org-chain/chain-main/v4/x/nft/types" ) -// GetNFT gets the the specified NFT +// GetNFT gets the specified NFT func (k Keeper) GetNFT(ctx sdk.Context, denomID, tokenID string) (nft exported.NFT, err error) { store := ctx.KVStore(k.storeKey)