Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NFT Module #4209

Merged
merged 180 commits into from
Aug 26, 2019
Merged
Show file tree
Hide file tree
Changes from 176 commits
Commits
Show all changes
180 commits
Select commit Hold shift + click to select a range
9d751b4
in sync with @okwme/cosmos-nft
okwme Apr 15, 2019
b7c8c7f
remove tmp tx
okwme Apr 15, 2019
8d57122
structuring and minor changes
fedekunze Apr 15, 2019
29b170d
supply and client files
fedekunze Apr 15, 2019
53ddc52
adding cli client
okwme Apr 16, 2019
bf8864e
complete cli/tx and rest.go
okwme Apr 17, 2019
e018425
cleanup and restructuring
fedekunze Apr 19, 2019
4fc18b0
restructure rest folder
fedekunze Apr 22, 2019
2183f39
Merge branch 'master' of https://github.com/cosmos/cosmos-sdk into bi…
fedekunze Apr 28, 2019
a9aa360
minor updates on clients
fedekunze Apr 28, 2019
6018b16
update querier
fedekunze Apr 28, 2019
b438068
encoding for clients and other changes
fedekunze Apr 28, 2019
c904493
genesis, invariants, and keeper updates
fedekunze Apr 29, 2019
8ebfdc9
update types
fedekunze Apr 29, 2019
dcb7e04
make golangcibot happy
fedekunze Apr 29, 2019
65194cf
renamed and removed bank keeper
okwme May 2, 2019
6fe5e40
remove handlers for editmetadata, mint, burn, buy
okwme May 2, 2019
7f18f53
nft interface
fedekunze May 3, 2019
d782701
minor cleanup
fedekunze May 3, 2019
a3a5d27
sort collections and nfts
fedekunze May 3, 2019
0663ae2
balance and find
fedekunze May 3, 2019
c9db8a1
nft query and tx
fedekunze May 7, 2019
2b058a7
touch ups
okwme May 14, 2019
9c9bf23
uint in place of int
sabau May 15, 2019
eea3138
little fixes:
sabau May 15, 2019
8b76ccd
module generalization changes
fedekunze May 15, 2019
a7cb226
fixes
fedekunze May 15, 2019
d681e09
query with data
fedekunze May 15, 2019
29bcf13
minor updates and TODOs
fedekunze May 15, 2019
efbdfaf
fix CLI tx
fedekunze May 15, 2019
612c66e
golang bot fixes
fedekunze May 15, 2019
4fb5b32
handlers and txs done
fedekunze May 16, 2019
a48bf2f
Merge branch 'master' of https://github.com/cosmos/cosmos-sdk into bi…
fedekunze May 16, 2019
300bb26
Merge branch 'master' of https://github.com/cosmos/cosmos-sdk into bi…
fedekunze May 16, 2019
e95299a
update module generalization
fedekunze May 16, 2019
ac0ec12
Added very basic tests which for some reason do not work
okwme May 20, 2019
cc3b825
fix test
sabau May 21, 2019
3c5252a
fixed test, now we should fix implementation, seems to fail
sabau May 21, 2019
71968ff
fix test, create new struct instead of changing the old one
sabau May 21, 2019
e84f147
fix handler with new logic
sabau May 21, 2019
872f614
let's make it compile
sabau May 21, 2019
e8dea9d
single failing test example, need to be fixed and extended
sabau May 21, 2019
11457a5
single failing test example, need to be fixed and extended
sabau May 22, 2019
c8d3da4
reverting work, still problems unmarshalling inside iterator from test
sabau May 22, 2019
2f46d0a
Setter in nft.go should return NFT instead of BaseNFT
sabau May 23, 2019
fa3d00c
remove TODOS
sabau May 23, 2019
0219084
comment out broken tests, we want at least a green mark here
sabau May 29, 2019
528384a
little fixes
sabau Jun 3, 2019
2f80a52
hopefully no conflict
okwme Jun 3, 2019
6b23fbd
Fixed marshall error
okwme Jun 3, 2019
08c07ae
Merge branch 'master' of https://github.com/cosmos/cosmos-sdk into bi…
fedekunze Jun 6, 2019
4efbaa8
minor changes for tests
tac0turtle Jun 6, 2019
789be16
Merge branch 'billy/nft' of https://github.com/cosmos/cosmos-sdk into…
tac0turtle Jun 6, 2019
0a6442d
change nft id to string, refactors
fedekunze Jun 6, 2019
edc4c92
messy pause
okwme Jun 7, 2019
430c581
slowly cleaning up beginning with keeper and keeper_tests
okwme Jun 7, 2019
541f254
Changes Balances to OWners add all necessary functions, updated Keepe…
okwme Jun 10, 2019
64431c4
pause dev to merge sdk master
okwme Jun 10, 2019
ea04c52
go.mod changes
okwme Jun 10, 2019
b916f06
Merge branch 'master' into billy/nft
okwme Jun 10, 2019
5f672ed
getting closer still need module.go
okwme Jun 10, 2019
02bf05b
builds!!!
okwme Jun 11, 2019
b970852
fix lint begin handler tests
okwme Jun 11, 2019
7b080a6
stableish
okwme Jun 11, 2019
a63a79a
re-order nft attributes, add back mint and burn msgs and handlers
okwme Jun 11, 2019
53a5cc0
add errors to minting the same NFT and burning an NFT that doesnt exist
okwme Jun 11, 2019
5e538b8
first querier test
okwme Jun 11, 2019
951fc8f
add simulations for nft msgs
fedekunze Jun 12, 2019
c55bdfe
Merge branch 'billy/nft' of https://github.com/cosmos/cosmos-sdk into…
fedekunze Jun 12, 2019
1235ac4
handler tests check tags now (fixed a bug!)
okwme Jun 12, 2019
71801b6
update simulation
fedekunze Jun 12, 2019
44dc8a6
Merge branch 'billy/nft' of https://github.com/cosmos/cosmos-sdk into…
fedekunze Jun 12, 2019
1c5a238
generic handler
okwme Jun 12, 2019
23a6054
Merge branch 'billy/nft' of github.com:cosmos/cosmos-sdk into billy/nft
okwme Jun 12, 2019
c1d93a6
need to check if it compiles on another machine
okwme Jun 15, 2019
54866ee
fix weird interface error
okwme Jun 15, 2019
3129199
add back cli
okwme Jun 15, 2019
623f3b2
wtfff
okwme Jun 15, 2019
fda61b3
codec error fixed, logs removed. still returning empty arrays of IDs
okwme Jun 15, 2019
80e5bd2
Take empty input as yes answer
alessio Jun 16, 2019
9619b5c
Add pending log entry
alexanderbez Jun 16, 2019
830cf9b
Merge branch 'billy/nft' into billy/merge-alessio
okwme Jun 16, 2019
10a250b
merged in master
okwme Jun 16, 2019
dd8be62
marshall errors
okwme Jun 16, 2019
ef4377a
build commands
okwme Jun 16, 2019
8a35375
working!!!
okwme Jun 16, 2019
ed2e501
merge master
tac0turtle Jun 25, 2019
d1052fa
linting errors
tac0turtle Jun 25, 2019
5b246d4
remove unused func
tac0turtle Jun 25, 2019
eac7eab
pause
okwme Jun 25, 2019
840bc23
Merge branch 'billy/nft' of github.com:cosmos/cosmos-sdk into billy/nft
okwme Jun 25, 2019
5fb86c6
fix burn error
okwme Jun 25, 2019
d667021
fix burn error
okwme Jul 1, 2019
94c6285
merged with maser
okwme Jul 1, 2019
1f75cb2
tests for querier
okwme Jul 1, 2019
5325b8a
typo
okwme Jul 1, 2019
770f0ea
tests for NFT types
okwme Jul 2, 2019
0ce5886
module spec standard
fedekunze Jul 2, 2019
095b497
tests for Collection and Collections types
okwme Jul 2, 2019
7ba4cfa
Merge branch 'billy/nft' of github.com:cosmos/cosmos-sdk into billy/nft
okwme Jul 2, 2019
6a40091
merge w Fede
okwme Jul 2, 2019
a9b5fea
tests for Owner Type
okwme Jul 2, 2019
fba52ed
added genesis tests and beefed up keeper, querier, handler & types tests
okwme Jul 3, 2019
9236347
linting errors deadcode
okwme Jul 3, 2019
c9d7ccc
Merge branch 'master' into billy/nft
okwme Jul 3, 2019
39b134a
DONT COVER test_common.go
okwme Jul 3, 2019
b60c6be
add msg type tests
okwme Jul 3, 2019
a718146
merge master update msg types
okwme Jul 3, 2019
785019a
Update x/nft/internal/keeper/key.go
okwme Jul 8, 2019
e4c0afa
Update x/nft/genesis.go
okwme Jul 8, 2019
1edff5a
Update x/nft/client/cli/query.go
okwme Jul 8, 2019
907be89
Apply suggestions from code review
fedekunze Jul 11, 2019
609f220
cleanup and address comments
fedekunze Jul 16, 2019
e859bc0
typo
fedekunze Jul 16, 2019
4092bc7
cleanup events
fedekunze Jul 16, 2019
b5fd467
split events
fedekunze Jul 16, 2019
97240dd
more cleanup
fedekunze Jul 18, 2019
3d1521f
remove restrictions from default handlers
okwme Jul 21, 2019
547613b
not sure where these go mod changes came from
okwme Jul 21, 2019
66ffc12
performance misspelling
okwme Jul 21, 2019
1918f54
sim generated changes
okwme Jul 23, 2019
a3937ef
merged master
okwme Jul 23, 2019
ebc912c
Merge branch 'master' of https://github.com/cosmos/cosmos-sdk into bi…
fedekunze Jul 23, 2019
3c1c0e9
make format
fedekunze Jul 23, 2019
df5e900
add mint and burn sims
fedekunze Jul 23, 2019
887324d
move NFT interface to nft/exported
fedekunze Jul 23, 2019
8e71f2d
make format
fedekunze Jul 23, 2019
72aecc5
NFT spec
fedekunze Jul 23, 2019
6f579e0
Updates
fedekunze Jul 23, 2019
91fede0
more updates
fedekunze Jul 23, 2019
b602b6d
update specs readme
fedekunze Jul 23, 2019
b518f2a
fix sims
fedekunze Jul 23, 2019
ef93ff5
rest additions
okwme Jul 29, 2019
bfea0a7
Merge branch 'master' into billy/nft
okwme Jul 29, 2019
95b037f
rest additions
okwme Jul 29, 2019
dae51c1
fix invariant
okwme Jul 29, 2019
47c9403
minimal nft without name, description or image
okwme Jul 29, 2019
61b3f1d
sim
okwme Jul 29, 2019
6985b53
fix sim
okwme Jul 29, 2019
caf41a2
fix sim
okwme Jul 29, 2019
6a521d8
fix Update methods
okwme Jul 29, 2019
99edbb4
merged nft
okwme Jul 29, 2019
494c36a
nothing
okwme Jul 29, 2019
a05d45e
Merge branch 'master' into billy/nft
sabau Jul 30, 2019
6a3436d
simplify update and remove
sabau Jul 30, 2019
241b6db
remove test on memory location
sabau Jul 30, 2019
7c050b0
TEST to get logs, need to be removed
sabau Jul 30, 2019
f047a59
fix simulator editMetadata Msg type
okwme Jul 30, 2019
ff8807f
owner not found start with empty collection
sabau Jul 30, 2019
e46495f
artifacts on errors in case of failure, else, no artifacts
sabau Jul 30, 2019
6611089
add more invariant checks to handler_tests
okwme Jul 30, 2019
8ef485f
Merge branch 'billy/nft' of github.com:cosmos/cosmos-sdk into billy/nft
okwme Jul 30, 2019
1d62300
never forget to overwrite
okwme Jul 30, 2019
96acd6e
merge min-nft, metadata removed except tokenURI
okwme Jul 30, 2019
f99777f
Merge branch 'billy/nft' into billy-fedekunze/4735-nft-spec
okwme Jul 30, 2019
5366c07
merge and update spec
okwme Jul 30, 2019
2e1fbb6
Merge pull request #4766 from cosmos/billy-fedekunze/4735-nft-spec
okwme Jul 30, 2019
0d99d6f
Merge branch 'master' into billy/nft
okwme Jul 30, 2019
85104ca
colins feedback
okwme Jul 31, 2019
b00a362
Merge branch 'billy/nft' of github.com:cosmos/cosmos-sdk into billy/nft
okwme Jul 31, 2019
da87464
code coverage test
okwme Jul 31, 2019
322a40d
code coverage test
okwme Jul 31, 2019
b7834cc
code coverage test
okwme Jul 31, 2019
c5c33d5
spelling
okwme Jul 31, 2019
733de25
clean up client
okwme Jul 31, 2019
c1fa44e
testing code coverage
okwme Jul 31, 2019
6b5e0ed
testing code coverage
okwme Jul 31, 2019
a859dfd
testing code coverage
okwme Jul 31, 2019
575d991
testing code coverage
okwme Jul 31, 2019
c613491
testing code coverage
okwme Jul 31, 2019
e0e68cd
Update docs/spec/nft/README.md
fedekunze Aug 2, 2019
a0c3799
Apply suggestions from code review
fedekunze Aug 2, 2019
7f79b92
merge master
fedekunze Aug 2, 2019
5e47cc2
minor changes
fedekunze Aug 2, 2019
caec9f3
Merge branch 'master' of https://github.com/cosmos/cosmos-sdk into bi…
fedekunze Aug 11, 2019
81dd140
merge master; add sim decoder
fedekunze Aug 24, 2019
151f309
integration tests and fixes
fedekunze Aug 24, 2019
e44c1db
minor golangCI fixes
fedekunze Aug 24, 2019
ccf6a52
Merge branch 'master' into billy/nft
rigelrozanski Aug 26, 2019
832de38
Update simapp/app.go
rigelrozanski Aug 26, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -76,27 +76,56 @@ jobs:
- make:
target: test_sim_import_export
description: "Test application import/export simulation"
- run:
command: |
mkdir -p /tmp/errors
cp /tmp/**/app-simulation-seed* /tmp/errors/
when: on_fail
- store_artifacts:
path: /tmp/errors

