MỚI: Helius mua lại Light Protocol
phát triển hợp đồng thông minh Solana với gill
Blog/Phát triển

Cách xây dựng ứng dụng Solana với Gill

Đang xây dựng @useDecal, trước đây tại @SolanaFndnNick Frostbutter trên XNick Frostbutter trên LinkedIn
Đọc trong 9 phút

Gill là thư viện công cụ mới nhất dành cho nhà phát triển Solana dựa trên JavaScript/TypeScript. Ban đầu, thư viện này được Nick Frostbutter, đồng sáng lập Decal, phát triển khi còn làm việc trong nhóm Quan hệ Nhà phát triển của Solana Foundation. gill hướng đến việc cải thiện đáng kể trải nghiệm phát triển cho các ứng dụng dựa trên JavaScript.

Gill cung cấp cả các lớp trừu tượng có định hướng nhẹ để tăng năng suất phát triển lẫn các thành phần nguyên thủy cấp thấp, giúp nhà phát triển linh hoạt lựa chọn phương pháp phù hợp.

Các lớp trừu tượng gọn nhẹ giúp giảm đáng kể độ phức tạp và mã soạn sẵn cần thiết để thực hiện những tương tác phổ biến với Solana. Trong khi đó, các thành phần nguyên thủy cấp thấp cung cấp những "lối thoát" khi nhà phát triển cần (hoặc muốn) kiểm soát logic ứng dụng chi tiết hơn.

Bài viết này sẽ trình bày kiến thức cơ bản về "thư viện gill", những thành phần có trong thư viện, cách bắt đầu với gill và sự khác biệt so với @solana/kit (trước đây gọi là "web3.js v2").

Gill là gì?

Gill là một thư viện TypeScript hiện đại để phát triển ứng dụng Solana trên mọi môi trường dựa trên JavaScript, từ trình duyệt và máy chủ đến thiết bị di động.

Thư viện gill dành cho nhà phát triển Solana ở mọi cấp độ kinh nghiệm, từ người mới bắt đầu đến chuyên gia. Bằng cách cung cấp các lớp trừu tượng cấp cao và thành phần nguyên thủy cấp thấp trong cùng một gói, nhà phát triển có thể dễ dàng sử dụng chức năng nâng cao hơn khi cần hoặc khi các lớp trừu tượng chưa hỗ trợ. 

Điểm tuyệt vời nhất? 

Gill hỗ trợ tree-shaking hoàn toàn, vì vậy trình đóng gói sẽ tự động loại bỏ mọi thành phần nguyên thủy hoặc lớp trừu tượng không được dùng trong cơ sở mã.

Mục tiêu chính của Gill là cải thiện trải nghiệm nhà phát triển bằng cách đơn giản hóa các tác vụ phát triển Solana phổ biến và loại bỏ mã soạn sẵn mà không làm mất khả năng thao tác ở cấp thấp hơn khi nhà phát triển muốn hoặc cần. Nhà phát triển không nên bị giới hạn ở lớp trừu tượng cấp cao hoặc thành phần nguyên thủy cấp thấp. Họ có thể dễ dàng chọn một trong hai khi phù hợp với nhu cầu.

Cài đặt Gill

Có thể cài đặt Gill vào mọi dự án dựa trên JavaScript hoặc TypeScript, bao gồm NodeJS/Bun, trình duyệt, React Native và hầu hết mọi môi trường JavaScript khác.

Mã
npm install gill

Thư viện gill hỗ trợ TypeScript rất tốt và có thể hoạt động ngay trong hầu hết ứng dụng. Tuy nhiên, cấu hình của từng dự án có thể cần được tinh chỉnh để hoạt động tốt hơn với gill. Hãy xem tài liệu để biết thêm thông tin về khả năng hỗ trợ TypeScript trong gill.

Gill và @solana/kit

Thư viện gill được xây dựng trực tiếp trên @solana/kit, bộ thành phần nguyên thủy JavaScript cấp thấp mới do Anza phát triển để thay thế @solana/web3.js cũ với hiệu năng cao hơn.

Vì Kit chỉ cung cấp các thành phần nguyên thủy cấp thấp này, nhà phát triển buộc phải tự tạo mọi thứ theo cách thủ công, khiến ứng dụng phình to với nhiều mã soạn sẵn dài dòng.

Và đó là lúc gill xuất hiện.

