NFT Phần 1 – Cách viết và triển khai NFT

Vinh Phan

Updated on:

Chào mọi người, bài viết trong series blockchain hôm nay sẽ giúp mọi người từ triển khai NFT lên mạng lưới ethereum, bài viết này chứa kiến thức lập trình nên mọi người cần biết một phần kiến thức về lập trình thì mới có thể hiểu rõ.
Mọi người có thể xem những bài viết dưới đây để có cái nhìn khái quát, sẽ hiểu rõ hơn cho bài viết này:

Blockchain là gì?
Smart contract – hợp đồng thông minh là gì?
Triển khai 1 token từ smart contract trên remix
Triển khai 1 token từ smart contract trên project

OK, bắt đầu thôi

Lời mở đầu

Với việc NFT đưa blockchain đến với công chúng, giờ đây là cơ hội tuyệt vời để bạn tự hiểu được bằng cách xuất bản hợp đồng NFT của riêng bạn (Mã thông báo ERC-721) trên chuỗi khối Ethereum!

Trong hướng dẫn này, mình sẽ hướng dẫn cách tạo và triển khai hợp đồng thông minh ERC-721 trên mạng thử nghiệm Sepolia bằng MetaMask, Solidity, Hardhat, Pinata và Alchemy (đừng lo lắng nếu bạn chưa hiểu bất kỳ điều nào trong số này có nghĩa là – mình sẽ sẽ giải thích điều đó khi đi vào chi tiết thôi).

KẾT NỐI VỚI MẠNG ETHEREUM

Có rất nhiều cách để thực hiện yêu cầu đối với chuỗi khối Ethereum, nhưng để mọi việc trở nên dễ dàng, chúng ta sẽ sử dụng tài khoản miễn phí trên Alchemy(mở trong tab mới), nền tảng nhà phát triển chuỗi khối và API cho phép chúng ta giao tiếp với Chuỗi Ethereum mà không cần phải chạy các nút của riêng chúng tôi.

Trong hướng dẫn này, mình cũng sẽ tận dụng các công cụ dành cho nhà phát triển của Alchemy để theo dõi và phân tích nhằm hiểu những gì đang diễn ra trong quá trình triển khai hợp đồng thông minh. Nếu bạn chưa có tài khoản Alchemy, bạn có thể đăng ký miễn phí tại đây

Tạo ứng dụng trong alchemy

Sau khi tạo tài khoản Alchemy, bạn có thể tạo khóa API bằng cách tạo một ứng dụng. Điều này sẽ cho phép chúng ta gửi yêu cầu tới mạng thử nghiệm Sepolia. Nếu bạn không quen với testnet, hãy xem hướng dẫn này.

Điều hướng đến trang “Create App” trong Bảng điều khiển của bạn bằng cách di chuột qua “Application” trong thanh điều hướng và nhấp vào “Create App”

triển khai nft

Nhập tên ứng dụng của bạn và đừng quên chọn mạng là sepolia nhé

Tạo một tài khoản trên ethereum

Bạn cần một tài khoản Ethereum để gửi và nhận giao dịch. Hãy sử dụng Metamask, ví ảo trong trình duyệt dùng để quản lý địa chỉ tài khoản Ethereum của bạn. Mình đã có bài viết về ví metamask rồi, bạn hãy xem lại nhé.

Bạn có thể tải xuống và tạo tài khoản Metamask miễn phí tại đây. Khi bạn đang tạo tài khoản hoặc nếu bạn đã có tài khoản, hãy đảm bảo chuyển sang “Mạng thử nghiệm Sepolia” ở phía trên bên phải.

triển khai nft

Thêm ETH cho mạng thử nghiệm sepolia

Để triển khai hợp đồng thông minh vào mạng thử nghiệm, sẽ cần một số Eth giả. Để nhận Eth, bạn có thể truy cập https://sepoliafaucet.com/ và nhập địa chỉ tài khoản ví metamask của bạn, sau đó nhấp vào “Send me ETH”. Có thể mất một thời gian để nhận được Eth giả của bạn do lưu lượng truy cập mạng. Bạn sẽ thấy Eth trong tài khoản Metamask của mình ngay sau đó!

Khởi tạo project

Đầu tiên, chúng ta cần tạo một thư mục cho dự án của mình.

mkdir my-nft
cd my-nft

Bây giờ chúng ta đang ở trong thư mục dự án, chúng ta sẽ sử dụng npm init để khởi tạo dự án. Nếu bạn chưa cài đặt npm, hãy làm theo các hướng dẫn sau (chúng tôi cũng sẽ cần Node.js vì vậy hãy tải xuống luôn!).

npm init # (or npm init --yes)

Việc bạn trả lời các câu hỏi cài đặt như thế nào thực sự không quan trọng, đây là cách chúng tôi đã thực hiện để tham khảo:

package name: (my-nft)
version: (1.0.0)
description: my-nft
entry point: (index.js)
test command:
git repository:
keywords:
author:
license: (ISC)

About to write to /Users/.../.../.../hello-world/package.json:

{
   "name": “my-nft,
   "version": "1.0.0",
   "description": "my-nft",
   "main": "index.js",
   "scripts": {
      "test": "echo \"Error: no test specified\" && exit 1"
   },
   "author": "",
   "license": "ISC"
}

Cài đặt HARDHAT

Hardhat là môi trường phát triển để biên dịch, triển khai, kiểm tra và gỡ lỗi phần mềm Ethereum của bạn. Nó giúp các nhà phát triển khi xây dựng hợp đồng thông minh và dApps cục bộ trước khi triển khai vào chuỗi trực tiếp.

npm install --save-dev hardhat

Tạo dự án với HARDHAT

Trong thư mục create-token, chạy lệnh sau:

npx hardhat

Sau đó, bạn sẽ thấy thông báo chào mừng và tùy chọn để chọn những gì bạn muốn làm. Chọn “tạo một hardhat.config.js trống”:

888    888                      888 888               888
888    888                      888 888               888
888    888                      888 888               888
8888888888  8888b.  888d888 .d88888 88888b.   8888b.  888888
888    888     "88b 888P"  d88" 888 888 "88b     "88b 888
888    888 .d888888 888    888  888 888  888 .d888888 888
888    888 888  888 888    Y88b 888 888  888 888  888 Y88b.
888    888 "Y888888 888     "Y88888 888  888 "Y888888  "Y888

👷 Welcome to Hardhat v2.0.11 👷‍

What do you want to do?
Create a sample project
Create an empty hardhat.config.js
Quit

Thao tác này sẽ tạo tệp hardhat.config.js cho chúng tôi, đây là nơi chúng ta sẽ chỉ định tất cả thiết lập cho dự án của mình.

Thêm folder vào project

Để giữ cho dự án của chúng ta được tổ chức, chúng ta sẽ tạo hai thư mục mới. Điều hướng đến thư mục gốc của dự án create-token bằng dòng lệnh và gõ

mkdir contracts
mkdir scripts

Contracts là nơi chúng tôi sẽ lưu giữ tệp mã hợp đồng thông minh my-nft của mình
Scripts/ là nơi chúng ta sẽ giữ các tập lệnh để triển khai và tương tác với hợp đồng của mình

Viết smart contract

Điều hướng đến thư mục contracts và tạo một tệp mới có tên MyNFT.sol

Dưới đây là mã hợp đồng thông minh NFT của chúng tôi, mã này dựa trên việc triển khai ERC-721 của thư viện OpenZeppelin. Sao chép và dán nội dung bên dưới vào tệp MyNFT.sol của bạn.

//Contract based on [https://docs.openzeppelin.com/contracts/3.x/erc721](https://docs.openzeppelin.com/contracts/3.x/erc721)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";

contract MyNFT is ERC721URIStorage, Ownable {
    using Counters for Counters.Counter;
    Counters.Counter private _tokenIds;

    constructor() ERC721("MyNFT", "NFT") {}

    function mintNFT(address recipient, string memory tokenURI)
        public onlyOwner
        returns (uint256)
    {
        _tokenIds.increment();

        uint256 newItemId = _tokenIds.current();
        _mint(recipient, newItemId);
        _setTokenURI(newItemId, tokenURI);

        return newItemId;
    }
}

Bởi vì đang kế thừa các lớp từ thư viện hợp đồng OpenZeppelin, nên trong dòng lệnh của bạn hãy chạy

npm install @openzeppelin/contracts 

để cài đặt thư viện vào thư mục

Giải thích qua về @openzeppelin

  • @openzeppelin/contracts/token/ERC721/ERC721.sol bao gồm việc triển khai tiêu chuẩn ERC-721 mà hợp đồng thông minh NFT của mình sẽ kế thừa. (Để trở thành NFT hợp lệ, hợp đồng thông minh của bạn phải triển khai tất cả các phương pháp của tiêu chuẩn ERC-721.)
  • @openzeppelin/contracts/utils/Counters.sol cung cấp các bộ đếm chỉ có thể tăng hoặc giảm một. Hợp đồng thông minh của mình sử dụng bộ đếm để theo dõi tổng số NFT được tạo ra và đặt ID duy nhất trên NFT mới của mình. (Mỗi NFT được tạo bằng hợp đồng thông minh phải được chỉ định một ID duy nhất—ở đây ID duy nhất của chúng tôi chỉ được xác định bằng tổng số NFT đang tồn tại. Ví dụ: NFT đầu tiên mà chúng tôi tạo ra bằng hợp đồng thông minh của mình có ID là “1, ” NFT thứ hai của chúng tôi có ID là “2”, v.v.)
  • @openzeppelin/contracts/access/Ownable.sol thiết lập kiểm soát quyền truy cập(mở trong tab mới) trên hợp đồng thông minh của mình, vì vậy chỉ chủ sở hữu hợp đồng thông minh (bạn) mới có thể đúc NFT. (Lưu ý, việc bao gồm kiểm soát quyền truy cập hoàn toàn là một tùy chọn. Nếu bạn muốn bất kỳ ai có thể đúc NFT bằng hợp đồng thông minh của mình, hãy xóa từ Có thể sở hữu ở dòng 10 và chỉ Chủ sở hữu ở dòng 17.)

