Tải bản đầy đủ (.pdf) (65 trang)

BÁO CÁO ĐỒ ÁN CUỐI KỲ MÔN HỌC CÁC CÔNG NGHỆ NỀN Đề tài XÂY DỰNG MARKETPLACE NFT

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (999.5 KB, 65 trang )

IE102.M21- Các cơng nghệ nền | Nhóm 4

ĐẠI HỌC QUỐC GIA THÀNH PHỐ HỒ CHÍ MINH
TRƯỜNG ĐẠI HỌC CƠNG NGHỆ THÔNG TIN
KHOA KHOA HỌC VÀ KỸ THUẬT THÔNG TIN

BÁO CÁO ĐỒ ÁN CUỐI KỲ
MÔN HỌC: CÁC CÔNG NGHỆ NỀN
Đề tài: XÂY DỰNG MARKETPLACE NFT
Lớp: IE102.M21 - Nhóm: 4
GVHD: ThS. Võ Tấn Khoa

Nhóm sinh viên thực hiện:
STT
1
2
3
4
5
6
7

MSSV
18520063
18521682
18521692
19521403
19521558
19521733
19521746


Tên
Bùi Quang Huy
Nguyễn Ngọc Thúy Vy
Nguyễn Phước Duy
Phan Đặng Tiến Dũng
Nguyễn Thị Huệ
Võ Thị Như Lài
Nguyễn Trúc Lân

□□Tp. Hồ Chí Minh, 05/2022 □□

1


IE102.M21- Các cơng nghệ nền | Nhóm 4

MỤC LỤC

MỤC LỤC

2

LỜI MỞ ĐẦU

4

CHƯƠNG 1: TỔNG QUAN VỀ ĐỀ TÀI

5


1.1 Lý do chọn đề tài

5

1.2 Yêu cầu của đề tài

5

1.3 Đối tượng

5

1.4 Phạm vi ứng dụng

5

1.5 Đặc điểm

5

1.6 Các module

6

1.7 Công cụ triển khai

6

CHƯƠNG 2: CƠ SỞ LÝ THUYẾT


7

2.1 Ngôn ngữ lập trình Solidity

7

2.2 Nền tảng Blockchain – Polygon (MATIC)

7

2.3 Tiêu chuẩn ERC-721

9

2.4 Frontend Frameworks

10

2.5 Ethereum Development Environment – Hardhat

11

2.6 Storage Platforms - IPFS

12

2.7 Ethereum Web Client Library - Ethers.js

12


CHƯƠNG 3: THIẾT KẾ HỆ THỐNG

13

3.1 Các thành phần

13

3.2 Các bước thực hiện

14

CHƯƠNG 4: CÀI ĐẶT MÔI TRƯỜNG

15

4.1 Tạo một ứng dụng Next.js

15

4.2 Cài đặt các dependencies cho ứng dụng

15

4.3 Cài đặt framework Tailwind

15

4.4 Cấu hình Hardhat


15
2


IE102.M21- Các cơng nghệ nền | Nhóm 4

CHƯƠNG 5: PHÂN TÍCH TRANG WEB

17

5.1 Smart contract

17

5.2 Màn hình trang chủ

21

5.3 Màn hình Sell NFT

27

5.4 Màn hình My NFTs

30

5.5 Màn hình Detail NFT

34


5.6 Màn hình Resell NFT

40

5.7 Màn hình Dashboard

42

5.8 Thanh Navbar (_app.js)

46

5.9 Login

48

5. 10 Thiết kế css

56

5. 11 API

59

CHƯƠNG 6: CÀI ĐẶT VÀ THỬ NGHIỆM

61

CHƯƠNG 6: NHẬN XÉT VÀ KẾT LUẬN


62

6.1 Kết quả đạt được

62

6.2 Ưu điểm

62

6.3 Nhược điểm

62

6.4 Hướng phát triển

62

TÀI LIỆU THAM KHẢO

63

PHÂN CHIA CÔNG VIỆC

64

3


IE102.M21- Các cơng nghệ nền | Nhóm 4


LỜI MỞ ĐẦU
NFT (Non-fungible token) là một tài sản số sử dụng công nghệ blockchain.
Làn sóng NFT phát triển mạnh mẽ trong thời gian gần đây và trở thành một trong
những nền tảng quan trọng của nền kinh tế tiền mã hóa. NFT đang được sử dụng
trong nhiều lĩnh vực như Nghệ thuật, Gaming, Metaverse, Collectible,… Cùng với
tiềm năng của NFT là nhu cầu tìm kiếm một nền tảng để có thể sở hữu, mua bán các
sản phẩm NFT với nhiều mục đích khác nhau được gọi là NFT Marketplace.
Trước nhu cầu đó, cùng với u cầu mơn học, nhóm chúng em quyết định chọn đề
tài Xây dựng NFT Marketplace.
Với đề tài và mơn học này, nhóm xin chân thành cảm ơn sự giúp đỡ tận tình
của Thầy Võ Tấn Khoa. Song, do cịn nhiều hạn chế đề tài nhóm xây dựng khơng
tránh khỏi những thiếu sót. Rất mong được thầy cơ và các bạn đóng góp ý kiến để
chương trình ngày càng được hoàn thiện.
Trân trọng cảm ơn!
 

