Tôi từng cho rằng việc xây dựng một NFT trên Solana đồng nghĩa với việc phải vật lộn với Metaplex. Đó là con đường mà mọi hướng dẫn đều gợi ý: khởi tạo một Candy Machine, quản lý các tài khoản metadata, xoay xở với các chương trình riêng biệt chỉ để gắn tên và hình ảnh vào một token. Hóa ra giả định đó đã lỗi thời. Chương trình Token Extensions, còn được gọi là Token-2022, đã thu gọn sự phức tạp đó vào chính tài khoản mint. Giờ đây, bạn có thể tạo một NFT hoạt động đầy đủ mà không cần chạm vào chương trình metadata hay phải nạp thêm tiền cho các tài khoản bổ sung. Bạn chỉ cần bật vài flag, ghi dữ liệu trực tiếp vào tài khoản mint là xong.
Điều này thay đổi cách các nhà phát triển nên tư duy về tài sản kỹ thuật số trên Solana. Trong phát triển web truyền thống, một NFT mang lại cảm giác như một cấu trúc dữ liệu riêng biệt, thứ gì đó đòi hỏi bảng và schema riêng. Trên Solana, thực tế phẳng hơn và thanh thoát hơn. Một NFT không phải là một đối tượng đặc biệt được quản lý bởi một giao thức bên ngoài. Nó đơn giản là một tài khoản mint được cấu hình với tổng cung chính xác là một và số thập phân bằng không. Một token tiêu chuẩn cho phép bạn chia nhỏ các đơn vị vì nó có tổng cung lớn và nhiều chữ số thập phân. Một NFT khóa tổng cung ở một đơn vị duy nhất, không thể chia cắt. Mọi thứ tạo nên sự độc nhất của nó đều nằm trong các extension đi kèm với tài khoản mint cốt lõi đó.
Cách làm cũ và Cách làm mới
Trước khi có Token Extensions, stack chuẩn bao gồm chương trình SPL Token cho chính việc mint, cộng với Metaplex cho metadata, collections và đôi khi là indexing off-chain. Metadata nằm trong các tài khoản riêng biệt, được liên kết bởi các địa chỉ mà bạn phải theo dõi. Nó hoạt động được, nhưng nó làm tăng độ phức tạp của hệ thống. Nhiều tài khoản hơn đồng nghĩa với việc tốn nhiều rent hơn, nhiều đường ký (signing paths) hơn và nhiều logic phía client hơn để có được bức tranh toàn cảnh về một token.
Token Extensions thay thế sự dàn trải đó bằng cách tích hợp trực tiếp các khả năng vào trong mint. Cần tên, ký hiệu và một con trỏ tới media off-chain? Hãy bật metadata extension. Cần nhóm các token vào một collection? Hãy sử dụng Group và Member extensions. Tài khoản mint trở thành nguồn sự thật duy nhất (single source of truth). Đối với các nhà phát triển đã quen với cơ sở dữ liệu quan hệ, sự chuyển dịch này giống như việc chuyển từ kiến trúc microservices phân tán trở lại một bảng đã được chuẩn hóa với các khóa ngoại được thiết kế tốt.
Cấu trúc của một NFT dựa trên Extension
Tạo một NFT với Token Extensions đòi hỏi sự hiểu biết chính xác về những gì làm cho một token trở nên không thể thay thế (non-fungible) trên chuỗi này. Tổng cung phải bằng một. Số thập phân phải bằng không. Hai ràng buộc đó ngăn chặn việc chia nhỏ (fractionalization). Sau khi các tham số đó được thiết lập, bạn bật các extension để lưu trữ các trường bổ sung trực tiếp trên tài khoản mint.
Metadata extension giữ tên, ký hiệu và URI. URI đó trỏ đến một tệp JSON, thường được lưu trữ trên bộ lưu trữ phi tập trung hoặc một máy chủ web tiêu chuẩn, mô tả hình ảnh, thuộc tính và các đặc điểm (traits). Không có tài khoản metadata riêng biệt để cần phải tìm kiếm và giải tuần tự hóa (deserialize). Dữ liệu nằm ngay trên chính mint, điều đó có nghĩa là các explorer, ví và phần mềm client có thể đọc được danh tính cốt lõi của token chỉ bằng cách kiểm tra một tài khoản duy nhất.
Tôi đã trực tiếp thử nghiệm điều này trên devnet. Tôi đã tạo một mint mới với metadata extension được bật, sau đó ghi trực tiếp tên và ký hiệu vào trạng thái (state) của mint. Giao dịch đã thành công và kết quả xuất hiện ngay lập tức trên Solana Explorer. Không cần tài khoản thứ hai để nạp tiền hay định vị. Sự đơn giản này gần như gây ngỡ ngàng sau nhiều tuần làm việc với metadata của Metaplex vốn yêu cầu nhiều tài khoản.
Xây dựng Collections giống như các hàng trong cơ sở dữ liệu
Collections là bước logic tiếp theo. Trong mô hình cũ, việc nhóm các NFT thường có nghĩa là phải dựa vào Metaplex Certified Collections hoặc các registry off-chain. Token Extensions giới thiệu hai nguyên ngữ (primitives) cụ thể: Group extension và Member extension.
Đây là cách luồng logic hoạt động. Bạn tạo một mint duy nhất đóng vai trò là tiêu đề của collection (collection header) và bật Group extension trên đó. Sau đó, đối với mỗi NFT riêng lẻ trong collection, bạn tạo một mint với Member extension được bật. Mỗi member mint lưu trữ một con trỏ trỏ ngược lại địa chỉ của collection mint. Mối quan hệ này hoạt động chính xác giống như một khóa ngoại trong cơ sở dữ liệu quan hệ. Hàng collection chỉ tồn tại một lần, và mỗi hàng thành viên sẽ tham chiếu đến nó mà không cần sao chép danh tính của collection.
Tôi đã xây dựng một collection thử nghiệm nhỏ theo cách này trên devnet. Collection mint chính mang flag group. Các token riêng lẻ mang flag member và tham chiếu đến địa chỉ cha. Việc truy vấn chuỗi cho tôi một cấu trúc sạch sẽ và có thể duyệt qua (traversable). Không cần đến một indexer bên thứ ba để đoán xem các token có thuộc về nhau hay không. Mối quan hệ này là rõ ràng và nằm ngay trên chuỗi (on-chain).
Open Schema and On-Chain Experimentation
One detail that stands out is the open schema of the metadata extension. Older standards often enforce a fixed field list. If you wanted to store something non-standard on-chain, you were stuck putting it in off-chain JSON or hacking around rigid account layouts.
Token Extensions takes a different approach. Because the metadata extension accepts custom fields, I was able to add a rarity attribute directly to the mint account. I wrote the field, sent the transaction, and refreshed the Solana Explorer. The rarity value appeared instantly alongside the name and symbol. For game developers or anyone building dynamic assets, this flexibility matters. You can surface critical traits on-chain without needing an external verifier to parse JSON.
The Off-Chain Gap: URIs and Caching
For all the elegance of on-chain storage, one lesson cut through clearly: identity still lives off-chain. The mint does not store your image. It stores a URI. When I updated that URI and committed the change to devnet, the chain reflected the new pointer immediately. Block explorers showed the updated link without delay.
But my wallet lagged. It continued displaying the old image for minutes, stubbornly serving a cached version while the underlying data on-chain had already changed. This is a practical reality developers must plan for. The Solana ledger is fast. Confirmation times are short. Yet the visual layer that users interact with depends on HTTP caches, CDN propagation, and wallet-specific refresh intervals. If you build a dynamic NFT that changes based on real-world events, you cannot assume the user sees the change the moment the transaction lands. You need cache-busting strategies, versioning in your URI paths, or explicit refresh triggers in your frontend.
What Comes Next
My devnet experiments have laid the groundwork for a more dynamic project. The next step is a collection