test_sim_after_import:
executor: golang
steps:
- make:
target: test_sim_after_import
description: "Test simulation after import"
- run:
command: |
mkdir -p /tmp/errors
cp /tmp/**/app-simulation-seed* /tmp/errors/
when: on_fail
- store_artifacts:
path: /tmp/errors

test_sim_multi_seed_long:
executor: golang
steps:
- make:
target: test_sim_multi_seed_long
description: "Test multi-seed simulation (long)"
- run:
command: |
mkdir -p /tmp/errors
cp /tmp/**/app-simulation-seed* /tmp/errors/
when: on_fail
- store_artifacts:
path: /tmp/errors

test_sim_multi_seed_short:
executor: golang
steps:
- make:
target: test_sim_multi_seed_short
description: "Test multi-seed simulation (short)"
- run:
command: |
mkdir -p /tmp/errors
cp /tmp/**/app-simulation-seed* /tmp/errors/
when: on_fail

- store_artifacts:
path: /tmp/errors

test_cover:
executor: golang
Expand Down
1 change: 1 addition & 0 deletions .codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,4 @@ ignore:
- "docs"
- "*.md"
- "*.rst"
- "x/**/test_common.go"
3 changes: 2 additions & 1 deletion crypto/keys/output_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ package keys
import (
"testing"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/multisig"
"github.com/tendermint/tendermint/crypto/secp256k1"

sdk "github.com/cosmos/cosmos-sdk/types"
)

