@@ -21,29 +21,29 @@ icons:
21
21
22
22
## What are we building?
23
23
24
- We are going to build on-chain NFTs, that have different Tiers ( and prices) .
24
+ We are going to build on-chain NFTs, that have different Tiers and prices.
25
25
26
26
In the previous lesson, we talked about NFTs and their use cases. If we can use
27
- an NFT to login to a web page, or to access a service, we can try to use them to
28
- differentiate different levels or categories in said service. Think of some
29
- streaming services out there ( Netflix, Disney+, etc) . Some have different levels
30
- of access depending on your subscription. We want to let users access different
31
- services depending on the NFT they mint/ own.
27
+ an NFT to login to a web page, or to access a service, we can use them to
28
+ differentiate between different levels or categories in that service. Think of some
29
+ streaming services out there such as Netflix, Disney+, etc. Some have different levels
30
+ of access depending on the subscription. We want to let users access different
31
+ services depending on the NFT they mint and own.
32
32
33
33
![ 1_diagram.png] ( /assets/lessons/3/1_diagram.png )
34
34
35
35
## First things first 👷♂️
36
36
37
- Before we start coding, we need to create our project. We are going to follow
37
+ Before we start coding, we need to create our project template . We are going to follow
38
38
the same steps as in previous lessons. Using our package manager (npm, yarn,
39
39
etc) we create a Hardhat project and remove unnecessary files.
40
40
41
41
If you’ve done our previous lesson, it’s the exact same process. Make a note of
42
- remembering these steps and what they do, for they are going to be used a lot in
42
+ remembering these steps and what they do, for we will use them a lot in
43
43
the future.
44
44
45
- Let’s ` cd ` into our D_D Academy projects folder, and create a folder for our
46
- NFT project:
45
+ Let’s first open a console and cd into our ` d_d_academy ` folder, or create it
46
+ first if you don't have it. Then let's create a folder for our NFT project:
47
47
48
48
``` bash
49
49
# # (OPTIONAL) create a folder for our D_D Academy projects
@@ -81,12 +81,13 @@ ok for us. Here's what mine asked me:
81
81
✔ Do you want to install this sample project' s dependencies with npm (@nomicfoundation/hardhat-toolbox)? (Y/n) · y
82
82
```
83
83
84
- - **Hardhat project root** → The folder where we want to create the project
84
+ - **Hardhat project root** → Hit enter (this is the folder where we want to create the project)
85
85
- **Do you want to add a .gitignore?** → Select ' y ' . If you are patient to
86
86
finish the lesson, you' ll learn what it' s for
87
87
- **Do you want to install this sample project' s dependencies with npm (…)?** →
88
88
Select ' y' . These are packages (programs) that our project needs to be able to
89
- run.
89
+ run. It will show the progress and several Warning messages that are normal .
90
+ If you get any Error messages, that' s different story.
90
91
91
92
<ContentCallout emoji=' 💡' size=' md' variant=' info' >
92
93
The project asked us to install `@nomicfoundation/hardhat-toolbox` in the
@@ -140,25 +141,25 @@ contract TierNFT {
140
141
}
141
142
```
142
143
143
- Now that we have our License, the version of solidity we will be using and the
144
- contract set up, we can add the logic and the state .
144
+ Now that we have our License, the version of solidity we are using and the
145
+ contract set up, we can add the logic and the variables we need to store .
145
146
146
147
## What do we need?
147
148
148
- As we are creating tiers (or categories/levels) for our NFTs, we need to store
149
- information about tiers on our contracts.
149
+ As we are creating tiers for the categories of our NFTs, we need to also store
150
+ information about tiers in our contracts.
150
151
151
152
Let’s write our smart contract within four steps. We will try to go step by
152
153
step.
153
154
154
155
### Inheriting OpenZeppelin ERC721 and adding a Mint Function
155
156
156
157
Let’s get started with a simple contract. We will inherit OpenZeppelin ERC721
157
- contract again .
158
+ contract like we did last time .
158
159
159
160
```solidity
160
- // SPDX-License-Identifier: UNLICENSED
161
- pragma solidity 0.8.11 ;
161
+ // SPDX-License-Identifier: MIT
162
+ pragma solidity 0.8.12 ;
162
163
163
164
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
164
165
@@ -170,16 +171,16 @@ contract TierNFT is ERC721 {
170
171
}
171
172
```
172
173
173
- We have a constructor on our contract. We need to have this constructor as we
174
- are inheriting ERC721 from OpenZeppelin implementation. If we didn’t have the
174
+ We have a constructor in our contract. We need to have this constructor as we
175
+ are inheriting ERC721 from the OpenZeppelin implementation. If we didn’t have the
175
176
constructor then the compiler would have thrown us errors.
176
177
177
178
Now let’s go ahead and add a mint function to our contract. We will add a
178
179
function that only uses `_safeMint`
179
180
180
181
```solidity
181
- // SPDX-License-Identifier: UNLICENSED
182
- pragma solidity 0.8.11 ;
182
+ // SPDX-License-Identifier: MIT
183
+ pragma solidity 0.8.12 ;
183
184
184
185
import ' @openzeppelin / contracts/ token/ ERC721/ ERC721.sol '
185
186
@@ -201,13 +202,13 @@ contract TierNFT is ERC721 {
201
202
202
203
### Adding Tiers and Using Them in the Mint Function
203
204
204
- Now it’s time for us to add our tiers. Just as we explained before each tiers
205
- will have different values as the service subscription . Now let’s go ahead and
205
+ Now it’s time for us to add our tiers. Just as we explained before each tier
206
+ will have a value that represents the service description . Now let’s go ahead and
206
207
add the tiers and assign their values.
207
208
208
209
```solidity
209
- // SPDX-License-Identifier: UNLICENSED
210
- pragma solidity 0.8.11 ;
210
+ // SPDX-License-Identifier: MIT
211
+ pragma solidity 0.8.12 ;
211
212
212
213
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
213
214
@@ -236,11 +237,8 @@ contract TierNFT is ERC721 {
236
237
}
237
238
````
238
239
239
- We have added three types of tiers such as `Basic` , `Medium` and `Premium` . We
240
- assigned their values also.
241
-
242
- The mapping `mapping(uint256 => uint256) public tokenTier;` will store the tiers
243
- that we select with our msg values.
240
+ We have added `Basic` , `Medium` and `Premium` as our tiers and assigned their
241
+ values. We store what tier each NFT hold in `mapping(uint256 => uint256) public tokenTier;`.
244
242
245
243
Now we need to modify our mint function for the tier NFTs:
246
244
@@ -266,21 +264,19 @@ Now we need to modify our mint function for the tier NFTs:
266
264
}
267
265
```
268
266
269
- With ` msg.value ` we are storing the tiers we are selecting. We are telling the
270
- mint function to select tiers based on the amount of value we have. If we don’t
271
- have enough value for our tier 0 then we will get a message mentioning us, "Not
267
+ We tell the mint function to select tiers based on the amount of value it received. If we don’t
268
+ have enough value for tier 0 we will get a message telling us, "Not
272
269
enough value for the minimum Tier".
273
270
274
- But if we have enough value then we can select the value we want otherwise our
275
- function will pick the possible tier value we can acquire with the amount we
276
- have.
271
+ But if we have enough value, we can select the value we want, otherwise the
272
+ function will choose tier for us, based on what we can afford.
277
273
278
274
<br/>
279
275
<details>
280
276
<summary>**View full code here**</summary>
281
277
```solidity
282
- // SPDX-License-Identifier: UNLICENSED
283
- pragma solidity 0.8.11 ;
278
+ // SPDX-License-Identifier: MIT
279
+ pragma solidity 0.8.12 ;
284
280
285
281
import ' @openzeppelin / contracts/ token/ ERC721/ ERC721.sol '
286
282
@@ -322,24 +318,23 @@ contract TierNFT is ERC721 {
322
318
323
319
### Create a (simple) tokenURI function
324
320
325
- When we inherited ERC721 contract, we also got a function for `tokenURI` where
326
- we can store anything that we want. It can be an image, video or anything that
327
- we want. With the help of the OpenZeppelin’s ERC721 contract we have the ability
328
- to define **a base path** for creating an unique URI which adds the token ID
329
- towards the end.
321
+ When we inherited ERC721 contract, it gave us a function for `tokenURI` where
322
+ we can store an image, a video and lots more. With the help of the OpenZeppelin’s
323
+ ERC721 contract we have the ability to define **a base path** for creating an
324
+ unique URI which adds the token ID at the end of it.
330
325
331
326
```solidity
332
- // Place this next to the other imports at the top:
327
+ // Place this under the other imports at the top:
333
328
import "@openzeppelin/contracts/utils/Base64.sol";
334
329
import "@openzeppelin/contracts/utils/Strings.sol";
335
330
````
336
331
337
- We imported `Base64` which will help us to encode the tokenURI so that it
338
- returns the JSON file we need for our tier NFTs.
332
+ We imported `Base64.sol ` which encodes the tokenURI so that it returns the JSON
333
+ file we need for our tier NFTs.
339
334
340
- Remember how we talked about having token ID towards the end of the unique URI?
335
+ Remember how we talked about having token ID at the end of the unique URI?
341
336
342
- To do that, we would need to import `Strings` which will be able to write our
337
+ To do that, we need to import `Strings.sol ` which will be able to write our
343
338
tokenID in a string inside the JSON file.
344
339
345
340
For this lesson we won’t be creating a separate JSON file. We will write it
@@ -390,10 +385,10 @@ Let’s break it down for us to understand.
390
385
NFT doesn' t exist.
391
386
- `imageSVG` is a placeholder for our image and we will deal with it a bit
392
387
later.
393
- - ` Base64.encode ` is for encoding the JSON in Base64 so browsers can translate
394
- that into a file ( the same way e-mail carry attached files inside them) .
395
- - ` string( abi.encodePacked () ) ` concatenates string the string in similar way,
396
- which we did during our previous lesson.
388
+ - `Base64.encode ` is for encoding the JSON into Base64 so browsers can translate
389
+ it into a file much in the same way as a file attached to an email .
390
+ - `string( abi.encodePacked () )` concatenates the string in similar way,
391
+ as in our previous lesson.
397
392
398
393
This is the JSON format of our metadata :
399
394
@@ -404,10 +399,10 @@ This is the JSON format of our metadata:
404
399
' "}'
405
400
```
406
401
407
- The part ` data:image/svg+xml;base64 ` tells the browser that the part following
408
- the comma is a string of text written in Base64, (image/svg…) so the browsers
402
+ The part ` data:image/svg+xml;base64 ` tells the browser that follows
403
+ the comma is a string of text written in Base64, so the browser
409
404
can decode it back into our SVG file format. Just as an example, if our
410
- collection ` TierNFT ` , and the TokenID was ` 3 ` , our JSON would end up look
405
+ collection ` TierNFT ` , and the TokenID were ` 3 ` , our JSON would end up look
411
406
something like this:
412
407
413
408
``` solidity
@@ -422,8 +417,8 @@ something like this:
422
417
<details >
423
418
<summary >** here’s the updated code** </summary >
424
419
``` solidity
425
- // SPDX-License-Identifier: UNLICENSED
426
- pragma solidity 0.8.11 ;
420
+ // SPDX-License-Identifier: MIT
421
+ pragma solidity 0.8.12 ;
427
422
428
423
import '@openzeppelin/contracts/token/ERC721/ERC721.sol'
429
424
import '@openzeppelin/contracts/utils/Base64.sol'
@@ -491,10 +486,9 @@ uint256) public tokenTier;
491
486
</details>
492
487
<br/>
493
488
494
- ### Complete TokenURI function (With our SVG!)
489
+ ### Complete TokenURI function with our SVG
495
490
496
- We did a bunch of things with our contract but now the time has come for us to
497
- create the incredible SVG we want.
491
+ We did a bunch of things with our contract and now we're going to tell you what and SVG is.
498
492
499
493
Add these lines right next to the other constants defined for the tiers:
500
494
@@ -553,8 +547,8 @@ trait types.
553
547
<details >
554
548
<summary >** View updated code** </summary >
555
549
``` solidity
556
- // SPDX-License-Identifier: UNLICENSED
557
- pragma solidity 0.8.11 ;
550
+ // SPDX-License-Identifier: MIT
551
+ pragma solidity 0.8.12 ;
558
552
559
553
import '@openzeppelin/contracts/token/ERC721/ERC721.sol'
560
554
import '@openzeppelin/contracts/utils/Base64.sol'
@@ -700,8 +694,8 @@ Now let’s write our withdraw function.
700
694
<details >
701
695
<summary >** View the Full Contract Here** </summary >
702
696
``` solidity
703
- // SPDX-License-Identifier: UNLICENSED
704
- pragma solidity 0.8.11 ;
697
+ // SPDX-License-Identifier: MIT
698
+ pragma solidity 0.8.12 ;
705
699
706
700
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
707
701
import "@openzeppelin/contracts/access/Ownable.sol";
@@ -860,7 +854,7 @@ require('dotenv').config()
860
854
861
855
/** @type import('hardhat/config').HardhatUserConfig */
862
856
module .exports = {
863
- solidity: ' 0.8.11 ' ,
857
+ solidity: ' 0.8.12 ' ,
864
858
networks: {
865
859
mumbai: {
866
860
url: ' https://rpc-mumbai.maticvigil.com' ,
0 commit comments