Skip to content

Commit

Permalink
Add Create an NFT Collection using LSP8 tutorial (#715)
Browse files Browse the repository at this point in the history
* create an NFT Collection using LSP8

* Update docs/learn/smart-contract-developers/create-nft-collection.md

Co-authored-by: Felix Hildebrandt <[email protected]>

* Update docs/learn/smart-contract-developers/create-nft-collection.md

Co-authored-by: Felix Hildebrandt <[email protected]>

* Update docs/learn/smart-contract-developers/create-nft-collection.md

Co-authored-by: Felix Hildebrandt <[email protected]>

* Update docs/learn/smart-contract-developers/create-nft-collection.md

Co-authored-by: Felix Hildebrandt <[email protected]>

* 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 <[email protected]>
Co-authored-by: Hugo Masclet <[email protected]>
  • Loading branch information
3 people authored Nov 24, 2023
1 parent 6213085 commit 8d558f8
Show file tree
Hide file tree
Showing 2 changed files with 209 additions and 4 deletions.
151 changes: 151 additions & 0 deletions docs/learn/smart-contract-developers/create-nft-collection.md
Original file line number Diff line number Diff line change
@@ -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.

<!-- prettier-ignore-start -->

```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
```

<!-- prettier-ignore-end -->

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/)

<!-- TODO: add link to NFT marketplaces / dapp that can read such NFTs -->

## References

- [BuildUP #2 | Create an NFT Collection using LSP7 or LSP8 (YouTube)](https://www.youtube.com/watch?v=DMpeMswK12w)
62 changes: 58 additions & 4 deletions docs/learn/smart-contract-developers/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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
Expand All @@ -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:
Expand Down Expand Up @@ -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(),
},
};
```

0 comments on commit 8d558f8

Please sign in to comment.