func TestBech32KeysOutput(t *testing.T) {
Expand Down
5 changes: 1 addition & 4 deletions docs/spec/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,7 @@ block.
- [Mint](./mint) - Staking token provision creation.
- [Params](./params) - Globally available parameter store.
- [Supply](./supply) - Total supply of the chain.

## Interchain standards

- [ICS30](./_ics/ics-030-signed-messages.md) - Signed messages standard.
- [NFT](./nft) - Non-fungible tokens.

For details on the underlying blockchain and p2p protocols, see
the [Tendermint specification](https://github.com/tendermint/tendermint/tree/master/docs/spec).
36 changes: 18 additions & 18 deletions docs/spec/SPEC-SPEC.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Specification of Specifications

This file intends to outline the common structure for specifications within
this directory.
this directory.

## Tense

Expand All @@ -15,43 +15,43 @@ be considered preferable. In certain instances, due to the complex nature of
the functionality being described pseudo-code may the most suitable form of
specification. In these cases use of pseudo-code is permissible, but should be
presented in a concise manner, ideally restricted to only the complex
element as a part of a larger description.
element as a part of a larger description.

## Common Layout

The following generalized file structure should be used to breakdown
specifications for modules. With the exception of README.md, `XX` at the
beginning of the file name should be replaced with a number to indicate
document flow (ex. read `01_state.md` before `02_state_transitions.md`). The
following list is nonbinding and all files are optional.

- `README.md` - overview of the module
- `XX_concepts.md` - describe specialized concepts and definitions used throughout the spec
- `XX_state.md` - specify and describe structures expected to marshalled into the store, and their keys
- `XX_state_transitions.md` - standard state transition operations triggered by hooks, messages, etc.
- `XX_messages.md` - specify message structure(s) and expected state machine behaviour(s)
- `XX_begin_block.md` - specify any begin-block operations
- `XX_end_block.md` - specify any end-block operations
- `XX_hooks.md` - describe available hooks to be called by/from this module
- `XX_tags.md` - list and describe event tags used
- `XX_params.md` - list all module parameters, their types (in JSON) and examples
- `XX_future_improvements.md` - describe future improvements of this module
- `XX_appendix.md` - supplementary details referenced elsewhere within the spec
following list is nonbinding and all files are optional.

- `README.md` - overview of the module
- `XX_concepts.md` - describe specialized concepts and definitions used throughout the spec
- `XX_state.md` - specify and describe structures expected to marshalled into the store, and their keys
- `XX_state_transitions.md` - standard state transition operations triggered by hooks, messages, etc.
- `XX_messages.md` - specify message structure(s) and expected state machine behaviour(s)
- `XX_begin_block.md` - specify any begin-block operations
- `XX_end_block.md` - specify any end-block operations
- `XX_hooks.md` - describe available hooks to be called by/from this module
- `XX_events.md` - list and describe event tags used
- `XX_params.md` - list all module parameters, their types (in JSON) and examples
- `XX_future_improvements.md` - describe future improvements of this module
- `XX_appendix.md` - supplementary details referenced elsewhere within the spec

### Notation for key-value mapping

Within `state.md` the following notation `->` should be used to describe key to
value mapping:

```
key -> value
key -> value
```

to represent byte concatenation the `|` may be used. In addition, encoding
type may be specified, for example:

```
0x00 | addressBytes | address2Bytes -> amino(value_object)
0x00 | addressBytes | address2Bytes -> amino(value_object)
```

Additionally, index mappings may be specified by mapping to the `nil` value, for example:
Expand Down
50 changes: 50 additions & 0 deletions docs/spec/nft/01_concepts.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Concepts

## NFT

The `NFT` Interface inherits the BaseNFT struct and includes getter functions for the asset data. It also includes a Stringer function in order to print the struct. The interface may change if metadata is moved to it’s own module as it might no longer be necessary for the flexibility of an interface.

```go
// NFT non fungible token interface
type NFT interface {
GetID() string // unique identifier of the NFT
GetOwner() sdk.AccAddress // gets owner account of the NFT
SetOwner(address sdk.AccAddress) // gets owner account of the NFT
GetTokenURI() string // metadata field: URI to retrieve the of chain metadata of the NFT
EditMetadata(tokenURI string) // edit metadata of the NFT
String() string // string representation of the NFT object
}
```

## Collections

A Collection is used to organized sets of NFTs. It contains the denomination of the NFT instead of storing it within each NFT. This saves storage space by removing redundancy.

```go
// Collection of non fungible tokens
type Collection struct {
Denom string `json:"denom,omitempty"` // name of the collection; not exported to clients
NFTs []*NFT `json:"nfts"` // NFTs that belongs to a collection
}
```

## Owner

An Owner is a struct that includes information about all NFTs owned by a single account. It would be possible to retrieve this information by looping through all Collections but that process could become computationally prohibitive so a more efficient retrieval system is to store redundant information limited to the token ID by owner.

```go
// Owner of non fungible tokens
type Owner struct {
Address sdk.AccAddress `json:"address"`
IDCollections IDCollections `json:"IDCollections"`
}
```

An `IDCollection` is similar to a `Collection` except instead of containing NFTs it only contains an array of `NFT` IDs. This saves storage by avoiding redundancy.
Copy link
Contributor

@rigelrozanski rigelrozanski Aug 2, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

EDIT:
we should most likely eliminate these structs if they are expected to be stored anywhere and simply replace them with indexes on the NFT object see my next comment


couple things, a) in the above owner struct the field is of type IDCollections however you only define the IDCollection (singular) struct below, we should probably also include the line:

type IDCollections [] IDCollection 

just for clarity.

b) type Collection should probably expose a function GetIDCollections() IDCollections and similarly NFT should expose a function GetIDCollection() IDCollection. These functions are worth mentioning maybe? add this into the NFT type interface at maybe?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