Gill cung cấp cả các thành phần nguyên thủy cấp thấp giống Kit lẫn các lớp trừu tượng có định hướng nhẹ để đơn giản hóa những tác vụ phổ biến, tất cả thông qua một giao diện tương thích duy nhất. Nhờ đơn giản hóa toàn diện với gill, nhà phát triển có thể dành nhiều thời gian hơn cho logic nghiệp vụ của ứng dụng và ít thời gian hơn cho mã soạn sẵn dài dòng.

Ví dụ mã Gill và Kit

Các đoạn mã sau minh họa cách đơn giản hóa mã mà vẫn giữ nguyên chức năng (và có thể bổ sung thêm chức năng). Gần như mọi ứng dụng đều cần thực hiện hai tác vụ: thiết lập kết nối với blockchain và tạo giao dịch.

Cách tạo kết nối với blockchain bằng @solana/kit như sau:

Mã
import {
  devnet,
  createSolanaRpc,
  createSolanaRpcSubscriptions,
  sendAndConfirmTransactionFactory,
} from "@solana/kit";

const rpc = createSolanaRpc(devnet("https://api.devnet.solana.com"));

const rpcSubscriptions = createSolanaRpcSubscriptions(
  devnet("wss://api.devnet.solana.com"),
);

const sendAndConfirmTransaction = sendAndConfirmTransactionFactory({
  rpc,
  rpcSubscriptions,
});

Có thể thực hiện cùng logic đó đơn giản hơn bằng hàm createSolanaClient của gill:

Mã
import { createSolanaClient } from "gill";

const { rpc, rpcSubscriptions, sendAndConfirmTransaction } = createSolanaClient({
  urlOrMoniker: "devnet",
});

Giờ đây, bạn có thể gửi các yêu cầu RPC đơn giản bằng đối tượng rpc được tạo bằng một trong hai thư viện trong các ví dụ trên:

Mã
// get the latest blockhash from your RPC provider
const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();

Cách tạo một giao dịch đơn giản có chứa chỉ thị memo với các tối ưu hóa cơ bản (sử dụng chỉ thị ngân sách điện toán) trong @solana/kit như sau:

Mã
import {
  pipe,
  createTransactionMessage,
  setTransactionMessageFeePayerSigner,
  appendTransactionMessageInstructions,
  setTransactionMessageLifetimeUsingBlockhash,
} from "@solana/kit";
import { getAddMemoInstruction } from "@solana-program/memo";
import {
  getSetComputeUnitLimitInstruction,
  getSetComputeUnitPriceInstruction,
} from "@solana-program/compute-budget";

const transaction = pipe(
  createTransactionMessage({ version: "legacy" }),
  (tx) => setTransactionMessageFeePayerSigner(signer, tx),
  (tx) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),
  (tx) =>
    appendTransactionMessageInstructions(
      [
        getAddMemoInstruction({
          memo: "gm world!",
        }),
        getSetComputeUnitLimitInstruction({ units: 5000 }),
        getSetComputeUnitPriceInstruction({ microLamports: 1000 }),
      ],
      tx,
    ),
);

Có thể đơn giản hóa đáng kể cùng logic đó bằng gill như sau:

Mã
import { createTransaction } from "gill";
import { getAddMemoInstruction } from "gill/programs";

const transaction = createTransaction({
  version: "legacy",
  feePayer: signer,
  instructions: [
    getAddMemoInstruction({
      memo: "gm world!",
    }),
  ],
  latestBlockhash,
  computeUnitLimit: 5000,
  computeUnitPrice: 1000,
});

Để xem phần so sánh toàn diện hơn giữa hai thư viện này, hãy đọc tài liệu gill về gill và @solana/kit.

Quy trình di chuyển từ Kit sang Gill gồm những gì?

Với mọi ứng dụng đang dùng thư viện @solana/kit, quy trình chuyển sang gói gill rất đơn giản:

  1. Cài đặt gill
  2. Thay thế mọi lệnh import @solana/kit bằng gill
  3. Gỡ cài đặt @solana/kit

Vì gill cũng tích hợp trực tiếp các máy khách Solana Program Library (SPL) phổ biến nhất, bạn cũng có thể thay thế lệnh import các gói đó bằng gill. Gill tích hợp các máy khách SPL sau, có thể truy cập trực tiếp từ đường dẫn import gill/programs:

  • @solana-program/system
  • @solana-program/memo
  • @solana-program/compute-budget
  • @solana-program/address-lookup-table
  • @solana-program/token-2022 (xem lưu ý bên dưới về máy khách chương trình token)

