Nhảy đến nội dung chính

Mint NFT

Trong hướng dẫn này bạn sẽ tìm hiểu làm thế nào để tạo NFT của riêng bạn một cách dễ dàng mà không cần phát triển bất cứ phần mềm nào, bằng cách sử dụng smart contract có sẵn và giải pháp lưu trữ phi tập trung là IPFS.

Tổng quan

Bài viết này sẽ hướng dẫn bạn cài đặt một NFT smart contract, và chỉ cho bạn cách build, testdeploy NFT contract này lên NEAR. Khi contract được deploy, bạn sẽ tìm hiểu cách mint non-fungible token từ các file media lưu trữ trên IPFS và xem chúng trong Wallet của bạn.

Điều kiện tiên quyết

Để hoàn thành tốt hướng dẫn này, bạn sẽ cần:

Wallet

Để lưu trữ các non-fungible token của mình, bạn cần một NEAR Wallet. Nếu chưa có account, bạn có thể dễ dàng tạo nó bằng cách làm theo các hướng dẫn này.

Tip: trong hướng dẫn này chúng ta sẽ sử dụng một wallet account trên testnet. Network testnet này miễn phí và không cần phải gửi tiền.

Khi bạn có Wallet account, bạn có thể nhấp vào tab Collectibles để xem danh sách tất cả các NFT của bạn:

Wallet

IPFS

InterPlanetary File System (IPFS) được biết đến như là một giao thức, một mạng ngang hàng (peer-to-peer) cho phép người dùng lưu trữ, chia sẻ dữ liệu trên một hệ thống tệp dữ liệu phân tán (distributed file system). IPFS sử dụng công nghệ content-addressing nhằm xác định tính duy nhất của từng file, trong một không gian toàn cục được hình thành bằng cách kết nối các thiết bị điện toán lại với nhau.

Upload image

Để upload một NFT image, chúng ta sẽ sử dụng dịch vụ miễn phí NFT Storage được xây dựng đặc biệt để lưu trữ dữ liệu off-chain của NFT. NFT Storage cung cấp dung lượng và băng thông miễn phí dành cho NFT trên IPFSFilecoin.

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

  1. Đăng ký một account và đăng nhập vào nft.storage.

  2. Đi tới phần Files, và nhấp lên nút Upload.

    nft.storage

  3. Một khi bạn đã upload file, bạn sẽ nhận được một CID duy nhất cho nội dung của bạn, và một URL giống như:

    https://bafyreiabag3ztnhe5pg7js4bj6sxuvkz3sdf76cjvcuqjoidvnfjz7vwrq.ipfs.dweb.link/

Tip: kiểm tra NFT.Storage Docs về thông tin của việc upload nhiều file và các API endpoint khả dụng.

Non-fungible Token contract

This repository includes an example implementation of a non-fungible token contract which uses near-contract-standards and simulation tests.

Clone NFT repository

Trong terminal của bạn chạy lệnh sau để clone NFT repo:

git clone https://github.com/near-examples/NFT

Khám phá smart contract

Source code của contract này có thể được tìm thấy tại nft/src/lib.rs. This contract contains logic which follows the NEP-171 standard (NEAR Enhancement Proposal) and the implementation of this standard which can be found here.

Lúc đầu, code có thể hơi choáng ngợp, nhưng nếu chúng ta chỉ quan tâm tới các khía cạnh của quá trình mint, chúng ta có thể chia nó thành 2 loại chính - contract struct và quá trình mint.

Contract Struct

Contract sẽ theo dõi hai phần thông tin - tokensmetadata. Đối với mục đích của hướng dẫn này, chúng ta chỉ xử lý field tokens.

#[near_bindgen]
#[derive(BorshDeserialize, BorshSerialize, PanicOnDefault)]
pub struct Contract {
tokens: NonFungibleToken,
metadata: LazyOption<NFTContractMetadata>,
}

Các token thuộc loại NonFungibleToken đến từ các tiêu chuẩn cốt lõi. Có một vài field nằm trong struct nhưng đối với mục đích của hướng dẫn này, chúng ta chỉ quan tâm đến field owner_by_id. Điều này giúp theo dõi thông tin chủ sở hữu của bất kỳ token cụ thể nào.

pub struct NonFungibleToken {
// chủ sở hữu của contract
pub owner_id: AccountId,

// theo dõi chủ sở hữu của bất kì token ID cụ thể nào.
pub owner_by_id: TreeMap<TokenId, AccountId>,

...
}

Chúng ta vừa khám phá hậu trường và nơi dữ liệu được lưu giữ, bây giờ hãy đi tiếp tới chức năng mint.

Mint

Để một token được mint, bạn sẽ cần call function nft_mint. Có ba argument được truyền vào function này:

  • token_id
  • receiver_id
  • token_metadata

Function này thực thi self.tokens.mint sẽ call tới function mint trong các tiêu chuẩn cốt lõi để tạo một record của token với người sở hữu là receiver_id.