```go
// IDCollection of non fungible tokens
type IDCollection struct {
Denom string `json:"denom"`
IDs []string `json:"IDs"`
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yo. Okay so I think that the NFT design should be restructured to eliminate the:

  • Owner struct
  • IDCollection struct

We should instead by applying the use of secondary indexes similarly to how the staking module stores references to the same validators by: operator-address, consensus-address, power, etc. (see example https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/keeper/validator.go#L70)
(see spec: https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/staking/01_state.md#validator)

This way we should be able to easily create functions on the NFTKeeper to get the NFTs efficiently without requiring these extra object. For example I'd suggest the keeper look like:

type NFTKeeper interface {
    GetNFTByID(string) NFT
    GetCollectionByDenom(string) []*NFT
    GetCollectionsByOwner(sdk.AccAddress) []Collection
}

Or something along those lines.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Opened the issue #4955

20 changes: 20 additions & 0 deletions docs/spec/nft/02_state.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# State

## Collections

As all NFTs belong to a specific `Collection`, they are kept on store in an array
within each `Collection`. Every time an NFT that belongs to a collection is updated,
it needs to be updated on the corresponding NFT array on the corresponding `Collection`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

whoa - are you saying NFTs are stored in two places? that sounds like asking for trouble. We should most certainly only store pointer objects in the collection to avoid having to update both. (See my suggested code change to the spec).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

`denomHash` is used as part of the key to limit the length of the `denomBytes` which is
a hash of `denomBytes` made from the tendermint [tmhash library](https://github.com/tendermint/tendermint/tree/master/crypto/tmhash).

- Collections: `0x00 | denomHash -> amino(Collection)`
- denomHash: `tmhash(denomBytes)`

## Owners

The ownership of an NFT is set initially when an NFT is minted and needs to be
updated every time there's a transfer or when an NFT is burned.

- Owners: `0x01 | addressBytes | denomHash -> amino(Owner)`
- denomHash: `tmhash(denomBytes)`
86 changes: 86 additions & 0 deletions docs/spec/nft/03_messages.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# Messages

## MsgTransferNFT

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 `MsgEditNFTMetadata` 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** |
|:----------|:-----------------|:--------------------------------------------------------------------------------------------------------------|
| Sender | `sdk.AccAddress` | 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 | `sdk.AccAddress` | The account address who will receive the NFT as a result of the transfer transaction. |
| Denom | `string` | The denomination of the NFT, necessary as multiple denominations are able to be represented on each chain. |
| ID | `string` | The unique ID of the NFT being transferred |

```go
// MsgTransferNFT defines a TransferNFT message
type MsgTransferNFT struct {
Sender sdk.AccAddress
Recipient sdk.AccAddress
Denom string
ID string
}
```

## MsgEditNFTMetadata

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** |
|:------------|:-----------------|:-----------------------------------------------------------------------------------------------------------|
| Sender | `sdk.AccAddress` | The creator of the message |
| ID | `string` | The unique ID of the NFT being edited |
| Denom | `string` | The denomination of the NFT, necessary as multiple denominations are able to be represented on each chain. |
| TokenURI | `string` | The URI pointing to a JSON object that contains subsequent metadata information off-chain |

```go
// MsgEditNFTMetadata edits an NFT's metadata
type MsgEditNFTMetadata struct {
Sender sdk.AccAddress
ID string
Denom string
TokenURI string
}
```

## MsgMintNFT

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** |
|:------------|:-----------------|:-----------------------------------------------------------------------------------------|
| Sender | `sdk.AccAddress` | The sender of the Message |
| Recipient | `sdk.AccAddress` | The recipiet of the new NFT |
| ID | `string` | The unique ID of the NFT being minted |
| Denom | `string` | The denomination of the NFT. |
| TokenURI | `string` | The URI pointing to a JSON object that contains subsequent metadata information off-chain |

```go
// MsgMintNFT defines a MintNFT message
type MsgMintNFT struct {
Sender sdk.AccAddress
Recipient sdk.AccAddress
ID string
Denom string
TokenURI string
}
```

### MsgBurnNFT

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** |
|:----------|:-----------------|:---------------------------------------------------|
| Sender | `sdk.AccAddress` | The account address of the user burning the token. |
| ID | `string` | The ID of the Token. |
| Denom | `string` | The Denom of the Token. |

```go
// MsgBurnNFT defines a BurnNFT message
type MsgBurnNFT struct {
Sender sdk.AccAddress
ID string
Denom string
}
```
48 changes: 48 additions & 0 deletions docs/spec/nft/04_events.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Events

The nft module emits the following events:

## Handlers

### MsgTransferNFT

| Type | Attribute Key | Attribute Value |
|--------------|---------------|--------------------|
| transfer_nft | denom | {nftDenom} |
| transfer_nft | nft-id | {nftID} |
| transfer_nft | recipient | {recipientAddress} |
| message | module | nft |
| message | action | transfer_nft |
| message | sender | {senderAddress} |

### MsgEditNFTMetadata

| Type | Attribute Key | Attribute Value |
|-------------------|---------------|-------------------|
| edit_nft_metadata | denom | {nftDenom} |
| edit_nft_metadata | nft-id | {nftID} |
| message | module | nft |
| message | action | edit_nft_metadata |
| message | sender | {senderAddress} |
| message | token-uri | {tokenURI} |

### MsgMintNFT

| Type | Attribute Key | Attribute Value |
|----------|---------------|-----------------|
| mint_nft | denom | {nftDenom} |
| mint_nft | nft-id | {nftID} |
| message | module | nft |
| message | action | mint_nft |
| message | sender | {senderAddress} |
| message | token-uri | {tokenURI} |

### MsgBurnNFTs

| Type | Attribute Key | Attribute Value |
|----------|---------------|-----------------|
| burn_nft | denom | {nftDenom} |
| burn_nft | nft-id | {nftID} |
| message | module | nft |
| message | action | burn_nft |
| message | sender | {senderAddress} |
5 changes: 5 additions & 0 deletions docs/spec/nft/05_future_improvements.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Future Improvements

There's interesting work that could be done about moving metadata into its own module. This could act as one of the `tokenURI` endpoints if a chain chooses to offer storage as a solution. Furthermore on-chain metadata can be trusted to a higher degree and might be used in secondary actions like price evaluation. Moving metadata to it's own module could be useful for the Bank Module as well. It would be able to describe attributes like decimal places and information regarding vesting schedules. It would be needed to have a level of introspection to describe the content without actually delivering the content for client libraries to interact with it. Using schema.org as a common location to settle metadata schema structure would be a good and impartial place to do so.

Inter-Blockchain Communication will need to develop its own Message types that allow NFTs to be transferred across chains. Making sure that spec is able to support the NFTs created by this module should be easy. What might be more complicated is a transfer that includes optional metadata so that a receiving chain has the option of parsing and storing it instead of making IBC queries when that data needs to be accessed (assuming that information stays up to date).
7 changes: 7 additions & 0 deletions docs/spec/nft/06_appendix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Appendix

* Cosmos SDK: [PR #4209](https://github.com/cosmos/cosmos-sdk/pull/4209)
* Cosmos SDK: [Issue #4046](https://github.com/cosmos/cosmos-sdk/issues/4046)
* Interchain Standards: [ICS #17](https://github.com/cosmos/ics/issues/30)
* Binance: [BEP #7](https://github.com/binance-chain/BEPs/pull/7)
* Ethereum: [EIP #721](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md)
Loading