Để sử dụng một gói gill duy nhất cho các máy khách chương trình SPL này:

  1. Thay thế lệnh import các gói @solana-program/* nêu trên bằng gill/programs
  2. Gỡ cài đặt các gói @solana-program/* nêu trên.

Sau khi cập nhật các lệnh import, ứng dụng có thể bắt đầu sử dụng thư viện "gill core" ngay lập tức. Giờ đây, bạn có thể dễ dàng tái cấu trúc để loại bỏ mã soạn sẵn dài dòng của Kit (như tạo kết nối blockchain và giao dịch) bằng bất kỳ lớp trừu tượng gill nào có sẵn.

Gill bao gồm những thành phần nào?

Có thể chia thư viện gill thành một số thành phần chính:

  • Chức năng cốt lõi (còn gọi là "gill core")
  • Trình trợ giúp dành riêng cho môi trường thực thi máy chủ (như NodeJS và Bun)
  • Máy khách chương trình
  • Trình dựng giao dịch
  • Chế độ gỡ lỗi

Các hàm trợ giúp Node.js

Gói gill gồm một số tiện ích dành riêng cho môi trường thực thi máy chủ JavaScript. Dù được cung cấp trong gói gill, chúng có đường dẫn import riêng để cải thiện khả năng tree-shaking. Các tiện ích này cho phép dễ dàng tải và lưu cặp khóa vào tệp hoặc biến ENV.

Mã
import { ... } from "gill/node"

Để dễ dàng tải tệp cặp khóa từ hệ thống tệp cục bộ (chẳng hạn như cặp khóa Solana CLI):

Mã
import { loadKeypairSignerFromFile } from "gill/node";

// default file path: ~/.config/solana/id.json
const signer = await loadKeypairSignerFromFile();
console.log("address:", signer.address);

Bạn cũng có thể tải cặp khóa được mã hóa base58 từ một biến ENV:

Mã
import { loadKeypairSignerFromEnvironmentBase58 } from "gill/node";

// loads signer from base58 keypair stored at `process.env[variableName]`
const signer = await loadKeypairSignerFromEnvironmentBase58(variableName);
console.log("address:", signer.address);

Trình dựng giao dịch

Để đơn giản hóa việc tạo các giao dịch phổ biến thường tương tác với nhiều chương trình cùng lúc, gill cung cấp nhiều "trình dựng giao dịch" giúp dễ dàng tập hợp các giao dịch sẵn sàng để ký cho những tác vụ này.

Vì mỗi trình dựng giao dịch chỉ tập trung vào một tác vụ, nó có thể dễ dàng trừu tượng hóa nhiều phần mã soạn sẵn, đồng thời giúp tạo giao dịch được tối ưu hóa.

Một số trình dựng giao dịch do gill cung cấp gồm:

  • buildCreateTokenTransaction - tạo token kèm siêu dữ liệu
  • buildMintTokensTransaction - đúc token vào ví đích
  • buildTransferTokensTransaction - chuyển token đến ví đích

Mỗi trình dựng giao dịch đều đi kèm một "trình dựng chỉ thị" để tăng tính linh hoạt cho nhà phát triển khi dùng các lớp trừu tượng của gill.

Chế độ gỡ lỗi

Trong gill, bạn có thể bật "chế độ gỡ lỗi" để tự động ghi nhật ký thông tin bổ sung, giúp khắc phục sự cố giao dịch.

Chế độ gỡ lỗi bị tắt theo mặc định để giảm thiểu nhật ký bổ sung từ ứng dụng. Với bộ điều khiển linh hoạt, bạn có thể bật chế độ gỡ lỗi từ những nơi mã thường chạy nhất, bao gồm ngay trong mã, backend NodeJS, hàm serverless và cả bảng điều khiển của trình duyệt web.

Để bật chế độ gỡ lỗi, hãy đặt bất kỳ mục nào sau đây thành true hoặc 1:

  • process.env.GILL_DEBUG
  • global.__GILL_DEBUG__
  • window.__GILL_DEBUG__ (ví dụ: trong bảng điều khiển của trình duyệt web)
  • hoặc đặt thủ công bất kỳ cấp độ nhật ký gỡ lỗi nào (xem tài liệu)

Hãy xem tài liệu về Chế độ gỡ lỗi của gill để biết thêm thông tin.

Các công cụ bổ trợ dành cho nhà phát triển xây dựng với Gill

@gillsdk/react

Ngay trong thư viện gill còn có một gói khác là @gillsdk/react, tập hợp các React hook được thiết kế để cải thiện đáng kể trải nghiệm phát triển ứng dụng frontend dựa trên React. Gói này cũng được xây dựng trên TanStack Query, một thư viện phản ứng phổ biến, nên các ứng dụng hiện có có thể sử dụng dễ dàng hơn.

Gói @gillsdk/react vẫn đang ở giai đoạn đầu và được tích cực phát triển. Hiện tại, gói cung cấp một số React hook hữu ích cho ứng dụng Solana:

  • useAccount - lấy thông tin tài khoản của một địa chỉ
  • useBalance - lấy số dư tài khoản (bằng lamport)
  • useLatestBlockhash - lấy blockhash mới nhất
  • useSignatureStatuses - lấy trạng thái chữ ký
  • useProgramAccounts - lấy các tài khoản chương trình (GPA)
  • useTokenMint - lấy tài khoản Mint của token đã giải mã
  • useTokenAccount - lấy tài khoản token cho một Mint và chủ sở hữu cụ thể (hoặc ATA)

Codama

Codama là công cụ cho phép nhà phát triển dùng IDL của một chương trình Solana để tạo thư viện máy khách (ví dụ: JavaScript, Rust) cho các ứng dụng khác sử dụng. Codama xử lý mọi sự phức tạp trong việc chuyển các chỉ thị Solana thành một IDL, một tệp cấu hình và một hàm import.

Gill và Codama dễ dàng tích hợp với nhau thông qua hàm createCodamaConfig của gill. Người duy trì gill cũng đang tích cực cải thiện hơn nữa khả năng tích hợp gill<>Codama, bao gồm cả hỗ trợ trực tiếp trong Codama CLI!

Theo mặc định, các máy khách chương trình TypeScript do Codama tạo sẽ dùng @solana/kit, nhưng có thể dễ dàng cập nhật điều này trong tệp cấu hình Codama của chương trình Solana. Hàm createCodamaConfig giúp việc nâng cấp cấu hình Codama để sử dụng gill trở nên rất đơn giản.

Sau đây là một tệp codama.js mẫu sẽ tạo máy khách TypeScript cho chương trình Solana sử dụng gill:

Mã
import { createCodamaConfig } from "gill";

export default createCodamaConfig({
  idl: "program/idl.json",
  clientJs: "clients/js/src/generated",
});

Bạn có thể tìm thấy hướng dẫn đầy đủ trong tài liệu gill về cách tạo máy khách chương trình Solana bằng Codama.

Tương lai của Gill

Tương lai của thư viện gill rất hứa hẹn và vẫn còn nhiều việc cần làm. Trang tài liệu chính thức của gill vừa ra mắt và thư viện đang tiến gần đến 20.000 lượt tải xuống mỗi tháng.

Bạn có thể tìm thêm thông tin về những nội dung hiện có trong lộ trình của gill trên trang GitHub Projects. Hiện tại, danh sách rút gọn gồm:

  • Hỗ trợ trực tiếp đặc tả Solana Pay
  • Tích hợp nguyên bản đặc tả API Digital Assets Standard (DAS)
  • Cải thiện khả năng hỗ trợ token dựa trên Token Extension
  • Cải thiện khả năng hỗ trợ Address Lookup Tables
  • Tài liệu toàn diện hơn

Gói @gillsdk/react được tích hợp trong thư viện gill vẫn đang ở giai đoạn đầu (với chín React hook khác nhau). Gói này tiếp tục được phát triển để giúp nhà phát triển dễ dàng bổ sung khả năng phản ứng vào các ứng dụng dựa trên React, bao gồm hỗ trợ mọi phương thức Solana RPC phổ biến và tích hợp chặt chẽ hơn với wallet-ui.

Thông tin thú vị: Có kế hoạch tích hợp trực tiếp gill vào framework Anchor, giúp nhà phát triển dễ dàng tận dụng các tối ưu hóa và cải tiến trải nghiệm phát triển của gill trong ứng dụng. Biết đâu gill sẽ trở thành lựa chọn mặc định trong Anchor v2. :shhh:

Cách đóng góp cho Gill

Thư viện gill là mã nguồn mở (giấy phép MIT) và luôn chào đón người đóng góp! Nếu muốn đóng góp cho thư viện, hãy xem các issue đang mở và cân nhắc tự xử lý một issue.

Nếu muốn đề xuất tính năng mới hoặc cải tiến cho thư viện, trước tiên hãy mở một issue để bắt đầu thảo luận với những người duy trì trước khi viết mã cho PR.

Tài nguyên bổ sung

Tìm thêm thông tin và tài nguyên về gill tại các liên kết sau:

Đăng ký nhận tin từ Helius

Luôn cập nhật những thông tin mới nhất về phát triển Solana và nhận thông báo khi chúng tôi đăng bài