From 8d558f86234e8f0eb31b1461838b27c179782177 Mon Sep 17 00:00:00 2001 From: biancabuzea200 <34369307+biancabuzea200@users.noreply.github.com> Date: Fri, 24 Nov 2023 21:23:47 +1000 Subject: [PATCH] Add Create an NFT Collection using LSP8 tutorial (#715) * create an NFT Collection using LSP8 * Update docs/learn/smart-contract-developers/create-nft-collection.md Co-authored-by: Felix Hildebrandt <61689369+fhildeb@users.noreply.github.com> * Update docs/learn/smart-contract-developers/create-nft-collection.md Co-authored-by: Felix Hildebrandt <61689369+fhildeb@users.noreply.github.com> * Update docs/learn/smart-contract-developers/create-nft-collection.md Co-authored-by: Felix Hildebrandt <61689369+fhildeb@users.noreply.github.com> * Update docs/learn/smart-contract-developers/create-nft-collection.md Co-authored-by: Felix Hildebrandt <61689369+fhildeb@users.noreply.github.com> * integrate feedback * minor improvements * move `hardhat.config.ts` part to getting started * add web3 version * add explanation for `_LSP4_TOKEN_TYPE_DATA_KEY` * minor fixes * implement feedback * Improve NFT collection guide --------- Co-authored-by: Felix Hildebrandt <61689369+fhildeb@users.noreply.github.com> Co-authored-by: Hugo Masclet --- .../create-nft-collection.md | 151 ++++++++++++++++++ .../getting-started.md | 62 ++++++- 2 files changed, 209 insertions(+), 4 deletions(-) create mode 100644 docs/learn/smart-contract-developers/create-nft-collection.md diff --git a/docs/learn/smart-contract-developers/create-nft-collection.md b/docs/learn/smart-contract-developers/create-nft-collection.md new file mode 100644 index 0000000000..af2c08d459 --- /dev/null +++ b/docs/learn/smart-contract-developers/create-nft-collection.md @@ -0,0 +1,151 @@ +--- +sidebar_label: '🗃 Create an NFT Collection' +sidebar_position: 4 +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Create an NFT Collection Using LSP8 + +This tutorial explains how to create a collection of unique Digital Assets based on the [LSP8-Identifiable-Digital-Asset](../../standards/tokens/LSP8-Identifiable-Digital-Asset.md) standard. + +:::note + +This guide builds on top of a Hardhat project using TypeScript as described in the [Getting Started](../smart-contract-developers/getting-started.md) section. + +::: + +:::info + +⌨️ The full code of this example can be found in the 👾 [LUKSO-Hardhat-template](https://github.com/CJ42/LUKSO-Hardhat-template) repository. + +::: + +## Setup + +To create your custom contract based on the [LUKSO smart contracts](../../contracts/introduction.md), you will need the [`@lukso/lsp-smart-contracts`](../../tools/lsp-smart-contracts/getting-started.md) library. Go ahead and add it to your project: + +```shell +npm install @lukso/lsp-smart-contracts +``` + +## Create the Smart Contracts + +When creating smart contracts representing digital assets on LUKSO, you will need to specify the token type and data keys for the 📄 [LSP4 Digital Asset Metadata](../../standards/tokens/LSP4-Digital-Asset-Metadata) that will be stored in the 🗂️ [ERC725Y](../../standards/lsp-background/erc725.md#erc725y-generic-data-keyvalue-store) storage of the Digital Asset. There are three different token types: + +- `0` = Token +- `1` = NFT +- `2` = Collection + +```solidity title="contracts/TokenTypes.sol" +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.4; + +bytes32 constant _LSP4_TOKEN_TYPE_DATA_KEY = 0xe0261fa95db2eb3b5439bd033cda66d56b96f92f243a8228fd87550ed7bdfdb3; + +enum TokenType { + TOKEN, + NFT, + COLLECTION +} +``` + +The data key value `0xe026...` is the keccak256 hash of the word `LSP4TokenType` as defined by the [LSP2 - ERC725Y JSON Schema](../../standards/generic-standards/lsp2-json-schema.md#singleton) standard. + +After defining the type of the asset and its 🗂️ [ERC725 data key](../../standards/lsp-background/erc725.md#erc725y-generic-data-keyvalue-store) you can create a custom 🌄 [LSP8 Identfiable Digital Asset Collection](../../standards/tokens/LSP8-Identifiable-Digital-Asset.md) that extends [LSP8Mintable](../../contracts/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8Mintable.md) so that new assets can be created within the smart contract. + +```solidity title="contracts/Example3/BasicNFTCollection.sol" +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.4; + +// modules +import { + LSP8Mintable +} from "@lukso/lsp-smart-contracts/contracts/LSP8IdentifiableDigitalAsset/presets/LSP8Mintable.sol"; + +// constants +import { + _LSP8_TOKENID_TYPE_NUMBER +} from "@lukso/lsp-smart-contracts/contracts/LSP8IdentifiableDigitalAsset/LSP8Constants.sol"; +import {_LSP4_TOKEN_TYPE_DATA_KEY, TokenType} from "../TokenTypes.sol"; + +contract BasicNFTCollection is LSP8Mintable { + constructor( + string memory nftCollectionName, + string memory nftCollectionSymbol, + address contractOwner + ) + LSP8Mintable( + nftCollectionName, // NFT collection name + nftCollectionSymbol, // NFT collection symbol + contractOwner, // owner of the NFT contract (the address that controls it, sets metadata, can transfer the ownership of the contract) + _LSP8_TOKENID_TYPE_NUMBER // type of NFT/ tokenIds + ) + { + // set token type + _setData(_LSP4_TOKEN_TYPE_DATA_KEY, abi.encode(TokenType.COLLECTION)); + } +} +``` + +## Deploy the Smart Contract + +The contract is ready, it's time to deploy it. You can easily do it with hardhat deployment script. + + + +```js title="scripts/deploy.ts" +import { ethers } from "hardhat"; + +import {BasicNFTCollection, BasicNFTCollection__factory} from "../typechain-types"; + +async function deployLSP8Collection() { + const accounts = await ethers.getSigners(); + const deployer = accounts[0]; + + const nftCollection: BasicNFTCollection = await new BasicNFTCollection__factory(deployer).deploy( + "NFT Collection Name", // collection name + "NFT", // collection symbol + deployer.address + ); + const nftCollectionAddress = await nftCollection.getAddress() + console.log("NFT Collection deployed to:", nftCollectionAddress) + console.log("Check the block explorer to see the deployed contract") +} + +deployLSP8Collection().catch((error) => { + console.error(error); + process.exitCode = 1; +}); +``` + +If you get issues related to `typechain-types`, you need to generate the types with: + +``` +npx hardhat typechain +``` + + + +Finally, run the deploy script: + +```sh +npx hardhat run --network luksoTestnet scripts/deploy.ts +``` + +:::tip + +The [Create a deploy script](./create-lsp7-token#create-a-deploy-script.md) section of the Create LSP7 Token guide gives more details and information about how to deploy the contracts. + +::: + +## View your NFT Collection + +You can now use the contract address to check the deployment on the [testnet execution block explorer](https://explorer.execution.testnet.lukso.network/) + + + +## References + +- [BuildUP #2 | Create an NFT Collection using LSP7 or LSP8 (YouTube)](https://www.youtube.com/watch?v=DMpeMswK12w) diff --git a/docs/learn/smart-contract-developers/getting-started.md b/docs/learn/smart-contract-developers/getting-started.md index 80eb3f0c07..2e1e6fe738 100644 --- a/docs/learn/smart-contract-developers/getting-started.md +++ b/docs/learn/smart-contract-developers/getting-started.md @@ -10,8 +10,7 @@ Smart contract developer, welcome to the LUKSO documentation! The LUKSO ecosyste As LUKSO is an EVM-based Blockchain, all tools and tutorials for Ethereum also work well for LUKSO. The following tutorial will teach you how to: - set up a [Hardhat](https://hardhat.org/) installation (using TypeScript) -- install the [`@lukso/lsp-smart-contracts`](https://www.npmjs.com/package/@lukso/lsp-smart-contracts) package (using version 0.11.0-rc.1) -- create a basic [`LSP7DigitalAsset` (token)](../../standards/tokens/LSP7-Digital-Asset.md) contract +- install the [`@lukso/lsp-smart-contracts`](https://www.npmjs.com/package/@lukso/lsp-smart-contracts) package. - deploy it on [LUKSO Testnet](../../networks/testnet/parameters). If you need more low level information about our contracts, you can check the dedicated [contracts](../../contracts/introduction.md) section. @@ -22,7 +21,7 @@ Happy coding 🧙 The first thing to do is to [create a new Hardhat project](https://hardhat.org/hardhat-runner/docs/getting-started#quick-start) that will use TypeScript: -```bash title="Setup new hardhat project" +```bash mkdir lukso-app cd lukso-app npx hardhat @@ -38,7 +37,7 @@ To work in the best condition possible, we will install libraries that includes ```bash npm i -D dotenv -npm i -s @lukso/lsp-smart-contracts@0.11.0-rc.1 +npm i -s @lukso/lsp-smart-contracts@0.12.1 ``` Update your `package.json` with the following: @@ -71,3 +70,58 @@ UP_ADDR=0x... ``` We now have a base Hardhat setup that we can use to develop and deploy our smart contracts. + +## Get testnet LYXt + +To pay for the deployment fees, you need LYXt. You can request some from the [LUKSO Testnet faucet](https://faucet.testnet.lukso.network/) + +## Deploy your contracts on the LUKSO Testnet + +:::info + +By default, the deployment will be to your local network. If you want to deploy to the LUKSO Testnet, you will need to add the LUKSO Testnet network in your `hardhat.config.ts`. + +::: + +```js title="hardhat.config.ts" +// ... +import { NetworkUserConfig } from 'hardhat/types'; + +import * as dotenv from 'dotenv'; +dotenv.config(); + +// ... + +function getTestnetChainConfig(): NetworkUserConfig { + const config: NetworkUserConfig = { + url: 'https://rpc.testnet.lukso.network', + chainId: 4201, + }; + + if (process.env.PRIVATE_KEY !== undefined) { + config['accounts'] = [process.env.PRIVATE_KEY]; + } + + return config; +} + +// Edit the default config object so it matches this one: +const config: HardhatUserConfig = { + solidity: { + version: '0.8.19', + settings: { + optimizer: { + enabled: true, + runs: 200, + }, + }, + }, + typechain: { + outDir: 'typechain-types', + target: 'ethers-v6', + }, + networks: { + luksoTestnet: getTestnetChainConfig(), + }, +}; +```