#[payable]
pub fn nft_mint(
&mut self,
token_id: TokenId,
receiver_id: ValidAccountId,
token_metadata: TokenMetadata,
) -> Token {
self.tokens.mint(token_id, receiver_id, Some(token_metadata))
}

Việc này tạo record đó bằng cách thêm token này vào cấu trúc dữ liệu owner_by_id mà chúng ta vừa đề cập trong phần trước.

self.owner_by_id.insert(&token_id, &owner_id);

Build contract

Chạy lệnh sau trong terminal của bạn để build contract, sử dụng Rust cargo.

./build.sh

Lệnh này sẽ tạo ra WASM binary ở trong thư mục res/. File WASM này là một smart contract mà chúng ta sẽ deploy lên trên NEAR blockchain.

Tip: Nếu bạn gặp lỗi, hãy đảm bảo rằng bạn đã cài đặt Rust và đang ở trong thư mục root của ví dụ NFT này.

Test contract

Có các test được viết sẵn nằm trong smart contract mà bạn có thể chạy. Chạy câu lệnh sau trong terminal của bạn để thực thi những test đơn giản này nhằm đảm bảo contract code hoạt động tốt.

cargo test -- --nocapture

Lưu ý: những test giả lập phức tạp hơn không được thực thi trong command này, nhưng bạn có thể tìm thấy chúng tại thư mục tests/sim.

Sử dụng NFT contract

Bây giờ bạn đã build và test NFT smart contract thành công, bạn đã sẵn sàng để deploy nó và bắt đầu sử dụng nó để mint NFT.

Deploy contract

Smart contract này sẽ được deploy trên NEAR account của bạn. Bởi vì NEAR cho phép khả năng nâng cấp contract trên cùng một account, các function khởi tạo phải được xóa.

Lưu ý: Nếu bạn muốn chạy ví dụ này trên một NEAR account đã được deploy contract trước đó, vui lòng sử dụng lệnh near delete của near-cli và sau đó tạo lại nó trong Wallet. Để tạo (hoặc tạo lại) một account, vui lòng làm theo các hướng dẫn trong Test Wallet hoặc (NEAR Wallet nếu chúng ta sử dụng mainnet).

Đăng nhập vào account vừa mới tạo với near-cli bằng cách chạy câu lệnh sau trong terminal của bạn.

near login

Để làm cho hướng dẫn này dễ dàng hơn với copy/paste, chúng tôi đã set một biến môi trường cho account ID của bạn. Trong câu lệnh dưới đây, hãy thay YOUR_ACCOUNT_NAME với tên account name mà bạn mới vừa đăng nhập, bao gồm cả .testnet (hoặc .near nếu trên mainnet):

export ID=YOUR_ACCOUNT_NAME

Kiểm tra biến môi trường được cài đặt đúng hay chưa bằng cách chạy:

echo $ID

Hãy xác nhận rằng account được in ra trong terminal là chính xác. Nếu mọi thứ đều đúng, thì bây giờ bạn có thể deploy contract của bạn. Trong thư mục root của NFT project, chạy câu lệnh sau để deploy smart contract của bạn.

near deploy --wasmFile res/non_fungible_token.wasm --accountId $ID
Ví dụ về response nhận được:

Starting deployment. Account id: ex-1.testnet, node: https://rpc.testnet.near.org, helper: https://helper.testnet.near.org, file: res/non_fungible_token.wasm
Transaction Id E1AoeTjvuNbDDdNS9SqKfoWiZT95keFrRUmsB65fVZ52
To see the transaction in the transaction explorer, please open this url in your browser
https://explorer.testnet.near.org/transactions/E1AoeTjvuNbDDdNS9SqKfoWiZT95keFrRUmsB65fVZ52
Done deploying to ex-1.testnet

Lưu ý: Đối với mainnet bạn cần thêm NEAR_ENV=mainnet vào trước câu lệnh của bạn. Xem tại đây để có thêm thông tin.

Mint NFT

Một smart contract có thể có một method khởi tạo để có thể được dùng để thiết lập các state ban đầu của contract. Trong trường hợp này, chúng ta cần khởi tạo NFT contract trước khi sử dụng. Bây giờ, chúng ta sẽ khởi tạo nó với metadata mặc định.

Lưu ý: mỗi account có một vùng dữ liệu gọi là storage, để lưu các function call và transaction. Ví dụ, khi bạn khởi tạo một contract, state ban đầu được lưu trong persistent storage này.

near call $ID new_default_meta '{"owner_id": "'$ID'"}' --accountId $ID

Tip: bạn có thể tìm thêm thông tin về NFT metadata tại nomicon.io.

Sau đó, bạn có thể xem metadata bằng cách chạy lệnh view call sau:

near view $ID nft_metadata
Ví dụ về response nhận được:

{
"spec": "nft-1.0.0",
"name": "Example NEAR non-fungible token",
"symbol": "EXAMPLE",
"icon": "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 288 288'%3E%3Cg id='l' data-name='l'%3E%3Cpath d='M187.58,79.81l-30.1,44.69a3.2,3.2,0,0,0,4.75,4.2L191.86,103a1.2,1.2,0,0,1,2,.91v80.46a1.2,1.2,0,0,1-2.12.77L102.18,77.93A15.35,15.35,0,0,0,90.47,72.5H87.34A15.34,15.34,0,0,0,72,87.84V201.16A15.34,15.34,0,0,0,87.34,216.5h0a15.35,15.35,0,0,0,13.08-7.31l30.1-44.69a3.2,3.2,0,0,0-4.75-4.2L96.14,186a1.2,1.2,0,0,1-2-.91V104.61a1.2,1.2,0,0,1,2.12-.77l89.55,107.23a15.35,15.35,0,0,0,11.71,5.43h3.13A15.34,15.34,0,0,0,216,201.16V87.84A15.34,15.34,0,0,0,200.66,72.5h0A15.35,15.35,0,0,0,187.58,79.81Z'/%3E%3C/g%3E%3C/svg%3E",
"base_uri": null,
"reference": null,
"reference_hash": null
}

Bây giờ, hãy bắt đầu mint token đầu tiên! Câu lệnh sau sẽ mint một bản copy của NFT. Thay thế media url với url mà bạn đã upload lên IPFS trước đó:

near call $ID nft_mint '{"token_id": "0", "receiver_id": "'$ID'", "token_metadata": { "title": "Some Art", "description": "My NFT media", "media": "https://bafkreiabag3ztnhe5pg7js4bj6sxuvkz3sdf76cjvcuqjoidvnfjz7vwrq.ipfs.dweb.link/", "copies": 1}}' --accountId $ID --deposit 0.1
Ví dụ response nhận được:

{
"token_id": "0",
"owner_id": "dev-xxxxxx-xxxxxxx",
"metadata": {
"title": "Some Art",
"description": "My NFT media",
"media": "https://bafkreiabag3ztnhe5pg7js4bj6sxuvkz3sdf76cjvcuqjoidvnfjz7vwrq.ipfs.dweb.link/",
"media_hash": null,
"copies": 1,
"issued_at": null,
"expires_at": null,
"starts_at": null,
"updated_at": null,
"extra": null,
"reference": null,
"reference_hash": null
},
"approved_account_ids": {}
}

Để xem các token được sở hữu bởi một account, bạn có thể call NFT contract với câu lệnh near-cli sau:

near view $ID nft_tokens_for_owner '{"account_id": "'$ID'"}'
Ví dụ về response nhận được:

[
{
"token_id": "0",
"owner_id": "dev-xxxxxx-xxxxxxx",
"metadata": {
"title": "Some Art",
"description": "My NFT media",
"media": "https://bafkreiabag3ztnhe5pg7js4bj6sxuvkz3sdf76cjvcuqjoidvnfjz7vwrq.ipfs.dweb.link/",
"media_hash": null,
"copies": 1,
"issued_at": null,
"expires_at": null,
"starts_at": null,
"updated_at": null,
"extra": null,
"reference": null,
"reference_hash": null
},
"approved_account_ids": {}
}
]


Tip: sau khi bạn mint xong non-fungible token đầu tiên, bạn có thể xem nó trong Wallet của bạn:

Wallet với token


Chúc mừng! Bạn vừa mới mint NFT token đầu tiên của mình trên NEAR blockchain! 🎉

Các chú thích cuối cùng

Ví dụ cơ bản này minh họa tất cả các bước cần thiết để deploy một NFT smart contract, lưu các file media trên IPFS, và bắt đầu mint các non-fungible token của riêng bạn.

Bây giờ bạn đã quen với quy trình này, bạn có thể kiểm tra Ví dụ NFT của chúng tôi và tìm hiểu thêm về code của smart contract và cách bạn có thể chuyển các token đã mint đến các account khác. Cuối cùng, nếu bạn là người mới đến với ngôn ngữ Rust và mong muốn tiến sâu hơn nữa vào lập trình smart contract, phần Hướng dẫn nhanh của chúng tôi là một điểm khởi đầu tốt.

Chúc bạn mint thành công! 🪙

Blockcraft - Phần mở rộng thực tế

Nếu bạn muốn tìm hiểu làm thế nào để dùng Minecraft để mint NFT và copy/dán các công trình trong các thế giới khác nhau, trong khi tất cả dữ liệu đều được lưu trữ on-chain, hãy xem ngay hướng dẫn Minecraft của chúng tôi

Version cho bài viết này

Tại thời điểm viết bài, ví dụ này tương thích với các version dưới đây:

  • cargo: cargo 1.54.0 (5ae8d74b3 2021-06-22)
  • rustc: rustc 1.54.0 (a178d0322 2021-07-26)
  • near-cli: 2.1.1