123# NFT Parachain45## Project Description67The NFT Pallet is the core of NFT functionality. Like ERC-721 standard in Ethereum ecosystem, this pallet provides the8basement for creating collections of unique non-divisible things, also called Non Fungible Tokens (NFTs), minting NFT of9a given Collection, and managing their ownership.1011The pallet also enables storing NFT properties. Though (according to ERC-721) NFT properties belong to logic of a12concrete application that operates a Collection, so purposefully the NFT Tracking Module does not have any knowledge13about properties except their byte size leaving application logic out to be controlled by Smart Contracts.1415The NFT Chain also provides:1617- Smart Contracts Pallet and example smart contract that interacts with NFT Runtime18- ERC-1155 Functionality (currently PoC as Re-Fungible tokens, i.e. items that are still unique, but that can be split19 between multiple users)20- Variety of economic options for dapp producers to choose from to create freemium games and other ways to attract21 users. As a step one, we implemented an economic model when a collection sponsor can be set to pay for collection22 Transfer transactions.2324Wider NFT Ecosystem (most of it was developed during Hackusama):2526- [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)2930Please see our [walk-thorugh instructions](doc/hackusama_walk_through.md) to try everything out!3132## Hackusama Update3334During the Kusama Hackaphon the following changes were made:3536- Enabled Smart Contracts Pallet37- Enabled integration between Smart Contracts and NFT Pallet (required special edition of RC4 Substrate version)38- Fixed misc. bugs in NFT Pallet39- 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 Mode42 - Off-Chain Schema to store token image URLs43 - Alternative economic model44 - White Lists and Public Mint Permission45- Use example: [SubstraPunks Game](https://github.com/usetech-llc/substrapunks), fully hosted on IPFS and NFT Testnet46 Blockchain.4748## Application Development4950If you are building an application that operates NFT tokens, use [this document](doc/application_development.md).5152## Building5354Building NFT chain requires special versions of Rust and toolchain. We don't use the most recent versions of everything55so that we can keep the builds stable.56571. Install Rust:5859```bash60curl https://sh.rustup.rs -sSf | sh61sudo apt-get install libssl-dev pkg-config libclang-dev clang62```63642. Remove all installed toolchains with `rustup toolchain list` and `rustup toolchain uninstall <toolchain>`.65663. Install Rust Toolchain 1.44.0:6768```bash69rustup install 1.44.070```71724. Make it default (actual toochain version may be different, so do a `rustup toolchain list` first)7374```bash75rustup toolchain list76rustup default 1.44.0-x86_64-unknown-linux-gnu77```78795. Install nightly toolchain and add wasm target for it:8081```bash82rustup toolchain install nightly-2020-05-0183rustup target add wasm32-unknown-unknown --toolchain nightly-2020-05-01-x86_64-unknown-linux-gnu84```85866. Build:8788```bash89cargo build90```9192## Run9394You can start a development chain with:9596```bash97cargo run -- --dev98```99100Detailed logs may be shown by running the node with the following environment variables set:101`RUST_LOG=debug RUST_BACKTRACE=1 cargo run -- --dev`.102103If you want to see the multi-node consensus algorithm in action locally, then you can create a local testnet with two104validator nodes for Alice and Bob, who are the initial authorities of the genesis chain that have been endowed with105testnet units. Give each node a name and expose them so they are listed on the Polkadot106[telemetry site](https://telemetry.polkadot.io/#/Local%20Testnet). You'll need two terminal windows open.107108We'll start Alice's substrate node first on default TCP port 30333 with her chain database stored locally at109`/tmp/alice`. The bootnode ID of her node is `QmQZ8TjTqeDj3ciwr93EJ95hxfDsb9pEYDizUAbWpigtQN`, which is generated from110the `--node-key` value that we specify below:111112```bash113cargo run -- \114 --base-path /tmp/alice \115 --chain=local \116 --alice \117 --node-key 0000000000000000000000000000000000000000000000000000000000000001 \118 --telemetry-url ws://telemetry.polkadot.io:1024 \119 --validator120```121122In the second terminal, we'll start Bob's substrate node on a different TCP port of 30334, and with his chain database123stored locally at `/tmp/bob`. We'll specify a value for the `--bootnodes` option that will connect his node to Alice's124bootnode ID on TCP port 30333:125126```bash127cargo run -- \128 --base-path /tmp/bob \129 --bootnodes /ip4/127.0.0.1/tcp/30333/p2p/QmQZ8TjTqeDj3ciwr93EJ95hxfDsb9pEYDizUAbWpigtQN \130 --chain=local \131 --bob \132 --port 30334 \133 --telemetry-url ws://telemetry.polkadot.io:1024 \134 --validator135```136137Additional CLI usage options are available and may be shown by running `cargo run -- --help`.138139## UI custom types140141```142{143 "Schedule": {144 "version": "u32",145 "put_code_per_byte_cost": "Gas",146 "grow_mem_cost": "Gas",147 "regular_op_cost": "Gas",148 "return_data_per_byte_cost": "Gas",149 "event_data_per_byte_cost": "Gas",150 "event_per_topic_cost": "Gas",151 "event_base_cost": "Gas",152 "call_base_cost": "Gas",153 "instantiate_base_cost": "Gas",154 "dispatch_base_cost": "Gas",155 "sandbox_data_read_cost": "Gas",156 "sandbox_data_write_cost": "Gas",157 "transfer_cost": "Gas",158 "instantiate_cost": "Gas",159 "max_event_topics": "u32",160 "max_stack_height": "u32",161 "max_memory_pages": "u32",162 "max_table_size": "u32",163 "enable_println": "bool",164 "max_subject_len": "u32"165 },166 "CollectionMode": {167 "_enum": {168 "Invalid": null,169 "NFT": "u32",170 "Fungible": "u32",171 "ReFungible": "(u32, u32)"172 }173 },174 "NftItemType": {175 "Collection": "u64",176 "Owner": "AccountId",177 "Data": "Vec<u8>"178 },179 "Ownership": {180 "owner": "AccountId",181 "fraction": "u128"182 },183 "ReFungibleItemType": {184 "Collection": "u64",185 "Owner": "Vec<Ownership<AccountId>>",186 "Data": "Vec<u8>"187 },188 "CollectionType": {189 "Owner": "AccountId",190 "Mode": "CollectionMode",191 "Access": "u8",192 "DecimalPoints": "u32",193 "Name": "Vec<u16>",194 "Description": "Vec<u16>",195 "TokenPrefix": "Vec<u8>",196 "CustomDataSize": "u32",197 "OffchainSchema": "Vec<u8>",198 "Sponsor": "AccountId",199 "UnconfirmedSponsor": "AccountId"200 },201 "RawData": "Vec<u8>",202 "Address": "AccountId",203 "LookupSource": "AccountId",204 "Weight": "u64"205}206```