123# NFT Parachain45## Project Description67The 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.89The 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 controller by Smart Contracts.1011The NFT Chain also provides:1213* Smart Contracts Pallet and example smart contract that interacts with NFT Runtime14* ERC-1155 Functionality (currently PoC as Re-Fungible tokens)15* Variety of economic options for dapp producers to choose from to create freemium games and other ways to attract users16* Solutions that allow non-blockchain developers to quickly deploy dApps for mass markets17* Interoperability that allows reaching much bigger audiences18* Scalability on par with non-blockhcain solutions1920## Kusama Hackaphon Update2122During the Kusama Hackaphon the following changes were made:23* Enabled Smart Contracts Pallet24* Enabled integration between Smart Contracts and NFT Pallet (required special edition of RC4 Substrate version)25* Fixed misc. bugs in NFT Pallet26* Deployed NFT TestNet. Public node available at wss://unique.usetech.com, custom UI types - see below in this README.27* New Features:28 * Re-Fungible Token Mode29 * Off-Chain Schema to store token image URLs30 * Alternative economic model31 * White Lists and Public Mint Permission32* Use example: [SubstraPunks Game](https://github.com/usetech-llc/substrapunks), fully hosted on IPFS and NFT Testnet Blockchain.3334## Application Development3536If you are building an application that operates NFT tokens, use [this document](doc/application_development.md).3738## Building3940Building 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.41421. Install Rust:4344```bash45curl https://sh.rustup.rs -sSf | sh46sudo apt-get install libssl-dev pkg-config libclang-dev clang47```48492. Remove all installed toolchains with `rustup toolchain list` and `rustup toolchain uninstall <toolchain>`.50513. Install Rust Toolchain 1.44.0:5253```bash54rustup install 1.44.055```56574. Make it default (actual toochain version may be different, so do a `rustup toolchain list` first)58```bash59rustup toolchain list60rustup default 1.44.0-x86_64-unknown-linux-gnu61```62635. Install nightly toolchain and add wasm target for it:6465```bash66rustup toolchain install nightly-2020-05-0167rustup target add wasm32-unknown-unknown --toolchain nightly-2020-05-01-x86_64-unknown-linux-gnu68```69706. Build:71```bash72cargo build73```7475## Run7677You can start a development chain with:7879```bash80cargo run -- --dev81```8283Detailed logs may be shown by running the node with the following environment variables set: `RUST_LOG=debug RUST_BACKTRACE=1 cargo run -- --dev`.8485If 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.8687We'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:8889```bash90cargo run -- \91 --base-path /tmp/alice \92 --chain=local \93 --alice \94 --node-key 0000000000000000000000000000000000000000000000000000000000000001 \95 --telemetry-url ws://telemetry.polkadot.io:1024 \96 --validator97```9899In 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:100101```bash102cargo run -- \103 --base-path /tmp/bob \104 --bootnodes /ip4/127.0.0.1/tcp/30333/p2p/QmQZ8TjTqeDj3ciwr93EJ95hxfDsb9pEYDizUAbWpigtQN \105 --chain=local \106 --bob \107 --port 30334 \108 --telemetry-url ws://telemetry.polkadot.io:1024 \109 --validator110```111112Additional CLI usage options are available and may be shown by running `cargo run -- --help`.113114115## UI custom types116```117{118 "Schedule": {119 "version": "u32",120 "put_code_per_byte_cost": "Gas",121 "grow_mem_cost": "Gas",122 "regular_op_cost": "Gas",123 "return_data_per_byte_cost": "Gas",124 "event_data_per_byte_cost": "Gas",125 "event_per_topic_cost": "Gas",126 "event_base_cost": "Gas",127 "call_base_cost": "Gas",128 "instantiate_base_cost": "Gas",129 "dispatch_base_cost": "Gas",130 "sandbox_data_read_cost": "Gas",131 "sandbox_data_write_cost": "Gas",132 "transfer_cost": "Gas",133 "instantiate_cost": "Gas",134 "max_event_topics": "u32",135 "max_stack_height": "u32",136 "max_memory_pages": "u32",137 "max_table_size": "u32",138 "enable_println": "bool",139 "max_subject_len": "u32"140 },141 "CollectionMode": {142 "_enum": {143 "Invalid": null,144 "NFT": "u32",145 "Fungible": "u32",146 "ReFungible": "(u32, u32)"147 }148 },149 "NftItemType": {150 "Collection": "u64",151 "Owner": "AccountId",152 "Data": "Vec<u8>"153 },154 "Ownership": {155 "owner": "AccountId",156 "fraction": "u128"157 },158 "ReFungibleItemType": {159 "Collection": "u64",160 "Owner": "Vec<Ownership<AccountId>>",161 "Data": "Vec<u8>"162 },163 "CollectionType": {164 "Owner": "AccountId",165 "Mode": "CollectionMode",166 "Access": "u8",167 "DecimalPoints": "u32",168 "Name": "Vec<u16>",169 "Description": "Vec<u16>",170 "TokenPrefix": "Vec<u8>",171 "CustomDataSize": "u32",172 "OffchainSchema": "Vec<u8>",173 "Sponsor": "AccountId",174 "UnconfirmedSponsor": "AccountId"175 },176 "RawData": "Vec<u8>",177 "Address": "AccountId",178 "LookupSource": "AccountId",179 "Weight": "u64"180}181```