Sau đó, mình sẽ có hợp đồng thông minh NFT tùy chỉnh, ngắn đến mức đáng ngạc nhiên – nó chỉ chứa bộ đếm, hàm tạo và một hàm duy nhất! Điều này là nhờ các hợp đồng OpenZeppelin kế thừa,l thực hiện hầu hết các phương pháp cần để tạo NFT, chẳng hạn như ownerOf trả về chủ sở hữu của NFT và transferFrom, chuyển quyền sở hữu NFT từ tài khoản này sang tài khoản khác.

Trong hàm tạo ERC-721, bạn sẽ nhận thấy có chuyển 2 chuỗi, “MyNFT” và “NFT”. Biến đầu tiên là tên của hợp đồng thông minh và biến thứ hai là ký hiệu của nó. Bạn có thể đặt tên cho từng biến này bất cứ điều gì bạn muốn!

Cuối cùng, chúng ta có chức năng mintNFT(người nhận địa chỉ, tokenURI bộ nhớ chuỗi) cho phép chúng ta đúc NFT! Bạn sẽ nhận thấy hàm này có hai biến:

  • string memory tokenURI: chỉ định địa chỉ sẽ nhận NFT mới được tạo của bạn
  • string memory tokenURI: là một chuỗi sẽ phân giải thành tài liệu JSON mô tả siêu dữ liệu của NFT. Siêu dữ liệu của NFT thực sự là thứ mang lại sự sống cho nó, cho phép nó có các thuộc tính có thể định cấu hình, chẳng hạn như tên, mô tả, hình ảnh và các thuộc tính khác. Trong phần 2 của hướng dẫn này, mình sẽ mô tả cách định cấu hình siêu dữ liệu này.

mintNFT gọi một số phương thức từ thư viện ERC-721 kế thừa và cuối cùng trả về một số đại diện cho ID của NFT mới được tạo.

Kết nối Metamask & Alchemy với dự án của bạn

Đầu tiên, cài đặt gói dotenv trong thư mục dự án của bạn:

npm install dotenv --save

Lấy thông tin từ alchemy

nft

.env của bạn sẽ trông như thế này:

API_URL = "https://eth-goerli.alchemyapi.io/v2/your-api-key"
PRIVATE_KEY = "your-metamask-private-key"

Cài đặt Ethers.js

Ethers.js là một thư viện giúp tương tác và đưa ra yêu cầu tới Ethereum dễ dàng hơn bằng cách gói các phương thức JSON-RPC tiêu chuẩn bằng các phương thức thân thiện với người dùng hơn.

Hardhat giúp việc tích hợp các Plugin để có thêm công cụ và chức năng mở rộng trở nên cực kỳ dễ dàng. Chúng tôi sẽ tận dụng plugin Ethers để triển khai hợp đồng (Ethers.js có một số phương pháp triển khai hợp đồng siêu rõ ràng).

Trong loại thư mục dự án của bạn:

npm install --save-dev @nomiclabs/hardhat-ethers "ethers@^5.0.0"

Cập nhật lại hardhat.config.js

Cập nhật hardhat.config.js của bạn trông như thế này:

/**
* @type import('hardhat/config').HardhatUserConfig
*/

require('dotenv').config();
require("@nomiclabs/hardhat-ethers");

const { API_URL, PRIVATE_KEY } = process.env;

module.exports = {
   solidity: "0.7.3",
   defaultNetwork:sepolia,
   networks: {
      hardhat: {},
      sepolia: {
         url: API_URL,
         accounts: [`0x${PRIVATE_KEY}`]
      }
   },
}

Biên soạn smart contract

Để đảm bảo mọi thứ vẫn hoạt động cho đến nay, hãy biên soạn hợp đồng của chúng ta. Tác vụ biên dịch là một trong những tác vụ hardhat được tích hợp sẵn.

npx hardhat compile

Viết kịch bản triển khai nFT

Bây giờ hợp đồng của chúng ta đã được viết và tệp cấu hình của chúng ta đã sẵn sàng, đã đến lúc viết tập lệnh triển khai hợp đồng.

Trong folder scripts, tạo file: deploy.js, thêm code sau:

async function main() {
  const MyNFT = await ethers.getContractFactory("MyNFT")

  // Start deployment, returning a promise that resolves to a contract object
  const myNFT = await MyNFT.deploy()
  await myNFT.deployed()
  console.log("Contract deployed to address:", myNFT.address)
}

main()
  .then(() => process.exit(0))
  .catch((error) => {
    console.error(error)
    process.exit(1)
  })

Triển khai smart contract

npx hardhat run scripts/deploy.js --network sepolia

Kết quả sẽ như thế này:

Contract deployed to address: 0xxxxxxxxxxxxxxxxxxxxxxx34xx243

Đến đây, bạn có thể lên sepolia testnet để kiểm tra hợp đồng của mình hoặc vào lại tài khoản alchemy của bạn để kiểm tra giao dịch

Kết thúc bài viết nhé mọi người, hi vọng mọi người có thể làm theo được.

Viết một bình luận