4


IE102.M21- Các cơng nghệ nền | Nhóm 4

CHƯƠNG 1: TỔNG QUAN VỀ ĐỀ TÀI
1.1 Lý do chọn đề tài
NFT là tài sản mật mã được tạo trên công nghệ blockchain có mã nhận dạng duy
nhất và siêu dữ liệu, giúp chúng có thể phân biệt, khác biệt và hồn tồn duy nhất.
NFT là tài sản kỹ thuật số đại diện cho các tài sản trong thế giới thực như nghệ
thuật, âm nhạc, vật phẩm trong trò chơi và video được liên kết với bằng chứng
quyền sở hữu. 
Vì vậy NFT Marketplace ra đời để có thể người dùng có thể tạo, mua hoặc bán

NFT. Thị trường này cũng được sử dụng để lưu trữ, hiển thị hoặc hiển thị giao dịch
và tạo mã thông báo NFT hoặc bất kỳ tài sản kỹ thuật số nào. Đối với người dùng,
trải nghiệm thị trường NFT thuận tiện như một sàn giao dịch tiền điện tử.
1.2 Yêu cầu của đề tài 
- Nắm được các kiến thức cơ bản về smart contract, cách deploy một smart
contract,...
-Tạo ra một sàn giao dịch NFT có các chức năng cơ bản như:cửa sổ mua sắm,
ví, đăng ký tài khoản, tìm kiếm,...
1.3 Đối tượng
1.3.1 Guest: 
- Khách viếng thăm
- Xem thông tin sản phẩm cũng như các tin tức khác
- Đăng ký để kết nối với ví Metamask
1.3.2 User:
- Đã có tài khoản kết nối với ví Metamask
- Đặt mua sản phẩm
- Bán sản phẩm
1.4 Phạm vi ứng dụng
Người dùng có nhu cầu tạo, thu thập, sưu tầm, mua và bán các NFT để thu
lợi nhuận.
1.5 Đặc điểm 
Website được thiết kế với
- Giao diện hài hoà, thân thiện, giúp người dùng dễ dàng sử dụng.
- Trang chủ sẽ hiển thị danh sách các sản phẩm được bán.
- Khách hàng có thể dễ dàng tìm thấy thơng tin chi tiết các sản phẩm mà họ
quan tâm.
- Khách hàng có thể tìm kiếm sản phẩm.
- Có chức năng đăng ký và liên kết với ví Metamask
5



IE102.M21- Các cơng nghệ nền | Nhóm 4

1.6 Các module
1.6.1 Module sản phẩm
Các NFT được liệt kê trên thị trường phải hiển thị tất cả thông tin quan
trọng theo cách tối ưu hóa nhất: tên, giá, mơ tả, chủ sở hữu, phương thức
thanh toán, v.v. 
1.6.2 Module đăng nhập
Đăng nhập bằng cách liên kết với ví Metamask hiện có của khách hàng
vào NFT Marketplace.
1.6.3 Module tìm kiếm sản phẩm
Các sản phẩm tại trang chủ có thể được tìm kiếm để hiển thị ra sản phẩm
phù hợp nhất với yêu cầu khách hàng.
1.6.4 Module quản lý sản phẩm
Người dùng có thể cập nhật những sản phẩm mình đã mua và đã bán
trong danh mục sản phẩm của mình.
1.7 Cơng cụ triển khai
- IDE: Visual Studio Code
- Quản lý code: Github
- Quản lý công việc: Excel
- Trao đổi, liên lạc: Microsoft Team, Facebook

6


IE102.M21- Các cơng nghệ nền | Nhóm 4

CHƯƠNG 2: CƠ SỞ LÝ THUYẾT 
Tech stack:

● Programing Language - Solidity
● Blockchain Platform - Polygon (MATIC)
● NFT Standards EERC-721
● Front-end Frameworks
● Web application framework - Next.js
● CSS framework - CSS Tailwind
● Storage Platforms  - IPFS
● Ethereum Web Client Library - Ethers.js
2.1 Ngôn ngữ lập trình Solidity 
Solidity được biết đến là một ngơn ngữ lập trình hướng contract, được sử dụng
hầu hết trong smart contract (nâng cấp và tạo lập) thuộc hệ sinh thái Ethereum.
Solidity có các cú pháp và câu lệnh gần giống với các ngơn ngữ lập trình phổ biến
hiện nay (Java, C++, C#...). Ngơn ngữ Solidity có những ứng dụng vơ cùng quan
trọng đối với cơng nghệ Blockchain. Một ví dụ điển hình của cơng nghệ Blockchain
hiện nay chính là tiền điện tử. Nhờ có sự ra đời của ngơn ngữ lập trình Solidity, các
nhà lập trình có thể dễ dàng ứng dụng công nghệ Blockchain này vào các lĩnh vực
kinh tế và đời sống. 
2.2 Nền tảng Blockchain – Polygon (MATIC) 
Polygon (MATIC) là một platform hỗ trợ phát triển cơ sở hạ tầng và
giúp Ethereum mở rộng quy mơ hay cịn gọi là layer 2. Polygon (MATIC) hỗ trợ
tất cả các công cụ Ethereum hiện có cùng với các giao dịch nhanh hơn và rẻ hơn.
Polygon (MATIC) cố gắng giải quyết các vấn đề về khả năng mở rộng và khả
năng sử dụng trong khi không ảnh hưởng đến phân quyền, bảo mật và tận dụng
cộng đồng nhà phát triển, hệ sinh thái hiện có. Polygon là một giải pháp mở rộng
off/side chain cho các nền tảng hiện có để cung cấp khả năng mở rộng và trải
nghiệm người dùng vượt trội cho DApps/ chức năng người dùng. 
Tính năng chính và điểm nổi bật: 
Khả năng mở rộng: giao dịch nhanh, chi phí thấp và an tồn trên các
sidechain Polygon với độ chính xác đạt được trên chuỗi chính và Ethereum là
layer 1 base chain tương thích đầu tiên. 

Thơng lượng cao: đạt được lên đến 10.000 TPS trên một single
sidechain trên testnet nội bộ. Nhiều chuỗi sẽ được thêm vào để mở rộng quy mô
theo chiều ngang. 

7


IE102.M21- Các cơng nghệ nền | Nhóm 4

Trải nghiệm người dùng: mượt mà và dễ sử dụng từ chain chính đến
Polygon, ứng dụng di động gốc và SDK có hỗ trợ Wallet Connect. 
Bảo mật: những người vận hành Polygon chain, chính họ là những
người đóng vai trị quan trọng trong hệ thống PoS. 
Public Sidechains: Polygon sidechain về bản chất là công khai (so với
chuỗi DApp riêng lẻ), khơng được phép và có khả năng hỗ trợ nhiều giao thức. 
Kiến trúc Polygon 
Gồm 4 layer có thể kết hợp: Execution layer, Polygon networks layer,
Security layer, Ethereum layer. 
 

 
Hình 2.1 Kiến trúc 4 lớp của Polygon
Execution layer 
Layer này diễn giải và thực hiện các giao dịch đã được thỏa thuận và đưa vào
các blockchain của mạng Polygon (MATIC). Nó bao gồm hai lớp con: 

Mơi trường thực thi (triển khai máy ảo có thể cắm được) 

Logic thực thi (chức năng chuyển đổi trạng thái của mạng Polygon,
thường được viết dưới dạng hợp đồng thông minh Ethereum) 

Polygon networks layer 
Một tập hợp của các mạng blockchain có chủ quyền. Mỗi mạng phục vụ
cộng đồng tương ứng của nó, duy trì các chức năng như: 

Đối chiếu giao dịch 

Sự đồng thuận của nội bộ 

Sản xuất khối 
8


IE102.M21- Các cơng nghệ nền | Nhóm 4

Các mạng có thể sử dụng giao thức Polygon (MATIC) để kết nối với nhau và
trao đổi thông tin tùy ý. 
Security layer 
Một layer chuyên biệt, không bắt buộc phải quản lý một tập hợp các trình
xác thực và có thể kiểm tra định kỳ tính hợp lệ của bất kỳ chuỗi Polygon
(MATIC) nào với một khoản phí. Lớp này có thể được triển khai như một siêu
blockchain chạy song song với Ethereum, phụ trách các chức năng như: 

Quản lý trình xác thực (đăng ký/ hủy đăng ký, phần thưởng…) 

Xác thực Polygon Chain 
Lớp bảo mật là fully abstract và có thể có nhiều trường hợp, được thực hiện
bởi các thực thể khác nhau, có các đặc điểm khác nhau. Nó cũng có thể được
thực hiện trực tiếp trên Ethereum, trong trường hợp đó, các thợ đào Ethereum
thực hiện việc xác nhận. 
Ethereum layer 

Polygon chain có thể sử dụng Ethereum, blockchain lập trình an tồn nhất
trên thế giới, để lưu trữ và thực hiện bất kỳ thành phần quan trọng nào trong
logic của chúng. Layer này được triển khai dưới dạng một tập hợp các hợp đồng
thơng minh Ethereum, phụ trách các chức năng như: 

Tính chất cuối cùng/điểm kiểm tra 

Staking 

Giải quyết tranh chấp 

Chuyển tiếp thông tin 
2.3 Tiêu chuẩn ERC-721 
Tiêu chuẩn non-fungible token ERC-721 được viết bằng ngơn ngữ Solidity trên
chuỗi khối Ethereum và nó cho phép các nhà phát triển mã hóa quyền sở hữu bất kỳ
dữ liệu tùy ý nào. Đặc biệt, tiêu chuẩn này nhằm mục đích tạo ra các mã thơng báo
có thể hốn đổi cho nhau. Một ví dụ về hợp đồng ER-721 là của OpenZeppelin, cho
phép các nhà phát triển theo dõi các vật phẩm trong trò chơi của họ. 

9


IE102.M21- Các cơng nghệ nền | Nhóm 4

Hình 2.2 Mã thông báo ERC-721
2.4 Frontend Frameworks 
2.4.1 Next.js 
Next.js là một framework dùng để phát triển các ứng dụng React.
React là một framework của javascript để xây dựng frontend với nhiều ưu điểm
như chia nhỏ các phần của web, module hoá css, xử lý sự kiện…Tuy nhiên,

react chỉ phù hợp để render dữ liệu phía client, việc này ảnh hưởng rất lớn đến
SEO của website khi mà hầu hết những data mà google đánh index đều phải
được render ở server. 
Phân biệt giữa Serverside Rendering và Clientside Rendering 
Serverside Rendering

Clientside Rendering

Server trả về cho browser file CSR trả về file HTML gần như trống cùng với
HTML của trang đã được link tới file JS 
rendered 
Nội dung file HTML đã hoàn Đối với CSR, ta sẽ cần chờ tới khi tất cả các quá
chỉnh và được hiển thị ngay khi trình xây dựng Virtual DOM và gắn các sự kiện
nó được load về máy 
hồn thành đến khi Virtual DOM được chuyển
vào browser DOM để website có thể xem được. 
Bảng 2.1 So sánh Serverside rendering và Clientside rendering

10


IE102.M21- Các cơng nghệ nền | Nhóm 4

-

Để hỗ trợ việc render ở phía server cho React, các nhà phát triển đã tạo ra
Next.js. Next.js tích hợp nhiều tính năng như:  
- Pre-rendering, cả static generation (SSG) và server-side rendering (SSR),  
- Tách mã tự động để tải trang nhanh hơn, mỗi page chỉ load những gì cần
thiết cho page đó. Ví dụ khi render trang chủ thì những page khác sẽ không

được khởi tạo, như vậy trang chủ sẽ được load nhanh cho dù website của bạn
có cả 100 page 
- Hỗ trợ refresh page nhanh chóng ở mơi trường development 
- Hồn tồn có thể mở rộng 
2.4.2 CSS Tailwind 
Tailwind là một CSS framework giúp ta có thể nhanh chóng xây dựng giao diện
người dùng. Tailwind giúp xây dựng website một cách nhanh chóng nhất với các
thuộc tính CSS đã được gán thành những class riêng và khi dùng ta chỉ việc gọi ra
sử dụng.  
2.5 Ethereum Development Environment – Hardhat 
- Hardhat là một môi trường để biên dịch, triển khai, test và debug dapp
ethereum được phát triển trên nền tảng javascript. 
- Một số điểm tính năng nổi bật của Hardhat 
- Tích hợp mạng local Hardhat, dễ dàng chạy và debug code ngay trên local. 
- Debug dễ dàng hơn: Với Hardhat, chúng ta có thể debug code Solidity dễ
dàng hơn khi có thể console.log ra các biến (Solidity vốn ko hỗ trợ console.log) 
- Hệ thống plugin: Giúp developer có thể bổ sung chức năng, tùy vào từng dự
án cụ thể 
- Hỗ trợ TypeScript 
- So sánh Hardhat và Truffle 
Hardhat

Truffle

Tài liệu hướng dẫn rõ ràng và được cấu Có tài liệu hướng dẫn rõ ràng, nhiều tài
trúc tốt, phù hợp cho người mới 
liệu tham khảo trên các web, blog,
youtube… 
Hardhat có một cộng đồng rất sơi nổi Truffle có cộng đồng hùng mạnh và sôi
bao gồm các nhà phát triển blockchain nổi nhờ ra đời sớm hơn. 

và các thành viên cốt lõi của
framework. 
Hardhat có rất nhiều thư viện và plugin, Truffle cũng có plugin hoặc thư viện gọi
người dùng có thể tự tạo plugin cho là Box, người dùng cũng có thể tự tạo
mình. 
Box cho mình nhưng cách dùng phức tạp
hơn. 
11


IE102.M21- Các cơng nghệ nền | Nhóm 4

Mơi trường thử nghiệm linh hoạt hơn do Thử nghiệm không thể tương tác với
có thể tương tác trực tiếp với smart contract. 
contract. 
Bảng 2.2 So sánh Truffle và Hardhat
2.6 Storage Platforms - IPFS 
- IPFS là viết tắt của từ Interplanetary File System, một hệ thống tập tin phân
tán ngang hàng kết nối tất cả các thiết bị máy tính với nhau. Cụ thể hơn, nó sẽ
phân phối dữ liệu được lưu trữ theo hình thức P2P, hay cịn gọi là mạng ngang
hàng. 
- Trong đó, các hoạt động của IPFS chủ yếu dựa vào khả năng tính tốn băng
thơng của tất cả các máy tham gia chứ không tập trung vào một phần nhỏ các
máy chủ trung tâm như giao thức HTTP. 
- IPFS là mạng lưới chuyển phát nội dung hoàn toàn phi tập trung cho phép
quản lý và lưu trữ dữ liệu một cách linh hoạt. Mỗi máy tính tham gia trong mạng
lưới đảm nhận nhiệm vụ download và upload dữ liệu mà không cần sự can thiệp
của máy chủ trung tâm. 
- Đầu tiên mọi dữ liệu sẽ được mã hoá và được lưu dưới dạng mã hash (còn
gọi là đối tượng IPFS). Ý tưởng chủ đạo là nếu trình duyệt của bạn muốn truy

cập một trang nào đó trên IPFS thì chỉ cần đưa ra mã hash rồi mạng sẽ tìm máy
có lưu trữ dữ liệu khớp với mã hash và sau đó tải dữ liệu, trang đó về từ máy
tính đấy về cho bạn. 
- Mỗi máy tính tham gia trong mạng lưới của nó sẽ đảm nhận cả việc
download lẫn upload dữ liệu mà khơng cần có sự có mặt của một máy chủ trung
tâm. Tổng quan, cách hoạt động của IPFS sẽ có 2 phần chính: 
- Xác định tệp có địa chỉ nội dung (giá trị hash của tệp đó). 
- Tìm dữ liệu được lưu trữ và tải xuống: khi bạn có đoạn hash của file hay
trang cần tải, mạng sẽ tìm và connect tới máy tốt nhất để tải dữ liệu xuống
cho bạn. 
2.7 Ethereum Web Client Library - Ethers.js 
Ethers.js là một thư viện được viết bằng javascript giúp dapp tương tác được với
mạng Ethereum Blockchain. 
Các tính năng nổi bật Ethers.js gồm có: 
- Giữ private key ở client một cách an tồn.
- Import và export JSON wallets.
- Import và export ví theo chuẩn BIP 39.
- Hỗ trợ ABI, ABIv2 và Human-Readable ABI.

12


IE102.M21- Các cơng nghệ nền | Nhóm 4

- Kết nối với Ethereum nodes thông qua nhiều provider như JSON-RPC,
INFURA, Etherscan, Alchemy, Cloudflare, MetaMask ... 
- Hỗ trợ ENS.
- Nhẹ (88kb khi nén và 284kb khi không nén).
- Hỗ trợ TypeScript.
CHƯƠNG 3: THIẾT KẾ HỆ THỐNG


Hình 2.3 Sơ đồ thiết kế hệ thống
Các thành phần và kiến trúc của NFT Marketplace
3.1 Các thành phần
3.1.1 Các thành phần kiến trúc
- Trang web NFT Marketplace là một ứng dụng web nơi người dùng bán và
mua NFT. 
- Metamask là một ví điện tử cung cấp dịch vụ trực tuyến để lưu trữ các quỹ
kỹ thuật số.
- Siêu dữ liệu NFT là mô tả của tài sản kỹ thuật số được bán dưới dạng NFT,
cụ thể là tên, ngày tạo, thuộc tính, chủ sở hữu, v.v.
- IPFS  là một hệ thống lưu trữ dữ liệu tránh tiêu tốn điện năng lưu trữ tài sản
kỹ thuật số với siêu dữ liệu trên blockchain.
- Hợp đồng thông minh tạo ra một số nhận dạng duy nhất cho mỗi NFT. Các
hợp đồng thông minh cho thị trường NFT sử dụng tiêu chuẩn ERC-721 để
tạo các mã thông báo không thể thay thế, giúp phân biệt NFT với các mã
thông báo tiền điện tử có thể thay thế.
13


IE102.M21- Các cơng nghệ nền | Nhóm 4

-

Blockchain là một cơ sở dữ liệu phân tán lưu trữ thông tin về các giao dịch
NFT.
3.1.2 Công nghệ và dịch vụ của bên thứ ba
- Solidity là một ngơn ngữ lập trình cho các hợp đồng thông minh.
- Infura.io là một dịch vụ cung cấp quyền truy cập vào chuỗi khối Ethereum.
3.2 Các bước thực hiện 

- Người dùng tải lên nội dung kỹ thuật số và điền vào siêu dữ liệu
- Siêu dữ liệu đã được xác minh và gửi tới bộ lưu trữ dữ liệu bên ngoài
- Một mã nhận dạng duy nhất được chỉ định cho nội dung và một NFT được
tạo ra
- NFT được thêm vào blockchain

14


IE102.M21- Các cơng nghệ nền | Nhóm 4

CHƯƠNG 4: CÀI ĐẶT MÔI TRƯỜNG
4.1 Tạo một ứng dụng Next.js 
npx create-next-app nft-marketplace
4.2 Cài đặt các dependencies cho ứng dụng
cd nft-marketplace
npm install ethers hardhat @nomiclabs/hardhat-waffle /
ethereum-waffle chai @nomiclabs/hardhat-ethers /
web3modal @openzeppelin/contracts ipfs-http-client /
axios
4.3 Cài đặt framework Tailwind
Thiết lập dependencies
npm install -D tailwindcss@latest postcss@latest autoprefixer@latest
Tạo các tệp cấu hình cần thiết để Tailwind hoạt động với Next.js
npx tailwindcss init -p
Cấu hình lại đường dẫn trong file tailwind.config.js
/* tailwind.config.js */
module.exports = {
  content: [
    "./pages/**/*.{js,ts,jsx,tsx}",

    "./components/**/*.{js,ts,jsx,tsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}
Xóa mã trong styles/ global.css và cập nhật tailwind vào ứng dụng
@tailwind base;
@tailwind components;
@tailwind utilities;
4.4 Cấu hình Hardhat
Khởi tạo một mơi trường phát triển Hardhat mới từ gốc của dự án
npx hardhat
? What do you want to do? Create a basic sample project
15


IE102.M21- Các cơng nghệ nền | Nhóm 4

?Hardhat project root: <Choose default path>
(Lưu ý: Nếu gặp lỗi khi tham chiếu đến tệp README.md, xóa README.md
và chạy lại npx hardhat.)
Sau khi chạy lệnh, một số tệp và thư mục mới sẽ được thêm vào thư mục gốc
hardhat.config.js - Chứa toàn bộ thiết lập Hardhat của ứng dụng (cấu hình,
plugin và các tác vụ tùy chỉnh).
scripts - Một thư mục chứa một tập lệnh có tên là sample-script.js sẽ triển
khai hợp đồng thông minh khi ứng dụng được thực thi.
test - Một thư mục chứa một tập lệnh thử nghiệm mẫu.
contracts - Một thư mục chứa một hợp đồng thông minh Solidity.

Cấu hình lại tệp hardhat.config.js  
/* hardhat.config.js */
require("@nomiclabs/hardhat-waffle")
module.exports = {
  defaultNetwork: "hardhat",
  networks: {
    hardhat: {
      chainId: 1337
    },
// kết nối với munbai testnet
//  unused configuration commented out for now
//  mumbai: {
//    url: "",
//    accounts: [process.env.privateKey]
//  }
  },
  solidity: {
    version: "0.8.4",
    settings: {
      optimizer: {
        enabled: true,
        runs: 200
      }
    }
  }
}

16



IE102.M21- Các cơng nghệ nền | Nhóm 4

17


IE102.M21- Các cơng nghệ nền | Nhóm 4

CHƯƠNG 5: PHÂN TÍCH TRANG WEB
5.1 Smart contract
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "@openzeppelin/contracts/utils/Counters.sol";
import
"@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
 

import "hardhat/console.sol";
 

contract NFTMarketplace is ERC721URIStorage {
    using Counters for Counters.Counter;
    Counters.Counter private _tokenIds;
    Counters.Counter private _itemsSold;
 

    uint256 listingPrice = 0.025 ether;
    address payable owner;
 


    mapping(uint256 => MarketItem) private idToMarketItem;
 

    struct MarketItem {
      uint256 tokenId;
      address payable seller;
      address payable owner;
      uint256 price;
      bool sold;
    }
 

    event MarketItemCreated (
      uint256 indexed tokenId,
      address seller,
      address owner,
      uint256 price,
      bool sold
    );
 

18


IE102.M21- Các cơng nghệ nền | Nhóm 4

    constructor() ERC721("Metaverse Tokens", "METT") {
      owner = payable(msg.sender);
    }
 


    /* Cập nhật giá niêm yết của hợp đồng*/
    function updateListingPrice(uint _listingPrice) public payable {
      require(owner == msg.sender, "Only marketplace owner can update listing
price.");
      listingPrice = _listingPrice;
    }
 

    /* Trả về giá niêm yết của hợp đồng*/
    function getListingPrice() public view returns (uint256) {
      return listingPrice;
    }
 

    /* Tạo Token và thêm nó vào marketplace */
    function createToken(string memory tokenURI, uint256 price) public payable
returns (uint) {
      _tokenIds.increment();
      uint256 newTokenId = _tokenIds.current();
 

      _mint(msg.sender, newTokenId);
      _setTokenURI(newTokenId, tokenURI);
      createMarketItem(newTokenId, price);
      return newTokenId;
    }
 

    function createMarketItem(

      uint256 tokenId,
      uint256 price
    ) private {
      require(price > 0, "Price must be at least 1 wei");
      require(msg.value == listingPrice, "Price must be equal to listing price");
 

      idToMarketItem[tokenId] =  MarketItem(
        tokenId,
        payable(msg.sender),

19


IE102.M21- Các cơng nghệ nền | Nhóm 4

        payable(address(this)),
        price,
        false
      );
 

      _transfer(msg.sender, address(this), tokenId);
      emit MarketItemCreated(
        tokenId,
        msg.sender,
        address(this),
        price,
        false
      );

    }
 

    /* cho phép ai đó bán lại token mà họ đã mua*/
    function resellToken(uint256 tokenId, uint256 price) public payable {
      require(idToMarketItem[tokenId].owner == msg.sender, "Only item owner can
perform this operation");
      require(msg.value == listingPrice, "Price must be equal to listing price");
      idToMarketItem[tokenId].sold = false;
      idToMarketItem[tokenId].price = price;
      idToMarketItem[tokenId].seller = payable(msg.sender);
      idToMarketItem[tokenId].owner = payable(address(this));
      _itemsSold.decrement();
 

      _transfer(msg.sender, address(this), tokenId);
    }
 

    /* Tạo chức năng mua bán một marketplace item */
    /* Chuyển quyền sở hữu item, cũng như tiền giữa các bên tham gia mua bán*/
    function createMarketSale(
      uint256 tokenId
      ) public payable {
      uint price = idToMarketItem[tokenId].price;
      address seller = idToMarketItem[tokenId].seller;
      require(msg.value == price, "Please submit the asking price in order to complete
the purchase");

20



IE102.M21- Các cơng nghệ nền | Nhóm 4

      idToMarketItem[tokenId].owner = payable(msg.sender);
      idToMarketItem[tokenId].sold = true;
      idToMarketItem[tokenId].seller = payable(address(0));
      _itemsSold.increment();
      _transfer(address(this), msg.sender, tokenId);
      payable(owner).transfer(listingPrice);
      payable(seller).transfer(msg.value);
    }
 

    /* Trả lại tất cả các item chưa bán được trên market*/
    function fetchMarketItems() public view returns (MarketItem[] memory) {
      uint itemCount = _tokenIds.current();
      uint unsoldItemCount = _tokenIds.current() - _itemsSold.current();
      uint currentIndex = 0;
 

      MarketItem[] memory items = new MarketItem[](unsoldItemCount);
      for (uint i = 0; i < itemCount; i++) {
        if (idToMarketItem[i + 1].owner == address(this)) {
          uint currentId = i + 1;
          MarketItem storage currentItem = idToMarketItem[currentId];
          items[currentIndex] = currentItem;
          currentIndex += 1;
        }
      }

      return items;
    }
 

    /* Chỉ trả lại các item mà người dùng đã mua*/
    function fetchMyNFTs() public view returns (MarketItem[] memory) {
      uint totalItemCount = _tokenIds.current();
      uint itemCount = 0;
      uint currentIndex = 0;
 

      for (uint i = 0; i < totalItemCount; i++) {
        if (idToMarketItem[i + 1].owner == msg.sender) {
          itemCount += 1;
        }
      }

21


IE102.M21- Các cơng nghệ nền | Nhóm 4

 

      MarketItem[] memory items = new MarketItem[](itemCount);
      for (uint i = 0; i < totalItemCount; i++) {
        if (idToMarketItem[i + 1].owner == msg.sender) {
          uint currentId = i + 1;
          MarketItem storage currentItem = idToMarketItem[currentId];
          items[currentIndex] = currentItem;

          currentIndex += 1;
        }
      }
      return items;
    }
 

    /* Chỉ trả lại các item mà người dùng đã liệt kê*/
    function fetchItemsListed() public view returns (MarketItem[] memory) {
      uint totalItemCount = _tokenIds.current();
      uint itemCount = 0;
      uint currentIndex = 0;
 

      for (uint i = 0; i < totalItemCount; i++) {
        if (idToMarketItem[i + 1].seller == msg.sender) {
          itemCount += 1;
        }
      }
 

      MarketItem[] memory items = new MarketItem[](itemCount);
      for (uint i = 0; i < totalItemCount; i++) {
        if (idToMarketItem[i + 1].seller == msg.sender) {
          uint currentId = i + 1;
          MarketItem storage currentItem = idToMarketItem[currentId];
          items[currentIndex] = currentItem;
          currentIndex += 1;
        }
      }

      return items;
    }
}

22


IE102.M21- Các cơng nghệ nền | Nhóm 4

5.2 Màn hình trang chủ
5.2.1 Màn hình và chức năng
● Màn hình:

Hình 5.1 Màn hình trang chủ.


Chức năng:

STT Thành phần

Mơ tả

1

Infinity Marketplace

Tên của trang

2


Thanh Navbar

Điều hướng đến các trang: Home, Sell NFT, My
NFTs, Dashboard 

3

Thơng tin ví người Hiển thị số tiền và địa chỉ tài khoản người dùng
dùng

4

Danh sách sản phẩm

Hiển thị những sản phẩm đang bán trên sàn

5

Nút Buy

Mua và thanh toán sản phẩm thơng qua ví metamask

6

Nút Detail

Xem chi tiết thơng tin sản phẩm
Bảng 5.1 Bảng chức năng trang chủ.

5.2.2 Code

/* pages/index.js */
import { ethers } from "ethers";
import { useEffect, useState } from "react";
import axios from "axios";
23


IE102.M21- Các cơng nghệ nền | Nhóm 4

import Web3Modal from "web3modal";
import { useRouter } from "next/router";
 

import { marketplaceAddress } from "../config";
 

import
NFTMarketplace
"../artifacts/contracts/NFTMarketplace.sol/NFTMarketplace.json";
export default function Home() {
  const [searchTerm, setSearchTerm] = useState("");
  const [nfts, setNfts] = useState([]);
  const [loadingState, setLoadingState] = useState("not-loaded");
  useEffect(() => {
    loadNFTs();
  }, []);

from

 


  const router = useRouter();
  useEffect(() => {
    loadNFTs();
  }, []);
 

  async function loadNFTs() {
   /* tạo một nhà cung cấp chung và truy vấn các item chưa bán được trên                                   
market*/
    const provider = new ethers.providers.JsonRpcProvider(
     " />    );
    const contract = new ethers.Contract(
      marketplaceAddress,
      NFTMarketplace.abi,
      provider
    );
    const data = await contract.fetchMarketItems();
 

    /*
     *  map over các item được trả về từ smart contract and format
     *  chúng được biết như là fetch token metadata
     */
    const items = await Promise.all(

24


IE102.M21- Các cơng nghệ nền | Nhóm 4


      data.map(async (i) => {
        const tokenUri = await contract.tokenURI(i.tokenId);
        const meta = await axios.get(tokenUri);
        let price = ethers.utils.formatUnits(i.price.toString(), "ether");
        let item = {
          price,
          tokenId: i.tokenId.toNumber(),
          seller: i.seller,
          owner: i.owner,
          image: meta.data.image,
          name: meta.data.name,
          description: meta.data.description,
          tokenURI: tokenUri,
        };
        return item;
      })
    );
    setNfts(items);
    setLoadingState("loaded");
  }
  async function buyNft(nft) {
    /* cần người dùng đăng ký vào giao dịch, vì vậy sẽ sử dụng Web3Provider và
đăng ký*/
    const web3Modal = new Web3Modal();
    const connection = await web3Modal.connect();
    const provider = new ethers.providers.Web3Provider(connection);
    const signer = provider.getSigner();
    const contract = new ethers.Contract(
      marketplaceAddress,

      NFTMarketplace.abi,
      signer
    );
 

    /* người dùng sẽ được nhắc thanh toán các thủ tục yêu cầu để hoàn thành giao
dịch*/
    const price = ethers.utils.parseUnits(nft.price.toString(), "ether");
    const transaction = await contract.createMarketSale(nft.tokenId, {
      value: price,
25


×