git.delta.rocks / unique-network / refs/commits / f847a9e5e48e

difftreelog

Markdown docs should use 120-character line lengths

Dan Forbes2020-09-12parent: #3fd1cbd.patch.diff
in: master

5 files changed

modifiedREADME.mddiffbeforeafterboth
44
5## Project Description5## Project Description
66
7The NFT Pallet is the core of NFT functionality. Like ERC-721 standard in Ethereum ecosystem, this pallet provides the basement for creating collections of unique non-divisible things, also called Non Fungible Tokens (NFTs), minting NFT of a given Collection, and managing their ownership.7The NFT Pallet is the core of NFT functionality. Like ERC-721 standard in Ethereum ecosystem, this pallet provides the
8basement for creating collections of unique non-divisible things, also called Non Fungible Tokens (NFTs), minting NFT of
9a given Collection, and managing their ownership.
810
9The pallet also enables storing NFT properties. Though (according to ERC-721) NFT properties belong to logic of a concrete application that operates a Collection, so purposefully the NFT Tracking Module does not have any knowledge about properties except their byte size leaving application logic out to be controlled by Smart Contracts.11The pallet also enables storing NFT properties. Though (according to ERC-721) NFT properties belong to logic of a
12concrete application that operates a Collection, so purposefully the NFT Tracking Module does not have any knowledge
13about properties except their byte size leaving application logic out to be controlled by Smart Contracts.
1014
11The NFT Chain also provides:15The NFT Chain also provides:
1216
13* Smart Contracts Pallet and example smart contract that interacts with NFT Runtime17- Smart Contracts Pallet and example smart contract that interacts with NFT Runtime
14* ERC-1155 Functionality (currently PoC as Re-Fungible tokens, i.e. items that are still unique, but that can be split between multiple users)18- ERC-1155 Functionality (currently PoC as Re-Fungible tokens, i.e. items that are still unique, but that can be split
19 between multiple users)
15* Variety of economic options for dapp producers to choose from to create freemium games and other ways to attract users. As a step one, we implemented an economic model when a collection sponsor can be set to pay for collection Transfer transactions.20- Variety of economic options for dapp producers to choose from to create freemium games and other ways to attract
21 users. As a step one, we implemented an economic model when a collection sponsor can be set to pay for collection
22 Transfer transactions.
1623
17Wider NFT Ecosystem (most of it was developed during Hackusama):24Wider NFT Ecosystem (most of it was developed during Hackusama):
18* [SubstraPunks Game hosted on IPFS](https://github.com/usetech-llc/substrapunks)
19* [NFT Wallet and UI](https://uniqueapps.usetech.com/#/nft)
20* [NFT Asset for Unity Framework](https://github.com/usetech-llc/nft_unity)
2125
26- [SubstraPunks Game hosted on IPFS](https://github.com/usetech-llc/substrapunks)
27- [NFT Wallet and UI](https://uniqueapps.usetech.com/#/nft)
28- [NFT Asset for Unity Framework](https://github.com/usetech-llc/nft_unity)
29
22Please see our [walk-thorugh instructions](doc/hackusama_walk_through.md) to try everything out!30Please see our [walk-thorugh instructions](doc/hackusama_walk_through.md) to try everything out!
2331
24## Hackusama Update32## Hackusama Update
2533
26During the Kusama Hackaphon the following changes were made:34During the Kusama Hackaphon the following changes were made:
27* Enabled Smart Contracts Pallet
28* Enabled integration between Smart Contracts and NFT Pallet (required special edition of RC4 Substrate version)
29* Fixed misc. bugs in NFT Pallet
30* Deployed NFT TestNet. Public node available at wss://unique.usetech.com, custom UI types - see below in this README.
31* New Features:
32 * Re-Fungible Token Mode
33 * Off-Chain Schema to store token image URLs
34 * Alternative economic model
35 * White Lists and Public Mint Permission
36* Use example: [SubstraPunks Game](https://github.com/usetech-llc/substrapunks), fully hosted on IPFS and NFT Testnet Blockchain.
3735
36- Enabled Smart Contracts Pallet
37- Enabled integration between Smart Contracts and NFT Pallet (required special edition of RC4 Substrate version)
38- Fixed misc. bugs in NFT Pallet
39- Deployed NFT TestNet. Public node available at wss://unique.usetech.com, custom UI types - see below in this README.
40- New Features:
41 - Re-Fungible Token Mode
42 - Off-Chain Schema to store token image URLs
43 - Alternative economic model
44 - White Lists and Public Mint Permission
45- Use example: [SubstraPunks Game](https://github.com/usetech-llc/substrapunks), fully hosted on IPFS and NFT Testnet
46 Blockchain.
47
38## Application Development48## Application Development
3949
40If you are building an application that operates NFT tokens, use [this document](doc/application_development.md).50If you are building an application that operates NFT tokens, use [this document](doc/application_development.md).
4151
42## Building52## Building
4353
44Building NFT chain requires special versions of Rust and toolchain. We don't use the most recent versions of everything so that we can keep the builds stable.54Building NFT chain requires special versions of Rust and toolchain. We don't use the most recent versions of everything
55so that we can keep the builds stable.
4556
461. Install Rust:571. Install Rust:
4758
59```70```
6071
614. Make it default (actual toochain version may be different, so do a `rustup toolchain list` first)724. Make it default (actual toochain version may be different, so do a `rustup toolchain list` first)
73
62```bash74```bash
63rustup toolchain list75rustup toolchain list
64rustup default 1.44.0-x86_64-unknown-linux-gnu76rustup default 1.44.0-x86_64-unknown-linux-gnu
72```84```
7385
746. Build:866. Build:
87
75```bash88```bash
76cargo build89cargo build
77```90```
84cargo run -- --dev97cargo run -- --dev
85```98```
8699
87Detailed logs may be shown by running the node with the following environment variables set: `RUST_LOG=debug RUST_BACKTRACE=1 cargo run -- --dev`.100Detailed logs may be shown by running the node with the following environment variables set:
101`RUST_LOG=debug RUST_BACKTRACE=1 cargo run -- --dev`.
88102
89If you want to see the multi-node consensus algorithm in action locally, then you can create a local testnet with two validator nodes for Alice and Bob, who are the initial authorities of the genesis chain that have been endowed with testnet units. Give each node a name and expose them so they are listed on the Polkadot [telemetry site](https://telemetry.polkadot.io/#/Local%20Testnet). You'll need two terminal windows open.103If you want to see the multi-node consensus algorithm in action locally, then you can create a local testnet with two
104validator nodes for Alice and Bob, who are the initial authorities of the genesis chain that have been endowed with
105testnet units. Give each node a name and expose them so they are listed on the Polkadot
106[telemetry site](https://telemetry.polkadot.io/#/Local%20Testnet). You'll need two terminal windows open.
90107
91We'll start Alice's substrate node first on default TCP port 30333 with her chain database stored locally at `/tmp/alice`. The bootnode ID of her node is `QmQZ8TjTqeDj3ciwr93EJ95hxfDsb9pEYDizUAbWpigtQN`, which is generated from the `--node-key` value that we specify below:108We'll start Alice's substrate node first on default TCP port 30333 with her chain database stored locally at
109`/tmp/alice`. The bootnode ID of her node is `QmQZ8TjTqeDj3ciwr93EJ95hxfDsb9pEYDizUAbWpigtQN`, which is generated from
110the `--node-key` value that we specify below:
92111
93```bash112```bash
94cargo run -- \113cargo run -- \
100 --validator119 --validator
101```120```
102121
103In the second terminal, we'll start Bob's substrate node on a different TCP port of 30334, and with his chain database stored locally at `/tmp/bob`. We'll specify a value for the `--bootnodes` option that will connect his node to Alice's bootnode ID on TCP port 30333:122In the second terminal, we'll start Bob's substrate node on a different TCP port of 30334, and with his chain database
123stored locally at `/tmp/bob`. We'll specify a value for the `--bootnodes` option that will connect his node to Alice's
124bootnode ID on TCP port 30333:
104125
105```bash126```bash
106cargo run -- \127cargo run -- \
115136
116Additional CLI usage options are available and may be shown by running `cargo run -- --help`.137Additional CLI usage options are available and may be shown by running `cargo run -- --help`.
117138
139## UI custom types
118140
119## UI custom types
120```141```
121{142{
122 "Schedule": {143 "Schedule": {
182 "LookupSource": "AccountId",203 "LookupSource": "AccountId",
183 "Weight": "u64"204 "Weight": "u64"
184}205}
185```206```
207
modifieddoc/application_development.mddiffbeforeafterboth
22
3## Architecture3## Architecture
44
5Both centralized and serverless architectures are supported and application creator can decide which one to use depending on how much logic and data they intend to manage off-chain and off-line.5Both centralized and serverless architectures are supported and application creator can decide which one to use
6depending on how much logic and data they intend to manage off-chain and off-line.
67
7### Server-based architecture8### Server-based architecture
89
9In server-based architecture the application creator manually creates NFT collections and authorizes server to perform operations on each collection. See NFT palette methods that have admin permission level to understand better what server (or administrators) can do.10In server-based architecture the application creator manually creates NFT collections and authorizes server to perform
11operations on each collection. See NFT palette methods that have admin permission level to understand better what server
12(or administrators) can do.
1013
11![](server_architecture.png)14![](server_architecture.png)
1215
13### Serverless architecture16### Serverless architecture
1417
15In serverless architecture the application creator does all initialization and token distribution manually. Alternatively, smart contracts may be used in order to implement some distribution mechanics such as token sales or claiming. The dApp has access to all properties of an NFT token, but it does not have any elevated permissions, since it resides on user site. All operations happen on user's behalf signed by user's private key.18In serverless architecture the application creator does all initialization and token distribution manually.
19Alternatively, smart contracts may be used in order to implement some distribution mechanics such as token sales or
20claiming. The dApp has access to all properties of an NFT token, but it does not have any elevated permissions, since it
21resides on user site. All operations happen on user's behalf signed by user's private key.
1622
17![](serverless_architecture.png)23![](serverless_architecture.png)
1824
27#### CreateCollection33#### CreateCollection
2834
29##### Description35##### Description
30This method creates a Collection of NFTs. Each Token may have multiple properties encoded as an array of bytes of certain length. The initial owner and admin of the collection are set to the address that signed the transaction. Both addresses can be changed later.
3136
37This method creates a Collection of NFTs. Each Token may have multiple properties encoded as an array of bytes of
38certain length. The initial owner and admin of the collection are set to the address that signed the transaction. Both
39addresses can be changed later.
40
32##### Permissions41##### Permissions
42
33Anyone43Anyone
3444
35##### Parameters45##### Parameters
46
36customDataSz: Size of NFT properties data.47customDataSz: Size of NFT properties data.
3748
38##### Events49##### Events
39CollectionCreated
40CollectionID: Globally unique identifier of newly created collection.
41Owner: Collection owner
4250
51CollectionCreated CollectionID: Globally unique identifier of newly created collection. Owner: Collection owner
52
43#### ChangeCollectionOwner53#### ChangeCollectionOwner
4454
45##### Description55##### Description
56
46Change the owner of the collection57Change the owner of the collection
4758
48##### Permissions59##### Permissions
60
49Collection Owner61Collection Owner
5062
51##### Parameters63##### Parameters
64
52CollectionId65CollectionId
5366
54#### DestroyCollection67#### DestroyCollection
5568
56##### Description69##### Description
57DANGEROUS: Destroys collection and all NFTs within this collection. Users irrecoverably lose their assets and may lose real money.
5870
71DANGEROUS: Destroys collection and all NFTs within this collection. Users irrecoverably lose their assets and may lose
72real money.
73
59##### Permissions74##### Permissions
75
60Collection Owner76Collection Owner
6177
62##### Parameters78##### Parameters
79
63CollectionId80CollectionId
6481
65#### CreateItem82#### CreateItem
6683
67##### Description84##### Description
85
68This method creates a concrete instance of NFT Collection created with CreateCollection method.86This method creates a concrete instance of NFT Collection created with CreateCollection method.
6987
70##### Permissions88##### Permissions
71Collection Owner
72Collection Admin
7389
90Collection Owner Collection Admin
91
74##### Parameters92##### Parameters
75CollectionID: ID of the collection
76Properties: Array of bytes that contains NFT properties. Since NFT Module is agnostic of properties’ meaning, it is treated purely as an array of bytes
77Owner: Address, initial owner of the NFT
7893
94CollectionID: ID of the collection Properties: Array of bytes that contains NFT properties. Since NFT Module is agnostic
95of properties’ meaning, it is treated purely as an array of bytes Owner: Address, initial owner of the NFT
96
79##### Events97##### Events
80ItemCreated
81ItemId: Identifier of newly created NFT, which is unique within the Collection, so the NFT is uniquely identified with a pair of values: CollectionId and ItemId.
8298
99ItemCreated ItemId: Identifier of newly created NFT, which is unique within the Collection, so the NFT is uniquely
100identified with a pair of values: CollectionId and ItemId.
101
83#### BurnItem102#### BurnItem
84103
85##### Description104##### Description
105
86This method destroys a concrete instance of NFT.106This method destroys a concrete instance of NFT.
87107
88##### Permissions108##### Permissions
89Collection Owner
90Collection Admin
91Current NFT Owner
92109
110Collection Owner Collection Admin Current NFT Owner
111
93##### Parameters112##### Parameters
94CollectionID: ID of the collection
95ItemID: ID of NFT to burn
96113
114CollectionID: ID of the collection ItemID: ID of NFT to burn
115
97##### Events116##### Events
98ItemDestroyed
99CollectionID
100ItemId: Identifier of burned NFT
101117
118ItemDestroyed CollectionID ItemId: Identifier of burned NFT
102119
103#### AddCollectionAdmin120#### AddCollectionAdmin
104121
105##### Description122##### Description
106NFT Collection can be controlled by multiple admin addresses (some which can also be servers, for example). Admins can issue and burn NFTs, as well as add and remove other admins, but cannot change NFT or Collection ownership.
107123
124NFT Collection can be controlled by multiple admin addresses (some which can also be servers, for example). Admins can
125issue and burn NFTs, as well as add and remove other admins, but cannot change NFT or Collection ownership.
126
108This method adds an admin of the Collection.127This method adds an admin of the Collection.
109128
110##### Permissions129##### Permissions
111Collection Owner
112Collection Admin
113130
131Collection Owner Collection Admin
132
114##### Parameters133##### Parameters
115CollectionID: ID of the Collection to add admin for
116Admin: Address of new admin to add
117134
135CollectionID: ID of the Collection to add admin for Admin: Address of new admin to add
136
118#### RemoveCollectionAdmin137#### RemoveCollectionAdmin
119138
120##### Description139##### Description
121Remove admin address of the Collection. An admin address can remove itself. List of admins may become empty, in which case only Collection Owner will be able to add an Admin.
122140
141Remove admin address of the Collection. An admin address can remove itself. List of admins may become empty, in which
142case only Collection Owner will be able to add an Admin.
143
123##### Permissions144##### Permissions
124Collection Owner
125Collection Admin
126145
146Collection Owner Collection Admin
147
127##### Parameters148##### Parameters
128CollectionID: ID of the Collection to remove admin for
129Admin: Address of admin to remove
130149
150CollectionID: ID of the Collection to remove admin for Admin: Address of admin to remove
151
131### Item Ownership and Transfers152### Item Ownership and Transfers
153
132This group of methods allows managing NFT ownership.154This group of methods allows managing NFT ownership.
133155
134#### GetOwner156#### GetOwner
135157
136##### Description158##### Description
137Return the address of the NFT owner.
138159
160Return the address of the NFT owner.
161
139##### Permissions162##### Permissions
163
140Anyone164Anyone
141165
142##### Parameters166##### Parameters
143CollectionId
144ItemId: ID of the NFT
145167
168CollectionId ItemId: ID of the NFT
169
146##### Returns170##### Returns
171
147Owner address172Owner address
148173
149#### BalanceOf174#### BalanceOf
150175
151##### Description176##### Description
152This method is included for compatibility with ERC-721. Return the total count of NFTs of a given Collection that belong to a given address.
153177
178This method is included for compatibility with ERC-721. Return the total count of NFTs of a given Collection that belong
179to a given address.
180
154##### Permissions181##### Permissions
182
155Anyone183Anyone
156184
157##### Parameters185##### Parameters
158CollectionId
159Address to count NFTs for
160186
187CollectionId Address to count NFTs for
188
161##### Returns189##### Returns
190
162Total count of NFTs for Address191Total count of NFTs for Address
163192
164
165#### Transfer193#### Transfer
166194
167##### Description195##### Description
196
168Change ownership of the NFT.197Change ownership of the NFT.
169198
170##### Permissions199##### Permissions
171Collection Owner
172Collection Admin
173Current NFT owner
174200
201Collection Owner Collection Admin Current NFT owner
202
175##### Parameters203##### Parameters
176Recipient: Address of token recipient
177ClassId: ID of item class
178ItemId: ID of the item
179204
205Recipient: Address of token recipient ClassId: ID of item class ItemId: ID of the item
206
180#### TransferFrom207#### TransferFrom
181208
182##### Description209##### Description
183Change ownership of a NFT on behalf of the owner. See Approve method for additional information. After this method executes, the approval is removed so that the approved address will not be able to transfer this NFT again from this owner.
184210
211Change ownership of a NFT on behalf of the owner. See Approve method for additional information. After this method
212executes, the approval is removed so that the approved address will not be able to transfer this NFT again from this
213owner.
214
185##### Permissions215##### Permissions
186Collection Owner
187Collection Admin
188Current NFT owner
189Address approved by current NFT owner
190216
217Collection Owner Collection Admin Current NFT owner Address approved by current NFT owner
218
191##### Parameters219##### Parameters
192Recipient: Address of token recipient
193ClassId: ID of item class
194ItemId: ID of the item
195220
221Recipient: Address of token recipient ClassId: ID of item class ItemId: ID of the item
196222
197#### Approve223#### Approve
198224
199##### Description225##### Description
226
200Set, change, or remove approved address to transfer the ownership of the NFT.227Set, change, or remove approved address to transfer the ownership of the NFT.
201228
202##### Permissions229##### Permissions
203Collection Owner
204Collection Admin
205Current NFT owner
206230
231Collection Owner Collection Admin Current NFT owner
232
207##### Parameters233##### Parameters
234
208Approved: Address that is approved to transfer this NFT or zero (if needed to remove approval)235Approved: Address that is approved to transfer this NFT or zero (if needed to remove approval) ClassId: ID of item class
209ClassId: ID of item class
210ItemId: ID of the item236ItemId: ID of the item
211237
212#### GetApproved238#### GetApproved
213239
214##### Description240##### Description
241
215Get the approved address for a single NFT.242Get the approved address for a single NFT.
216243
217##### Permissions244##### Permissions
245
218Anyone246Anyone
219247
220##### Parameters248##### Parameters
221ClassId: ID of item class
222ItemId: ID of the item
223249
250ClassId: ID of item class ItemId: ID of the item
251
224##### Returns252##### Returns
253
225Approved address254Approved address
226255
modifieddoc/demo_milestone1-2.mddiffbeforeafterboth
66
7### A running chain7### A running chain
88
9**Substrate based blockchain node to host NFT Tracking Module created with substrate-up scripts (currently substrate-up only support Substrate 1.0)**9**Substrate based blockchain node to host NFT Tracking Module created with substrate-up scripts (currently substrate-up
10only support Substrate 1.0)**
1011
11We have created chain based on both versions of substrate: 1 and 2. Nonetheless, the substrate 1 is not being widely used and we decided to obsolete this branch of code. The code still exists in [substrate1](https://github.com/usetech-llc/nft_parachain/tree/substrate1) branch, but this delivery document is based on substrate 2 version.12We have created chain based on both versions of substrate: 1 and 2. Nonetheless, the substrate 1 is not being widely
13used and we decided to obsolete this branch of code. The code still exists in
14[substrate1](https://github.com/usetech-llc/nft_parachain/tree/substrate1) branch, but this delivery document is based
15on substrate 2 version.
1216
13The node can be run using docker container:17The node can be run using docker container:
18
14```19```
15docker-compose up -d20docker-compose up -d
16```21```
1722
18#### NFT Tracking Module23#### NFT Tracking Module
19Open extrinsics tab of the [standard UI](https://polkadot.js.org/apps/#/extrinsics) and find "nft" in the module list. This proves that NFT module is deployed.
2024
21#### Balances Module, Other modules included by default 25Open extrinsics tab of the [standard UI](https://polkadot.js.org/apps/#/extrinsics) and find "nft" in the module list.
22The [same UI](https://polkadot.js.org/apps/#/extrinsics) allows verification that all other modules are also installed as needed.26This proves that NFT module is deployed.
2327
28#### Balances Module, Other modules included by default
29
30The [same UI](https://polkadot.js.org/apps/#/extrinsics) allows verification that all other modules are also installed
31as needed.
32
24#### Configuration of runtime as needed (e.g. for hot module updates)33#### Configuration of runtime as needed (e.g. for hot module updates)
2534
26The `set_code` method worked out of the box and we did not need to perform any additional customizations to upload an updated WASM version of NFT palette.35The `set_code` method worked out of the box and we did not need to perform any additional customizations to upload an
36updated WASM version of NFT palette.
2737
28### NFT Tracking Module38### NFT Tracking Module
2939
30Before we continue, we need to do some preparations in the UI: Add NFT Data types so that the UI knows how to decode them. Go to [Settings-Developer Tab](https://polkadot.js.org/apps/#/settings/developer) and add following types to the JSON object in there:40Before we continue, we need to do some preparations in the UI: Add NFT Data types so that the UI knows how to decode
41them. Go to [Settings-Developer Tab](https://polkadot.js.org/apps/#/settings/developer) and add following types to the
42JSON object in there:
43
31```44```
32{45{
5063
51#### CreateCollection64#### CreateCollection
5265
53Before running test, open [chain state tab](https://polkadot.js.org/apps/#/chainstate) and read `nft`.`nextCollectionId` state variable, which shows how many collections were created so far. If you just started the chain, this should equal 0. 66Before running test, open [chain state tab](https://polkadot.js.org/apps/#/chainstate) and read `nft`.`nextCollectionId`
67state variable, which shows how many collections were created so far. If you just started the chain, this should
68equal 0.
5469
55Open extrinsics tab of the [standard UI](https://polkadot.js.org/apps/#/extrinsics) and select ALICE account. Select `nft` module and `createCollection` method. Put 1 in `custom_data_size` and run the transaction. After it is finalized, read the `nft`.`nextCollectionId` state variable. It will be equal 1.70Open extrinsics tab of the [standard UI](https://polkadot.js.org/apps/#/extrinsics) and select ALICE account. Select
71`nft` module and `createCollection` method. Put 1 in `custom_data_size` and run the transaction. After it is finalized,
72read the `nft`.`nextCollectionId` state variable. It will be equal 1.
5673
57Also, read the state variable `nft`.`collection` with ID = 1 (Because everything in NFT Palette is numbered from 1, not from 0). You will see something like this:74Also, read the state variable `nft`.`collection` with ID = 1 (Because everything in NFT Palette is numbered from 1, not
75from 0). You will see something like this:
5876
59```77```
60nft.collection: CollectionType78nft.collection: CollectionType
6785
68### ChangeCollectionOwner86### ChangeCollectionOwner
6987
70Open extrinsics tab of the [standard UI](https://polkadot.js.org/apps/#/extrinsics). Select `nft` module and `changeCollectionOwner` method. First, try to execute it to change owner to BOB for collection 1 from some different account than ALICE - FERDIE to see that it is not possible because ALICE owns collection 1 and FERDIE is not allowed to give it to BOB. Second, select ALICE as transaction signer and run it again. This time the collection owner changes, which will be reflected if you read the state variable `nft`.`collection` with ID = 1:88Open extrinsics tab of the [standard UI](https://polkadot.js.org/apps/#/extrinsics). Select `nft` module and
89`changeCollectionOwner` method. First, try to execute it to change owner to BOB for collection 1 from some different
90account than ALICE - FERDIE to see that it is not possible because ALICE owns collection 1 and FERDIE is not allowed to
91give it to BOB. Second, select ALICE as transaction signer and run it again. This time the collection owner changes,
92which will be reflected if you read the state variable `nft`.`collection` with ID = 1:
7193
72```94```
73nft.collection: CollectionType95nft.collection: CollectionType
84106
85**Note: Before destroying collection, you can see Milestone 2 deliverables to avoid creating collection again**107**Note: Before destroying collection, you can see Milestone 2 deliverables to avoid creating collection again**
86108
87Run `nft`.`destroyCollection` with collection ID = 1, and then read collection from state. The returned fields will have default values, which indicates that collection does not exsit anymore: 109Run `nft`.`destroyCollection` with collection ID = 1, and then read collection from state. The returned fields will have
110default values, which indicates that collection does not exsit anymore:
111
88```112```
89nft.collection: CollectionType113nft.collection: CollectionType
108132
109**using Polkadot UI from https://substrate-ui.parity.io/**133**using Polkadot UI from https://substrate-ui.parity.io/**
110134
111This document, except we are using Substrate v2, so we can use the newer version of the UI: https://polkadot.js.org/apps/#135This document, except we are using Substrate v2, so we can use the newer version of the UI:
136https://polkadot.js.org/apps/#
112137
113## Milestone 2138## Milestone 2
139
114### NFT Tracking Module140### NFT Tracking Module
141
115**Note:** If you have destroyed collection, create it again using `nft`.`createCollection` method.142**Note:** If you have destroyed collection, create it again using `nft`.`createCollection` method.
116143
117**Note 2:** The order of items in this section is different from the original spec to make the acceptance workflow more natural.144**Note 2:** The order of items in this section is different from the original spec to make the acceptance workflow more
145natural.
118146
119If you did not destroy collection while looking at Milestone 1 deliverables, use collection ID 1 in the further examples, otherwise use collection ID = 2.147If you did not destroy collection while looking at Milestone 1 deliverables, use collection ID 1 in the further
148examples, otherwise use collection ID = 2.
120149
121#### CreateItem150#### CreateItem
122Before creating an NFT item, let's read ALICE balance for your collection, which indicates how many NFT tokens ALICE owns in this collection. Read the chain state `nft`.`balance(<Collection ID>, ALICE)`, and it will be 0.
123151
124Execute extrinsic `nft`.`createItem` from ALICE account. Set properties to `0x01`. Now if you read the chain state `nft`.`balance(<Collection ID>, ALICE)`, it will be equal to 1. Also, you can read chain state `nft`.`itemList(<Collection ID>, 1)`, and it will return data for the token 1:152Before creating an NFT item, let's read ALICE balance for your collection, which indicates how many NFT tokens ALICE
153owns in this collection. Read the chain state `nft`.`balance(<Collection ID>, ALICE)`, and it will be 0.
125154
155Execute extrinsic `nft`.`createItem` from ALICE account. Set properties to `0x01`. Now if you read the chain state
156`nft`.`balance(<Collection ID>, ALICE)`, it will be equal to 1. Also, you can read chain state
157`nft`.`itemList(<Collection ID>, 1)`, and it will return data for the token 1:
158
126```159```
127nft.itemList: NftItemType160nft.itemList: NftItemType
128{161{
133```166```
134167
135#### GetOwner168#### GetOwner
169
136Reading the ownership is done by reading chainstate `nft`.`itemList(<Collection ID>, 1)`. One of the returned fields is Owner:170Reading the ownership is done by reading chainstate `nft`.`itemList(<Collection ID>, 1)`. One of the returned fields is
171Owner:
172
137```173```
138nft.itemList: NftItemType174nft.itemList: NftItemType
144```180```
145181
146#### Transfer182#### Transfer
183
147Execute `nft`.`transfer` from ALICE address to transfer token 1 to BOB and check the ownership again:184Execute `nft`.`transfer` from ALICE address to transfer token 1 to BOB and check the ownership again:
185
148```186```
149nft.itemList: NftItemType187nft.itemList: NftItemType
150{188{
159#### BalanceOf197#### BalanceOf
160198
161Read the chain state `nft`.`balance` for ALICE address and see that she owns 1 token:199Read the chain state `nft`.`balance` for ALICE address and see that she owns 1 token:
200
162```201```
163nft.balance: u64202nft.balance: u64
16412031
165```204```
166205
167#### AddCollectionAdmin206#### AddCollectionAdmin
168Execute `nft`.`AddCollectionAdmin` from ALICE account and let CHARLIE be an admin. Now you can see that CHARLIE can transfer ALICE's token from ALICE's account to EVE and back. Also, you can read admin list from chain state and see that it is not empty:
169207
208Execute `nft`.`AddCollectionAdmin` from ALICE account and let CHARLIE be an admin. Now you can see that CHARLIE can
209transfer ALICE's token from ALICE's account to EVE and back. Also, you can read admin list from chain state and see that
210it is not empty:
211
170```212```
171nft.adminList: Vec<AccountId>213nft.adminList: Vec<AccountId>
172[214[
175```217```
176218
177#### RemoveCollectionAdmin219#### RemoveCollectionAdmin
178Execute `nft`.`RemoveCollectionAdmin` from ALICE account to remove CHARLIE from admins. Now you can see that CHARLIE cannot transfer ALICE's tokens anymore. If you read the chan state `nft`.`adminList`, the response will be empty:
179220
221Execute `nft`.`RemoveCollectionAdmin` from ALICE account to remove CHARLIE from admins. Now you can see that CHARLIE
222cannot transfer ALICE's tokens anymore. If you read the chan state `nft`.`adminList`, the response will be empty:
223
180```224```
181nft.adminList: Vec<AccountId>225nft.adminList: Vec<AccountId>
182[]226[]
183```227```
184228
185#### BurnItem229#### BurnItem
230
186Execute `nft`.`burnItem` from ALICE account to burn token 1, and then read the chain state `nft`.`itemList(<Collection ID>, 1)`. This time the chain state returns default values in fields because token does not exist anymore. You can also check ALICE balance in chain state, now it is equal 0 again.231Execute `nft`.`burnItem` from ALICE account to burn token 1, and then read the chain state
232`nft`.`itemList(<Collection ID>, 1)`. This time the chain state returns default values in fields because token does not
233exist anymore. You can also check ALICE balance in chain state, now it is equal 0 again.
234
187```235```
188nft.itemList: NftItemType236nft.itemList: NftItemType
194```242```
195243
196### Economic Model Specification244### Economic Model Specification
245
197[Economic Model Specification](economic_model.md)246[Economic Model Specification](economic_model.md)
198247
199### Contracts Module Specification248### Contracts Module Specification
249
200https://docs.google.com/document/d/1gDtYjPR9C1VZChxEA-xAdQWQyEvMg245XrZR_MpE3cg/edit?usp=sharing250https://docs.google.com/document/d/1gDtYjPR9C1VZChxEA-xAdQWQyEvMg245XrZR_MpE3cg/edit?usp=sharing
201251
202### Bonus goal252### Bonus goal
203253
204**Basic demo - Cryptopunks representation on the Substrate Chain.**254**Basic demo - Cryptopunks representation on the Substrate Chain.**
205255
206See this repo, it has running and playing instructions:256See this repo, it has running and playing instructions: https://github.com/usetech-llc/substrapunks
207https://github.com/usetech-llc/substrapunks
208257
modifieddoc/economic_model.mddiffbeforeafterboth
22
3## Economy Goals3## Economy Goals
44
5One of the goals of this specification is to find means to provide for network infrastructure (incentivisation of validators) and development support for NFT Parachain. Transaction fees will be used as the main source of funds. Fees will be distributed among network participants. The distribution of fees will depend on validator contribution to the network (similarly to Polkadot network) and the chosen fee structure (model).5One of the goals of this specification is to find means to provide for network infrastructure (incentivisation of
6validators) and development support for NFT Parachain. Transaction fees will be used as the main source of funds. Fees
7will be distributed among network participants. The distribution of fees will depend on validator contribution to the
8network (similarly to Polkadot network) and the chosen fee structure (model).
69
7## Summary10## Summary
811
9We are going to offer several fee models for our users. Some models will be implemented immediately, some will wait until there is a demand. 12We are going to offer several fee models for our users. Some models will be implemented immediately, some will wait
13until there is a demand.
1014
11The fee models can be setup by Collection and by Smart Contract address. Every Collection or Smart Contract has a fee model associated with it, which determines how transactions are paid. Network users can choose the fee model that better suits their application. The fee model can be changed later as well.15The fee models can be setup by Collection and by Smart Contract address. Every Collection or Smart Contract has a fee
16model associated with it, which determines how transactions are paid. Network users can choose the fee model that better
17suits their application. The fee model can be changed later as well.
1218
13Initially we offer 4 models for consideration:19Initially we offer 4 models for consideration:
1420
15* User paid fees (conventional blockchain method)21- User paid fees (conventional blockchain method)
16* Sponsored (same as above, but paid by sponsor)22- Sponsored (same as above, but paid by sponsor)
17* Prepaid plan23- Prepaid plan
18* Resource purchase24- Resource purchase
1925
20## Token and Accounts26## Token and Accounts
2127
22Network Tokens are tracked via standard Balances module, which is included in NFT Parachain.28Network Tokens are tracked via standard Balances module, which is included in NFT Parachain.
2329
24User Account matches to user address in the network. Among other properties user Account has Balance, which will be used later on.30User Account matches to user address in the network. Among other properties user Account has Balance, which will be used
31later on.
2532
26## Settings Economic Model33## Settings Economic Model
2734
3138
32#### Description39#### Description
3340
34Set the collection sponsor address. The sponsorship needs to be confirmed by sending a ConfirmSponsorship transaction from that address. Also, the protection measures need to be in place so that sponsor account cannot be depleted by malicious users. White listing is one of the measured. It can be enabled with SetPublicAccessMode method.41Set the collection sponsor address. The sponsorship needs to be confirmed by sending a ConfirmSponsorship transaction
42from that address. Also, the protection measures need to be in place so that sponsor account cannot be depleted by
43malicious users. White listing is one of the measured. It can be enabled with SetPublicAccessMode method.
3544
36##### List of transactions45##### List of transactions
46
37Transactions that can be sponsored:47Transactions that can be sponsored:
38* Transfer
39* Approve
40* TransferFrom
41* TransferWithData
42* TransferFromWithData
43* BurnItem
4448
49- Transfer
50- Approve
51- TransferFrom
52- TransferWithData
53- TransferFromWithData
54- BurnItem
55
45##### Rate Limiting56##### Rate Limiting
4657
47This is a design proposal, actual implementation may change.58This is a design proposal, actual implementation may change.
4859
49Features:60Features:
50* Token transactions per day: The timestamp of last transaction performed on a token (NFT only) is associated with token ID in a dictionary. When a next transaction is run, the time is checked against this timestamp and, if less than allowed by rate limit, the fee is paid by caller account instead of the sponsor.
51* Address transactions per day: The timestamp of last transaction performed by an address (only if transaction is in the [list of affected transactions](#list-of-transactions)) is associated with caller address in a dictionary. Further, the logic is similar to limiting by token as above. If only one of the limits (by token or by address) indicates that fee should be paid by the user, the fee is paid by the user.
52* A pallet method (SetCollectionRateLimits) will be added to set these parameters and enable rate limiting.
53* One idea to consider is deposits that must be made by an address in order to become white listed (instead of admin review).
5461
62- Token transactions per day: The timestamp of last transaction performed on a token (NFT only) is associated with
63 token ID in a dictionary. When a next transaction is run, the time is checked against this timestamp and, if less
64 than allowed by rate limit, the fee is paid by caller account instead of the sponsor.
65- Address transactions per day: The timestamp of last transaction performed by an address (only if transaction is in
66 the [list of affected transactions](#list-of-transactions)) is associated with caller address in a dictionary.
67 Further, the logic is similar to limiting by token as above. If only one of the limits (by token or by address)
68 indicates that fee should be paid by the user, the fee is paid by the user.
69- A pallet method (SetCollectionRateLimits) will be added to set these parameters and enable rate limiting.
70- One idea to consider is deposits that must be made by an address in order to become white listed (instead of admin
71 review).
72
55#### Permissions73#### Permissions
5674
57* Collection Owner75- Collection Owner
5876
59#### Parameters77#### Parameters
6078
61* CollectionId: ID of the collection79- CollectionId: ID of the collection
62* Sponsor: Sponsor address80- Sponsor: Sponsor address
63* Fee Model ID: ID of selected economic model. Currently, only "Sponsored" mode is supported, which will be ID = 1.81- Fee Model ID: ID of selected economic model. Currently, only "Sponsored" mode is supported, which will be ID = 1.
6482
65### ConfirmSponsorship83### ConfirmSponsorship
84
66#### Description85#### Description
86
67Confirm sponsorship of a collection. This call is needed to protect sponsor address from malicious collection creators.87Confirm sponsorship of a collection. This call is needed to protect sponsor address from malicious collection creators.
6888
69#### Permissions89#### Permissions
70* Collection Sponsor only
7190
91- Collection Sponsor only
92
72#### Parameters93#### Parameters
73* CollectionId: ID of the collection
7494
95- CollectionId: ID of the collection
96
75### RemoveCollectionSponsor97### RemoveCollectionSponsor
98
76#### Description99#### Description
100
77Switch back to pay-per-own-transaction model.101Switch back to pay-per-own-transaction model.
78102
79#### Permissions103#### Permissions
80* Collection owner
81104
105- Collection owner
106
82#### Parameters107#### Parameters
83* collectionId: ID of the collection
84108
109- collectionId: ID of the collection
110
85### ClaimContract111### ClaimContract
112
86#### Description113#### Description
87Claim the contract ownership for the purpose of sponsoring. Once the contract is claimed, only the contract owner can manage the contract sponsorship. Also, the contract may be claimed only once.
88114
115Claim the contract ownership for the purpose of sponsoring. Once the contract is claimed, only the contract owner can
116manage the contract sponsorship. Also, the contract may be claimed only once.
117
89#### Permissions118#### Permissions
90* Anyone
91119
120- Anyone
121
92#### Parameters122#### Parameters
93* ContractAddress: Address of the contract
94* Sponsor: Sponsor address
95123
124- ContractAddress: Address of the contract
125- Sponsor: Sponsor address
126
96### SetContractSponsor127### SetContractSponsor
128
97#### Description129#### Description
98Set the contract sponsor address. The sponsorship needs to be confirmed by sending a ConfirmContractSponsorship transaction from that address. The spam protection measures are similar to collection sponsorship.
99130
131Set the contract sponsor address. The sponsorship needs to be confirmed by sending a ConfirmContractSponsorship
132transaction from that address. The spam protection measures are similar to collection sponsorship.
133
100#### Permissions134#### Permissions
101* Contract Owner
102135
136- Contract Owner
137
103#### Parameters138#### Parameters
104* ContractAddress: Address of the contract
105* Sponsor: Sponsor address
106* Fee Model ID: ID of selected economic model. Currently, only "Sponsored" mode is supported, which will be ID = 1.
107139
140- ContractAddress: Address of the contract
141- Sponsor: Sponsor address
142- Fee Model ID: ID of selected economic model. Currently, only "Sponsored" mode is supported, which will be ID = 1.
143
108### ConfirmContractSponsorship144### ConfirmContractSponsorship
145
109#### Description146#### Description
147
110Confirm sponsorship of a contract. This call is needed to protect sponsor address from malicious sponsorship requests.148Confirm sponsorship of a contract. This call is needed to protect sponsor address from malicious sponsorship requests.
111149
112#### Permissions150#### Permissions
113* Contract Sponsor only
114151
152- Contract Sponsor only
153
115#### Parameters154#### Parameters
116* ContractAddress: Address of the contract
117155
156- ContractAddress: Address of the contract
157
118### RemoveContractSponsor158### RemoveContractSponsor
159
119#### Description160#### Description
161
120Switch back to pay-per-own-transaction model.162Switch back to pay-per-own-transaction model.
121163
122#### Permissions164#### Permissions
123* Contract owner
124165
166- Contract owner
167
125#### Parameters168#### Parameters
126* contractAddress: Address of the contract
127169
170- contractAddress: Address of the contract
171
128### SetPublicAccessMode172### SetPublicAccessMode
173
129#### Description174#### Description
130Toggle between normal and white list access for the methods with access for “Anyone”. If White List mode is enabled, AddToWhiteList and RemoveFromWhiteList methods can be called to add to and remove addresses from the white list.
131175
132White list mode is the property of collection. If it is turned on, all public operations such as token transfers, for example, which normally have “Anyone” permission, become white listed, i.e. are only available to collection owner, admins, and addresses from the white list. White lists can be helpful for rate limiting of transfers when collection sponsoring is enabled.176Toggle between normal and white list access for the methods with access for “Anyone”. If White List mode is enabled,
177AddToWhiteList and RemoveFromWhiteList methods can be called to add to and remove addresses from the white list.
133178
179White list mode is the property of collection. If it is turned on, all public operations such as token transfers, for
180example, which normally have “Anyone” permission, become white listed, i.e. are only available to collection owner,
181admins, and addresses from the white list. White lists can be helpful for rate limiting of transfers when collection
182sponsoring is enabled.
183
134#### Permissions184#### Permissions
135* Collection Owner
136185
186- Collection Owner
187
137#### Parameters188#### Parameters
138* CollectionID: ID of the Collection to set access mode for
139* Mode
140 * 0 = Normal
141 * 1 = White list
142189
190- CollectionID: ID of the Collection to set access mode for
191- Mode
192 - 0 = Normal
193 - 1 = White list
194
143### AddToWhiteList195### AddToWhiteList
196
144#### Description197#### Description
198
145Add an address to white list.199Add an address to white list.
146200
147#### Permissions201#### Permissions
148* Collection Owner
149* Collection Admin
150202
203- Collection Owner
204- Collection Admin
205
151#### Parameters206#### Parameters
152* CollectionID: ID of the Collection
153* Address
154207
208- CollectionID: ID of the Collection
209- Address
210
155### RemoveFromWhiteList211### RemoveFromWhiteList
212
156#### Description213#### Description
214
157Remove an address from white list.215Remove an address from white list.
158216
159#### Permissions217#### Permissions
160* Collection Owner
161* Collection Admin
162218
219- Collection Owner
220- Collection Admin
221
163#### Parameters222#### Parameters
164* CollectionID: ID of the Collection
165* Address
166223
224- CollectionID: ID of the Collection
225- Address
226
167### SetCollectionRateLimits227### SetCollectionRateLimits
228
168#### Description229#### Description
230
169Enable or disable rate limits for a collection231Enable or disable rate limits for a collection
170232
171#### Permissions233#### Permissions
172* Collection Owner
173* Collection Admin
174234
235- Collection Owner
236- Collection Admin
237
175#### Parameters238#### Parameters
176* CollectionID: ID of the Collection
177* TokenInterval: Number of seconds allowed between sponsored token trasnsactions. 0 means there is no limit.
178* AddressInterval: Number of seconds allowed between sponsored address trasnsactions. 0 means there is no limit.
179239
240- CollectionID: ID of the Collection
241- TokenInterval: Number of seconds allowed between sponsored token trasnsactions. 0 means there is no limit.
242- AddressInterval: Number of seconds allowed between sponsored address trasnsactions. 0 means there is no limit.
180243
181## User Paid Fees244## User Paid Fees
182245
183This is conventional fee model, when every Account pais for the transactions they sign and send. Transaction fee will gradually increase if the network load is higher to prevent denial of service. The same type of transaction (with the same transaction weight) will result in higher fee if previous block's weight gets close to maximum block weight. The ratio for multiplying fees will be determined empirically. The multiplication will take place until the blocks stop overpopulating, but with certain saturation. If blocks underfill, i.e. block weight is under the certain threshold, then the next block will have lower fees. The lowering will continue until blocks stop underpopulating, with some saturation.246This is conventional fee model, when every Account pais for the transactions they sign and send. Transaction fee will
247gradually increase if the network load is higher to prevent denial of service. The same type of transaction (with the
248same transaction weight) will result in higher fee if previous block's weight gets close to maximum block weight. The
249ratio for multiplying fees will be determined empirically. The multiplication will take place until the blocks stop
250overpopulating, but with certain saturation. If blocks underfill, i.e. block weight is under the certain threshold, then
251the next block will have lower fees. The lowering will continue until blocks stop underpopulating, with some saturation.
184252
185Each module call will have weight annotation that will determine the weight calculation for this call:253Each module call will have weight annotation that will determine the weight calculation for this call:
186254
187* CreateCollection: Fixed255- CreateCollection: Fixed
188* ChangeCollectionOwner: Fixed256- ChangeCollectionOwner: Fixed
189* DestroyCollection: Linear of number of items (or owner addresses, depending on the collection type) multiplied by Collection Data Size257- DestroyCollection: Linear of number of items (or owner addresses, depending on the collection type) multiplied by
258 Collection Data Size
190* CreateItem: Linear of Collection Data Size259- CreateItem: Linear of Collection Data Size
191* BurnItem: Linear of Collection Data Size260- BurnItem: Linear of Collection Data Size
192* AddCollectionAdmin: Fixed261- AddCollectionAdmin: Fixed
193* RemoveCollectionAdmin: Fixed262- RemoveCollectionAdmin: Fixed
194* Transfers and approvals: Fixed263- Transfers and approvals: Fixed
195* Transfers with data: Fixed + linear of data size264- Transfers with data: Fixed + linear of data size
196* All other: Fixed265- All other: Fixed
197266
198This model is default and will be set for each collection until collection owner decides to change it to some other model.267This model is default and will be set for each collection until collection owner decides to change it to some other
268model.
199269
200### Fee Distribution270### Fee Distribution
201271
202The fees will be burned. Incentivization is done through network token inflation, which will be designed in tokenomics.272The fees will be burned. Incentivization is done through network token inflation, which will be designed in tokenomics.
203273
204## Sponsored274## Sponsored
205275
206The only difference from User Paid Fees model is that collection owner will be paying for their users. The collection owner must have enough balance on his account in order to pay for user transactions.276The only difference from User Paid Fees model is that collection owner will be paying for their users. The collection
277owner must have enough balance on his account in order to pay for user transactions.
207278
208### Fee Distribution279### Fee Distribution
209280
210Same as in User Paid Fees.281Same as in User Paid Fees.
211282
212
213## Prepaid Plan283## Prepaid Plan
214284
215Collection Owner makes regular payments to prepay for some planned network load, i.e. some fixed number of transactions, created items, etc.285Collection Owner makes regular payments to prepay for some planned network load, i.e. some fixed number of transactions,
286created items, etc.
216287
217
218### Fee Distribution288### Fee Distribution
219289
220Same as in User Paid Fees.290Same as in User Paid Fees.
221291
222
223## Resource Purchase292## Resource Purchase
224293
225Collection Owner purchases some fixed amount of network resource, which can be measured in number of users and their monthly transactions, for example. This is a one time payment. If Collection Owner decides to switch to a different fee model, the resources may be sold back to the system (with some commission).294Collection Owner purchases some fixed amount of network resource, which can be measured in number of users and their
295monthly transactions, for example. This is a one time payment. If Collection Owner decides to switch to a different fee
296model, the resources may be sold back to the system (with some commission).
226297
227Received funds will be converted to DOTs and used in staking (nomination or validation), which will allow to receive the income that will pay for infrastructure and development support.298Received funds will be converted to DOTs and used in staking (nomination or validation), which will allow to receive the
299income that will pay for infrastructure and development support.
228300
229### Fee Distribution301### Fee Distribution
230
231Fixed percentage of staking income is distributed between validators proportionally to their contribution to the network. The rest is credited to the network owner.
232302
303Fixed percentage of staking income is distributed between validators proportionally to their contribution to the
304network. The rest is credited to the network owner.
233305
modifieddoc/hackusama_walk_through.mddiffbeforeafterboth
88
9### Deployed NFT TestNet9### Deployed NFT TestNet
1010
11The TestNet public node is avaiable at wss://unique.usetech.com. It is easy to verify that it functions with the standard AppsUI:11The TestNet public node is avaiable at wss://unique.usetech.com. It is easy to verify that it functions with the
12standard AppsUI:
1213
131. Open the [Apps UI](https://polkadot.js.org/apps/#)141. Open the [Apps UI](https://polkadot.js.org/apps/#)
142. Click on the network icon in the top left corner152. Click on the network icon in the top left corner
153. Scroll down the list and input `wss://unique.usetech.com` under "custom endpoint"163. Scroll down the list and input `wss://unique.usetech.com` under "custom endpoint"
164. After connection is established, copy these [UI Custom Types](https://github.com/usetech-llc/nft_parachain#ui-custom-types) and paste them in [Developer Settings](https://polkadot.js.org/apps/#/settings/developer). Hit "Save" button.174. After connection is established, copy these
18 [UI Custom Types](https://github.com/usetech-llc/nft_parachain#ui-custom-types) and paste them in
19 [Developer Settings](https://polkadot.js.org/apps/#/settings/developer). Hit "Save" button.
175. Now the NFT node is connected with AppsUI. 205. Now the NFT node is connected with AppsUI.
186. Go to [Chain State](https://polkadot.js.org/apps/#/chainstate) and verify that NFT pallet is visible and you can read information from it.216. Go to [Chain State](https://polkadot.js.org/apps/#/chainstate) and verify that NFT pallet is visible and you can read
22 information from it.
197. For example, select nft -> collection, and enter collection ID 4 (for SubstraPunks) and click "+" button. You will see the collection properties such as UTF-16 encoded collection name and description, UTF-8 encoded token prefix, the size of custom data, etc.237. For example, select nft -> collection, and enter collection ID 4 (for SubstraPunks) and click "+" button. You will
24 see the collection properties such as UTF-16 encoded collection name and description, UTF-8 encoded token prefix, the
25 size of custom data, etc.
2026
21#### Getting some Unique Tokens27#### Getting some Unique Tokens
2228
231. Install Polkadot{.js} extension if you don't have it already installed. Here are the links for [Chrome](https://chrome.google.com/webstore/detail/polkadot%7Bjs%7D-extension/mopnmbcafieddcagagdcbnhejhlodfdd) and [Firefox](https://addons.mozilla.org/en-US/firefox/addon/polkadot-js-extension/) extensions.291. Install Polkadot{.js} extension if you don't have it already installed. Here are the links for
30 [Chrome](https://chrome.google.com/webstore/detail/polkadot%7Bjs%7D-extension/mopnmbcafieddcagagdcbnhejhlodfdd) and
31 [Firefox](https://addons.mozilla.org/en-US/firefox/addon/polkadot-js-extension/) extensions.
242. Create an address322. Create an address
253. Contact us at [Unique Network Telegram channel](https://t.me/joinchat/DPVt1RwN50Uic_Q9lFcg9A) in order to get some Unique token and some Re-Fungible tokens. Faucet is comming soon, we will update this instructions when it goes live.333. Contact us at [Unique Network Telegram channel](https://t.me/joinchat/DPVt1RwN50Uic_Q9lFcg9A) in order to get some
34 Unique token and some Re-Fungible tokens. Faucet is comming soon, we will update this instructions when it goes live.
2635
27### Smart Contracts Pallet36### Smart Contracts Pallet
2837
291. Open [Contracts](https://polkadot.js.org/apps/#/contracts) tab. It only appears in the UI when Smart Contracts pallet is included in the runtime.381. Open [Contracts](https://polkadot.js.org/apps/#/contracts) tab. It only appears in the UI when Smart Contracts pallet
39 is included in the runtime.
302. Additionally, we can find an existing smart contract. Click on "Add an existing contract" link.402. Additionally, we can find an existing smart contract. Click on "Add an existing contract" link.
313. Input this contract address: `5GdNqKMv4Sszq3SRd3TkXNa6a9ct4D3nXvtTWTFR7rTyccVJ`413. Input this contract address: `5GdNqKMv4Sszq3SRd3TkXNa6a9ct4D3nXvtTWTFR7rTyccVJ`
324. Input any contract name, for example `Claim Substrapunks`424. Input any contract name, for example `Claim Substrapunks`
335. Download and drag-and-drop this [metadata.json](https://github.com/usetech-llc/substrapunks/releases/download/v1.0.2/metadata.json) file into contract ABI field.435. Download and drag-and-drop this
44 [metadata.json](https://github.com/usetech-llc/substrapunks/releases/download/v1.0.2/metadata.json) file into
45 contract ABI field.
346. Click Save. The contract appears in the page. If the contract did not exist at that address, the UI would display an error message: "Unable to find deployed contract code at the specified address".466. Click Save. The contract appears in the page. If the contract did not exist at that address, the UI would display an
47 error message: "Unable to find deployed contract code at the specified address".
3548
36### Integration Between Smart Contracts and NFT Pallet49### Integration Between Smart Contracts and NFT Pallet
3750
38This was one of the most challenging parts of the Hackusama for us. The pre-RC4 versions of Substrate did not function properly when we tried to use `ext_dispatch_call` to dispatch a runtime call to NFT pallet from Contracts pallet, and RC4 had the `ext_dispatch_call` already removed to "free space" for some friendlier way of interaction between pallets, that was not yet implemented. Thanks to Alexander Theißen who reverted the removal of `ext_dispatch_call` and created a special branch based on RC4 for us!51This was one of the most challenging parts of the Hackusama for us. The pre-RC4 versions of Substrate did not function
52properly when we tried to use `ext_dispatch_call` to dispatch a runtime call to NFT pallet from Contracts pallet, and
53RC4 had the `ext_dispatch_call` already removed to "free space" for some friendlier way of interaction between pallets,
54that was not yet implemented. Thanks to Alexander Theißen who reverted the removal of `ext_dispatch_call` and created a
55special branch based on RC4 for us!
3956
40The smart contract source code exists in this [repository folder](https://github.com/usetech-llc/nft_parachain/tree/master/smart_contract/ink-types-node-runtime), but the best way to test how the interaction between smart contracts and NFT pallet works is to see it in action using the [SubstraPunks Game Example](https://ipfs-gateway.usetech.com/ipns/QmaMtDqE9nhMX9RQLTpaCboqg7bqkb6Gi67iCKMe8NDpCE/) that uses smart contract to claim free characters. The complete demo of this game will come later, so please bare with us and let's put this item demonstration for a bit later.57The smart contract source code exists in this
58[repository folder](https://github.com/usetech-llc/nft_parachain/tree/master/smart_contract/ink-types-node-runtime), but
59the best way to test how the interaction between smart contracts and NFT pallet works is to see it in action using the
60[SubstraPunks Game Example](https://ipfs-gateway.usetech.com/ipns/QmaMtDqE9nhMX9RQLTpaCboqg7bqkb6Gi67iCKMe8NDpCE/) that
61uses smart contract to claim free characters. The complete demo of this game will come later, so please bare with us and
62let's put this item demonstration for a bit later.
4163
42### Re-Fungibility support64### Re-Fungibility support
4365
44This feature is best demonstrated in action using our NFT wallet. First, you need to have some Unique and Re-Fungible tokens. [This section](#getting-some-unique-tokens) tells how to get them.66This feature is best demonstrated in action using our NFT wallet. First, you need to have some Unique and Re-Fungible
67tokens. [This section](#getting-some-unique-tokens) tells how to get them.
4568
461. Open the [NFT Wallet](https://uniqueapps.usetech.com/#/nft)691. Open the [NFT Wallet](https://uniqueapps.usetech.com/#/nft)
472. Search for collection called "Artwork". Search can be done either by collection name or collection ID (which is 2).702. Search for collection called "Artwork". Search can be done either by collection name or collection ID (which is 2).
483. Click on "+ Add collection" in search results. The collection will appear under "My collections"713. Click on "+ Add collection" in search results. The collection will appear under "My collections"
494. Expand the "Artwork" collection and see that you own a token with a partial balance724. Expand the "Artwork" collection and see that you own a token with a partial balance
505. Transfer the token to some other address: Click "Transfer token" and enter address and the amount. Amount should be entered as decimal fraction. For example "0.01" to transfer 1/100th part of the token. 735. Transfer the token to some other address: Click "Transfer token" and enter address and the amount. Amount should be
74 entered as decimal fraction. For example "0.01" to transfer 1/100th part of the token.
516. Observe that your balance decreased by the amount you entered.756. Observe that your balance decreased by the amount you entered.
5276
53#### The Hard Way77#### The Hard Way
84 fraction: 1,000108 fraction: 1,000
85 }109 }
86 ],110 ],
87 Data: 111 Data:
88}112}
89```113```
90114
91The Owner field contains a list of owners with the fractions they own. The fractions are represented as fixed point decimals. The number of decimal points in this fraction is determined by collection properties. For example, in the Artwork collection this property is equal to 4. The owned fraction is then determined as `fraction` divided by 10^DecimalPoints, i.e. 10,000 in this case.115The Owner field contains a list of owners with the fractions they own. The fractions are represented as fixed point
116decimals. The number of decimal points in this fraction is determined by collection properties. For example, in the
117Artwork collection this property is equal to 4. The owned fraction is then determined as `fraction` divided by
11810^DecimalPoints, i.e. 10,000 in this case.
92119
935. Staying in Chain State, select "nft" - "colection"1205. Staying in Chain State, select "nft" - "colection"
946. Input "2" and click "+"1216. Input "2" and click "+"
957. Observe the following structure returned. It tells that collection is ReFungible and DecimalPoints field is equal to 4.1227. Observe the following structure returned. It tells that collection is ReFungible and DecimalPoints field is equal
123 to 4.
96124
97```125```
98{126{
111139
112### Off-Chain Schema to store token image URLs140### Off-Chain Schema to store token image URLs
113141
114This feature is best demonstrated in action using our NFT wallet. First, you need to have some Unique and Re-Fungible tokens. [This section](#getting-some-unique-tokens) tells how to get them.142This feature is best demonstrated in action using our NFT wallet. First, you need to have some Unique and Re-Fungible
143tokens. [This section](#getting-some-unique-tokens) tells how to get them.
115144
1161. Open the [NFT Wallet](https://uniqueapps.usetech.com/#/nft)1451. Open the [NFT Wallet](https://uniqueapps.usetech.com/#/nft)
1172. Search for collection called "Artwork". Search can be done either by collection name or collection ID (which is 2).1462. Search for collection called "Artwork". Search can be done either by collection name or collection ID (which is 2).
1183. Expand "Artwork" collection1473. Expand "Artwork" collection
1194. Click on the image to zoom in. 1484. Click on the image to zoom in.
1205. Right-click on the image and select "Open Image in New Tab"1495. Right-click on the image and select "Open Image in New Tab"
1216. Note the image URL:1506. Note the image URL:
151
122```152```
123https://ipfs-gateway.usetech.com/ipfs/QmUSv64cUmL2m44QYkUFWmH89qykC8VLPFwjhpeAScjejS/image1.jpg153https://ipfs-gateway.usetech.com/ipfs/QmUSv64cUmL2m44QYkUFWmH89qykC8VLPFwjhpeAScjejS/image1.jpg
124``` 154```
155
1257. Open [Chain State](https://uniqueapps.usetech.com/#/chainstate).1567. Open [Chain State](https://uniqueapps.usetech.com/#/chainstate).
1268. Select "nft" - "colection"1578. Select "nft" - "colection"
1279. Input "2" and click "+"1589. Input "2" and click "+"
12810. Scroll down:15910. Scroll down:
160
129```161```
130 ],162 ],
131 TokenPrefix: ARTu0000,163 TokenPrefix: ARTu0000,
135 UnconfirmedSponsor: 5C4hrfjw9DjXZTzV3MwzrrAr9P1MJhSrvWGWqi1eSuyUpnhM167 UnconfirmedSponsor: 5C4hrfjw9DjXZTzV3MwzrrAr9P1MJhSrvWGWqi1eSuyUpnhM
136}168}
137```169```
13811. Observe the field called `OffchainSchema`. This field defines the URL schema that is used to contruct token URLs based on the token ID. In this particular example, the {id} template variable is replaced with token id 1, which results in the proper image URL.
139170
17111. Observe the field called `OffchainSchema`. This field defines the URL schema that is used to contruct token URLs
172 based on the token ID. In this particular example, the {id} template variable is replaced with token id 1, which
173 results in the proper image URL.
174
140### New economic models175### New economic models
141176
142This feature is best demonstrated when you own a SubstraPunk character. Please proceed with the demonstration, and then come back after you claim one.177This feature is best demonstrated when you own a SubstraPunk character. Please proceed with the demonstration, and then
178come back after you claim one.
143179
1441. Create a new address in Polkadot{.js} extension. We need an address that has zero balance in Unique tokens. Let's call it "ZERO BALANCE" address.1801. Create a new address in Polkadot{.js} extension. We need an address that has zero balance in Unique tokens. Let's
181 call it "ZERO BALANCE" address.
1452. Open the [NFT Wallet](https://uniqueapps.usetech.com/#/nft)1822. Open the [NFT Wallet](https://uniqueapps.usetech.com/#/nft)
1463. Search for collection called "SubstraPunks" (partial search also works, so you can just type "punk" and hit Enter)1833. Search for collection called "SubstraPunks" (partial search also works, so you can just type "punk" and hit Enter)
1474. Add collection1844. Add collection
1485. Expand substrapunks collection and transfer your PNK token to your "ZERO BALANCE" address.1855. Expand substrapunks collection and transfer your PNK token to your "ZERO BALANCE" address.
1496. Now select your "ZERO BALANCE" address in the drop-down list and repeat searching and adding the collection for this address.1866. Now select your "ZERO BALANCE" address in the drop-down list and repeat searching and adding the collection for this
187 address.
1507. Transfer token back to your main address. Observe that despite the zero balance, the transfer is successful.1887. Transfer token back to your main address. Observe that despite the zero balance, the transfer is successful.
151189
152### White Lists and Public Mint Permission190### White Lists and Public Mint Permission
153191
154We did not complete these features in time by Hackusama deadline, but because they are important for security of the network, we completed them after the deadline anyway. They can be seen in branch [feature/white_list](https://github.com/usetech-llc/nft_parachain/tree/feature/white_list). Here are the permalinks to essential functions:192We did not complete these features in time by Hackusama deadline, but because they are important for security of the
193network, we completed them after the deadline anyway. They can be seen in branch
194[feature/white_list](https://github.com/usetech-llc/nft_parachain/tree/feature/white_list). Here are the permalinks to
195essential functions:
155196
156[white_lists](https://github.com/usetech-llc/nft_parachain/blob/b7c59f0085ed2bc1922e937adf68ef4174a8ba36/pallets/nft/src/lib.rs#L659)197[white_lists](https://github.com/usetech-llc/nft_parachain/blob/b7c59f0085ed2bc1922e937adf68ef4174a8ba36/pallets/nft/src/lib.rs#L659)
157198
163204
164All features of the NFT Wallet were already demonstrated previously:205All features of the NFT Wallet were already demonstrated previously:
165206
166* Enables adding favorite collections207- Enables adding favorite collections
167* Shows tokens owned208- Shows tokens owned
168* Allows NFT and Re-Fungible transfers209- Allows NFT and Re-Fungible transfers
169* Shows Re-Fungible Balances210- Shows Re-Fungible Balances
170* Shows Token Images211- Shows Token Images
171212
172## Our version of AppsUI213## Our version of AppsUI
173214
174The UI was also mainly demonstrated. We only need to show some configuration that happens behind the scenes:215The UI was also mainly demonstrated. We only need to show some configuration that happens behind the scenes:
175216
176### Loads appropriate custom API types217### Loads appropriate custom API types
218
1771. Open the [NFT Wallet Developer Settings](https://uniqueapps.usetech.com/#/settings/developer)2191. Open the [NFT Wallet Developer Settings](https://uniqueapps.usetech.com/#/settings/developer)
1782. Observe that Custom UI types are already in place2202. Observe that Custom UI types are already in place
179221
191233
192[Demonstration](https://github.com/usetech-llc/nft_unity/blob/master/src/DemoApplication/readme.md)234[Demonstration](https://github.com/usetech-llc/nft_unity/blob/master/src/DemoApplication/readme.md)
193235
194
195## SubstraPunks Game236## SubstraPunks Game
196237
197[Project Description](https://github.com/usetech-llc/substrapunks/blob/master/README.md)238[Project Description](https://github.com/usetech-llc/substrapunks/blob/master/README.md)
198239
199First, you will need some Unique balance. [This section](#getting-some-unique-tokens) tells how to get the TestNet currency.240First, you will need some Unique balance. [This section](#getting-some-unique-tokens) tells how to get the TestNet
241currency.
200242
2011. Open this [SubstraPunks Game](https://ipfs-gateway.usetech.com/ipns/QmaMtDqE9nhMX9RQLTpaCboqg7bqkb6Gi67iCKMe8NDpCE/) IPFS link2431. Open this [SubstraPunks Game](https://ipfs-gateway.usetech.com/ipns/QmaMtDqE9nhMX9RQLTpaCboqg7bqkb6Gi67iCKMe8NDpCE/)
244 IPFS link
2022. Find a character you like that still has red background. Red indicates that the character was not yet claimed by anyone.2452. Find a character you like that still has red background. Red indicates that the character was not yet claimed by
246 anyone.
2033. Allow access for Polkadot{.js} to this site2473. Allow access for Polkadot{.js} to this site
2044. Click "Claim" button2484. Click "Claim" button
2055. Select the account that has some Unique balance2495. Select the account that has some Unique balance
2066. Click "Claim" again, sign transaction, and wait until it mines. 2506. Click "Claim" again, sign transaction, and wait until it mines.
207251
208Let's make a pause here: You were just demonstrated how the integration between smart contracts and NFT Pallet works. This is what we've been previously talking about [here](#integration-between-smart-contracts-and-nft-pallet)252Let's make a pause here: You were just demonstrated how the integration between smart contracts and NFT Pallet works.
253This is what we've been previously talking about [here](#integration-between-smart-contracts-and-nft-pallet)
209254
210The source code of the generic smart contract is located in [smart_contract](https://github.com/usetech-llc/nft_parachain/tree/dev/smart_contract/ink-types-node-runtime) folder. But to demonstrate smart contracts in practice we created additional [Claim Contract](https://github.com/usetech-llc/substrapunks/tree/master/smart_contract) to implement claiming functionality in this game. 255The source code of the generic smart contract is located in
256[smart_contract](https://github.com/usetech-llc/nft_parachain/tree/dev/smart_contract/ink-types-node-runtime) folder.
257But to demonstrate smart contracts in practice we created additional
258[Claim Contract](https://github.com/usetech-llc/substrapunks/tree/master/smart_contract) to implement claiming
259functionality in this game.
211260
212Here is how Claiming works: Claim Contract owns all characters in the game initially. Player sends a transaction calling the method claim:261Here is how Claiming works: Claim Contract owns all characters in the game initially. Player sends a transaction calling
262the method claim:
263
213```264```
214fn claim(&mut self, collection_id: u64, item_id: u64, new_owner: AccountId)265fn claim(&mut self, collection_id: u64, item_id: u64, new_owner: AccountId)
215```266```
216267
217Inside the method `claim` there is a call made to NFT pallet to transfer the token that is being claimed to the player:268Inside the method `claim` there is a call made to NFT pallet to transfer the token that is being claimed to the player:
269
218```270```
219runtime_calls::transfer(collection_id, item_id, new_owner);271runtime_calls::transfer(collection_id, item_id, new_owner);
220```272```
221273
2227. Follow the link to [NFT Wallet](https://uniqueapps.usetech.com/#/nft)2747. Follow the link to [NFT Wallet](https://uniqueapps.usetech.com/#/nft)
2238. Search for "SubstraPunks" collection, add it2758. Search for "SubstraPunks" collection, add it
2249. Expand the collection and find your character in there!2769. Expand the collection and find your character in there!
22510. Now you can try transfers and test the [economic model](#new-economic-models), the last thing we put off until a SubstraPunks character is claimed.27710. Now you can try transfers and test the [economic model](#new-economic-models), the last thing we put off until a
226278 SubstraPunks character is claimed.
227279
228